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.
- 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
- 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.
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.
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.
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.
- Gõ lại chương trình, chạy và thử các lỗi nhập sai.
- Thêm chức năng xóa một khoản chi theo số thứ tự.
- Thêm trường ngày và lọc chi tiêu theo tháng.
- Đẩy dự án lên GitHub (xem loạt bài Git và GitHub).
- 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.