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.
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. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.
About the internship