"""Chạy: python kiem_lich.py [lich.csv]. Tiêu đề CSV: lop,ca,phong.""" from collections import Counter from csv import DictReader from pathlib import Path import sys LOP = { "ctdl": ("a", 35, "lt"), "pttk": ("a", 30, "lt"), "kiemthu": ("b", 22, "th"), "android": ("c", 20, "th"), } PHONG = {"p101": (45, "lt"), "lab02": (24, "th")} CA = {"t2", "t4", "t6"} KHONG_RANH = {("c", "t2")} MAU = [ ("ctdl", "t2", "p101"), ("pttk", "t6", "p101"), ("kiemthu", "t2", "lab02"), ("android", "t4", "lab02"), ] def doc_csv(duong_dan): with Path(duong_dan).open(encoding="utf-8-sig", newline="") as tep: reader = DictReader(tep) if reader.fieldnames != ["lop", "ca", "phong"]: raise ValueError("Tiêu đề phải là lop,ca,phong") rows = [] for dong, row in enumerate(reader, start=2): if None in row or any(not isinstance(row[key], str) for key in reader.fieldnames): raise ValueError(f"Dòng {dong}: sai số cột") rows.append(tuple(row[key].strip() for key in reader.fieldnames)) return rows def kiem_lich(rows): loi = [] dem_lop = Counter() phong_da_dung = {} gv_da_day = {} ca_cua_a = set() for vi_tri, (lop, ca, phong) in enumerate(rows, start=1): if lop not in LOP or ca not in CA or phong not in PHONG: loi.append(f"Bản ghi {vi_tri}: mã lớp, ca hoặc phòng không hợp lệ") continue dem_lop[lop] += 1 gv, si_so, loai = LOP[lop] suc_chua, loai_phong = PHONG[phong] if si_so > suc_chua or loai != loai_phong: loi.append(f"Bản ghi {vi_tri}: phòng không phù hợp cho {lop}") if (gv, ca) in KHONG_RANH: loi.append(f"Bản ghi {vi_tri}: GV {gv} không rảnh vào {ca}") for da_xep, khoa, nhan in ( (phong_da_dung, (ca, phong), f"trùng phòng {phong}"), (gv_da_day, (ca, gv), f"trùng giảng viên {gv}"), ): truoc = da_xep.setdefault(khoa, vi_tri) if truoc != vi_tri: loi.append(f"Bản ghi {vi_tri} và {truoc}: {nhan} vào {ca}") if gv == "a": ca_cua_a.add(ca) for lop in LOP: if dem_lop[lop] != 1: loi.append(f"Lớp {lop} có {dem_lop[lop]} phân công hợp lệ về mã; cần đúng 1") diem = None if loi else 5 * {"t2", "t6"}.issubset(ca_cua_a) return loi, diem if __name__ == "__main__": try: rows = doc_csv(sys.argv[1]) if len(sys.argv) > 1 else MAU except (OSError, ValueError) as exc: sys.exit(str(exc)) loi, diem = kiem_lich(rows) if loi: print("\n".join(loi)) sys.exit(1) print(f"Lịch khả thi. Điểm phạt: {diem}")