1.2.15 · D4Introduction to Programming (Python)

Exercises — if - elif - else — syntax, indentation rules

2,576 words12 min readBack to topic

Level 1 — Recognition

You are just spotting valid syntax and predicting simple output.

Recall Solution 1.1

WHAT is wrong: the header line if x > 3 has no colon :. WHY it matters: the colon is what opens a block. Without it Python raises a SyntaxError. FIX:

if x > 3:
    print("big")

Output after fix: big.

Recall Solution 1.2

temp > 2530 > 25True, so the if block runs and else is skipped. Output: hot.

Recall Solution 1.3

Exactly one. A clean if/elif/.../else chain is mutually exclusive — Python stops at the first True condition. If none are True, the single else runs. So no matter what a is, precisely one block executes.


Level 2 — Application

Now you write and trace real conditions.

Recall Solution 2.1
n = 7
if n % 2 == 0:
    print("even")
else:
    print("odd")

WHY % 2 == 0? % is the remainder operator. A number is even exactly when dividing by 2 leaves remainder 0. Trace n = 7: 7 % 21, and 1 == 0False. So else runs. Output: odd.

Recall Solution 2.2

score = 76: >=90 False, >=80 False (76<80), >=70 True → grade="C". Output: C. score = 80: >=90 False, >=80 True → grade="B", and the >=70 test is never checked. Output: B. Key idea: the chain is read top to bottom and stops at the first True — see the flow figure below.

Figure — if  -  elif  -  else — syntax, indentation rules
Recall Solution 2.3
day = "Sun"
if day == "Sat" or day == "Sun":
    print("weekend")
else:
    print("weekday")

WHY or? We want the block to run when either comparison is True. or gives True if at least one side is True — see Logical operators and, or, not. Trace: "Sun" == "Sat" → False, "Sun" == "Sun" → True. False or True → True. Output: weekend.


Level 3 — Analysis

Here you explain why code behaves as it does, and find hidden bugs.

Recall Solution 3.1

These are three separate ifs, so all three are evaluated in order.

  • score >= 70 True → grade = "C"
  • score >= 80 True → grade = "B" (overwrites C)
  • score >= 90 True → grade = "A" (overwrites B)

Output: A — but only by luck, because the tests happen to be ordered so the tightest wins last. If you reordered them (>=90 first), grade would end as C. An elif chain is mutually exclusive: it stops at the first True, so order-of-writing doesn't silently corrupt the result. Output: A.

Recall Solution 3.2

Never. Any x that satisfies x > 3 also satisfies x > 0, and x > 0 is checked first. Since the chain stops at the first True, the elif is unreachable for all x > 3. For x = 5: x > 0 True → prints positive and stops. Output: positive. Lesson: in an elif chain, put the most specific / tightest condition first.

Recall Solution 3.3

"B" needs score >= 80 to be True while score >= 90 is False. So 80 <= score <= 89. The lowest such integer is 80. Answer: 80.


Level 4 — Synthesis

Now you design multi-branch logic from a spec.

Recall Solution 4.1
n = 15
if n % 3 == 0 and n % 5 == 0:
    print("FizzBuzz")
elif n % 3 == 0:
    print("Fizz")
elif n % 5 == 0:
    print("Buzz")
else:
    print(n)

WHY test "both" first? 15 is divisible by 3 and by 5. If Fizz (only-3) came first it would fire and hide FizzBuzz. The most specific case must lead. Trace n = 15: 15%3==0 and 15%5==0True and True → True → FizzBuzz. Trace n = 9: first test True and False → False; 9%3==0 → True → Fizz. Outputs: FizzBuzz, then Fizz.

Recall Solution 4.2
age = 65
if age < 5:
    price = 0
elif age <= 17:
    price = 10
elif age <= 64:
    price = 20
else:
    price = 12
print(price)

WHY only one bound per elif? Reaching elif age <= 17 already guarantees age >= 5 (the first test was False). So each branch only needs its upper bound — the lower bound is inherited from all the failed tests above. Trace age = 65: all upper-bound tests fail (65<5 F, <=17 F, <=64 F) → elseprice = 12. Trace age = 4: 4 < 5 True → price = 0. Outputs: 12, then 0.

Recall Solution 4.3
age = 20
registered = False
if age >= 18:
    if registered:
        print("vote")
    else:
        print("register first")
else:
    print("too young")

WHY nest? The registered question only makes sense once age passed. Nesting puts it inside the age-True block (8 spaces of indent). Trace: age >= 18 True → enter block. registered False → inner else. Output: register first.


Level 5 — Mastery

Subtle behaviour: truthiness, the ternary form, and reachability proofs.

Recall Solution 5.1

A non-boolean placed in an if is judged by its truthiness. An empty list [] is falsy (treated as False), just like 0, "", and None. So the condition is False → else runs. Output: empty.

Recall Solution 5.2
sign = "non-negative" if x >= 0 else "negative"

WHY it works: the ternary is a compact if/else that produces a value. Form: value_if_true if condition else value_if_false. Evaluate x = -4: -4 >= 0 False → picks the else value. Result: sign = "negative".

Recall Solution 5.3

To reach the third elif x < 0, both earlier tests must be False: in particular the first test x < 0 was already False, i.e. x >= 0. But the third test asks x < 0 again — impossible when we already know x >= 0. Therefore "neg again" can never run: dead code. Trace x = -2: first test x < 0 True → prints neg and stops. Output: neg.

Recall Solution 5.4
  • 89: >=90 F, >=80 T → B
  • 90: >=90 T → A
  • 70: >=90 F, >=80 F, >=70 T → C
  • 69: all fail → F

The boundary figure below shows the number line split into four zones with the cutoffs marked.

Figure — if  -  elif  -  else — syntax, indentation rules

Recall Master recap

First True wins ::: In any if/elif/else chain, exactly one block runs — the first whose condition is True, or else if none are. Narrowest first ::: Order conditions from most specific to broadest so no branch becomes unreachable. Truthiness ::: 0, "", [], {}, None are falsy; most other values are truthy. Ternary ::: a if cond else b is a compact if/else that yields a value.


Connections