Nhập môn Tư duy Lập trình/Phân rã — chia tới khi mỗi bước gõ được ngay
20/31
Bài 20 / 31~13 phútTừ đề bài tới thuật toánMiễn phí lượt xem

Phân rã — chia tới khi mỗi bước gõ được ngay

Ô xử lý ở giữa vẫn là một câu tiếng Việt to đùng. Phân rã là chia nó xuống, với đúng một tiêu chí dừng: bước đó gõ được ngay hay chưa.

TL;DR: Phân rã một lời giải là chia nó thành các bước nhỏ hơn cho tới khi mỗi bước gõ thành lệnh Python được ngay. Chỉ có đúng một tiêu chí để biết khi nào dừng chia: bước đó đã gõ được thành lệnh hay còn là một câu tiếng Việt mơ hồ. Ví dụ đếm số bạn Gioi, Kha, Yeu bắt đầu bằng ba bước lớn; bước "xác định xếp loại" vẫn là ý tưởng nên phải chia tiếp thành ba nhánh so sánh, hai bước kia đã gõ được nên dừng tại đó. Chia thêm bước đã gõ được là phí công; chia chưa đủ bước còn mơ hồ là bỏ dở giữa chừng.

Bạn đã bóc đề, giải tay vài ca, và vẽ được lưu đồ có cấu trúc. Nhưng gần như ai mới học cũng hỏi đúng một câu ở đây: bước "xác định xếp loại của một bạn" nghe rất rõ ràng, vậy tại sao máy vẫn không chạy được nó?

Vì "rõ ràng với bạn" và "gõ thành lệnh được" là hai chuyện khác nhau — và bài này chia một bước còn mơ hồ xuống tới khi nó chỉ còn phép so sánh, phép gán, hoặc lệnh in cụ thể, dừng đúng lúc, không chia thêm cho đẹp.

1. Analogy — bản hướng dẫn lắp ráp: chia tới đâu tay mới làm được

Một bản hướng dẫn lắp tủ có nhiều cách viết. Viết "lắp xong cái tủ" thì đúng nhưng vô dụng — không ai cầm một câu đó mà lắp được ngay. Viết "cầm ốc vít, xoay cổ tay 30 độ" thì lại thừa: người lắp tủ chỉ cần biết "vặn ốc A vào lỗ B bằng bốn con vít gỗ" là làm được ngay. Bản hướng dẫn tốt dừng đúng ở mức tay người đọc làm được — phân rã lời giải cũng vậy, mức vừa đủ là mức bạn gõ được thành lệnh Python.

Bản hướng dẫn lắp tủPhân rã lời giải
"Lắp xong cái tủ" — quá to, không ai làm ngay được"Giải xong bài toán" — quá to, không gõ được ngay
"Vặn ốc A vào lỗ B bằng bốn con vít gỗ" — đúng mức tay làm ngayMột bước gõ được thành 1–3 dòng lệnh Python
Không có bước "cầm tay siết từng thớ gỗ" — thừa, không ai chia tới đóKhông chia nhỏ hơn mức "gõ được ngay" — chia quá tay

2. Chia tới bao giờ thì thôi?

Tiêu chí dừng chỉ có một: bước đó GÕ THÀNH LỆNH ĐƯỢC NGAY hay chưa. Chưa thì chia tiếp, được rồi thì dừng — không chia thêm cho đẹp.

"Gõ được ngay" nghĩa là bạn viết được bước đó thành một phép gán, so sánh, lệnh print/input, if, hoặc vòng lặp — không còn khoảng trống phải tự suy diễn. "Xác định xếp loại" chưa đạt mức đó: không nói rõ so sánh với số nào. "Đọc danh sách điểm vào một biến" thì đã đạt: gõ diem = [...] là xong.

Ô XỬ LÝ ở giữa khung vào–xử lý–ra là đúng chỗ bạn đang phân rã. Bài 1 cố ý để nó còn nguyên một câu tiếng Việt; bài này chia đúng ô đó xuống tới khi mỗi mảnh gõ được ngay.

Cây phân rã: hộp nét đứt trên cùng ghi đếm cả lớp có bao nhiêu bạn Gioi, Kha, Yeu; ba mũi tên xuống ba hộp là đọc danh sách điểm vào một biến, với mỗi điểm xác định xếp loại, in ba con số đếm được; dưới hộp trái và hộp phải là hai ô xanh lá ghi gõ được ngay, dưới hộp giữa là ô cam ghi còn là câu tiếng Việt nên chia tiếp; từ ô cam một mũi tên xuống ô xanh lá cuối ghi nếu điểm từ 8 trở lên ra Gioi, còn nếu từ 5 trở lên ra Kha, còn lại ra Yeu, giờ mới gõ được

3. Phân rã ví dụ chạy chính — đếm lớp có bao nhiêu bạn Gioi, Kha, Yeu

Đề bài: một lớp có một danh sách điểm. Ngưỡng giữ nguyên như module trước — từ 8 trở lên là Gioi, từ 5 trở lên là Kha, còn lại Yeu. Đếm và in ra bao nhiêu bạn mỗi loại.

Tầng một

Phân rã lần đầu, chỉ nhìn "đề bài cần làm những việc lớn nào":

  1. đọc danh sách điểm vào một biến
  2. với MỖI điểm: xác định xếp loại
  3. in ba con số đếm được

Kiểm từng bước bằng tiêu chí dừng ở mục trước:

  • Bước 1 — gõ được ngay ✓: diem = [8, 5, 9, 3, 6, 4, 10, 2], không còn gì phải đoán.
  • Bước 2 — chưa gõ được: "xác định xếp loại" không nói so sánh với số mấy.
  • Bước 3 — gõ được ngay ✓: ba lệnh print(dem_gioi), print(dem_kha), print(dem_yeu).

Hai trên ba bước dừng lại được, chỉ bước giữa cần chia thêm một tầng.

Tầng hai — chia riêng bước còn mơ hồ

Bước 1 và 3 đã gõ được, chia thêm là phí công (bẫy "chia quá tay" bên dưới). Bạn chỉ chia bước 2:

nếu điểm từ 8 trở lên → Gioi; còn nếu từ 5 trở lên → Kha; còn lại → Yeu

Đây là lưu đồ con của bước 2, vẽ bằng đúng bốn ký hiệu đã học ở bài trước:

Lưu đồ con: hình bầu dục ghi vào một điểm, xuống hình thoi hỏi diem từ 8 trở lên, nhánh đúng đi sang phải tới hộp xep_loai gán chuỗi Gioi, nhánh sai đi xuống hình thoi thứ hai hỏi diem từ 5 trở lên, nhánh đúng đi sang phải tới hộp xep_loai gán chuỗi Kha, nhánh sai đi xuống hộp xep_loai gán chuỗi Yeu; cả ba hộp kết quả cùng đổ về hình bầu dục ghi ra một chuỗi xếp loại

Đọc theo đúng ký hiệu đã học: từ bầu dục vào, gặp thoi hỏi điểm có từ 8 trở lên không, đúng thì rẽ ngang vào chữ nhật gán Gioi; sai thì xuống thoi thứ hai hỏi từ 5 trở lên, rồi mới rẽ vào Kha hoặc Yeu. Ba nhánh, hai câu hỏi lồng nhau, và mỗi hộp giờ gõ được ngay bằng if / elif / else:

diem = [8, 5, 9, 3, 6, 4, 10, 2]

dem_gioi = 0
dem_kha = 0
dem_yeu = 0

for d in diem:
    if d >= 8:
        dem_gioi = dem_gioi + 1
    elif d >= 5:
        dem_kha = dem_kha + 1
    else:
        dem_yeu = dem_yeu + 1

print(dem_gioi)
print(dem_kha)
print(dem_yeu)

Tiêu chí "gõ được ngay" không mơ hồ, vì máy chỉ thi hành đúng từng lệnh một, không suy diễn ý định — nghĩa là bạn phải viết thành đúng một lệnh máy làm được, không còn là ý định chờ diễn giải thêm.

4. 🖊️ Thử đoán

🖊️ Thử đoán

Đề bài: đọc danh sách điểm vào một biến, kiểm tra xem có bạn nào bị nhập điểm âm (gõ nhầm dấu trừ) không; nếu có thì in "Co du lieu loi", không thì in "Du lieu hop le". Phân rã thành ba bước tầng một, y hệt cách chia ở ví dụ Gioi/Kha/Yeu:

  1. đọc danh sách điểm vào một biến
  2. kiểm tra xem có điểm nào âm không
  3. in kết quả tương ứng

Bước nào gõ được ngay, bước nào còn phải chia tiếp? Viết câu trả lời ra giấy trước khi mở phần dưới.

Kết quả

5. Tới lượt bạn

Đề bài: một quán trà sữa ghi lại giá tiền các đơn hàng trong một buổi. Viết chương trình đọc danh sách giá tiền đó, rồi in ra hai con số: có bao nhiêu đơn từ 50000 trở lên (đơn "lớn"), và bao nhiêu đơn dưới 50000 (đơn "nhỏ").

Tự phân rã đề này theo đúng quy trình vừa học: viết tầng một — những việc lớn đề bài cần làm; với mỗi bước, tự hỏi đúng một câu bước này gõ thành lệnh Python được ngay chưa; bước nào trả lời "chưa" thì chia tiếp, cho tới khi mọi bước đều trả lời "được".

Đừng chép khung của ví dụ Gioi/Kha/Yeu — đề trà sữa chỉ có hai nhóm thay vì ba, nên số tầng và số nhánh sẽ khác. Việc của bạn là tự áp tiêu chí dừng, không phải khớp hình dạng của ví dụ cũ.

6. Bẫy thường gặp

Chia quá tay: chia một bước đã gõ được ngay thành nhiều bước nhỏ hơn nữa, ví dụ tách dem_gioi = dem_gioi + 1 thành "lấy giá trị", "cộng thêm 1", "gán lại". Kết quả là một bản liệt kê gần như từng dòng code, không còn là lời giải. ✅ Bước đã gõ được thành 1–3 dòng lệnh liền mạch thì dừng lại, không chia thêm.

Chia lệch tầng: một nhánh chia tới tận lệnh cụ thể, nhánh song song thì vẫn ở mức ý tưởng. Ví dụ "nếu điểm từ 8 trở lên thì dem_gioi = dem_gioi + 1, còn lại thì xử lý phù hợp" — nhánh sau ("xử lý phù hợp") chưa gõ được. ✅ Kiểm tiêu chí dừng cho TỪNG nhánh song song. Hai nhánh của cùng một quyết định phải dừng ở cùng một mức cụ thể.

Đặt tên bước bằng danh từ mơ hồ: "xử lý dữ liệu", "tính toán kết quả" — nghe hợp lý nhưng không nói bạn phải làm động tác gì. ✅ Đặt tên bước bằng động từ cụ thể làm được ngay: "cộng thêm 1 vào dem_gioi", "so sánh điểm với 8".

7. 📚 Đào sâu

📚 Đào sâu

Phân rã không phải kỹ năng riêng của Python — tiêu chí dừng ("gõ được ngay chưa?") không phụ thuộc cú pháp ngôn ngữ nào, nên chuyển thẳng sang bất kỳ ngôn ngữ bạn học sau này.

Một nghiên cứu năm 2026 phân tích 55 sơ đồ phân rã bài toán do sinh viên nhập môn tự vẽ, và phát hiện 51 trong số đó — khoảng 93% — thiếu ít nhất một thành phần bắt buộc mà giảng viên yêu cầu. Vấn đề không phải sơ đồ vẽ xấu hay đẹp — sinh viên dừng phân rã quá sớm, bỏ sót những mảnh còn mơ hồ mà không nhận ra, đúng bẫy "chia lệch tầng" ở mục trên nhưng xảy ra trên diện rộng cả lớp học.

Ghi chú: tiêu chí dừng tường minh, chứ không phải kỹ năng vẽ đẹp, mới là thứ quyết định một bản phân rã có dùng được hay không.

8. Liên hệ các bài khác

  • Bài 1 — Đọc đề — ô xử lý của khung vào–xử lý–ra ở bài đó còn nguyên một câu; bài này là chỗ bạn quay lại chia đúng ô đó.
  • Bài 2 — Làm tay trước khi làm máy — quy luật rút ra khi giải tay ba ca cụ thể chính là nguyên liệu cho từng bước phân rã.
  • Bài 3 — Lưu đồ có cấu trúc — bốn ký hiệu của bài đó dùng để vẽ lại đúng những gì bạn vừa phân rã.
  • Bài 5 — Hàm — mỗi bước đã "gõ được ngay" là ứng viên tự nhiên để gói thành một hàm có tên.

9. Tóm tắt

  • Phân rã một đề nhiều bước là chia liên tục cho tới khi mỗi bước gõ thành lệnh Python được ngay; không có mức "vừa đủ" nào khác ngoài tiêu chí đó.
  • Ví dụ đếm Gioi/Kha/Yeu cho thấy ba bước tầng một không đều nhau: hai bước đã gõ được ngay, một bước còn phải chia tiếp thành ba nhánh Gioi/Kha/Yeu qua hai quyết định lồng nhau.
  • Lưu đồ ghi lại đúng những gì bạn phân rã — dùng lại bốn ký hiệu đã học, không cần ký pháp riêng cho "phân rã".
  • Ba lỗi chia quá tay, chia lệch tầng và đặt tên mơ hồ đều không làm chương trình báo lỗi gì — chúng chỉ âm thầm làm bản phân rã vô dụng, phải soi bằng mắt mới thấy.
  • Bài sau dùng đúng các bước "gõ được ngay" này làm ranh giới để gói thành hàm có tên.

10. Tự kiểm tra

Tự kiểm tra
0/7 câu đã trả lời
  1. Q1
    Vì sao tiêu chí dừng khi phân rã không phải là "chia đủ ba tầng" hay "mỗi bước một dòng code", mà là một câu hỏi duy nhất?
  2. Q2
    Trong ví dụ đếm Gioi/Kha/Yeu, vì sao bước "với mỗi điểm: xác định xếp loại" chưa gõ được ngay ở tầng một?
  3. Q3
    Đoạn code sau in gì? diem = [7, 5, 2] dem_gioi = 0 dem_kha = 0 dem_yeu = 0 for d in diem: if d >= 8: dem_gioi = dem_gioi + 1 elif d >= 5: dem_kha = dem_kha + 1 else: dem_yeu = dem_yeu + 1 print(dem_gioi) print(dem_kha) print(dem_yeu)
  4. Q4
    Vì sao đặt tên một bước là "xử lý dữ liệu" lại là dấu hiệu cảnh báo khi phân rã, kể cả khi bước đó nghe rất hợp lý?
  5. Q5
    Bạn phân rã một quyết định thành "nếu đúng thì cộng 1 vào biến đếm, nếu sai thì xử lý phù hợp". Bước này đã dừng chia được chưa? Vì sao?
  6. Q6
    Cùng một bản phân rã, vì sao ghi bằng lưu đồ lại nói được nhiều hơn ghi bằng danh sách gạch đầu dòng?
  7. Q7
    Vì sao kỹ năng phân rã học ở bài này không gắn riêng với Python?

Bài tiếp theo: Hàm — đặt tên cho một nhóm bước, nhận vào gì trả ra gì

Bài này đáng gửi cho bạn học cùng?

Copy link đã gắn nguồn — dán group, chat, hoặc LinkedIn.

Bài này có giúp bạn hiểu bản chất không?

Hỏi đáp về bài này

Chưa có câu hỏi

Đặt câu hỏi

Có gì chưa rõ trong bài? Đặt câu hỏi đầu tiên — câu trả lời từ cộng đồng giúp bạn (và người sau).

Đặt câu hỏi đầu tiên

Bài tiếp theo

Hàm — đặt tên cho một nhóm bước, nhận vào gì trả ra gì