27.3.2 Hướng dẫn làm từng bước Dự án mẫu
Tạo thư mục, tập tin cho dự án
- Tạo thư mục mới, đặt tên theo chuẩn Pascal, tiếng Việt, không dấu, ví dụ QuanLyBangDiemLop7
- Trong thư mục QuanLyBangDiemLop7, tạo tập tin mã nguồn của dự án, ví dụ main.py
Lập trình hàm main()
- Trong main.py, viết hàm main() và chạy thử
- Bạn nên viết mã nguồn bằng IDLE hoặc Notepad để không có gợi ý của trình viết mã, giúp bạn học được nhiều hơn. Sau này, biết nhiều rồi thì mới nên dùng VS Code hoặc một IDE bất kỳ.
[main.py]
def main():
print("hi")
if __name__ == "__main__":
main()
- Bạn nên hỏi AI về lệnh if ở đoạn mã trên, để hiểu cách Python gọi hàm main() khi thực thi. Có thể hiểu đơn giản: __name__ là biến ẩn của Python, nó sẽ được gán giá trị là __main__ khi bạn chạy trực tiếp một tập tin .py. Và khi đó, Python sẽ sẽ gọi hàm main() để thực thi.
- Chạy thử đoạn mã trên, bạn sẽ thấy chữ “hi” xuất hiện trên màn hình kết quả, vậy là bạn đã sẵn sàng để lập trình
- Cho xuất hiện menu của chương trình:
[main.py]
def main():
while True:
print("\n === QUẢN LÝ BẢNG ĐIỂM HỌC SINH LỚP 7 ===")
print("1. Xem danh sách & bảng điểm")
print("2. Thêm học sinh mới")
# sau này bạn sẽ thêm các chức năng ở đây
print("0. Thoát chương trình")
lua_chon = input("Mời bạn chọn chức năng (0-2): ").strip()
if lua_chon == "1":
print("Danh sách lớp & bảng điểm")
elif lua_chon == 2:
print("Thêm học sinh mới")
elif lua_chon == "0":
print("Đã thoát chương trình!")
break
else:
print("Lựa chọn không hợp lệ!")
if __name__ == "__main__":
main()
- Bạn chạy thử chương trình, nhập các số khác nhau để kiểm tra xem chương trình chạy đúng chưa
Tạo tập tin lưu danh sách lớp
- Việc đầu tiên chúng ta cần làm là: trong thư mục dự án, tạo tập tin để lưu danh sách lớp và điểm của mỗi bạn (đặt tên là bang_diem_lop7.csv)
Tập tin bang_diem_lop7.csv được định dạng theo chuẩn csv:
- Hàng đầu tiên là tiêu đề
- Các hàng tiếp theo là thông tin của học sinh và điểm, mỗi học sinh sẽ có nhiều hàng, mỗi hàng gồm nhiều trường, mỗi trường sẽ cách nhau bằng dấu phẩy (,). Riêng trường điểm thường xuyên (tx), vì có nhiều, nên sẽ dùng dấu chấm phẩy (;) để ngăn cách
Ví dụ:
ma_hs,ho_ten,mon,tx,gk,ck
HS01,Nguyễn Văn Tèo,Toán,8.0;7.0,7.5,9.0
HS01,Nguyễn Văn Tèo,Ngữ văn,7.0;6.0,7.0,7.5
Ở bảng dữ liệu trên, bạn Tèo sẽ có mã số là HS01, có dòng điểm cho môn Toán gồm 2 điểm thường xuyên là 8.0 và 7.0, điểm giữa kỳ (gk) là 7.5 và điểm cuối kỳ (ck) là 9. Và dòng điểm cho môn Ngữ văn.
Bạn hãy chèn nội dung trên vào tập tin bang_diem_lop7.csv
[bang_diem_lop7.csv]
ma_hs,ho_ten,mon,tx,gk,ck
HS01,Nguyễn Văn Tèo,Toán,8.0;7.0,7.5,9.0
HS01,Nguyễn Văn Tèo,Ngữ văn,7.0;6.0,7.0,7.5
Viết hàm đọc dữ liệu từ tập tin
- Để đọc dữ liệu từ tập tin CSV, cần sử dụng thư viện csv. Chúng ta sẽ thêm lệnh gọi thư viện (import csv) vào đầu tập tin main.py. Đồng thời, chúng ta cũng sử dụng thư viện os để xử lý tập tin. Khai báo hằng FILE_PATH để tiện khi lập trình.
[main.py]
import csv
import os
FILE_PATH = "bang_diem_lop7.csv"
def main():
...
- Trong tập tin main.py, sau hàm def main(), tạo hàm doc_file_csv(), với nội dung sau: sử dụng cấu trúc try…except để bẫy lỗi FileNotFoundError.
[main.py]
…
else:
print("Lựa chọn không hợp lệ!")
# hàm đọc tập tin csv
def doc_file_csv():
danh_sach_lop = []
if not os.path.exists(FILE_PATH):
return danh_sach_lop
try:
with open(FILE_PATH, mode="r", encoding="utf-8") as f:
reader = csv.DictReader(f)
print("trong doc_file")
print(reader)
# bạn nên chèn các đoạn mã, để kiểm tra chạy từng bước
except FileNotFoundError:
return[]
if __name__ == "__main__":
main()
- Gọi hàm doc_file_csv() trong hàm main(), để chạy và kiểm tra:
…
if lua_chon == "1":
doc_file_csv()
elif lua_chon == 2:
…
- Tiếp tục hoàn thành hàm doc_file_csv()
# hàm đọc tập tin csv
def doc_file_csv():
danh_sach_lop = []
if not os.path.exists(FILE_PATH):
return danh_sach_lop
try:
with open(FILE_PATH, mode="r", encoding="utf-8") as f:
reader = csv.DictReader(f)
students = {}
for row in reader:
ma = row["ma_hs"]
if ma not in students:
students[ma] = {"ma_hs": ma, "ho_ten": row["ho_ten"], "diem": {}}
if row["mon"]:
tx = [float(x) for x in row["tx"].split(";") if x]
gk = float(row["gk"]) if row["gk"] else 0.0
ck = float(row["ck"]) if row["ck"] else 0.0
students[ma]["diem"][row["mon"]] = {"tx": tx, "gk": gk, "ck": ck}
return list(students.values())
- Thêm một đoạn mã nhỏ trong hàm main(), để kiểm tra kết quả chạy của hàm doc_file_csv():
…
if lua_chon == "1":
danh_sach_hs = doc_file_csv()
print(danh_sach_hs)
elif lua_chon == 2:
…
Nếu chạy được, chương trình sẽ xuất ra kết quả là:
[{'ma_hs': 'HS01', 'ho_ten': 'Nguyễn Văn Tèo', 'diem': {'Toán': {'tx': [8.0, 7.0], 'gk': 7.5, 'ck': 9.0}, 'Ngữ văn': {'tx': [7.0, 6.0], 'gk': 7.0, 'ck': 7.5}}}]
...
Tuy nhiên, chức năng số 1 là: hiển thị Danh sách và bảng điểm.
Danh sách và bảng điểm sẽ có dạng như sau:
Tương ứng với nội dung dữ liệu trong tập tin bang_diem_lop7.csv có dạng như sau:
ma_hs,ho_ten,mon,tx,gk,ck
HS001,Nguyễn Văn Tèo,Toán,8.0;7.0,7.5,9.0
HS001,Nguyễn Văn Tèo,Ngữ văn,7.0;6.0,7.0,7.5
HS001,Nguyễn Văn Tèo,Tiếng Anh,9.0;10.0,9.5,9.0
HS002,Trần Thị Tí,Toán,6.0;6.5,6.0,7.0
HS002,Trần Thị Tí,Lịch sử_Địa lý,8.0;8.5,8.0,8.5
HS003,Lê Sửu,,,
Hàm doc_file_csv() đã trả về một List chứa thông tin của tất cả học sinh, cùng với các điểm thành phần. Chúng ta sẽ viết tiếp hàm hien_thi_bang_diem(danh_sach_lop) để hiển thị Danh sách lớp và bảng điểm.
Vì hàm hien_thi_bang_diem(danh_sach_lop) có dùng tới biến danh_sach_lop, nên chúng ta khai báo và gọi hàm doc_file_csv() để có dữ liệu. Đồng thời gọi hàm hien_thi_bang_diem(danh_sach_lop) trong mục chọn 1.
[main.py]
def main():
danh_sach_lop = doc_file_csv()
while True:
...
if lua_chon == "1":
hien_thi_bang_diem(danh_sach_lop)
elif lua_chon == 2:
...
Viết hàm hien_thi_bang_diem(danh_sach_lop) ngay phía dưới hàm doc_file_csv().
[main.py]
…
except FileNotFoundError:
return[]
# hàm hiển thị danh sách và bảng điểm
def hien_thi_bang_diem(danh_sach_lop):
"""Hiển thị Danh sách và bảng điểm"""
if not danh_sach_lop:
print("\n Danh sách không có học sinh nào!")
return
print("\n" + "=" * 65)
print(f"{'MÃ HS':<10}{'HỌ VÀ TÊN':<20}{'MÔN':<15}{'ĐTB MÔN':<10}{'XẾP LOẠI'}")
print("=" * 65)
for hs in danh_sach_lop:
print(f"{hs['ma_hs']:<10}{hs['ho_ten']:<20}")
if not hs["diem"]:
print(f"{'':<30}(Chưa có điểm)")
else:
for mon, d in hs["diem"].items():
#dtb = tinh_dtb_mon(d) - sẽ viết sau
#xl = xep_loai(dtb) - sẽ viết sau
dtb = 5.0
xl = "Trung bình"
print(f"{'':<10}{'':<20}{mon:<15}{dtb:<10}{xl}")
print("-" * 65)
if __name__ == "__main__":
…
- Chạy chương trình để xem kết quả:

