← Lập trình Python cơ bản

Bài 11 · Vận dụng · 30 phút· Cập nhật 11/06/2026

Dự án cuối khoá: 3 app Python

Biên soạn bởi Nguyễn Anh Tuấn

Dự án Python cho người mới: dựng 3 app dòng lệnh (CLI) chạy được - quiz, sổ việc lưu JSON, phân tích văn bản - rồi đưa lên GitHub làm portfolio.

Bạn đã đi qua biến → kiểu dữ liệu → điều khiển luồng → hàm → cấu trúc dữ liệu → lỗi → module, và hiểu cả bản chất bytecode. Giờ ghép tất cả thành ba app dòng lệnh chạy được. Cả ba chung một khung đơn giản - chọn dự án để xem:

Chọn dự án:

Quiz trắc nghiệm - Hỏi từng câu, người dùng chọn số, chấm điểm cuối cùng.

1. Dữ liệu
list các dict câu hỏi {hoi, dap_an, dung}
2. Xử lý
vòng lặp qua câu hỏi, so đáp án chọn với đáp án đúng, cộng điểm
3. Nhập – Xuất
print câu hỏi & lựa chọn; input() đọc số; in điểm
Kỹ năng áp dụng (từ các bài đã học):
list & dict (bài 6)vòng lặp + enumerate (bài 4)hàm (bài 5)f-string (bài 3)try/except cho input (bài 8)
🧩 Cả ba dự án chung MỘT khung: Dữ liệu → Xử lý → Nhập–Xuất. Học một khuôn, làm được nhiều app - chỉ đổi dữ liệu và nghiệp vụ.
  • Khung chung: Dữ liệu (list/dict) → Xử lý (vòng lặp/hàm) → Nhập-Xuất.
  • Quiz là bản mẫu đầy đủ; Sổ việc & Phân tích văn bản là đề bài có cột mốc.
  • Mục tiêu: ba sản phẩm chạy được để đưa lên GitHub.

Câu hỏi là một list các dict; một hàm hỏi từng câu và trả đúng/sai; vòng lặp cộng điểm. try/except giúp nhập sai không làm sập:

quiz.py

cau_hoi = [
    {"hoi": "Thu do Viet Nam?", "dap_an": ["Ha Noi", "Hue"], "dung": 1},
    {"hoi": "2 + 2 * 2 = ?", "dap_an": ["6", "8"], "dung": 1},
    {"hoi": "Python thuoc loai ngon ngu nao?",
     "dap_an": ["Bien dich thang ra ma may", "Thong dich (qua bytecode)"], "dung": 2},
]

def hoi_mot_cau(cau):
    print("\n" + cau["hoi"])
    for i, da in enumerate(cau["dap_an"], start=1):
        print(f"  {i}. {da}")
    while True:
        try:
            chon = int(input("Chon (so): "))
            if 1 <= chon <= len(cau["dap_an"]):
                return chon == cau["dung"]
            print("  So ngoai pham vi, thu lai.")
        except ValueError:
            print("  Phai nhap mot SO.")   # nhap "abc" -> khong sap

def main():
    diem = 0
    for cau in cau_hoi:
        if hoi_mot_cau(cau):
            diem += 1
    print(f"\nKet qua: {diem}/{len(cau_hoi)}")

if __name__ == "__main__":
    main()

Kết quả khi chạy

Thu do Viet Nam?
  1. Ha Noi
  2. Hue
Chon (so): 1
...
Ket qua: 3/3
  • Dữ liệu: list các dict {hoi, dap_an, dung} - dễ thêm câu mới.
  • enumerate(..., start=1) để đánh số lựa chọn từ 1.
  • try/except ValueError + while: nhập sai thì hỏi lại, không sập.

Cùng khung, đổi dữ liệu thành list các dict việc và thêm phần lưu file để app “nhớ”. Module json đổi list/dict ↔ str JSON:

phần lưu/đọc - việc của bạn ghép vào CLI

import json

def tai(path):
    try:
        with open(path) as f:
            return json.load(f)      # JSON -> list cac dict
    except FileNotFoundError:
        return []                    # chua co file -> rong

def luu(path, viec):
    with open(path, "w") as f:
        json.dump(viec, f, ensure_ascii=False, indent=2)

# moi viec la mot dict: {"ten": "hoc Python", "xong": False}
con_lai = sum(1 for v in viec if not v["xong"])   # dem viec chua xong
  • Cột mốc 1: tai(path) đọc todo.json; chưa có file → trả list rỗng (try/except).
  • Cột mốc 2: luu(path, viec) ghi JSON (ensure_ascii=False để giữ tiếng Việt).
  • Cột mốc 3: lệnh thêm việc & đánh dấu xong (sửa dict trong list).
  • Cột mốc 4: đếm “còn N việc chưa xong”, lưu lại khi thoát.

Trọng tâm là dict & set: tách từ, đếm tần suất, và tìm số từ khác nhau:

lõi đếm từ - verify chạy thật

text = "python la python python"
tu = text.split()              # ['python', 'la', 'python', 'python']

dem = {}
for t in tu:
    dem[t] = dem.get(t, 0) + 1  # dem tan suat
print(dem)                      # {'python': 3, 'la': 1}

print("tu khac nhau:", len(set(tu)))   # 2

Kết quả khi chạy

{'python': 3, 'la': 1}
tu khac nhau: 2
  • Cột mốc 1: tách văn bản thành list từ bằng .split().
  • Cột mốc 2: đếm bằng dict.get(t, 0) + 1.
  • Cột mốc 3: số từ khác nhau = len(set(tu)).
  • Cột mốc 4: từ dài nhất max(tu, key=len); lọc từ > 3 ký tự bằng comprehension.

Một app chạy được là tốt; một app người khác cài & chạy được mới là sản phẩm. Hoàn thiện mỗi app theo checklist nhỏ này:

cấu trúc gọn cho mỗi app

quiz/
├── quiz.py
├── README.md        # app lam gi + cach chay (python quiz.py)
└── .gitignore       # bo __pycache__/, .venv/

# Dua len GitHub:
git init && git add . && git commit -m "feat: app quiz trac nghiem"
git remote add origin <url> && git push -u origin main
  • README ngắn: app làm gì + lệnh chạy - để người khác (và bạn sau này) dùng được ngay.
  • .gitignore bỏ __pycache__/ và .venv/ - đừng commit thứ sinh ra tự động.
  • if __name__ == "__main__": để file vừa chạy trực tiếp, vừa import lại được (tái dùng hàm).
  • Bonus: tách hàm thuần (đếm điểm, đếm từ) để sau dễ VIẾT TEST (khoá nâng cao).

Hết khoá Python cơ bản 🎉 - bạn đã có 3 sản phẩm

Bạn đã đi trọn: làm quen & cách Python chạy → biến/đối tượng → int/float/bool/str → điều khiển luồng → hàm & phạm vi → list/tuple/dict/set → bản chất bytecode → lỗi & ngoại lệ → module/gói & venv/uv → và giờ là ba app chạy được trên GitHub. Bạn không chỉ viết được Python, mà còn HIỂU nó chạy thế nào. Bước tiếp: khoá Python nâng cao - OOP, kiểm thử, làm việc với tệp/CSDL/internet, và phần “khó mà hay”: GIL, đa luồng/đa tiến trình, free-threading không-GIL, async/await.

Câu hỏi thường gặp

Vì hầu hết app dòng lệnh đều theo khuôn: có DỮ LIỆU (list/dict), có phần XỬ LÝ (vòng lặp/hàm), và phần NHẬP-XUẤT (print/input/file). Nhận ra khuôn chung giúp bạn dựng app mới nhanh: chỉ thay dữ liệu và nghiệp vụ.

Bọc int(input(...)) trong try/except ValueError (bài 8). Nếu người dùng gõ "abc", int() ném ValueError; ta bắt và yêu cầu nhập lại trong một vòng while - chương trình không sập.

JSON là một định dạng văn bản để biểu diễn dữ liệu (list, dict, int/float, str). Module json đổi list/dict Python ↔ str JSON, nên rất hợp để lưu một list các dict ra file rồi đọc lại - dữ liệu “nhớ” qua mỗi lần chạy.

with open(path) as f: tự ĐÓNG file khi xong (kể cả khi có lỗi) - an toàn và gọn hơn tự gọi f.close(). Đây là một “context manager”; bạn sẽ học kỹ hơn ở khoá nâng cao.

Bài “Làm việc với hệ thống tệp” - khoá Python nâng cao →

Tách văn bản bằng .split() thành list từ, rồi đếm bằng một dict: dem[t] = dem.get(t, 0) + 1. Số TỪ KHÁC NHAU là len(set(tu)). Lọc/biến đổi nhanh bằng comprehension.

Hoàn thiện, chạy thử cho mượt, rồi đưa mỗi dự án lên một repo GitHub kèm README (cách chạy: uv run main.py). Đây là portfolio Python đầu tay - minh chứng bạn dựng được phần mềm thật.

Tick những điều em tự tin làm được. Càng lên cao, em càng hiểu sâu.

Tick những điều em tự tin làm được sau khi học bài này. 0/6

Trả lời vài câu để chắc rằng em đã nắm bài.

Câu 1/3 Điểm: 0

Khung chung mà cả ba app dòng lệnh trong bài đều theo là gì?

  1. 1

    Dựng Quiz

    Gõ lại app Quiz ở Bước 2, thêm 2 câu hỏi của riêng bạn, chạy và chấm điểm.

    Hoàn thành khi: Chạy bằng python (hoặc uv run); nhập đáp án ra đúng điểm N/đúng; gõ chữ không làm sập.

  2. 2

    Sổ việc nhớ được

    Viết app Sổ việc: thêm việc, đánh dấu xong, lưu vào todo.json; mở lại thấy còn nguyên.

    Hoàn thành khi: json.dump/json.load hoạt động; thoát rồi mở lại, danh sách việc vẫn còn.

  3. 3

    Đếm từ

    Viết app Phân tích văn bản: nhập một đoạn, in mỗi từ xuất hiện mấy lần và số từ khác nhau.

    Hoàn thành khi: Dùng split + dict.get để đếm; len(set(...)) cho số từ khác nhau.

  4. 4

    Từ dài nhất

    Bổ sung app đếm từ: in TỪ DÀI NHẤT (dùng max với key=len) và các từ > 3 ký tự (comprehension).

    Hoàn thành khi: max(tu, key=len) ra từ dài nhất; [t for t in tu if len(t) > 3] lọc đúng.

  5. 5

    Khung chung

    Chọn một dự án ở Bước 1 và viết ra đâu là Dữ liệu, đâu là Xử lý, đâu là Nhập-Xuất.

    Hoàn thành khi: Chỉ rõ ba phần - đúng khuôn list/dict → vòng lặp/hàm → print/input/file.

  6. 6

    Lên GitHub

    Đưa một dự án lên GitHub kèm README ghi cách chạy.

    Hoàn thành khi: Repo có mã nguồn + README (vd “uv run main.py”). Sản phẩm Python đầu tay của bạn.