Session 4 - Conditionals (if / elif / else)

Session 4 of the Python Fundamentals series, covered in depth. It makes the program choose using if, elif, and else, starting with the colon and the indentation that mark a block. It covers the comparison operators, else and elif chains checked in order so that the first true branch wins, the difference between == and =, comparing strings and converted input, nested ifs, and boundary conditions. It ends with the classic traps: separate ifs that all fire, using = where == was meant, and indentation errors. Every snippet and error message was copied verbatim from CPython 3.12.

Subject: Python Fundamentals · 98 slides · code lesson

Open the interactive version of this deck · Homework for this lesson

What this lesson covers

The lesson, slide by slide

1. Programs That Decide

Title

Python Fundamentals - Session 4

if / elif / else - choosing what to do

2. What you will be able to do

Objectives

Until now every line always ran. Now the program will pick a path. By the end you can:

  1. Write an if block that runs only when a condition is true.
  2. Build conditions with the comparison operators.
  3. Add else for the fallback and elif for extra cases.
  1. Explain how an elif chain is checked in order - first true branch wins.
  2. Use == (not =) to compare, and compare text and converted input.
  3. Avoid the traps: separate ifs that all fire, = vs ==, and indentation errors.

3. What survived from Session 3 - Input & Output?

Warm-up

Discussion prompt

Before we open Session 4 - Conditionals (if / elif / else): without looking back, what was the main idea of Session 3 - Input & Output, and what could you do by the end of it that you could not do before?

Hint: One sentence for the idea, one for the skill. If the second one is blank, that is the part to revisit.

Answer:

That session covers why input() returns text, how to convert it with int() before doing math, and how to produce clean output with commas and f-strings.

4. The if Statement

Section

Part 1

5. if: run this only when true

Concept

if condition: runs the indented block below it only when the condition is true. If it is false, that block is skipped.

Two pieces of punctuation carry the meaning: the colon ends the if line, and the indentation marks which lines are inside.

block — The indented lines under an if/elif/else. The indentation - not braces - is how Python knows which lines belong to that branch.

6. Break it if you can: if: run this only when true

Counterexample

Discussion prompt

Two pieces of punctuation carry the meaning: the colon ends the if line, and the indentation marks which lines are inside.

That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.

Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.

7. A fork in the road

Intuition

Picture the program walking down a path and reaching a fork. The condition is the sign: true goes one way, false the other.

if alone is a side trail that only some walkers take; if / else is a two-way fork that everyone takes one side of.

8. By analogy: A fork in the road

Analogy

Discussion prompt

Explain A fork in the road by analogy to something with no Python Fundamentals in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.

Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.

Answer:

Picture the program walking down a path and reaching a fork. The condition is the sign: true goes one way, false the other.

9. A single if

Worked example

score = 75
if score >= 60:
    print("You passed!")

Line 2 checks: is 75 >= 60?

Why: 75 is at least 60, so the condition is true.

The indented line runs

Why: Verified by execution: prints You passed! If score were below 60, nothing would print.

scorescore >= 60prints
75TrueYou passed!
40False(nothing)

10. Fill in: score >= 60 for A single if

Comparison

Comparison matrix

From A single if: refill the score >= 60 column from what you know. The rest of the table is as it appeared.

scorescore >= 60prints
75TrueYou passed!
40False(nothing)

11. A block can be several lines

Concept

Every line indented under the if is part of the block, and they all run together when the condition is true.

Line them up at the same indentation - Python uses that alignment to group them.

12. Teach it back: A block can be several lines

Explain it

Discussion prompt

Explain A block can be several lines to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.

Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.

Answer:

Every line indented under the if is part of the block, and they all run together when the condition is true.

13. Two lines inside one if

Worked example

temp = 95
if temp > 90:
    print("It is hot.")
    print("Drink water.")

Both indented lines belong to the if

Why: They share the same indentation, so both run when temp > 90 is true.

Read the output

Why: Verified by execution: two lines print because the condition held.

conditionlines that run
temp > 90 = TrueIt is hot.
Drink water.

14. What each one costs: Two lines inside one if

Trade off

Comparison matrix

From Two lines inside one if: every row here is a choice with a cost. Fill the lines that run column, then say which row you would actually pick and what you give up for it.

conditionlines that run
temp > 90 = TrueIt is hot.
Drink water.

15. The comparison operators

Concept

Conditions are built from comparisons: == equal, != not equal, < less, > greater, <= at most, >= at least.

Each one produces a bool - True or False - which the if then acts on.

16. Predict the next row: What each comparison gives

Pattern

Predict first

The table runs: 5 == 5 | True · 5 != 3 | True · 4 < 7 | True

In What each comparison gives, given the rows so far: what is the next one — the row where expression is 8 >= 10?

Correct: 8 >= 10 | False

expressionvalue
5 == 5True
5 != 3True
4 < 7True
8 >= 10False

Why: The relationship between the columns, not the individual numbers, is what generates the next row. The comparison is computed just like arithmetic, but the result is a bool.

17. What each comparison gives

Worked example

print(5 == 5)
print(5 != 3)
print(4 < 7)
print(8 >= 10)

Each line evaluates to True or False

Why: The comparison is computed just like arithmetic, but the result is a bool.

Read the output

Why: Verified by execution.

expressionvalue
5 == 5True
5 != 3True
4 < 7True
8 >= 10False

18. Which is which, by value

Discrimination

Sort into buckets

Sort these by value, from memory, without looking back at What each comparison gives. Telling them apart on the spot is the skill; the table is only where the answer happens to be written down.

True
5 == 5; 5 != 3; 4 < 7
False
8 >= 10
g1
value is "True" for 5 == 5, 5 != 3, 4 < 7 — that is what the table on "What each comparison gives" records, and it is the single property separating this group from the rest.
g2
value is "False" for 8 >= 10 — that is what the table on "What each comparison gives" records, and it is the single property separating this group from the rest.

19. else and elif

Section

Part 2

20. else: the otherwise branch

Concept

else: runs when the if condition was false. Together they guarantee exactly one branch runs.

else has no condition of its own - it is the catch-all for everything the if did not match.

21. Pass or try again

Worked example

score = 55
if score >= 60:
    print("Pass")
else:
    print("Try again")

55 >= 60 is false, so the if block is skipped

Why: The condition fails, so Python looks to else.

The else block runs instead

Why: Verified by execution: prints Try again.

scorescore >= 60branchprints
55FalseelseTry again

22. Inspect it line by line: Pass or try again

Error analysis

Annotate

Walk the callouts on Pass or try again. Each one is a place this is easy to get subtly wrong.

  • The condition fails, so Python looks to else.
  • Verified by execution: prints Try again.

23. elif: more than two cases

Concept

For several categories, chain with elif ('else if'). Python checks each condition top to bottom and runs the block of the first true one.

Once a branch runs, the rest are skipped. A final else catches whatever is left.

24. What has to happen first: A letter grade

Ranking

Put in order

Put the moves of A letter grade into the order they have to happen.

  1. 83 >= 90? No - skip A
  2. 83 >= 80? Yes - print B and stop
  3. The rest never run

Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. First true condition wins; the chain ends here.

25. A letter grade

Worked example

score = 83
if score >= 90:
    print("A")
elif score >= 80:
    print("B")
elif score >= 70:
    print("C")
else:
    print("F")

83 >= 90? No - skip A

Why: First condition false, move on.

83 >= 80? Yes - print B and stop

Why: First true condition wins; the chain ends here.

The rest never run

Why: Verified by execution: prints B.

conditiontrue?action
score >= 90Falseskip
score >= 80Trueprint B, stop
score >= 70-not checked
else-not reached

26. Which is which, by true?

Discrimination

Sort into buckets

Sort these by true?, from memory, without looking back at A letter grade. Telling them apart on the spot is the skill; the table is only where the answer happens to be written down.

False
score >= 90
True
score >= 80
-
score >= 70; else
g1
true? is "False" for score >= 90 — that is what the table on "A letter grade" records, and it is the single property separating this group from the rest.
g2
true? is "True" for score >= 80 — that is what the table on "A letter grade" records, and it is the single property separating this group from the rest.
g3
true? is "-" for score >= 70, else — that is what the table on "A letter grade" records, and it is the single property separating this group from the rest.

27. Order matters in an elif chain

Concept

Because the first true condition wins, the most specific / strictest condition must come first.

Put >= 90 before >= 80. If the looser one comes first, it grabs high scores before the stricter one is ever checked.

28. Something is wrong here: loosest condition first

Anomaly

Predict first

A student writes this, and it looks reasonable:

Grades with the cutoffs in the wrong order. score is 95.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: The loose condition matches every high score, so the >= 90 branch is never reached.

Strictest cutoff first.

Why: The loose condition matches every high score, so the >= 90 branch is never reached. A 95 wrongly gets a C.

29. Trap: loosest condition first

Trap

The trap

Grades with the cutoffs in the wrong order. score is 95.

if score >= 70:
    print("C")
elif score >= 90:
    print("A")

95 >= 70 is true first, so it prints C

Why: The loose condition matches every high score, so the >= 90 branch is never reached. A 95 wrongly gets a C.

scoreprintswanted
95CA

The fix

Strictest cutoff first.

if score >= 90:
    print("A")
elif score >= 70:
    print("C")

Now 95 hits >= 90 first

Why: The strict condition is checked before the loose one, so a 95 correctly prints A.

scoreprints
95A

30. Break it on purpose: loosest condition first

Break the constraint

Discussion prompt

The rule this trap just fixed:

The strict condition is checked before the loose one, so a 95 correctly prints A.

Now break it on purpose. Build a case that violates it and follow the consequences until something visibly fails. Where does the failure first show up — and would you have noticed it if you had not been looking?

Hint: The dangerous rules are the ones whose violation still produces an answer. If yours fails loudly, try to find one that fails quietly.

Answer:

The loose condition matches every high score, so the >= 90 branch is never reached. A 95 wrongly gets a C.

31. Only one branch runs

Concept

An if / elif / ... / else picks exactly one block. After it runs, execution jumps past the whole chain.

This is the key difference from separate if statements, which each decide on their own (and can all run).

32. Sorting into one bucket

Worked example

temp = 5
if temp < 10:
    print("cold")
elif temp < 20:
    print("mild")
else:
    print("warm")

temp < 10 is true, so print cold

Why: The first true branch runs.

The mild and warm branches are skipped

Why: Verified by execution: exactly one label, cold - even though temp < 20 is also true.

branchtrue?runs?
temp < 10Trueyes
temp < 20Trueno - already done
else-no

33. Draw the shape of it: Sorting into one bucket

Blank canvas

Draw it

Draw what Sorting into one bucket just did — the shape of it, not the line-by-line working. One picture, labels only where you need them. Then check it against the steps: anything you could not draw is a step you followed rather than understood.

34. Comparing Values

Section

Part 3

35. == compares, = assigns

Concept

= assigns a value to a name. == asks whether two values are equal. They are completely different jobs.

In a condition you always want ==. Mixing them up is the single most common beginner bug.

36. Something is wrong here: = instead of ==

Anomaly

Predict first

A student writes this, and it looks reasonable:

Using a single = inside an if condition.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: = means assign, which is not allowed inside an if test.

= means assign, which is not allowed inside an if test. Python stops before running - and even suggests the fix.

Why: = means assign, which is not allowed inside an if test. Python stops before running - and even suggests the fix.

37. Trap: = instead of ==

Trap

The trap

Using a single = inside an if condition.

x = 5
if x = 5:
    print("yes")

A single = cannot be a condition

Why: = means assign, which is not allowed inside an if test. Python stops before running - and even suggests the fix.

you writeresult
if x = 5:SyntaxError: invalid syntax. Maybe you meant '==' ... instead of '='?

The fix

Use == to compare.

x = 5
if x == 5:
    print("yes")

== asks 'are these equal?'

Why: x == 5 is True, so the block runs. Real output: yes.

expressionvalue
x == 5True

38. Comparing text

Concept

== works on strings too: answer == "yes" is True only if the text matches exactly.

It is case-sensitive: "Yes" == "yes" is False. (Session 11 shows how .lower() smooths this over.)

39. String equality is exact

Worked example

print("yes" == "yes")
print("Yes" == "yes")

Identical text is equal

Why: "yes" == "yes" is True.

Different capitalization is not

Why: Verified by execution: "Yes" == "yes" is False - the Y differs.

expressionvalue
"yes" == "yes"True
"Yes" == "yes"False

40. Where does each piece belong: Session 4 - Conditionals (if / elif / else)

Sorting

Sort into buckets

These are the pieces of Session 4 - Conditionals (if / elif / else), out of order. Put each one back under the part of the lesson it belongs to.

The if Statement
if: run this only when true; A fork in the road; A single if
else and elif
else: the otherwise branch; Pass or try again; elif: more than two cases
Comparing Values
== compares, = assigns; Comparing text; String equality is exact
s1
The if Statement is where Session 4 - Conditionals (if / elif / else) puts if: run this only when true, A fork in the road, A single if. Knowing which part of the lesson a problem belongs to is most of knowing which method to reach for.
s2
else and elif is where Session 4 - Conditionals (if / elif / else) puts else: the otherwise branch, Pass or try again, elif: more than two cases. Knowing which part of the lesson a problem belongs to is most of knowing which method to reach for.
s3
Comparing Values is where Session 4 - Conditionals (if / elif / else) puts == compares, = assigns, Comparing text, String equality is exact. Knowing which part of the lesson a problem belongs to is most of knowing which method to reach for.

41. Restore the missing line: Deciding on an answer

Fill the middle

Fill in the blanks

From Deciding on an answer — one line has had its right-hand side removed. Put it back.

answer = input("Continue? ")
if answer == "yes":
print("Great, moving on.")
else:
print("Okay, stopping.")

Why: answer is what everything below it consumes, so the wrong expression here fails later and somewhere else. answer is the str "yes", which matches, so the if runs.

42. Deciding on an answer

Worked example

The user types yes:

answer = input("Continue? ")
if answer == "yes":
    print("Great, moving on.")
else:
    print("Okay, stopping.")

Compare the text answer with "yes"

Why: answer is the str "yes", which matches, so the if runs.

Read the output

Why: Verified by execution: prints Great, moving on. Typing Yes or Y would fall to else, since the match is exact.

user typesanswer == "yes"prints
yesTrueGreat, moving on.
YesFalseOkay, stopping.

43. Convert numbers before comparing

Concept

Input arrives as text, and comparing text to a number is a mismatch. Convert first: age = int(input(...)), then compare age >= 18.

44. An age gate

Worked example

The user types 20:

age = int(input("Age? "))
if age >= 18:
    print("Welcome in.")
else:
    print("Too young.")

int() makes age a number so >= works

Why: age is 20; 20 >= 18 is true.

Read the output

Why: Verified by execution: prints Welcome in.

ageage >= 18prints
20TrueWelcome in.
15FalseToo young.

45. Nested ifs: a decision inside a decision

Concept

An if block can contain another if. The inner one is only reached when the outer condition is true.

Indent the inner block one more level so Python knows it lives inside the outer one.

46. Restore the missing line: Two conditions in sequence

Fill the middle

Fill in the blanks

From Two conditions in sequence — one line has had its right-hand side removed. Put it back.

age = 20
ticket = "yes"
if age >= 18:
if ticket == "yes":
print("Enter")
else:
print("Need a ticket")
else:
print("Too young")

Why: ticket is what everything below it consumes, so the wrong expression here fails later and somewhere else. Verified by execution: prints Enter.

47. Two conditions in sequence

Worked example

age = 20
ticket = "yes"
if age >= 18:
    if ticket == "yes":
        print("Enter")
    else:
        print("Need a ticket")
else:
    print("Too young")

Outer check: age >= 18 is true

Why: So we go inside and check the ticket.

Inner check: ticket == "yes" is true

Why: Verified by execution: prints Enter. Change ticket to "no" and it prints Need a ticket instead.

ageticketprints
20yesEnter
20noNeed a ticket
15yesToo young

48. Watch it run: Two conditions in sequence

Pattern

Step through it

Step through Two conditions in sequence one row at a time. What is driving the change, and what would the row after the last one be?

  1. Step 1: age is 20
  2. Step 2: age is 20
  3. Step 3: age is 15

49. Edges & Pitfalls

Section

Part 4

50. Watch the boundary: >= vs >

Concept

At the exact cutoff, >= includes the value and > excludes it. A pass mark of exactly 60 needs >= 60 to count as a pass.

Off-by-one at the boundary is a classic bug. Always ask: should the exact value be in or out?

51. Exactly at the cutoff

Worked example

score = 60
if score >= 60:
    print("Pass")
else:
    print("Fail")

60 >= 60 is true

Why: The equals part of >= includes the boundary value.

Read the output

Why: Verified by execution: 60 prints Pass; 59 would print Fail. With > 60 instead, even 60 would fail.

scorescore >= 60prints
60TruePass
59FalseFail

52. Something is wrong here: separate ifs all fire

Anomaly

Predict first

A student writes this, and it looks reasonable:

Sorting a temperature but using separate ifs. temp is 5.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: 5 < 10 and 5 < 20 are both true, and these are independent statements - so you get two labels.

Chain with elif so only the first match runs.

Why: 5 < 10 and 5 < 20 are both true, and these are independent statements - so you get two labels.

53. Trap: separate ifs all fire

Trap

The trap

Sorting a temperature but using separate ifs. temp is 5.

temp = 5
if temp < 10:
    print("cold")
if temp < 20:
    print("mild")

Each if is checked on its own, so both run

Why: 5 < 10 and 5 < 20 are both true, and these are independent statements - so you get two labels.

statementtrue?prints
if temp < 10Truecold
if temp < 20Truemild

The fix

Chain with elif so only the first match runs.

temp = 5
if temp < 10:
    print("cold")
elif temp < 20:
    print("mild")

elif ties the checks together

Why: 5 < 10 is true, prints cold, and the elif is skipped. Real output: just cold.

branchruns?
if temp < 10yes -> cold
elif temp < 20skipped

54. Fill in: runs? for Trap: separate ifs all fire

Comparison

Comparison matrix

From Trap: separate ifs all fire: refill the runs? column from what you know. The rest of the table is as it appeared.

branchruns?
if temp < 10yes -> cold
elif temp < 20skipped

55. Something is wrong here: forgetting to indent

Anomaly

Predict first

A student writes this, and it looks reasonable:

The if needs an indented block

It is wrong. Say what breaks — and say it before you turn the page.

Correct: Python reaches the next line expecting indentation and finds none, so it stops before running.

Indent the block (4 spaces is standard).

Why: Python reaches the next line expecting indentation and finds none, so it stops before running.

56. Trap: forgetting to indent

Trap

The trap

No indentation under the if.

if True:
print("hi")

The if needs an indented block

Why: Python reaches the next line expecting indentation and finds none, so it stops before running.

you writeresult
print not indentedIndentationError: expected an indented block after 'if' statement on line 1

The fix

Indent the block (4 spaces is standard).

if True:
    print("hi")

The indentation marks the block

Why: Now the print clearly belongs to the if. Real output: hi. Keep indentation consistent throughout a block.

you writeshows
indented printhi

57. More Decisions in Practice

Section

Part 5

58. Three-way categories

Concept

Three outcomes need if / elif / else: test the first case, the second, then fall through to the last.

A classic is the sign of a number: positive, negative, or zero.

59. Positive, negative, or zero

Worked example

n = -3
if n > 0:
    print("positive")
elif n < 0:
    print("negative")
else:
    print("zero")

n > 0? No; n < 0? Yes

Why: -3 is not above 0, but it is below 0, so the elif wins.

else catches exactly zero

Why: Verified by execution: -3 prints negative; 0 would reach else and print zero.

nprints
7positive
-3negative
0zero

60. Watch it run: Positive, negative, or zero

Pattern

Step through it

Step through Positive, negative, or zero one row at a time. What is driving the change, and what would the row after the last one be?

  1. Step 1: n is 7
  2. Step 2: n is -3
  3. Step 3: n is 0

61. Range buckets with elif

Concept

To sort a value into ranges, list the cutoffs in order. Each elif covers 'not the ones above, but below this next line'.

You only test one edge per branch, because the earlier branches already ruled out everything below them.

62. Predict the next row: Shipping cost by weight

Pattern

Predict first

The table runs: 0.5 | 3 · 3 | 6

In Shipping cost by weight, given the rows so far: what is the next one — the row where weight is 9?

Correct: 9 | 10

weightcost
0.53
36
910

Why: The relationship between the columns, not the individual numbers, is what generates the next row. Verified by execution: 3 is under 5, so it prints 6 and stops.

63. Shipping cost by weight

Worked example

weight = 3
if weight < 1:
    print(3)
elif weight < 5:
    print(6)
else:
    print(10)

weight < 1? No - skip

Why: 3 is not under 1.

weight < 5? Yes - cost is 6

Why: Verified by execution: 3 is under 5, so it prints 6 and stops. The 5-and-up case is handled by else.

weightcost
0.53
36
910

64. Watch it run: Shipping cost by weight

Pattern

Step through it

Step through Shipping cost by weight one row at a time. What is driving the change, and what would the row after the last one be?

  1. Step 1: weight is 0.5
  2. Step 2: weight is 3
  3. Step 3: weight is 9

65. elif is a staircase

Intuition

Picture the conditions as steps. The value walks down and stops on the first step it fits, never checking the ones below.

That is why you only need one comparison per step: standing on a step already means you were not on the ones above.

66. else is optional

Concept

You do not have to write an else. Sometimes you only want to act in one case and do nothing otherwise.

Without an else, a false condition simply skips the block and the program continues.

67. Warn only when needed

Worked example

battery = 80
if battery < 20:
    print("Low battery!")
print("Done.")

battery < 20 is false, so the warning is skipped

Why: 80 is not under 20, so nothing inside the if runs.

The line after the if still runs

Why: Verified by execution: prints only Done. With battery = 10, it would print Low battery! then Done.

batteryprints
80Done.
10Low battery! then Done.

68. A condition can drive a calculation

Concept

Conditions are not only for printing. Use them to decide a value - like whether a discount applies.

69. Restore the missing line: Discount over $100

Fill the middle

Fill in the blanks

From Discount over $100 — one line has had its right-hand side removed. Put it back.

total = 120
if total >= 100:
total = **total * 0.9**
print(total)

Why: total is what everything below it consumes, so the wrong expression here fails later and somewhere else. 120 qualifies, so total becomes 120 * 0.9.

70. Discount over $100

Worked example

total = 120
if total >= 100:
    total = total * 0.9
print(total)

total >= 100 is true, so apply 10% off

Why: 120 qualifies, so total becomes 120 * 0.9.

Read the output

Why: Verified by execution: prints 108.0. An 80 total would skip the discount and print 80.

total inqualifies?total out
120yes108.0
80no80

71. A value on its own is a condition

Concept

if name: is true when name is 'truthy' - a non-empty string, a non-zero number. It is false for an empty string or 0.

It reads as 'if there is a name'. A handy shortcut for 'did the user actually type something?'

72. Teach it back: A value on its own is a condition

Explain it

Discussion prompt

Explain A value on its own is a condition to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.

Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.

Answer:

if name: is true when name is 'truthy' - a non-empty string, a non-zero number. It is false for an empty string or 0.

73. Guess the shape of the answer: Did they enter a name?

Estimation

Predict first

The user just presses Enter (types nothing):

Commit before you compute: what does Did they enter a name? come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.

Correct: Read the output

Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. Verified by execution: with nothing typed, prints No name given; typing Sam prints Hi Sam.

74. Did they enter a name?

Worked example

The user just presses Enter (types nothing):

name = input("Name: ")
if name:
    print("Hi", name)
else:
    print("No name given")

An empty string is falsy

Why: Typing nothing makes name the empty string "", so if name: is false.

Read the output

Why: Verified by execution: with nothing typed, prints No name given; typing Sam prints Hi Sam.

user typesif name:prints
SamTrueHi Sam
(nothing)FalseNo name given

75. Inspect it line by line: Did they enter a name?

Error analysis

Annotate

Walk the callouts on Did they enter a name?. Each one is a place this is easy to get subtly wrong.

  • Typing nothing makes name the empty string "", so if name: is false.
  • Verified by execution: with nothing typed, prints No name given; typing Sam prints Hi Sam.

76. Something is wrong here: comparing text to a number

Anomaly

Predict first

A student writes this, and it looks reasonable:

Comparing raw input (text) to a number. The user types 5.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: "5" == 5 is False - a string never equals a number, even one that looks identical.

Convert the input first, then compare numbers to numbers.

Why: "5" == 5 is False - a string never equals a number, even one that looks identical. So it always says Nope.

77. Trap: comparing text to a number

Trap

The trap

Comparing raw input (text) to a number. The user types 5.

guess = input("Guess: ")
if guess == 5:
    print("Correct!")
else:
    print("Nope")

guess is the TEXT "5", not the number 5

Why: "5" == 5 is False - a string never equals a number, even one that looks identical. So it always says Nope.

expressionvalue
"5" == 5False

The fix

Convert the input first, then compare numbers to numbers.

guess = int(input("Guess: "))
if guess == 5:
    print("Correct!")
else:
    print("Nope")

int() makes guess the number 5

Why: Now 5 == 5 is True. Real output with 5 typed: Correct! Compare like with like.

expressionvalue
int("5") == 5True

78. Which of these survive contact with Session 4 - Conditionals (if / elif / else)?

Two truths and a lie

Sort into buckets

Some of these hold up and some are the exact mistakes this lesson is built to prevent. Sort them.

Holds up
Two pieces of punctuation carry the meaning: the colon ends the if line, and the indentation marks which lines are inside.; Picture the program walking down a path and reaching a fork. The condition is the sign: true goes one way, false the other.; Every line indented under the if is part of the block, and they all run together when the condition is true.
Breaks
Grades with the cutoffs in the wrong order. score is 95.; Using a single = inside an if condition.
sound
These are stated as this lesson states them — each one survives the edge cases Session 4 - Conditionals (if / elif / else) puts it through.
flawed
Each of these is lifted from a trap in this deck: reasonable-sounding, and wrong in a way that only shows up once you rely on it.

79. One comparison per condition

Concept

Keep each condition simple and readable. If you need two tests at once (age AND ticket), that is what and / or are for - the very next session.

80. By analogy: One comparison per condition

Analogy

Discussion prompt

Explain One comparison per condition by analogy to something with no Python Fundamentals in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.

Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.

Answer:

Keep each condition simple and readable. If you need two tests at once (age AND ticket), that is what and / or are for - the very next session.

81. A tiny guessing check

Worked example

The secret is 7; the user types 7:

secret = 7
guess = int(input("Guess 1-10: "))
if guess == secret:
    print("You got it!")
else:
    print("Not this time")

Convert, then compare to the secret

Why: guess is 7, which equals secret.

Read the output

Why: Verified by execution: prints You got it! Next session's loops turn this into a full guessing game.

guessguess == secretprints
7TrueYou got it!
4FalseNot this time

82. Draw the shape of it: A tiny guessing check

Blank canvas

Draw it

Draw what A tiny guessing check just did — the shape of it, not the line-by-line working. One picture, labels only where you need them. Then check it against the steps: anything you could not draw is a step you followed rather than understood.

83. Reading conditions out loud

Concept

A good habit: read each condition as an English sentence. if score >= 60: becomes 'if the score is at least 60'.

If it does not read like a clear yes/no question, it is probably the wrong condition - or two conditions that need and / or.

84. Break it if you can: Reading conditions out loud

Counterexample

Discussion prompt

A good habit: read each condition as an English sentence. if score >= 60: becomes 'if the score is at least 60'.

That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.

Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.

Answer:

If it does not read like a clear yes/no question, it is probably the wrong condition - or two conditions that need and / or.

85. Patterns & Checks

Section

Part 6

86. Building a decision

Pattern

1. Start with if and a condition; end the line with a colon

Why: if score >= 60: - the colon says the block starts here.

2. Indent the lines that belong to that branch

Why: The indentation is how Python groups the block. Keep it consistent.

3. Add else for the fallback, elif for more cases

Why: One chain runs exactly one branch; separate ifs each decide alone.

4. Order elif from strictest to loosest

Why: First true wins, so put >= 90 before >= 80, or the loose one grabs the case first.

87. Writing correct conditions

Pattern

Compare with ==, not =

Why: == asks equal; = assigns. Using = in an if is a SyntaxError.

Convert input before numeric comparisons

Why: int(input(...)) >= 18. Comparing text to a number does not do what you want.

Mind the boundary and case

Why: >= includes the cutoff, > excludes it; "Yes" != "yes". Decide what should count.

88. Where this shows up: Session 4 - Conditionals (if / elif / else)

Real world

Discussion prompt

Outside this lesson: where does Session 4 - Conditionals (if / elif / else) actually turn up? Name one concrete situation — a job, a piece of software someone ships, a decision somebody has to make — and say which part of Writing correct conditions is doing the work in it.

Hint: Vague is the failure mode here. "Engineering" is not a situation; "deciding whether this build is fast enough to ship" is.

Answer:

Session 4 of the Python Fundamentals series, in depth. Making the program choose with if / elif / else: the colon and indentation that mark a block; comparison operators; else and elif chains checked in order with the first true branch winning; == vs = ; comparing strings and converted input; nested ifs; boundary conditions; and the classic traps (separate ifs that all fire, using = instead of ==, indentation errors).

89. Check: which grade?

Check

Walk the chain for score 85.

score = 85
if score >= 90:
    print("A")
elif score >= 80:
    print("B")
elif score >= 70:
    print("C")
else:
    print("F")
conditiontrue?
score >= 90?
score >= 80?

Check your understanding

What does this print?

  • A. B (correct)
  • B. A
  • C. C
  • D. B and C

Answer: A

Why: 85 >= 90 is false (skip A); 85 >= 80 is true, so it prints B and the chain stops. Verified by execution.

Why B tempts people
85 is not at least 90, so A is skipped.
Why C tempts people
The chain stops at the first true branch (>= 80); it never reaches >= 70.
Why D tempts people
An elif chain runs only one branch - after B, later elifs are skipped.

90. What each one costs: Check: which grade?

Trade off

Comparison matrix

From Check: which grade?: every row here is a choice with a cost. Fill the true? column, then say which row you would actually pick and what you give up for it.

conditiontrue?
score >= 90?
score >= 80?

91. Check: separate ifs

Check

n is 3. These are two separate ifs.

n = 3
if n > 0:
    print("positive")
if n < 5:
    print("small")
statementtrue?
if n > 0?
if n < 5?

Check your understanding

How many lines does this print?

  • A. Two: positive and small (correct)
  • B. One: positive
  • C. One: small
  • D. None

Answer: A

Why: Two independent ifs: 3 > 0 is true (positive) and 3 < 5 is true (small), so both blocks run. Verified by execution.

Why B tempts people
Only an elif would stop after the first match. Separate ifs each fire.
Why C tempts people
The first if is true too, so positive also prints.
Why D tempts people
Both conditions are true for n = 3, so both run.

92. Fill in: true? for Check: separate ifs

Comparison

Comparison matrix

From Check: separate ifs: refill the true? column from what you know. The rest of the table is as it appeared.

statementtrue?
if n > 0?
if n < 5?

93. Check: = or ==?

Check

Spot the bug.

x = 5
if x = 5:
    print("match")
lineresult
2?

Check your understanding

What happens?

  • A. Prints match
  • B. SyntaxError (correct)
  • C. Prints nothing
  • D. NameError

Answer: B

Why: A single = means assign and is not allowed as an if condition, so Python raises a SyntaxError before running. You need ==. Verified by execution.

Why A tempts people
It cannot print match because the file never runs - the = makes it a SyntaxError.
Why C tempts people
It does not run silently; it fails to start with a syntax error.
Why D tempts people
x is defined, so it is not a NameError - the problem is = versus ==.

94. Check: the boundary

Check

score is exactly 70.

score = 70
if score > 70:
    print("above")
else:
    print("not above")
score > 70value
70 > 70?

Check your understanding

What does this print?

  • A. not above (correct)
  • B. above
  • C. both
  • D. nothing

Answer: A

Why: 70 > 70 is false because > excludes the exact value. So the else runs, printing not above. Using >= would make it print above. Verified by execution.

Why B tempts people
> is strictly greater, so 70 does not count as above 70.
Why C tempts people
if/else runs exactly one branch, never both.
Why D tempts people
The else branch always runs when the if is false, so something prints.

95. Check: string match

Check

The user types Yes (capital Y).

a = input("Go? ")
if a == "yes":
    print("going")
else:
    print("stopping")
aa == "yes"
"Yes"?

Check your understanding

What does this print?

  • A. stopping (correct)
  • B. going
  • C. Error
  • D. nothing

Answer: A

Why: String comparison is case-sensitive, so "Yes" == "yes" is False. The else runs, printing stopping. Lowercasing the input first would fix it. Verified by execution.

Why B tempts people
going needs an exact match with "yes". Capital Y makes it unequal.
Why C tempts people
Comparing two strings is valid - no error.
Why D tempts people
The else branch runs when the if is false, so it prints stopping.

96. Check: nested if

Check

age is 16, ticket is yes.

age = 16
ticket = "yes"
if age >= 18:
    if ticket == "yes":
        print("Enter")
    else:
        print("Need a ticket")
else:
    print("Too young")
age >= 18value
16 >= 18?

Check your understanding

What does this print?

  • A. Too young (correct)
  • B. Enter
  • C. Need a ticket
  • D. nothing

Answer: A

Why: The outer condition 16 >= 18 is false, so Python jumps straight to the outer else and prints Too young - the inner ticket check is never reached. Verified by execution.

Why B tempts people
Enter is inside the age >= 18 block, which is skipped because 16 is under 18.
Why C tempts people
The ticket check only runs when age >= 18. It never runs here.
Why D tempts people
The outer else runs, so Too young prints.

97. Connect it up: Session 4 - Conditionals (if / elif / else)

Connect it up

Draw it

One page, no notation unless you need it: draw how these connect — The if Statement · else and elif · Comparing Values · Edges & Pitfalls · More Decisions in Practice · Patterns & Checks. Put an arrow wherever one of them is what makes another possible, and label the arrow with why.

98. What you can do now

Recap

if condition: runs its indented block only when true; else handles otherwise; elif adds cases and the first true branch wins.

You wantUse
one thing, only when trueif
a fallback for falseif / else
several categories, pick oneif / elif / ... / else
to compare equality== (never =)
a numeric input comparisonint(input(...)) first

Mind the colon, the indentation, the elif order, and the boundary. Next session we make conditions smarter by combining them with and, or, and not.

Sources

  1. Python 3 Tutorial - if Statements and Comparisons
  2. Python 3 Reference - Comparisons
  3. All snippets and error messages executed and copied from CPython 3.12. — Author verification run, 2026-07-15 (Python Fundamentals series, Session 4).

Want this taught 1-on-1? Alexander tutors Python Fundamentals — $55/session, free consultation.

Book on Wyzant · Text (657) 465-8108