Nhập môn Tư duy Lập trình/Rẽ nhánh — điều kiện là một biểu thức đúng hoặc sai
9/31
Bài 9 / 31~10 phútRẽ nhánh & lặpMiễn phí lượt xem

Rẽ nhánh — điều kiện là một biểu thức đúng hoặc sai

Lần đầu tiên thứ tự trên xuống bị bẻ. Máy tính điều kiện ra đúng hoặc sai, đi đúng một nhánh, và bỏ qua hoàn toàn các nhánh còn lại — kể cả nhánh trông có vẻ cũng hợp.

TL;DR: Một điều kiện không phải câu mệnh lệnh, nó là một câu hỏi mà máy tính ra đúng hoặc sai. Gặp if rồi một chuỗi elif, máy hỏi từng câu theo thứ tự từ trên xuống, dừng ở câu đúng đầu tiên, chạy đúng khối đó rồi nhảy thẳng xuống dưới cả cụm. Tài liệu tham chiếu Python viết thẳng rằng khi một nhánh đã chạy thì "không phần nào khác của câu lệnh if được thi hành hoặc được tính". Hệ quả trực tiếp cho việc trace: nhánh không được chọn hoàn toàn vắng mặt khỏi bảng trace, không để lại một hàng nào.

Từ đầu khoá tới giờ, mọi chương trình bạn đọc đều chạy thẳng một mạch: dòng 1, dòng 2, dòng 3, hết. Nhưng chương trình thật phải biết chọn. Đơn hàng trên hai trăm nghìn thì phí ship khác, dưới thì khác. Điểm từ tám trở lên xếp giỏi, không thì không.

Bài này cho bạn cấu trúc để máy chọn đường — và quan trọng hơn, cho bạn cách nhìn ra nhánh nào không chạy, thứ mà đọc lướt gần như không bao giờ thấy.

1. Analogy — quầy soát vé có nhiều cửa

Bạn xếp hàng vào một sự kiện có ba cửa, treo biển theo thứ tự: cửa VIP, cửa vé thường, cửa vé mời. Nhân viên nhìn vé bạn, hỏi lần lượt từ trái sang. "VIP không?" Không. "Vé thường không?" Đúng rồi — thế là bạn đi cửa hai, và nhân viên không thèm hỏi tiếp câu thứ ba. Không phải anh ta hỏi rồi bỏ qua câu trả lời; anh ta dừng luôn ở đó.

Quầy soát véRẽ nhánh trong code
Mỗi biển là một câu hỏi có/khôngMỗi điều kiện cho ra đúng hoặc sai
Hỏi lần lượt từ trái sang phảiMáy tính từng điều kiện từ trên xuống
Dừng ở câu trả lời "đúng" đầu tiênDừng ở nhánh đúng đầu tiên
Các biển sau không được hỏi tớiCác nhánh sau không được tính tới
Không khớp biển nào thì đi cửa cuốiKhông nhánh nào đúng thì chạy else
💡 Cách nhớ

ifelifcâu hỏi. elsecửa cuối — nó không hỏi gì cả, nó chỉ nhận những ai không lọt qua cửa nào phía trên.

2. Điều kiện là một câu hỏi, không phải một mệnh lệnh

Dấu = một gạch là phép gán: nó chép giá trị vào ô nhớ bên trái. Nó không hỏi gì hết. Bài này dùng dấu == hai gạch, và đó là thứ hoàn toàn khác: một câu hỏi so sánh hai bên có bằng nhau không.

Trước khi xem if, hãy nhìn riêng phần điều kiện. Với diem đang bằng 7:

diem = 7

# Moi dong duoi day la mot CAU HOI, khong phai mot menh lenh
print(diem >= 8)
print(diem >= 5)
print(diem == 7)

Output thật:

False
True
True

FalseTrue là hai giá trị duy nhất một câu hỏi có thể cho ra. Chúng là một kiểu riêng, y như số và chuỗi là hai kiểu riêng ở module trước. Cả if lẫn elif đều không làm gì khác ngoài việc nhìn vào một trong hai giá trị này rồi quyết định có chạy khối bên dưới hay không.

Các câu hỏi so sánh bạn dùng suốt module: == (bằng nhau), != (khác nhau), >< (lớn hơn, nhỏ hơn), >=<= (lớn hơn hoặc bằng, nhỏ hơn hoặc bằng).

Một gạch hay hai gạch

diem = 8gán: nó đặt diem thành 8, xoá mất giá trị cũ. diem == 8hỏi: nó không đổi gì cả, chỉ cho ra True hoặc False. Viết nhầm một gạch vào chỗ cần hỏi là lỗi kinh điển của người mới ở mọi ngôn ngữ.

3. Máy chạy nhánh nào khi hai điều kiện cùng đúng?

Đoạn code xếp loại theo điểm:

diem = 7

if diem >= 8:
    xep_loai = "Gioi"
elif diem >= 5:
    xep_loai = "Kha"
else:
    xep_loai = "Yeu"

print(xep_loai)

Máy đi thế này, từng nhịp một:

Sơ đồ luồng: hộp nét đứt diem = 7 ở trên, mũi tên xuống hình thoi hỏi diem lớn hơn hoặc bằng 8, nhánh đúng đi sang phải tới hộp mờ xep_loai gán chuỗi Gioi, nhánh sai đi xuống hình thoi thứ hai hỏi diem lớn hơn hoặc bằng 5, nhánh đúng đi sang phải tới hộp nhấn màu xanh xep_loai gán chuỗi Kha, nhánh sai đi xuống hộp mờ xep_loai gán chuỗi Yeu

Hai ô mờ trên hình là thứ đáng để ý nhất. Với diem bằng 7, máy chưa từng đọc tới dòng xep_loai = "Gioi" lẫn dòng xep_loai = "Yeu". Chúng không chạy rồi bị ghi đè; chúng đứng ngoài đường đi.

Tài liệu tham chiếu Python nói đúng chuyện này: câu lệnh if "chọn đúng một trong các khối bằng cách tính các biểu thức lần lượt cho tới khi gặp một biểu thức đúng; rồi khối đó được thi hành (và không phần nào khác của câu lệnh if được thi hành hoặc được tính)".

Từ elif là viết tắt của "else if", đúng như tài liệu ghi. Nghĩa là nó vừa đóng vai "nếu các câu trên đều sai", vừa đặt thêm một câu hỏi mới.

4. Thử đoán trước khi đọc tiếp

Vẫn đoạn code ở mục 3, nhưng đổi dòng đầu thành diem = 9.

🖊️ Thử đoán

Chương trình in ra chuỗi nào? Và trong ba dòng gán xep_loai, có bao nhiêu dòng thật sự chạy? Viết cả hai câu trả lời ra giấy rồi mới bấm nút.

Kết quả

5. Tới lượt bạn — điền cột "câu hỏi ra gì"

Bảng trace: cột là biến, hàng là dòng lệnh vừa chạy xong, mỗi hàng ghi lại giá trị hiện tại của mọi biến. Bài này giữ nguyên cách đọc đó và thêm đúng một cột mới — kết quả của câu hỏi ở dòng đó.

Đoạn code tính phí ship:

tong_don = 250000

if tong_don >= 500000:
    phi = 0
elif tong_don >= 200000:
    phi = 15000
else:
    phi = 30000

print(phi)

Bảng trace dưới đây điền sẵn hai hàng đầu. Ba hàng còn lại để trống — cột "Câu hỏi ra gì" ghi True, False, hoặc dấu gạch khi dòng đó không phải câu hỏi; cột phi ghi giá trị sau khi dòng đó chạy xong.

DòngLệnhCâu hỏi ra gìtong_donphi
1tong_don = 250000250000
3if tong_don >= 500000:False250000
5elif tong_don >= 200000:
6phi = 15000
10print(phi)
🖊️ Dừng lại — điền ba hàng còn thiếu

Chép bảng ra giấy và điền nốt. Rồi trả lời thêm một câu không có trong bảng: dòng nào của đoạn code này không hề chạy? Xong hết mới bấm nút bên dưới.

Đáp án

6. Bẫy thường gặp khi viết nhiều nhánh

Nhầm 1 — tưởng mọi nhánh đều được kiểm tra. Người mới hay nghĩ máy chạy hết cả cụm rồi mới chọn kết quả cuối. Nếu đúng vậy thì với diem bằng 9, xep_loai sẽ thành "Kha" (nhánh sau ghi đè nhánh trước), chứ không phải "Gioi".

✅ Máy dừng ở nhánh đúng đầu tiên rồi nhảy hẳn ra ngoài cụm. Muốn kiểm tra suy nghĩ của mình, hỏi: "nếu hai điều kiện cùng đúng, cái nào thắng?" — luôn là cái ở trên.

Nhầm 2 — xếp thứ tự nhánh sai mà không báo lỗi. Đảo hai nhánh của đoạn xếp loại:

if diem >= 5:
    xep_loai = "Kha"
elif diem >= 8:
    xep_loai = "Gioi"

Đoạn này chạy trơn tru, không lỗi cú pháp, không lỗi lúc chạy. Nhưng diem bằng 9 giờ ra "Kha" — vì diem >= 5 đúng trước, và nhánh "Gioi" vĩnh viễn không bao giờ chạy được với bất kỳ giá trị nào.

✅ Với các nhánh so sánh theo ngưỡng, xếp từ hẹp nhất tới rộng nhất. Nhánh nào bao trùm nhánh khác phải đứng sau.

7. 📚 Đào sâu — tài liệu tham chiếu Python

📚 Đào sâu (không bắt buộc)

8. Compound statements — Python documentation — mục "The if statement" là nguồn của câu trích ở mục 3. Đây là tài liệu tham chiếu, viết cho người cần độ chính xác tuyệt đối, nên câu chữ khô hơn hẳn tài liệu hướng dẫn — nhưng đúng chỗ này thì cái khô đó lại quý: nó nói thẳng "no other part of the if statement is executed or evaluated", tức là không tính, không chỉ là không chạy.

4. More Control Flow Tools — Python documentation — bản hướng dẫn dễ đọc hơn cho cùng chủ đề, kèm câu giải thích elif là viết tắt của "else if".

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

9. Tóm tắt

  • Nghi thứ tự nhánh sai? Lấy một giá trị nằm trong vùng chồng lấn của hai ngưỡng rồi hỏi nhánh nào thắng; ra khác ý bạn là thứ tự đang sai.
  • Có nhánh nào trong code bạn chưa bao giờ thấy chạy? Kiểm xem nhánh phía trên nó có bao trùm nó không — nhánh chết không báo lỗi bao giờ.
  • Trace mà bảng thiếu hàng cho một dòng gán? Đúng rồi, không phải bạn quên: dòng ở nhánh không được chọn thì không có hàng nào cả.
  • Trace tới dòng elif mà không biết điền gì vào cột biến? Điền dấu gạch: elif chỉ hỏi, việc gán nằm ở dòng bên trong khối.
  • Định viết if x = 5? Python sẽ dừng ngay tại đó — đây là một trong số ít lỗi loại này mà bạn được báo thẳng.

10. Tự kiểm tra

Tự kiểm tra
0/6 câu đã trả lời
  1. Q1
    Vì sao nói các nhánh không được chọn là "không hề chạy", chứ không phải "chạy rồi bị bỏ kết quả"? Hai cách nói này khác nhau ở đâu?
  2. Q2
    Với diem = 9, cả hai điều kiện diem >= 8diem >= 5 đều đúng. Vì sao chỉ một nhánh chạy, và nhánh nào?
  3. Q3
    Nếu đảo hai nhánh thành if diem >= 5 trước rồi elif diem >= 8, chương trình có báo lỗi không? Chuyện gì xảy ra?
  4. Q4
    Ở bảng trace mục 5, hàng của dòng elif tong_don >= 200000: có cột câu hỏi bằng True nhưng cột phi vẫn để trống. Vì sao?
  5. Q5
    Dấu = và dấu == khác nhau thế nào? Điều gì xảy ra nếu bạn định hỏi mà lại viết một gạch?
  6. Q6
    Khi xếp nhiều nhánh so sánh theo ngưỡng, vì sao phải đặt ngưỡng hẹp nhất lên trên? Cho một cách tự kiểm tra nhanh trước khi chạy code.

Bài tiếp theo: Điều kiện phức hợp — and, or, not

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

Điều kiện phức hợp — and, or, not