Học Viện Liên Ngân Hà

Dự Án Hệ Thống Phân Tích Bảng Điểm Học Viện Thiên Hà

Thời gian dự kiến: 300 phút (Đây là một nhiệm vụ quan trọng, hãy kiên nhẫn!)

1. Mở Đầu: Tiên Đoán Tương Lai Các Học Giả Vũ Trụ

Chào mừng các bạn, những kỹ sư dữ liệu tương lai của Học Viện Thiên Hà!

Sau những chuyến du hành khám phá vũ trụ tri thức của Python, từ những viên gạch đầu tiên của String, List, cho đến các kho tàng thông tin thông minh như Dictionary và Set, đã đến lúc chúng ta áp dụng tất cả những gì đã học vào một nhiệm vụ quan trọng: phân tích bảng điểm và tiên đoán tiềm năng đại học của các học giả vũ trụ!

Hãy hình dung, bạn là một nhà khoa học dữ liệu tại Học Viện Sao Kim, nơi các học sinh từ khắp các thiên hà đổ về. Hàng ngàn hồ sơ điểm số được gửi về mỗi kỳ, và nhiệm vụ của bạn là không chỉ tính toán điểm trung bình mà còn phải đánh giá năng lực học tập và thậm chí là dự đoán khả năng thành công trong các kỳ thi tuyển sinh vào các Đại học Liên Hành Tinh danh giá (như Đại học Sao Hỏa, Đại học Ngân Hà…).

Nghe có vẻ phức tạp, phải không? Nhưng đừng lo, với Python và các cấu trúc dữ liệu mà chúng ta đã thuần thục, bạn sẽ biến khối dữ liệu khổng lồ này thành những thông tin hữu ích chỉ trong chớp mắt. Dự án này sẽ là cơ hội để bạn:

• Vận dụng hàm: Tạo ra các “module chức năng” tinh vi để xử lý từng bước của quá trình phân tích.

• Thao tác String: “Giải mã” các chuỗi dữ liệu đầu vào phức tạp.

• Sử dụng List, Tuple, Dictionary: Sắp xếp, lưu trữ và truy cập thông tin bảng điểm một cách hiệu quả nhất.

• Làm việc với File: Đọc dữ liệu từ “hồ sơ mật” và ghi kết quả “tiên đoán” ra thành báo cáo.

Bạn đã sẵn sàng trở thành người định hướng tương lai cho các học giả vũ trụ chưa? Hãy cùng bắt đầu “nhiệm vụ” này!

2. Lý Thuyết & Khái Niệm: Các Cấu Trúc Dữ Liệu Tinh Vi Cho Phân Tích

Dự án này là sự tổng hợp của nhiều kiến thức đã học. Chúng ta sẽ tập trung vào việc áp dụng chúng một cách linh hoạt.

2.1. String – Giải Mã Hồ Sơ Học Sinh

Dữ liệu bảng điểm sẽ được cung cấp dưới dạng văn bản (.txt). Bạn cần sử dụng các phương thức của String như split(), strip() để phân tách và làm sạch dữ liệu từ mỗi dòng.

• split(): Tách chuỗi thành List các chuỗi con dựa trên một dấu phân cách (ví dụ: dấu phẩy, dấu chấm phẩy, khoảng trắng).

• strip(): Loại bỏ khoảng trắng thừa ở đầu và cuối chuỗi.

Ví dụ: Nếu một dòng điểm là “Toán: 8,7,9,10; Lý: 7,8,7,9”, bạn cần split(‘;’) để tách từng môn, sau đó split(‘:’) để lấy tên môn và chuỗi điểm, và cuối cùng split(‘,’) để tách các điểm thành phần.

2.2. List – Lưu Trữ Dòng Điểm và Kết Quả Tạm Thời

List sẽ là nơi lý tưởng để lưu trữ tạm thời các điểm thành phần của một môn, danh sách các môn học, hoặc danh sách các học sinh.

• append(): Thêm phần tử vào cuối List.

• Duyệt List bằng vòng lặp for.

• Truy cập phần tử bằng chỉ mục (index).

2.3. Dictionary – Hồ Sơ Học Sinh Toàn Diện & Kết Quả Dự Đoán

Đây là cấu trúc dữ liệu quan trọng nhất cho dự án này. Dictionary sẽ giúp bạn:

• Lưu trữ điểm trung bình của từng môn cho mỗi học sinh (khóa là tên học sinh, giá trị là Dictionary khác chứa điểm các môn).

• Lưu trữ kết quả xếp loại học lực.

• Lưu trữ kết quả dự đoán thi đại học theo từng khối.

Cấu trúc dự kiến:

# Ví dụ về cách lưu trữ dữ liệu điểm
student_grades = {
    ‘Nguyen Hai Nam’: {
        ‘Toan’: [8, 7, 9, 10],
        ‘Ly’: [7, 8, 7, 9],
        # … các môn khác
    },
    ‘Tran Thi An’: {
        ‘Toan’: [9, 9, 8, 10],
        # …
    }
}

# Ví dụ về cách lưu trữ điểm trung bình và xếp loại
student_final_scores = {
    ‘Nguyen Hai Nam’: {
        ‘DTB_Toan’: 8.5,
        ‘DTB_Ly’: 7.75,
        ‘DTB_TongKet’: 8.2,
        ‘XepLoai’: ‘Giỏi’,
        ‘DuDoan_DH’: {
            ‘A’: ‘Loai 1’,
            ‘A1’: ‘Loai 2’,
            # …
        }
    },
    # … các học sinh khác
}

Bạn sẽ sử dụng các thao tác với Dictionary như:

• Truy cập giá trị bằng khóa.

• Sử dụng get() để tránh lỗi khi khóa không tồn tại.

• Duyệt qua các cặp khóa-giá trị bằng items().

2.4. File Handling – Truy Xuất Thông Tin Mật & Ghi Báo Cáo

Bạn sẽ cần đọc dữ liệu từ tệp diem_chitiet.txt (đầu vào) và ghi kết quả phân tích ra một tệp mới (đầu ra).

• open(): Mở tệp để đọc (‘r’) hoặc ghi (‘w’).

• readline() hoặc vòng lặp for để đọc từng dòng.

• write(): Ghi dữ liệu vào tệp.

• Đảm bảo đóng tệp sau khi sử dụng (close() hoặc dùng with open(…) as f:).

2.5. Hàm (Functions) – Xây Dựng Các Module Phân Tích

Để chương trình có cấu trúc rõ ràng và dễ bảo trì, bạn sẽ chia nhỏ bài toán lớn thành các hàm con:

• tinhdiem_trungbinh(): Hàm này sẽ đọc file, tính toán điểm trung bình cho từng môn của mỗi học sinh và trả về một cấu trúc dữ liệu (có thể là Dictionary lồng Dictionary) chứa tất cả thông tin này.

• xeploai_hocsinh(): Hàm này nhận dữ liệu điểm trung bình tổng kết, sau đó áp dụng các tiêu chí để xếp loại học lực (Trung bình, Trung bình Khá, Khá, Giỏi).

• xeploai_thidaihoc_hocsinh(): Hàm này nhận dữ liệu điểm trung bình của từng môn, sau đó áp dụng các tiêu chí khối thi để dự đoán xếp loại thi đại học (Loại 1, Loại 2, Loại 3, Loại 4).

• main(): Hàm chính để điều phối toàn bộ chương trình, gọi các hàm trên và xử lý việc đọc/ghi file.

2.6. Tuple – Đóng Gói Dữ Liệu Không Thay Đổi (Nếu cần)

Mặc dù Dictionary và List là chính, bạn có thể sử dụng Tuple để lưu trữ các bộ dữ liệu cố định không thay đổi, ví dụ: các tỷ lệ phần trăm điểm thành phần cho từng loại môn học. Điều này giúp code an toàn và dễ đọc hơn.

# Tỷ lệ điểm thành phần cho môn tự nhiên (Miệng, 15 phút, 1 tiết, Cuối kỳ)
TY_LE_TU_NHIEN = (0.05, 0.10, 0.15, 0.70)
# Tỷ lệ điểm thành phần cho môn xã hội (Chuyên cần, Bài luận, 1 tiết, 2 tiết, Cuối kỳ)
TY_LE_XA_HOI = (0.05, 0.10, 0.10, 0.15, 0.60)

(Tham khảo thêm: [Bài 10.docx] và [Tuples.pdf] để hiểu về Tuple.)

3. Thực Hành & Vận Dụng: “Code” Hệ Thống Phân Tích

Chúng ta sẽ xây dựng các hàm theo từng bước. Hãy sẵn sàng cho hành trình “lập trình” đầy thử thách này!

3.1. Thiết lập môi trường:

• Tạo một file Python mới, ví dụ: tinhtoan_diemtongket.py hoặc sử dụng Google Colab.

• Đảm bảo bạn có tệp diem_chitiet.txt mẫu trong cùng thư mục (hoặc biết đường dẫn đến nó).

3.2. Hàm tinhdiem_trungbinh(file_path)

Mục tiêu: Đọc dữ liệu từ file và tính điểm trung bình cho từng môn của mỗi học sinh.

• Input: file_path (đường dẫn đến file diem_chitiet.txt).

• Output: Một Dictionary chứa toàn bộ điểm trung bình của từng môn cho mỗi học sinh. Ví dụ: {‘Nguyen Hai Nam’: {‘Toan’: 8.5, ‘Ly’: 7.75, …}}.

def tinhdiem_trungbinh(file_path):
    “””
    Tính toán toàn bộ điểm trung bình của sinh viên theo từng môn học từ file bảng điểm chi tiết.
    Args:
        file_path (str): Đường dẫn đến file “diem_chitiet.txt”.
    Returns:

dict: Dictionary chứa điểm trung bình của từng môn cho mỗi học sinh.
              Ví dụ: {‘Nguyen Hai Nam’: {‘Toan’: 8.5, ‘Ly’: 7.75, …}}
    “””
    hocsinh_diem_tb = {}
   
    # Định nghĩa tỷ lệ điểm cho môn tự nhiên và xã hội
    TY_LE_TU_NHIEN = (0.05, 0.10, 0.15, 0.70) # Miệng, 15′, 1 tiết, Cuối kỳ
    TY_LE_XA_HOI = (0.05, 0.10, 0.10, 0.15, 0.60) # Chuyên cần, Bài luận, 1 tiết, 2 tiết, Cuối kỳ

    # Các môn học thuộc khối tự nhiên và xã hội
    MON_TU_NHIEN = [‘Toan’, ‘Ly’, ‘Hoa’, ‘Sinh’]
    MON_XA_HOI = [‘Van’, ‘Anh’, ‘Su’, ‘Dia’]

    try:
        with open(file_path, ‘r’, encoding=’utf-8′) as f:
            lines = f.readlines()
            if not lines:
                print(“File rỗng hoặc không có dữ liệu.”)
                return hocsinh_diem_tb
           
            # Bỏ qua dòng tiêu đề
            header = lines[0].strip().split(‘;’)
           
            for line in lines[1:]: # Bắt đầu từ dòng thứ 2 (dữ liệu học sinh)
                line = line.strip()
                if not line: # Bỏ qua dòng trống
                    continue

                parts = line.split(‘;’)
                ma_hs = parts[0].strip() # Mã học sinh
               
                diem_mon_hoc = {}
                # Duyệt qua từng môn học từ header để lấy điểm tương ứng
                for i in range(1, len(header)):
                    mon_hoc_raw = header[i].strip()
                    mon_hoc_name = mon_hoc_raw.split(‘:’)[0].strip() # Lấy tên môn học
                   
                    # Tìm chuỗi điểm cho môn học hiện tại (ví dụ: “Toan:8,7,9,10”)
                    # Cách tiếp cận này cần điều chỉnh nếu format phức tạp hơn
                    # Hiện tại, giả định các điểm môn học nối tiếp nhau theo thứ tự header
                   
                    # Tìm chuỗi điểm tương ứng với môn học từ `parts`
                    diem_raw = parts[i].split(‘:’)[-1].strip() # Lấy phần điểm sau dấu ‘:’
                    diem_thanh_phan_str = diem_raw.split(‘,’)
                    diem_thanh_phan = [float(d) for d in diem_thanh_phan_str]

                    diem_tb_mon = 0.0
                    if mon_hoc_name in MON_TU_NHIEN:
                        # Kiểm tra đủ số lượng điểm thành phần
                        if len(diem_thanh_phan) == len(TY_LE_TU_NHIEN):
                            for idx, diem in enumerate(diem_thanh_phan):
                                diem_tb_mon += diem * TY_LE_TU_NHIEN[idx]
                        else:
                            print(f”Cảnh báo: Môn {mon_hoc_name} của {ma_hs} không đủ điểm thành phần tự nhiên.”)
                            diem_tb_mon = 0.0 # Hoặc xử lý lỗi khác
                    elif mon_hoc_name in MON_XA_HOI:
                        if len(diem_thanh_phan) == len(TY_LE_XA_HOI):
                            for idx, diem in enumerate(diem_thanh_phan):
                                diem_tb_mon += diem * TY_LE_XA_HOI[idx]
                        else:
                            print(f”Cảnh báo: Môn {mon_hoc_name} của {ma_hs} không đủ điểm thành phần xã hội.”)
                            diem_tb_mon = 0.0 # Hoặc xử lý lỗi khác
                    else:
                        print(f”Cảnh báo: Môn {mon_hoc_name} không xác định loại môn.”)
                        diem_tb_mon = 0.0

                    diem_mon_hoc[mon_hoc_name] = round(diem_tb_mon, 2) # Làm tròn 2 chữ số thập phân
               
                hocsinh_diem_tb[ma_hs] = diem_mon_hoc
               
    except FileNotFoundError:
        print(f”Lỗi: Không tìm thấy file ‘{file_path}'”)
    except Exception as e:
        print(f”Đã xảy ra lỗi khi đọc file: {e}”)
   
    return hocsinh_diem_tb

# Ví dụ về định dạng file diem_chitiet.txt để hàm này hoạt động:
# Mã HS;Toan:8,7,9,10;Ly:7,8,7,9;Hoa:6,7,8,9;Sinh:7,7,8,8;Van:8,8,7,9,9;Anh:9,9,9,8,10;Su:7,6,7,8,7;Dia:8,8,8,7,9
# HS001;Toan:8,7,9,10;Ly:7,8,7,9;Hoa:6,7,8,9;Sinh:7,7,8,8;Van:8,8,7,9,9;Anh:9,9,9,8,10;Su:7,6,7,8,7;Dia:8,8,8,7,9
# HS002;Toan:7,6,8,9;Ly:6,7,6,8;Hoa:7,6,7,8;Sinh:6,6,7,7;Van:7,7,6,8,8;Anh:8,8,8,7,9;Su:6,5,6,7,6;Dia:7,7,7,6,8
# (Lưu ý: Format này cần được chỉnh sửa để khớp hoàn toàn với mô tả “Mỗi môn học tự nhiên có 4 đầu điểm… mỗi môn học xã hội có 5 đầu điểm… Các điểm thành phần của 1 môn được phân cách bằng dấu phẩy, các môn được phân cách bằng dấu chấm phẩy.”
# Hiện tại, header chỉ là tên môn, cần có cả tên môn và cấu trúc điểm. Dòng đầu tiên trong file phải chứa đầy đủ tiêu đề các cột như “Mã HS, Toán , Lý, Hóa, Sinh, Văn, Anh, Sử, Địa” hoặc tương tự để phân tách đúng.)

# Để đơn giản, hãy tạo một file diem_chitiet.txt mẫu theo cấu trúc dự kiến trong hướng dẫn:
“””
Mã HS;Toán;Lý;Hóa;Sinh;Văn;Anh;Sử;Địa
HS001;8,7,9,10;7,8,7,9;6,7,8,9;7,7,8,8;8,8,7,9,9;9,9,9,8,10;7,6,7,8,7;8,8,8,7,9
HS002;7,6,8,9;6,7,6,8;7,6,7,8;6,6,7,7;7,7,6,8,8;8,8,8,7,9;6,5,6,7,6;7,7,7,6,8
HS003;9,8,9,10;8,9,8,10;7,8,7,9;8,8,9,9;9,9,8,10,10;10,10,9,9,10;8,7,8,9,8;9,9,9,8,10
“””
# Lưu ý: Hàm `tinhdiem_trungbinh` hiện tại đang giả định format hơi khác một chút so với mô tả gốc.
# Mô tả: “Hàng đầu tiên gồm các đề mục: “Mã HS, Toán , Lý, Hóa, Sinh, Văn, Anh, Sử, Địa”. Hàng thứ 2 trở đi là bảng điểm chi tiết cho từng sinh viên (tên sinh viên + điểm chi tiết). Mỗi môn học tự nhiên có 4 đầu điểm, mỗi môn học xã hội có 5 đầu điểm. Các điểm thành phần của 1 môn được phân cách bằng dấu phẩy, các môn được phân cách bằng dấu chấm phẩy.”
# Dựa trên mô tả này, mỗi phần tử trong `parts` (sau khi split bằng `;`) sẽ là một chuỗi điểm, không chứa tên môn.
# Cần điều chỉnh logic phân tích `parts` để khớp với `header` và tỷ lệ điểm tương ứng.
# Điều chỉnh lại hàm `tinhdiem_trungbinh` cho phù hợp với format mô tả:
def tinhdiem_trungbinh_v2(file_path):
    “””
    Tính toán toàn bộ điểm trung bình của sinh viên theo từng môn học từ file bảng điểm chi tiết.
    Sử dụng format header và dữ liệu đã cho.
    Args:
        file_path (str): Đường dẫn đến file “diem_chitiet.txt”.
    Returns:
        dict: Dictionary chứa điểm trung bình của từng môn cho mỗi học sinh.
              Ví dụ: {‘Nguyen Hai Nam’: {‘Toan’: 8.5, ‘Ly’: 7.75, …}}
    “””
    hocsinh_diem_tb = {}
   
    TY_LE_TU_NHIEN = (0.05, 0.10, 0.15, 0.70) # Miệng, 15′, 1 tiết, Cuối kỳ
    TY_LE_XA_HOI = (0.05, 0.10, 0.10, 0.15, 0.60) # Chuyên cần, Bài luận, 1 tiết, 2 tiết, Cuối kỳ

    MON_TU_NHIEN = [‘Toan’, ‘Ly’, ‘Hoa’, ‘Sinh’]
    MON_XA_HOI = [‘Van’, ‘Anh’, ‘Su’, ‘Dia’]

    try:
        with open(file_path, ‘r’, encoding=’utf-8′) as f:
            lines = f.readlines()
            if not lines:
                print(“File rỗng hoặc không có dữ liệu.”)
                return hocsinh_diem_tb
           
            # Đọc dòng tiêu đề để xác định thứ tự các môn
            header_parts = [h.strip() for h in lines[0].strip().split(‘;’)]
            # Loại bỏ ‘Mã HS’ khỏi danh sách môn học
            mon_hoc_names_in_order = header_parts[1:]
           
            for line in lines[1:]: # Bắt đầu từ dòng thứ 2 (dữ liệu học sinh)
                line = line.strip()
                if not line:
                    continue

                parts = [p.strip() for p in line.split(‘;’)]
                ma_hs = parts[0]
               
                diem_mon_hoc = {}
               
                # Duyệt qua các chuỗi điểm của từng môn
                for i in range(len(mon_hoc_names_in_order)):
                    mon_hoc_name = mon_hoc_names_in_order[i]
                    diem_raw = parts[i + 1] # +1 vì parts[0] là Mã HS
                   
                    diem_thanh_phan_str = diem_raw.split(‘,’)
                    diem_thanh_phan = [float(d) for d in diem_thanh_phan_str]

                    diem_tb_mon = 0.0
                    if mon_hoc_name in MON_TU_NHIEN:
                        if len(diem_thanh_phan) == len(TY_LE_TU_NHIEN):
                            for idx, diem in enumerate(diem_thanh_phan):
                                diem_tb_mon += diem * TY_LE_TU_NHIEN[idx]
                        else:
                            print(f”Cảnh báo: Môn {mon_hoc_name} của {ma_hs} không đủ điểm thành phần tự nhiên. Bỏ qua môn này.”)
                            continue # Bỏ qua môn này và chuyển sang môn tiếp theo
                    elif mon_hoc_name in MON_XA_HOI:
                        if len(diem_thanh_phan) == len(TY_LE_XA_HOI):
                            for idx, diem in enumerate(diem_thanh_phan):
                                diem_tb_mon += diem * TY_LE_XA_HOI[idx]
                        else:
                            print(f”Cảnh báo: Môn {mon_hoc_name} của {ma_hs} không đủ điểm thành phần xã hội. Bỏ qua môn này.”)
                            continue # Bỏ qua môn này và chuyển sang môn tiếp theo
                    else:
                        print(f”Cảnh báo: Môn {mon_hoc_name} không xác định loại môn. Bỏ qua môn này.”)
                        continue

                    diem_mon_hoc[mon_hoc_name] = round(diem_tb_mon, 2)
               
                hocsinh_diem_tb[ma_hs] = diem_mon_hoc
               
    except FileNotFoundError:
        print(f”Lỗi: Không tìm thấy file ‘{file_path}'”)
    except Exception as e:
        print(f”Đã xảy ra lỗi khi đọc file: {e}”)
   
    return hocsinh_diem_tb

# Ví dụ về tạo file diem_chitiet.txt để test hàm tinhdiem_trungbinh_v2:
# Mã HS;Toán;Lý;Hóa;Sinh;Văn;Anh;Sử;Địa
# HS001;8,7,9,10;7,8,7,9;6,7,8,9;7,7,8,8;8,8,7,9,9;9,9,9,8,10;7,6,7,8,7;8,8,8,7,9
# HS002;7,6,8,9;6,7,6,8;7,6,7,8;6,6,7,7;7,7,6,8,8;8,8,8,7,9;6,5,6,7,6;7,7,7,6,8
# HS003;9,8,9,10;8,9,8,10;7,8,7,9;8,8,9,9;9,9,8,10,10;10,10,9,9,10;8,7,8,9,8;9,9,9,8,10

3.3. Hàm xeploai_hocsinh(hocsinh_diem_tb)

Mục tiêu: Xếp loại học lực cho từng học sinh dựa trên điểm tổng kết trung bình.

• Input: Dictionary hocsinh_diem_tb (đã tính toán ở bước trước).

• Output: Dictionary mới chứa điểm tổng kết trung bình và xếp loại học lực cho mỗi học sinh. Ví dụ: {‘Nguyen Hai Nam’: {‘DTB_TongKet’: 8.2, ‘XepLoai’: ‘Giỏi’}, …}.

:

Tiêu chí xếp loại học lực (bổ sung)

• Giỏi: Điểm tổng kết trung bình >= 8.0

• Khá: Điểm tổng kết trung bình >= 6.5 và < 8.0

• Trung bình Khá: Điểm tổng kết trung bình >= 5.0 và < 6.5

• Trung bình: Điểm tổng kết trung bình < 5.0

def xeploai_hocsinh(hocsinh_diem_tb):
    “””
    Xếp loại học lực của học sinh dựa vào điểm tổng kết trung bình.
    Args:
        hocsinh_diem_tb (dict): Dictionary chứa điểm trung bình của từng môn cho mỗi học sinh.
    Returns:
        dict: Dictionary chứa điểm tổng kết trung bình và xếp loại học lực cho mỗi học sinh.
    “””
    hocsinh_xeploai = {}
   
    for ma_hs, diem_mon in hocsinh_diem_tb.items():
        # Tính điểm tổng kết trung bình của học sinh
        if not diem_mon: # Nếu không có điểm môn nào (do cảnh báo bỏ qua)
            dtb_tong_ket = 0.0
        else:
            tong_diem = sum(diem_mon.values())
            so_mon = len(diem_mon)
            dtb_tong_ket = round(tong_diem / so_mon, 2) if so_mon > 0 else 0.0

        xep_loai = “”
        if dtb_tong_ket >= 8.0:
            xep_loai = “Gioi”
        elif dtb_tong_ket >= 6.5:
            xep_loai = “Kha”
        elif dtb_tong_ket >= 5.0:
            xep_loai = “Trung binh Kha”
        else:
            xep_loai = “Trung binh”
       
        hocsinh_xeploai[ma_hs] = {
            ‘DTB_TongKet’: dtb_tong_ket,
            ‘XepLoai’: xep_loai
        }
   
    return hocsinh_xeploai

3.4. Hàm xeploai_thidaihoc_hocsinh(hocsinh_diem_tb)

Mục tiêu: Đưa ra đánh giá sơ bộ về kết quả thi đại học dự kiến theo các khối.

• Input: Dictionary hocsinh_diem_tb (đã tính toán ở bước 1).

• Output: Dictionary mới chứa kết quả dự đoán thi đại học cho mỗi học sinh, ví dụ: {‘Nguyen Hai Nam’: {‘A’: ‘Loai 1’, ‘A1’: ‘Loai 2’, …}}.

Tiêu chí xếp loại thi đại học (từ Hướng dẫn dự án 2.docx):

• Khối tự nhiên (A, A1, B):

• Loại 1: Tổng điểm TB môn của 3 môn trong khối >= 24

• Loại 2: Tổng điểm TB môn của 3 môn trong khối < 24 và >= 18

• Loại 3: Tổng điểm TB môn của 3 môn trong khối < 18 và >= 12

• Loại 4: Tổng điểm TB môn của 3 môn trong khối < 12

• Khối xã hội (C):

• Loại 1: Tổng điểm TB môn của 3 môn trong khối >= 21

• Loại 2: Tổng điểm TB môn của 3 môn trong khối < 21 và >= 15

• Loại 3: Tổng điểm TB môn của 3 môn trong khối < 15 và >= 12

• Loại 4: Tổng điểm TB môn của 3 môn trong khối < 12

• Khối cơ bản (D):

• Loại 1: Tổng điểm TB môn >= 32 (điểm tiếng Anh hệ số nhân đôi)

• Loại 2: Tổng điểm TB môn < 32 và >= 24

• Loại 3: Tổng điểm TB môn < 24 và >= 20

• Loại 4: Tổng điểm TB môn < 20

def xeploai_thidaihoc_hocsinh(hocsinh_diem_tb):
    “””
    Đưa ra đánh giá sơ bộ về kết quả thi đại học dự kiến của học sinh theo các khối.
    Args:
        hocsinh_diem_tb (dict): Dictionary chứa điểm trung bình của từng môn cho mỗi học sinh.
    Returns:
        dict: Dictionary chứa kết quả dự đoán thi đại học cho mỗi học sinh theo từng khối.
              Ví dụ: {‘Nguyen Hai Nam’: {‘A’: ‘Loai 1’, ‘A1’: ‘Loai 2’, …}}
    “””
    hocsinh_du_doan_dh = {}
   
    for ma_hs, diem_mon in hocsinh_diem_tb.items():
        du_doan_khoi = {}
       
        # Khối A (Toán, Lý, Hóa)
        diem_A = diem_mon.get(‘Toan’, 0) + diem_mon.get(‘Ly’, 0) + diem_mon.get(‘Hoa’, 0)
        if diem_A >= 24: du_doan_khoi[‘A’] = ‘Loai 1’
        elif diem_A >= 18: du_doan_khoi[‘A’] = ‘Loai 2’
        elif diem_A >= 12: du_doan_khoi[‘A’] = ‘Loai 3’
        else: du_doan_khoi[‘A’] = ‘Loai 4’

        # Khối A1 (Toán, Lý, Anh)
        diem_A1 = diem_mon.get(‘Toan’, 0) + diem_mon.get(‘Ly’, 0) + diem_mon.get(‘Anh’, 0)
        if diem_A1 >= 24: du_doan_khoi[‘A1’] = ‘Loai 1’
        elif diem_A1 >= 18: du_doan_khoi[‘A1’] = ‘Loai 2’
        elif diem_A1 >= 12: du_doan_khoi[‘A1’] = ‘Loai 3’
        else: du_doan_khoi[‘A1’] = ‘Loai 4’

        # Khối B (Toán, Hóa, Sinh)
        diem_B = diem_mon.get(‘Toan’, 0) + diem_mon.get(‘Hoa’, 0) + diem_mon.get(‘Sinh’, 0)
        if diem_B >= 24: du_doan_khoi[‘B’] = ‘Loai 1’
        elif diem_B >= 18: du_doan_khoi[‘B’] = ‘Loai 2’
        elif diem_B >= 12: du_doan_khoi[‘B’] = ‘Loai 3’
        else: du_doan_khoi[‘B’] = ‘Loai 4’

        # Khối C (Văn, Sử, Địa)
        diem_C = diem_mon.get(‘Van’, 0) + diem_mon.get(‘Su’, 0) + diem_mon.get(‘Dia’, 0)
        if diem_C >= 21: du_doan_khoi[‘C’] = ‘Loai 1’
        elif diem_C >= 15: du_doan_khoi[‘C’] = ‘Loai 2’
        elif diem_C >= 12: du_doan_khoi[‘C’] = ‘Loai 3’
        else: du_doan_khoi[‘C’] = ‘Loai 4’
       
        # Khối D (Toán, Văn, Anh – Anh hệ số 2)
        diem_D = diem_mon.get(‘Toan’, 0) + diem_mon.get(‘Van’, 0) + (diem_mon.get(‘Anh’, 0) * 2)
        if diem_D >= 32: du_doan_khoi[‘D’] = ‘Loai 1’
        elif diem_D >= 24: du_doan_khoi[‘D’] = ‘Loai 2’
        elif diem_D >= 20: du_doan_khoi[‘D’] = ‘Loai 3’
        else: du_doan_khoi[‘D’] = ‘Loai 4’
       
        hocsinh_du_doan_dh[ma_hs] = du_doan_khoi
       
    return hocsinh_du_doan_dh

3.5. Hàm luu_ket_qua(file_output_path, diem_tb, xep_loai, du_doan_dh)

Mục tiêu: Lưu toàn bộ kết quả phân tích ra một tệp văn bản.

• Input: Đường dẫn file output, các Dictionary chứa kết quả điểm trung bình, xếp loại, và dự đoán đại học.

• Output: Ghi file kết quả.

def luu_ket_qua(file_output_path, diem_tb, xep_loai, du_doan_dh):
    “””
    Lưu toàn bộ kết quả phân tích vào một file văn bản.
    Args:
        file_output_path (str): Đường dẫn file để lưu kết quả.
        diem_tb (dict): Dictionary chứa điểm trung bình từng môn.
        xep_loai (dict): Dictionary chứa xếp loại học lực.
        du_doan_dh (dict): Dictionary chứa dự đoán thi đại học.
    “””
    try:
        with open(file_output_path, ‘w’, encoding=’utf-8′) as f:
            f.write(“BÁO CÁO PHÂN TÍCH BẢNG ĐIỂM HỌC VIỆN THIÊN HÀ\n\n”)
           
            for ma_hs in diem_tb.keys(): # Duyệt qua từng học sinh
                f.write(f”— Học sinh: {ma_hs} —\n”)
               
                # In điểm trung bình từng môn
                f.write(“Điểm trung bình các môn:\n”)
                for mon, diem in diem_tb[ma_hs].items():
                    f.write(f”  – {mon}: {diem}\n”)
               
                # In xếp loại học lực
                if ma_hs in xep_loai:
                    f.write(f”Xếp loại học lực tổng kết: {xep_loai[ma_hs][‘XepLoai’]} (Điểm TB: {xep_loai[ma_hs][‘DTB_TongKet’]})\n”)
               
                # In dự đoán thi đại học
                if ma_hs in du_doan_dh:
                    f.write(“Dự đoán kết quả thi đại học theo khối:\n”)
                    for khoi, loai in du_doan_dh[ma_hs].items():
                        f.write(f”  – Khối {khoi}: {loai}\n”)
               
                f.write(“\n”) # Xuống dòng giữa các học sinh
        print(f”Đã lưu báo cáo phân tích vào: {file_output_path}”)
    except Exception as e:
        print(f”Lỗi khi lưu file báo cáo: {e}”)

3.6. Hàm main()

Mục tiêu: Điều phối toàn bộ chương trình.

def main():
    “””
    Hàm chính điều phối chương trình phân tích bảng điểm.
    “””
    input_file = “diem_chitiet.txt”
    output_file = “danhgia_hocsinh.txt” # Đổi tên file output theo format yêu cầu

    print(“Bắt đầu phân tích bảng điểm học sinh…”)
   
    # Bước 1: Load dữ liệu và tính điểm trung bình từng môn
    diem_tb_mon_hoc = tinhdiem_trungbinh_v2(input_file)
    if not diem_tb_mon_hoc:
        print(“Không có dữ liệu để phân tích. Chương trình kết thúc.”)
        return

    print(“\nĐiểm trung bình từng môn của học sinh đã được tính toán.”)
    # print(diem_tb_mon_hoc) # Debug: In ra để kiểm tra

    # Bước 2: Xếp loại học lực tổng kết
    ket_qua_xeploai = xeploai_hocsinh(diem_tb_mon_hoc)
    print(“Xếp loại học lực tổng kết của học sinh đã được thực hiện.”)
    # print(ket_qua_xeploai) # Debug: In ra để kiểm tra

    # Bước 3: Đánh giá sơ bộ kết quả thi đại học dự kiến
    ket_qua_du_doan_dh = xeploai_thidaihoc_hocsinh(diem_tb_mon_hoc)
    print(“Dự đoán kết quả thi đại học theo khối đã hoàn tất.”)
    # print(ket_qua_du_doan_dh) # Debug: In ra để kiểm tra
   
    # Bước 4: Lưu kết quả ra file
    luu_ket_qua(output_file, diem_tb_mon_hoc, ket_qua_xeploai, ket_qua_du_doan_dh)
   
    print(“\nQuá trình phân tích bảng điểm hoàn tất!”)

# Gọi hàm main để chạy chương trình
if __name__ == “__main__”:
    main()

Google Colab (Thực hành cốt lõi):

Bạn có thể tạo một notebook Google Colab, copy-paste toàn bộ code trên vào đó, tạo một cell mới để tạo file diem_chitiet.txt (hoặc upload file lên Colab), và sau đó chạy hàm main().

Các bước trên Colab:

1 Mở Google Colab.

2 Tạo một notebook mới.

3 Tạo một cell code và dán nội dung sau vào để tạo file diem_chitiet.txt:
# Tạo file diem_chitiet.txt mẫu để thử nghiệm
file_content = “””Mã HS;Toán;Lý;Hóa;Sinh;Văn;Anh;Sử;Địa
HS001;8,7,9,10;7,8,7,9;6,7,8,9;7,7,8,8;8,8,7,9,9;9,9,9,8,10;7,6,7,8,7;8,8,8,7,9
HS002;7,6,8,9;6,7,6,8;7,6,7,8;6,6,7,7;7,7,6,8,8;8,8,8,7,9;6,5,6,7,6;7,7,7,6,8
HS003;9,8,9,10;8,9,8,10;7,8,7,9;8,8,9,9;9,9,8,10,10;10,10,9,9,10;8,7,8,9,8;9,9,9,8,10
“””
with open(“diem_chitiet.txt”, “w”, encoding=”utf-8″) as f:
    f.write(file_content)
print(“Đã tạo file diem_chitiet.txt”)

4 Tạo một cell code khác và dán toàn bộ các hàm tinhdiem_trungbinh_v2, xeploai_hocsinh, xeploai_thidaihoc_hocsinh, luu_ket_qua, và main() vào đó.

5 Chạy cell này. Sau khi chạy, bạn sẽ thấy file danhgia_hocsinh.txt được tạo ra trong phần Files của Colab.

4. Câu Chuyện HaivanStory & Liên Hệ Thực Tế: AI Tư Vấn Hướng Nghiệp Từ Bảng Điểm Vũ Trụ

Trong tương lai không xa, tại các Học Viện Liên Hành Tinh, hệ thống AI không chỉ đơn thuần là chấm điểm. Chúng là những “Cố Vấn Định Hướng” thông minh, có khả năng phân tích hàng triệu dữ liệu học tập của học sinh qua nhiều thế hệ để đưa ra những lời khuyên chính xác nhất về lộ trình phát triển.

Chương trình Python mà bạn vừa xây dựng chính là nền tảng của một hệ thống AI như vậy. Khi bạn “load dữ liệu bảng điểm chi tiết”, đó chính là lúc AI đang tiếp nhận “ký ức” học tập của các học giả. Việc bạn “tính điểm trung bình từng môn” và “xếp loại học lực” là cách AI đánh giá hiệu suất hiện tại.

Đặc biệt, chức năng “dự đoán kết quả thi đại học” chính là trái tim của hệ thống tư vấn này. Bằng cách áp dụng các tiêu chí về khối thi (như Khối A, A1, B, C, D), AI có thể nhìn vào điểm mạnh của từng học sinh (ví dụ: một học sinh giỏi khối tự nhiên A có điểm Toán, Lý, Hóa vượt trội) và dự đoán “Loại 1” – tức là tiềm năng cao để đỗ vào các chuyên ngành khoa học vũ trụ, kỹ thuật robot. Ngược lại, một học sinh “Loại 4” ở một khối cụ thể sẽ được AI gợi ý tập trung cải thiện kiến thức hoặc xem xét các khối thi khác phù hợp hơn.

Đây không chỉ là những con số trên một bảng điểm; đây là những dữ liệu định hình tương lai. Với khả năng xử lý và phân tích dữ liệu hiệu quả, bạn đang đóng góp vào việc xây dựng những hệ thống thông minh, giúp các học giả vũ trụ định hình lộ trình học tập, phát huy tối đa tiềm năng và vươn tới những vì sao tri thức.

5. Tổng Kết & Hướng Đi Tiếp Theo: Hoàn Thành Nhiệm Vụ Quan Trọng!

Trong dự án này, bạn đã thực hiện một nhiệm vụ toàn diện, từ việc đọc dữ liệu thô, xử lý chúng bằng các thao tác String, lưu trữ thông tin có cấu trúc bằng Dictionary, đến việc áp dụng logic phức tạp để phân loại và dự đoán. Đặc biệt, việc chia nhỏ bài toán thành các hàm đã giúp bạn xây dựng một chương trình mạch lạc, dễ hiểu và dễ bảo trì.

Đây là một bước tiến lớn trong hành trình lập trình của bạn! Bạn đã thực sự biến những kiến thức cơ bản thành công cụ mạnh mẽ để giải quyết một bài toán thực tế.

Hướng đi tiếp theo:

• Tối ưu hóa và kiểm thử: Hãy thử nghiệm chương trình với nhiều bộ dữ liệu khác nhau, bao gồm cả những trường hợp ngoại lệ (ví dụ: thiếu điểm, điểm không hợp lệ) để đảm bảo tính ổn định của code.

• Mở rộng tính năng: Bạn có thể mở rộng chương trình để:

• Thêm chức năng phân tích thống kê (điểm trung bình chung của cả lớp, môn học có điểm cao nhất/thấp nhất).

• Tạo giao diện người dùng đơn giản (sử dụng thư viện tkinter hoặc streamlit nếu bạn muốn nâng cao).

• Lưu kết quả ra các định dạng khác như CSV, JSON để dễ dàng xử lý bằng các công cụ khác.

Bạn đã hoàn thành một dự án đáng tự hào. Hãy tự tin vào kỹ năng của mình!

6. Kêu Gọi Hành Động: Chia Sẻ Sáng Tạo Của Bạn!

Bạn đã xây dựng thành công Hệ Thống Phân Tích Bảng Điểm Học Viện Thiên Hà của riêng mình chưa? Có bất kỳ phần nào khiến bạn băn khoăn hay muốn chia sẻ mẹo hay không?

Hãy để lại bình luận dưới đây, chia sẻ kết quả hoặc những ý tưởng mở rộng của bạn! Chúng ta cùng nhau học hỏi và xây dựng một cộng đồng những nhà phát triển Python tài năng.

Đừng quên nộp bài tập theo đúng format: “Mã SV_PYB101x_asm2.zip” (chứa file .ipynb hoặc .py).

Và tất nhiên, hãy tiếp tục theo dõi HaivanStory Blog để không bỏ lỡ những nhiệm vụ và khám phá mới trong vũ trụ Python!