Unit 04 · lesson
`if`, `elif`, and `else`
if, elif, and else
Core path: 30 minutes
A comparison gives us True or False. How does that change execution?
This is where a program stops being a straight line.
Until now, most of our code has executed top to bottom with every line getting its turn. A conditional introduces a fork: some statements run only when a condition is true.
Start with one gate
score = 85
if score >= 70:
print("You passed.")
Read it as:
Evaluate
score >= 70. If the result isTrue, execute the indented block.
The condition does not "contain" the branch. It controls whether Python enters the block.
score = 85
↓
85 >= 70 ?
↓ True
print("You passed.")
If score were 60, Python would skip that indented line and continue after the block.
Indentation is executable structure
if score >= 70:
print("You passed.")
print("Nice work.")
print("Program finished.")
The first two print() calls belong to the if block because they are indented under it.
The final line is outside the block.
So if the score is 60:
"You passed." skipped
"Nice work." skipped
"Program finished." runs
Indentation is not visual decoration in Python. It changes which statements belong to which control structure.
else handles the opposite path
score = 60
if score >= 70:
print("You passed.")
else:
print("You did not pass yet.")
Exactly one of those branches runs.
Think of else as:
None of the earlier conditions in this chain succeeded, so use the fallback path.
It does not need another condition because it represents everything left over.
elif creates more possible outcomes
score = 85
if score >= 90:
print("A")
elif score >= 80:
print("B")
elif score >= 70:
print("C")
else:
print("Needs improvement")
Python checks the conditions in order.
For score = 85:
85 >= 90 ? False
↓
85 >= 80 ? True
↓
print("B")
↓
STOP CHECKING THIS CHAIN
The >= 70 condition is also mathematically true for 85, but Python never reaches it. The earlier elif already won.
That is the part students often miss.
Use the live branch model as an execution trace
Change the score. Watch Python choose a branch.
Move one input value and watch the first true condition become the only active execution path.
Drag score across the grade boundaries. Predict the output before you move it, then compare your prediction to the execution trace.
Change the values and watch the code, trace, and model update together.
score = 85
if score >= 90:
print("A")
elif score >= 80:
print("B")
elif score >= 70:
print("C")
else:
print("Needs improvement")- 85 >= 90 → False
- 85 >= 80 → True
Current model for score = 85. Active connections show the path or transfer currently being demonstrated.
Drag nodes to inspect the relationships. Motion shows the active path; the plain background keeps attention on the relationships instead of graph-paper decoration.
View static diagram
The boxes represent checks and outcomes.
The moving/highlighted path represents the route Python actually takes for the current score.
Change the score across these values:
69
70
79
80
89
90
Before moving the slider, predict which comparison will be the first true one.
Then watch where the execution path stops.
The dim branches are not "wrong." They are possible paths that were not selected for that input.
Order is part of the program's policy
This code is syntactically valid:
score = 95
if score >= 70:
print("C or better")
elif score >= 80:
print("B or better")
elif score >= 90:
print("A")
But it cannot produce A for 95.
Why?
The first condition is already true:
95 >= 70 → True
Python enters that branch and exits the chain.
The more specific thresholds must appear before broader thresholds when using this descending pattern.
That is not style. It is behavior.
A decision table can exist before the code
Suppose the requirement is:
| Age | Category |
|---|---|
| 0–12 | Child |
| 13–17 | Teen |
| 18–64 | Adult |
| 65+ | Senior |
One implementation:
age = int(input("Age: "))
if age >= 65:
print("Senior")
elif age >= 18:
print("Adult")
elif age >= 13:
print("Teen")
else:
print("Child")
Trace age = 70:
70 >= 65 → True → Senior
Trace age = 15:
15 >= 65 → False
15 >= 18 → False
15 >= 13 → True → Teen
The table helps define the intended behavior before syntax enters the picture.
Run one branch chain with real input
Use the browser runner to test a smaller branch chain before you build your own.
One line is returned for each input() call, in order.
Run the code to see output.
Change the input to 55, 71, and 86. The evidence should prove which branch runs at each boundary.
Change the input to 55, 71, and 86.
For each run, write the first condition that becomes true. Do not only copy the final label.
This runner is a small evidence surface. Your larger projects still belong in the real workspace.
Independent if statements behave differently
Compare:
if score >= 70:
print("Passed")
if score >= 90:
print("Excellent")
with:
if score >= 90:
print("Excellent")
elif score >= 70:
print("Passed")
For score = 95, the first version can print both messages because the if statements are independent.
The second version selects only the first matching branch in one chain.
This is an important design choice:
multiple independent facts may all be true → separate if statements
one choice among mutually exclusive outcomes → if/elif/else chain
Guided trace
Use:
battery = 18
if battery <= 10:
state = "SHUTDOWN"
elif battery <= 20:
state = "LOW BATTERY"
else:
state = "NORMAL"
print(state)
Predict battery = 10, 11, 20, and 21.
For each value, write the condition results in the order Python checks them.
Do not skip straight to the final label.
The skill for this week
When a branch behaves incorrectly, ask:
- What values entered the decision?
- What was the first condition Python checked?
- Was it
TrueorFalse? - Which condition came next?
- Which branch ran?
- Which later conditions were never reached?
That is much more useful than staring at indentation hoping the bug reveals itself.
Vocabulary lab
Flip the idea, not just the card
Explain the term before you reveal the back. Then compare your explanation with the definition, example, and warning.
Read all terms without animation
- Conditional
- Control flow that chooses whether or which block of code executes based on Boolean conditions. Example: An if/elif/else chain selects one grade branch. Do not confuse it with: A loop that repeats a block.
- Branch
- One possible execution path inside a decision structure. Example: The block under elif score >= 80. Do not confuse it with: Every statement in the entire program.
- Indentation
- Leading whitespace Python uses to define code blocks. Example: Indented print statements belong to the if block above them. Do not confuse it with: Optional visual formatting.
- Branch Priority
- The effect of checking conditions in a defined order where an earlier match can prevent later branches from running. Example: score >= 90 must appear before score >= 70 in a descending grade chain. Do not confuse it with: The numerical size of a value by itself.
- Fallback
- The path used when no earlier condition in a decision chain succeeds. Example: The else branch in a grade classifier. Do not confuse it with: A condition that Python checks before the others.