if, elif and else
Up to now your programs have run every line, top to bottom, every time. That is a calculator. A program decides — it does one thing in one situation and something else in another, and this lesson is where that starts.
The shape of it
age = 20
if age >= 18:
print("You can vote.")
Three things to notice, and the third is the one that matters.
The condition is age >= 18. It produces True or False — the booleans
from the last module, now earning their keep.
The colon ends the line. Forget it and you get SyntaxError: expected ':'.
You will forget it. Everybody does, for about a week.
The indentation is how Python knows what belongs inside the if. Not curly
braces, not begin and end — whitespace. Four spaces is the convention, and
your editor will insert them when you press Tab after a colon.
This is Python's most distinctive feature and its most unforgiving one:
if age >= 18:
print("You can vote.")
IndentationError: expected an indented block after 'if' statement on line 1
The if promised a block and none arrived.
else
age = 15
if age >= 18:
print("You can vote.")
else:
print("Too young to vote.")
Exactly one of those runs. Never both, never neither.
else takes no condition — it is "everything the if did not catch", which is
why it needs nothing after it but a colon.
elif
When there are more than two possibilities, elif chains them:
score = 72
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
elif score >= 50:
grade = "D"
else:
grade = "F"
print(f"Grade: {grade}")
Grade: C
Order matters more than you think. Python checks top to bottom and stops at
the first match. A score of 95 is also greater than 80 and 70, but A is
checked first, so it wins and the rest are skipped entirely.
Reverse the order and it breaks quietly:
score = 95
if score >= 50:
grade = "D" # 95 matches this first
elif score >= 70:
grade = "C"
...
Every score above 50 becomes a D. No error, no warning, just wrong grades. This is worth being deliberate about: when your conditions overlap, put the most specific first.
Note also that elif is exclusive. Compare:
# A chain: at most one runs
if x > 10:
print("big")
elif x > 5:
print("medium")
# Separate ifs: both can run
if x > 10:
print("big")
if x > 5:
print("medium")
With x = 20, the first prints big. The second prints both. Use separate
ifs only when you genuinely mean "these are independent questions".
Nesting
An if can live inside another:
age = 20
has_id = False
if age >= 18:
if has_id:
print("Entry allowed.")
else:
print("Come back with ID.")
else:
print("Too young.")
That works. But nesting gets unreadable fast, and two levels is usually the point to stop and think.
Often the nesting is not needed at all:
if age >= 18 and has_id:
print("Entry allowed.")
elif age >= 18:
print("Come back with ID.")
else:
print("Too young.")
Flatter, and it reads closer to how you would say it out loud. When you find yourself three levels deep, that is a signal — either combine the conditions, or handle the simple cases first and get them out of the way.
Handling the awkward cases first
A pattern worth learning now, because it will make your code better for years:
username = input("Username: ").strip()
if not username:
print("Username cannot be empty.")
elif len(username) < 3:
print("Username is too short.")
elif not username.isalnum():
print("Letters and numbers only, please.")
else:
print(f"Welcome, {username}.")
Each problem is dealt with and dismissed, and the success case sits at the
bottom with nothing left to worry about. The alternative — a single deeply
nested if where the real work is buried four levels in — is harder to read and
much harder to change.
Three errors you will meet
Missing colon:
if age >= 18
print("ok")
SyntaxError: expected ':'
Using = instead of ==:
if age = 18:
print("exactly eighteen")
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
Modern Python guesses correctly here, which is kind of it. In C this would compile, silently assign, and cause a bug you would hunt for an hour.
Inconsistent indentation:
if age >= 18:
print("line one")
print("line two")
IndentationError: unexpected indent
Nothing asked for that extra level. This is also where mixing tabs and spaces causes trouble — the reason the VS Code lesson had you switch on whitespace rendering.
A note on pass
Sometimes you need a block that does nothing yet:
if age >= 18:
pass # TODO: check the voter roll
else:
print("Too young.")
An empty block is a syntax error; pass fills the space and does nothing. It is
scaffolding, useful while you are sketching out structure before writing it.
Check your work
Positive, negative or zero.
if number > 0:
print("Positive")
elif number < 0:
print("Negative")
else:
print("Zero")
Three outcomes need elif. Two separate ifs would work here and stop working
the moment the conditions overlap.
The grade boundaries. 95 → A, 90 → A, 89 → B, 50 → D, 49 → F. If 90 gave
you B, your first condition is > 90 rather than >= 90 — off-by-one at a
boundary, which is where these bugs live.
Leap year with if.
if year % 4 != 0:
print("Not a leap year")
elif year % 100 != 0:
print("Leap year")
elif year % 400 != 0:
print("Not a leap year")
else:
print("Leap year")
Username validation — handle each problem and dismiss it, so the success case sits at the bottom with nothing left to check:
if not username:
print("Username cannot be empty.")
elif len(username) < 3:
print("Username is too short.")
elif not username.isalnum():
print("Letters and numbers only, please.")
else:
print(f"Welcome, {username}.")
Reversing the grade order makes every score above 50 a D, with no error and no warning. Sit with that: a program that runs perfectly and is wrong is the hardest kind of bug there is. When conditions overlap, the most specific must come first.
Nested versus flat. The flat version reads closer to how you would say it aloud, and adding a fourth case is one more line rather than one more level of indentation. Prefer it.
Practice
- Ask for a number and print whether it is positive, negative or zero. Three
outcomes, so you need
elif. - Write the grading program above, then test it with 95, 90, 89, 50 and 49. The boundaries are where bugs live — check each one deliberately.
- Ask for a year and print whether it is a leap year. You worked out the
condition in module 2; now express it with
ifandelif. - Ask for a username and validate it with the pattern above: not empty, at least 3 characters, letters and numbers only.
- Deliberately reverse the order of the grade checks so every score returns D. Run it, see it silently produce wrong answers, then fix it. Sit with that for a moment — a program that runs perfectly and is wrong is the hardest kind of bug there is.
- Write a nested version of the age-and-ID check, then rewrite it flat using
and. Decide which you would rather read in six months.
Next: the comparison and logical operators in more depth, including two that look interchangeable and are not.
Stuck on this lesson?
Being stuck is part of it — but being stuck alone for three days is not. Selected students who finish a course can join our internship, with real-world projects and code review from a working engineer.
About the internship