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 is True, 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

Python value lab

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.

Current code
score = 85

if score >= 90:
    print("A")
elif score >= 80:
    print("B")
elif score >= 70:
    print("C")
else:
    print("Needs improvement")
Observed result
B
  1. 85 >= 90 → False
  2. 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 diagramStatic if elif else execution path

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:

AgeCategory
0–12Child
13–17Teen
18–64Adult
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.

branch_temperature.py

One line is returned for each input() call, in order.

OutputRun with button or Ctrl/Cmd+Enter
Run the code to see output.
Ready to edit. Press Run when you want evidence.

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:

  1. What values entered the decision?
  2. What was the first condition Python checked?
  3. Was it True or False?
  4. Which condition came next?
  5. Which branch ran?
  6. 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.

1 / 5
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.