← Home

041. Elif Statement

Mutually exclusive condition chains

041. Elif Statement

RAM Manager: Memory Pressure Levels

Aryan’s RAM manager needs to classify memory usage into alert levels:

0-50%   → "normal"
51-75%  → "moderate"
76-90%  → "high"
91-100% → "critical"

His first attempt uses separate if statements. This works for the current ranges because of accidental ordering, BUT the broken version computes the percentage incorrectly — it divides by 100 instead of total_ram. So mem_pressure(4096, 8192) gives "normal" (pct ≈ 0.5%) instead of "moderate" (pct = 50%).

The fix requires both: correcting the percentage calculation AND converting the separate if chain to if/elif/else to make branches truly mutually exclusive.


💡 Fun fact: Python has no switch/case statement before version 3.10 — by design. Guido van Rossum, Python’s creator, argued that if/elif chains were clear enough and a switch would just add redundancy. Python 3.10 finally added match/case in 2021, but only after a decade of community debate. Most real-world Python code still uses if/elif for simple dispatch.

⚠️ Watch out: The classic mistake is using separate if statements instead of elif for mutually exclusive ranges. A score of 95 satisfies score >= 90, score >= 80, score >= 70, and score >= 60 — all four conditions are true. With separate if blocks each one runs, and the final value of grade will be "D" because the last matching assignment wins.

🤔 Think about it: The broken code uses a mutable grade variable that gets overwritten on each matching if. The fixed code returns immediately from the first matching elif. Both work if refactored correctly — but which approach is safer when you add a new grade tier later, and why?

Learning objectives

  • Use elif for mutually exclusive conditions
  • Understand that elif only runs when all prior conditions were False
  • Choose elif vs multiple if statements correctly

Key concepts

  • elif
  • conditional chains
  • mutually exclusive

Try it

Concept detail

if/elif/else creates mutually exclusive branches — AT MOST ONE block runs.

The critical difference:

Separate if — ALL run independently

if score >= 90: grade = “A” # True for 95 → grade = “A” if score >= 80: grade = “B” # True for 95 → grade = “B” (overwrites!) if score >= 70: grade = “C” # True for 95 → grade = “C” (overwrites!) if score >= 60: grade = “D” # True for 95 → grade = “D” (overwrites!)

result: “D” for score 95 — completely wrong

elif — stops after first match

if score >= 90: return “A” # True for 95 → returns “A”, done elif score >= 80: return “B” # never reached elif score >= 70: return “C” # never reached

When to use separate if vs elif: Use elif when branches are mutually exclusive (one range per branch, classify something) Use separate if when multiple conditions can be true simultaneously (checking multiple flags)

Python has no switch/case statement before 3.10. Use if/elif chains. Python 3.10+ has ‘match/case’ (structural pattern matching) for more complex dispatch.

Solution

def letter_grade(score):
    if score >= 90:
        return "A"
    elif score >= 80:
        return "B"
    elif score >= 70:
        return "C"
    elif score >= 60:
        return "D"
    else:
        return "F"

Tests

def test_grade_a():
    assert letter_grade(95) == "A"
    assert letter_grade(90) == "A"

def test_grade_b():
    assert letter_grade(85) == "B"
    assert letter_grade(80) == "B"

def test_grade_b_not_overwritten():
    # Broken code: score=85 sets grade="B" then grade="C" then grade="D"
    # Because all if conditions >= 80, >= 70, >= 60 are True for 85
    result = letter_grade(85)
    assert result == "B", f"Got {repr(result)} — separate ifs overwrite grade for 85"

def test_grade_c():
    assert letter_grade(75) == "C"

def test_grade_d():
    assert letter_grade(65) == "D"
    assert letter_grade(60) == "D"

def test_grade_f():
    assert letter_grade(59) == "F"
    assert letter_grade(0) == "F"

Resources