Bài 10. Dự án nhỏ

Kết thúc loạt bài bằng một dự án nhỏ: quản lý chi tiêu cá nhân, dùng mọi kiến thức đã học.

60 phútTổng hợp
Bạn sẽ học được
  • Chia bài toán thành các hàm
  • Lưu dữ liệu vào tệp và đọc lại
  • Xây menu chương trình bằng vòng lặp
  • Biết hướng học tiếp sau khóa cơ bản
Thuật ngữ cần biết
Yêu cầu
Điều chương trình phải làm được.
Giao diện dòng lệnh (CLI)
Chương trình tương tác qua chữ trong terminal.
Lưu trữ dữ liệu
Ghi dữ liệu ra tệp để không mất khi tắt chương trình.

Khái niệm và lý thuyết

Dự án nhỏ là lúc ghép các mảnh kiến thức. Quy trình phát triển phần mềm cơ bản gồm: phân tích yêu cầu (chương trình phải làm gì), thiết kế (chia thành các hàm, chọn cấu trúc dữ liệu), cài đặt (viết mã từng phần), kiểm thử (chạy thử với nhiều dữ liệu) và cải tiến.

Với "Sổ chi tiêu": dữ liệu là danh sách các từ điển, mỗi từ điển là một khoản chi. Dữ liệu được tách khỏi giao diện: các hàm doc, ghi lo việc lưu trữ; them, xem lo nghiệp vụ; main lo menu. Việc phân tách trách nhiệm như vậy gọi là mô-đun hóa và là nguyên tắc thiết kế cốt lõi, giúp sau này thay giao diện dòng lệnh bằng giao diện web mà không phải viết lại phần lưu trữ.

Định dạng JSON chuyển cấu trúc Python (list, dict) thành văn bản và ngược lại, nên rất tiện lưu trạng thái chương trình.

Yêu cầu bài toán

Ứng dụng "Sổ chi tiêu": thêm khoản chi (mô tả, số tiền), xem danh sách, xem tổng, dữ liệu lưu trong tệp chi_tieu.json.

MenuChọn chức năngXử lýLưu tệpQuay lại menu

Mã hoàn chỉnh

import json, os

TEP = "chi_tieu.json"

def doc():
    if os.path.exists(TEP):
        with open(TEP, encoding="utf-8") as f:
            return json.load(f)
    return []

def ghi(ds):
    with open(TEP, "w", encoding="utf-8") as f:
        json.dump(ds, f, ensure_ascii=False, indent=2)

def them(ds):
    mo_ta = input("Mô tả: ")
    try:
        tien = int(input("Số tiền: "))
    except ValueError:
        print("Số tiền không hợp lệ"); return
    ds.append({"mo_ta": mo_ta, "tien": tien})
    ghi(ds)

def xem(ds):
    for i, k in enumerate(ds, 1):
        print(f"{i}. {k['mo_ta']}: {k['tien']:,} đ")
    print("Tổng:", f"{sum(k['tien'] for k in ds):,} đ")

def main():
    ds = doc()
    while True:
        print("\n1. Thêm  2. Xem  0. Thoát")
        c = input("Chọn: ")
        if c == "1": them(ds)
        elif c == "2": xem(ds)
        elif c == "0": break

main()

Cách làm bài từng bước

Với bài tập lớn, đừng viết hết rồi mới chạy. Hãy chia thành các bước nhỏ: (1) in menu và nhập lựa chọn, chạy thử; (2) thêm chức năng đầu tiên, chạy thử; (3) thêm chức năng tiếp theo. Mỗi bước chạy được rồi mới đi tiếp. Khi gặp lỗi, bạn biết ngay nó nằm ở đoạn mới thêm.

Hướng phát triển

Thêm ngày tháng, phân loại, xóa khoản chi, thống kê theo tháng, xuất CSV, vẽ biểu đồ bằng matplotlib, hoặc làm giao diện web bằng Flask.

Tình huống: Từ bài tập thành công cụ

Cô Hoa là kế toán trường, dùng chính chương trình kiểu này để tổng hợp phiếu chi mỗi tuần, tiết kiệm hàng giờ so với nhập tay.

Mẹo hay

Làm từng bước nhỏ: chạy được chức năng thêm rồi mới viết chức năng xem. Dự án chạy ổn ở mỗi bước dễ sửa hơn nhiều.

Thực hành
  1. Gõ lại chương trình, chạy và thử các lỗi nhập sai.
  2. Thêm chức năng xóa một khoản chi theo số thứ tự.
  3. Thêm trường ngày và lọc chi tiêu theo tháng.
  4. Đẩy dự án lên GitHub (xem loạt bài Git và GitHub).
Tóm tắt bài học
  • Dự án nhỏ ghép nhiều kỹ năng: hàm, tệp, vòng lặp, xử lý lỗi.
  • Dữ liệu cần lưu ra tệp (JSON, CSV).
  • Bước tiếp theo: pandas, web (Flask, FastAPI) hoặc tự động hóa.