1.2 Thực hành: Refactor code cũ

30 phút đọc

Đề bài

Đoạn code dưới đây chạy được nhưng khó đọc. Hãy refactor: đặt tên lại, tách hàm, thêm type hints và docstring, giữ nguyên kết quả.

d={}
f=open("sv.csv",encoding="utf-8")
for l in f.readlines()[1:]:
    x=l.strip().split(",")
    if x[1] not in d: d[x[1]]=[]
    d[x[1]].append(float(x[2]))
f.close()
for k in d:
    print(k,sum(d[k])/len(d[k]))

File sv.csv có dạng:

ten,lop,diem
An,11A1,8.5
Bình,11A2,7
Chi,11A1,9

Lời giải tham khảo

import csv
from collections import defaultdict
from pathlib import Path


def doc_diem_theo_lop(duong_dan: Path) -> dict[str, list[float]]:
    """Đọc file CSV, gom điểm theo lớp."""
    diem_theo_lop: dict[str, list[float]] = defaultdict(list)
    with open(duong_dan, newline="", encoding="utf-8") as f:
        for hang in csv.DictReader(f):
            diem_theo_lop[hang["lop"]].append(float(hang["diem"]))
    return diem_theo_lop


def trung_binh(diem: list[float]) -> float:
    return sum(diem) / len(diem) if diem else 0.0


def main() -> None:
    for lop, diem in doc_diem_theo_lop(Path("sv.csv")).items():
        print(f"{lop}: {trung_binh(diem):.2f}")


if __name__ == "__main__":
    main()

Mở rộng

- Chạy mypy trên lời giải và sửa đến khi không còn cảnh báo.

Đọc xong rồi? Đánh dấu để lưu tiến độ nhé.

Mục lục chương

0/2

Chương 1: Ôn tập và quy ước