Đọc đề — vào cái gì, ra cái gì, ràng buộc gì
Đề bài lẫn dữ kiện với yêu cầu. Bước đầu không phải nghĩ cách giải, mà là bóc nó thành ba ô: vào cái gì, ra cái gì, ràng buộc gì.
TL;DR: Một đề bài chỉ là một câu tiếng Việt, nhưng code không chấp nhận sự mơ hồ của tiếng Việt. Trước khi gõ dòng đầu tiên, bạn bóc đề thành ba ô cố định: VÀO (dữ liệu được cho, kèm kiểu và ràng buộc), XỬ LÝ (việc phải làm — được phép còn là một câu tiếng Việt ở bước này), RA (đúng một kết quả cụ thể). Điểm dễ bỏ sót nhất là ô VÀO: ghi tên dữ liệu thôi chưa đủ, phải ghi cả kiểu (số hay chuỗi) lẫn ràng buộc (khoảng giá trị, có thể rỗng hay không) — Thiếu chi tiết nào, chi tiết đó quay lại thành lỗi lúc bạn viết code.
Bạn vừa xong module 2: rẽ nhánh, vòng lặp, danh sách — biết gõ if, while, for thành thạo. Giờ cô giáo, hoặc đề bài trong sách, đưa bạn đúng một câu: "Cho danh sách điểm của cả lớp. In ra điểm cao nhất." Không có gợi ý gì thêm. Bạn mở trình soạn thảo, ngón tay đặt trên phím, và không biết gõ dòng đầu tiên là gì.
Vấn đề không phải bạn thiếu công cụ — for và if bạn đã có cả rồi. Vấn đề là đề bài viết bằng tiếng Việt, còn code thì không chấp nhận sự mơ hồ của tiếng Việt. Người viết code có kinh nghiệm không nhảy thẳng vào gõ; họ có một bước trung gian cố định: bóc câu văn xuôi đó thành ba ô rõ ràng, trước khi nghĩ tới một dòng code nào.
1. Analogy — máy pha cà phê tự động
Hình dung một máy pha cà phê tự động ở văn phòng. Bạn đổ hạt cà phê và nước vào phễu — đúng loại máy yêu cầu, không phải hạt gì cũng đổ vào được. Máy nghiền, ép, pha theo đúng một quy trình cố định, không đổi tuỳ hứng giữa chừng. Rồi một cốc cà phê ra ở vòi: đúng một cốc, không phải bã cà phê lẫn nước dư chảy tràn ra bàn.
Ba giai đoạn đó có tên riêng khi bạn giải một đề bài lập trình:
| Máy pha cà phê | Ba ô của một đề |
|---|---|
| Hạt cà phê + nước, đúng loại máy yêu cầu | VÀO — dữ liệu được cho, kèm kiểu và ràng buộc |
| Nghiền, ép, pha theo quy trình cố định | XỬ LÝ — việc phải làm với dữ liệu vào |
| Một cốc cà phê ra ở vòi | RA — đúng một kết quả cụ thể |
Máy pha cà phê không tự hỏi "nước bao nhiêu là đủ" giữa chừng — mọi ràng buộc đã được khai từ đầu, lúc đổ nguyên liệu vào phễu. Đề bài lập trình cũng vậy: ô VÀO càng khai rõ ngay từ đầu, ô XỬ LÝ càng đỡ phải đoán mò.
2. Ba ô: input, xử lý, output — bóc đề mẫu
Quay lại đúng câu đề ở đầu bài: "Cho danh sách điểm của cả lớp. In ra điểm cao nhất." Bóc nó ra ba ô:
- VÀO: một danh sách số · mỗi số từ 0 tới 10 · danh sách có thể rỗng
- XỬ LÝ: tìm số lớn nhất trong danh sách (còn là một câu tiếng Việt — bài 04 mới phân rã tiếp)
- RA: đúng một số, là điểm cao nhất, in ra màn hình

Để ý: câu đề gốc chỉ có một câu ngắn, nhưng ba ô phía trên nhiều chữ hơn hẳn đề gốc. Đó không phải bạn bịa thêm — đó là bạn làm rõ những thứ đề bài giấu trong hai chữ "danh sách điểm" và "điểm cao nhất". Đề không nói điểm nằm trong khoảng nào, không nói danh sách có bắt buộc phải có ít nhất một điểm hay không, và không nói "điểm cao nhất" được in ra màn hình hay được đưa cho chỗ khác dùng tiếp. Ba câu hỏi đó, bạn phải tự trả lời trước khi gõ dòng code đầu tiên.
3. Vì sao ô VÀO phải ghi cả kiểu lẫn ràng buộc?
So sánh hai cách viết ô VÀO cho cùng một đề:
- "một danh sách điểm" — chỉ có tên dữ liệu.
- "một danh sách số, mỗi số từ 0 tới 10, danh sách có thể rỗng" — có tên, có kiểu, có ràng buộc.
Cách viết đầu nghe cũng xuôi tai, nhưng nó không nói cho bạn biết mỗi phần tử là số hay chuỗi, không nói khoảng giá trị hợp lệ, và không nói danh sách rỗng có xảy ra hay không. Ba chỗ trống đó không tự biến mất — chúng chỉ dời sang lúc bạn viết code, và ở đó chúng biến thành lỗi bạn phải debug ngược lại tận đề bài.
Bài đó bạn đã học: thứ gõ vào bằng input() luôn là chuỗi, muốn tính toán được phải tự đổi sang số bằng int(...). Đó là lý do ô VÀO ở đây ghi "một danh sách số" chứ không phải chép lại chữ trong đề — đó là một quyết định có hệ quả: nếu dữ liệu này đến từ người dùng gõ tay, bạn còn phải tự chuyển đổi kiểu trước khi dùng được.
Ràng buộc "danh sách có thể rỗng" ở đề điểm số cũng là một quyết định kiểu vậy: đề không nói gì về việc lớp có thể chưa nhập điểm ai, nhưng bạn vẫn ghi nó vào ô VÀO, vì đó là một khả năng có thật và bạn cần biết nó tồn tại trước khi viết XỬ LÝ. Ghi ra không có nghĩa là bạn đã giải quyết nó ngay — ràng buộc này quay lại đúng chỗ ở bài 06 — Ca biên, khi bạn học cách xử lý nó cho đàng hoàng. Việc của bài này chỉ là đừng bỏ sót.
4. Thử đoán — tự bóc một đề
Đề mới: "Cho danh sách tên các bạn trong lớp. In ra tên xếp đầu tiên theo thứ tự bảng chữ cái." Ô XỬ LÝ cho sẵn dưới đây, bạn tự điền VÀO và RA.
- VÀO: tự điền
- XỬ LÝ: tìm tên đứng đầu theo thứ tự bảng chữ cái trong danh sách
- RA: tự điền
Viết ra giấy ô VÀO và ô RA của đề trên, theo đúng khuôn đã học ở mục 2: VÀO có tên, có kiểu, có ràng buộc; RA là đúng một kết quả cụ thể. Đừng mở đáp án trước khi viết xong.
- VÀO: một danh sách chuỗi (tên) · mỗi tên không rỗng · danh sách có ít nhất một tên
- XỬ LÝ: tìm tên đứng đầu theo thứ tự bảng chữ cái trong danh sách
- RA: đúng một chuỗi, là tên đứng đầu bảng chữ cái, in ra màn hình
Để ý ràng buộc VÀO ở đây khác đề điểm số: đề điểm cho phép danh sách rỗng, còn đề tên lại cần "ít nhất một tên". Ràng buộc không phải công thức chép y hệt giữa các đề — nó phải suy ra từ chính XỬ LÝ. Cả hai đề đều bí như nhau khi danh sách trống — không có phần tử nào để so sánh. Khác nhau nằm ở quyết định của người ra đề: đề điểm cho phép lớp rỗng và bắt lời giải xử lý ca đó, còn đề tên loại nó khỏi phạm vi ngay từ ô ràng buộc.
5. Tới lượt bạn
Đề: "Cho hai số nguyên là điểm thi giữa kỳ và điểm thi cuối kỳ. In ra điểm trung bình, biết cuối kỳ tính gấp đôi giữa kỳ." Tự bóc đề này thành ba ô — bài này không có đáp án mẫu cho đề này.
Trước khi coi là xong, tự hỏi ba câu:
- Ô VÀO có ghi rõ kiểu (số nguyên hay số thực) và ràng buộc (điểm có thể âm không, có giới hạn trên không) chưa?
- Ô XỬ LÝ có đang là một câu tiếng Việt bình thường, hay bạn đã cố nhét công thức Python vào đó?
- Ô RA có đúng một kết quả, và bạn biết rõ nó là số nguyên hay số thực chưa?
Ba câu hỏi trên chính là cách bạn tự chấm bài tập này, không cần đáp án mẫu nào cả.
6. Bẫy thường gặp
Bẫy nặng nhất: đọc đề xong là mở ngay trình soạn thảo, gõ for hay if mà chưa viết ra ba ô. Bạn sẽ code được vài dòng rồi khựng lại, xoá đi viết lại, vì chưa biết chắc VÀO là gì. Ba ô là bước tiết kiệm thời gian, không phải tốn thêm.
Bẫy thứ hai nằm ở ô VÀO: chép lại đúng chữ trong đề ("một danh sách điểm") mà bỏ kiểu và ràng buộc — mục 3 vừa nói vì sao đây là chỗ nguy hiểm nhất.
Bẫy thứ ba nằm ở ô RA: viết chung chung như "in ra kết quả" thay vì "đúng một số, là điểm cao nhất". Đến lúc code, "kết quả" không nói bạn nên in một số, một danh sách, hay một câu chữ — ba đoạn code khác hẳn nhau.
7. 📚 Đào sâu — I-P-O không phải phát minh riêng của lập trình
Khung ba ô bạn vừa dùng có tên chính thức: I-P-O — input, process, output (vào, xử lý, ra). Nó không phải mẹo riêng của lập trình: người ta dùng khung này để mô tả bất kỳ cỗ máy xử lý nào, từ máy giặt (vào: quần áo, nước, bột giặt — xử lý: quay, xả, vắt — ra: quần áo sạch) tới cả một dây chuyền nhà máy. Lập trình chỉ mượn nó rồi thu nhỏ xuống mức một hàm.
Bạn sẽ gặp lại khung này ở quy mô lớn hơn khi phân rã một đề nhiều bước (bài 04): mỗi bước con cũng có VÀO, XỬ LÝ, RA riêng của nó — chỉ khác là VÀO của bước sau thường chính là RA của bước trước.
8. Liên hệ các bài khác
- Bài 7 module 2 — Tổng kết module —
if/while/forbạn học ở đó là công cụ để gõ ra ô XỬ LÝ, sau khi nó được phân rã đủ nhỏ. - Bài 02 — Làm tay trước khi làm máy — sau khi có ba ô, bước tiếp theo là giải tay vài ca cụ thể trước khi viết bước chung.
- Bài 04 — Phân rã — nơi ô XỬ LÝ từ một câu tiếng Việt được tách nhỏ tới mức gõ được ngay.
- Bài 06 — Ca biên — nơi ràng buộc "danh sách có thể rỗng" bạn ghi ở mục 3 quay lại, và bạn học cách không để chương trình gãy vì nó.
9. Tóm tắt
- Đề càng ngắn càng dễ chủ quan bỏ qua bước bóc ba ô; đề một câu chính là chỗ người ta hay nhảy thẳng vào code nhất.
- Ô VÀO thiếu kiểu hoặc thiếu ràng buộc là ô VÀO chưa xong; "một danh sách số, có thể rỗng" khác hẳn "một danh sách".
- Ràng buộc không phải lúc nào cũng nằm sẵn trong đề — có ràng buộc bạn phải tự suy ra và ghi rõ thành giả định.
- XỬ LÝ được phép còn là một câu tiếng Việt ở bước này; ép nó thành code ngay là đang nhảy cóc quy trình.
- RA luôn là đúng một kết quả cụ thể, không phải một câu mô tả chung chung.
10. Tự kiểm tra
- Q1Vì sao ô VÀO ghi "một danh sách số, mỗi số từ 0 tới 10, danh sách có thể rỗng" tốt hơn ghi "một danh sách điểm"?
- Q2Đề chỉ nói "cho danh sách điểm", không nói khoảng điểm là 0 tới 10. Ràng buộc đó từ đâu ra, và vì sao vẫn cần ghi vào ô VÀO?
- Q3Vì sao ô XỬ LÝ ở bài này được phép viết "tìm số lớn nhất trong danh sách" — một câu tiếng Việt — mà không cần gõ được ngay?
- Q4Nếu ô RA của bạn viết "in ra kết quả" thay vì "in ra đúng một số là điểm cao nhất", điều gì có thể xảy ra khi bạn bắt đầu viết code?
- Q5Đề tên ("in ra tên đứng đầu bảng chữ cái") cần ràng buộc "danh sách có ít nhất một tên", trong khi đề điểm lại cho phép "danh sách có thể rỗng" — vì sao hai ràng buộc này khác nhau dù cùng dạng đề?
- Q6Bạn gặp một đề hoàn toàn mới, không giống ví dụ nào ở bài này. Bạn nên bắt đầu từ đâu?
Bài tiếp theo: Làm tay trước khi làm máy — giải ba ca rồi mới rút quy luật
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
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