Making Decisions: if, elif, and else
A fork in the road: one sign, one question, and you only walk down one path.
Every program you've written so far runs straight from top to bottom, every line, every time. That's fine for printing an ID card. But a grading program needs to say "passed" to some students and "try again" to others. A login screen needs to let the right password in and keep the wrong ones out.
To do that, your program has to make decisions. In Python, decisions start with if.
A fork in the road
Imagine walking and reaching a fork with a sign: "If it's raining, take the covered path. Otherwise, take the park path." You check the weather, pick one path, and never walk both.
An if statement is that sign. It asks a yes-or-no question, and the answer decides which code runs. The question is a condition: any expression that's true or false, like the comparisons from Operators and Expressions.
if: do this only when...
score = 82
if score >= 75:
print("You passed!")
print("Well done.")
print("Thanks for taking the quiz.")You passed!
Well done.
Thanks for taking the quiz.The parts:
ifstarts the decision, followed by the condition,score >= 75.- A colon
:ends the line. It means "here comes the code that belongs to this." - The lines that belong to the
ifare indented underneath it. They only run when the condition isTrue. - The first line that isn't indented,
print("Thanks..."), is back outside theif, and runs no matter what.
Change the score to 60, and only the "Thanks" line prints.
Indentation is the grammar
In most languages, curly braces show which lines belong together, and indentation is just for looks. In Python, the indentation is the grammar. The indented lines under an if are its block, and the block ends as soon as a line goes back to the left.
The standard is four spaces per level. Your code editor inserts them automatically when you press Tab after a line ending in a colon. Whatever you use, be consistent: every line in a block must be indented by exactly the same amount.
Forget to indent, and Python stops you:
score = 82
if score >= 75:
print("You passed!") # error: IndentationError: expected an indented block after 'if' statement on line 2else: otherwise...
Add else to say what should happen when the condition is False:
score = 60
if score >= 75:
print("You passed!")
else:
print("Not this time. Keep practicing!")Not this time. Keep practicing!else has no condition of its own, and it needs a colon too. Exactly one of the two blocks runs: never both, never neither. That's the fork in the road.
elif: more than two paths
Real decisions often have more than two outcomes. Letter grades are a classic example. Chain the choices together with elif, short for "else if":
score = 84
if score >= 90:
print("Grade: A")
elif score >= 80:
print("Grade: B")
elif score >= 70:
print("Grade: C")
else:
print("Grade: F")Grade: BPython checks each condition from top to bottom, runs the block of the first one that's true, and skips everything else in the chain.
That's why the order matters. A score of 84 is also >= 70, but Python never gets that far: score >= 80 matched first. Look what happens if you put the checks in the wrong order:
score = 95
if score >= 70:
print("Grade: C")
elif score >= 90:
print("Grade: A")Grade: CA 95 gets a C! When you're checking ranges like this, start with the strictest condition and work down. The final else is optional, but it's a good safety net for everything that didn't match.
Combining conditions
Use and, or, and not from Operators and Expressions inside any condition, and chained comparisons for ranges:
score = 93
absences = 1
age = 15
if score >= 90 and absences <= 3:
print("Honor roll!")
if 13 <= age <= 19:
print("Teenager")Honor roll!
TeenagerTruthy and falsy conditions
In Type Conversion, you saw that empty and zero values count as False, and everything else counts as True. That means a condition doesn't have to be a comparison. Any value works:
name = ""
if name:
print("Hello,", name)
else:
print("You didn't type a name.")You didn't type a name.if name: reads as "if there's a name." It's a common, clean way to check whether a string (or a list, later) is empty. Similarly, for a variable that might be None, write if value is None:. Use is for None, and == for everything else.
Decisions inside decisions
You can put an if inside another if. The inner one is simply indented one level further:
submitted = True
score = 68
if submitted:
if score >= 75:
print("Passed")
else:
print("Submitted, but needs a retake")
else:
print("Missing")Submitted, but needs a retakeNotice if submitted: instead of if submitted == True:. A boolean is already true or false, so it can be the whole condition, and its opposite is if not submitted:.
Nesting is useful, but more than two or three levels gets hard to follow. Often and or an elif chain does the same job more clearly.
Compact choices: the conditional expression
When all you need is to pick one of two values, Python has a one-line form:
score = 82
result = "Pass" if score >= 75 else "Fail"
print(result)PassRead it as English: "result is Pass if the score is at least 75, else Fail." Keep it for simple choices of a value; when you need to run different actions, use a full if statement.
Try it
This program turns a score into a letter grade, checks the honor roll, and handles a missing submission and a blank name. Predict what it prints.
Running Python here
Running Python right in the browser is coming to Syntaxia soon. For now, you can read and edit the code here. If you have Python installed on your computer (see Setting Up), save it as main.py and run it with python main.py (or python3 main.py on macOS and Linux).
Check your prediction
Maria: 87 (B)
Great score, but too many absences for the honor roll.
Nickname: (none)
Report complete.87 isn't >= 90, but it is >= 80, so the chain stops at B. The honor roll check needs both conditions, and 4 absences fails the second, so the elif runs instead. nickname is an empty string, which is falsy, so the conditional expression picks "(none)".
Try it yourself
- Change
absencesto 2, thenscoreto 92. Predict the output each time before checking. - Set
submittedtoFalse. Which lines print now? - Add a grade
Dfor scores from 60 to 69. Where in the chain does it have to go?
Check your understanding
Up next
So far, every line in your programs runs at most once. What if you want to keep asking a question until the answer is right, or count down from 10? That's while Loops.
