Python conditionals — solved exercises with movies, tax brackets, passwords and the number guessing game (and the or that let everybody in)
My first attempt at the movie exercise had this line: if age >= 13 or age < 17:. The idea was “between 13 and 16”. I tested it with my own age, it worked, and I called it done. A few days later I showed it to my 8-year-old cousin so he could play with it, and the program told him he could watch a 13+ movie, no problem. An 8-year-old is “under 17”, and with an or that’s enough. That line is snippet 2 in “What’s wrong here?”, so you can catch it before it catches you.
These are Python conditionals exercises with solutions: four exercises across three levels (basic, intermediate and challenge), three buggy snippets to predict, the solutions commented line by line and a cheat sheet to review before the exam. If you haven’t yet, read the conditionals theory and the practice with three programs first: here I no longer give you the code.
Table of Contents
How to use this article
- Read the statement and the expected output. The data is fixed in variables at the top of the program, so your output has to match the article’s. Once it works, swap the variables for
input(). - Try to solve it in VS Code without looking at anything. If you’ve been stuck for more than 10 minutes, read the hint.
- Before looking at the solution, test your boundaries: the exact value of each threshold and the one just below it. That’s where conditionals break.
- Compare with the commented solution and read “Why it’s done this way”: sometimes your version works and there’s still something to learn from the other one.
Basic level
Exercise 1 — Movie rating system
Write a program that, given the user’s age, a movie’s rating and whether they’re with an adult, says whether they can watch it. The ratings are:
| Rating | Meaning | Minimum age without an adult |
|---|---|---|
| G | All audiences | 0 |
| PG | Under 10 with an adult | 10 |
| PG-13 | Not recommended under 13 | 13 |
| R | Not recommended under 17 | 17 |
| NC-17 | 18 and over only | 18 |
Rules: if they reach the minimum age, they can watch it; if not, but they’re with an adult, they can too, except for NC-17, which allows no exceptions. The rating may come in lowercase ("r"). If it isn’t one of the five, the program says so. With age = 15, rating = "r" and with_adult = False, the expected output is:
--- Result --- Rating R: not recommended under 17 Your age: 15 Access: ✗ You cannot watch this movie without an adult
First turn the rating into capitals with .upper(). Then, an if/elif chain that only assigns min_age and description. For the final decision you need an or (“old enough or with an adult”) with an and inside it (“with an adult and not NC-17″).
Exercise 2 — Income tax calculator
Write a program that, given the annual gross salary, picks the rate that applies according to these simplified brackets and applies it to the whole salary:
| Annual gross salary | Rate |
|---|---|
| Up to 12,450 € | 19 % |
| Up to 20,200 € | 24 % |
| Up to 35,200 € | 30 % |
| Up to 60,000 € | 37 % |
| More than 60,000 € | 45 % |
It must show the gross salary, the rate applied, the tax, the annual net salary and the net per month over 12 payments, with two decimals. With salary = 28000.0, the expected output is:
--- Simplified calculation --- Gross salary: 28000.00 € Rate applied: 30 % Tax: 8400.00 € Net salary: 19600.00 € Net per month (12 payments): 1633.33 €
These brackets are based on Spain’s income tax (IRPF), but the real tax is progressive: each rate only applies to the part of the salary that falls in its bracket (the first 12,450 € at 19 %, the next part at 24 %…), and there are personal allowances and social security on top. Here a single rate is applied to the whole salary to practise the elif chain. Don’t use this program to work out your taxes.
The brackets say “up to”, so the natural comparison is <=. And with <=, the order is the opposite of the grades one: from the lowest threshold up. If you put salary <= 60000 first, a 28,000 € salary would go in there.
Intermediate level
Exercise 3 — Password strength validator
Write a program that analyses a password against five criteria, says which ones it meets and which it doesn’t, and gives it a score from 0 to 5:
- At least 8 characters → +1 point.
- Has capitals → +1 point.
- Has lowercase letters → +1 point.
- Has digits → +1 point.
- Has a special character from
!@#$%^&*→ +1 point.
Final classification: 0 to 2 points, “Very weak 🔓”; 3, “Weak 🔐”; 4, “Strong 🔒”; 5, “Very strong 🔒”. With password = "Python@2024", the expected output is:
--- Password analysis --- ✓ Long enough (11 characters) ✓ Has capitals ✓ Has lowercase letters ✓ Has digits ✓ Has special characters Score: 5/5 Strength: Very strong 🔒
any(c.isupper() for c in password) answers “is any character a capital?” (you saw it in the practice with digits). Think carefully about which part of the program is independent checks and which part is a classification with a single result: they aren’t written the same way.
Final challenge
Exercise 4 — Number guessing game
The classic. The program thinks of a number between 1 and 100 and the player tries to guess it. After each attempt, the program says “Too low”, “Too high” or “Correct!”, and at the end it shows how many attempts it took and a rating: 1 to 3, “Incredible 🏆”; 4 to 6, “Great 👏”; 7 to 10, “Good ✓”; more than 10, “Keep practising 💪”.
So your output can be compared, fix secret_number = 69 and keep the guesses in a list, guesses = [50, 75, 63, 69], instead of reading them with input(). The expected output is:
=== GUESS THE NUMBER === I'm thinking of a number between 1 and 100... Attempt 1: 50 → Too low Attempt 2: 75 → Too high Attempt 3: 63 → Too low Attempt 4: 69 → Correct! 🎉 --- Result --- You guessed it in 4 attempts Rating: Great 👏
You need to repeat “get a number and compare it” until it’s right. That’s a while loop, which you’ll see in depth in the next topic; for this exercise while not guessed: is enough, setting guessed = True when the guess is right. The guess for each turn is guesses[attempts] before adding 1 to attempts. In your final version, import random and secret_number = random.randint(1, 100).
What’s wrong here?
Three short snippets, each with a typical bug. Before reading the explanation, predict what each one prints.
Snippet 1: the grade that came from input()
grade = "7" # input() ALWAYS returns text, even if you type a number
if grade >= 5:
print("Pass")
Does it print “Pass”? It doesn’t get to print anything:
Traceback (most recent call last):
File "text.py", line 3, in <module>
if grade >= 5:
^^^^^^^^^^
TypeError: '>=' not supported between instances of 'str' and 'int'
grade is "7", with quotes: it’s a string, just like everything input() returns. And Python has no idea whether the string "7" is greater than or equal to the number 5, so it refuses with a TypeError. Careful: with == there’d be no error ("7" == 7 is simply False), which is worse, because it would fail silently.
Comparing what input() returns directly with a number. Convert it first with int() or float().
The fix is to convert the string before comparing:
grade = "7"
grade = float(grade) # turns the text into a number before comparing
if grade >= 5:
print("Pass")
Output:
Pass
The usual way is to convert on the same line you read: grade = float(input("Grade: ")). That way the variable is born a number.
Snippet 2: the age band with or
age = 8
# We want the 13 to 16 age band (can watch PG-13, not R yet)
if age >= 13 or age < 17:
print("13-16 band: can watch PG-13")
else:
print("Outside the 13-16 band")
With an 8-year-old, what does it print?
13-16 band: can watch PG-13
It’s my cousin’s or. age >= 13 is False, but age < 17 is True (8 is less than 17), and an or only needs one. In fact, that condition is true for any age: every number is at least 13, or below 17, or both.
Writing a range (“between 13 and 16”) with or. A range is “at least the minimum and below the maximum”: it needs and.
The fix, with a chained comparison:
age = 8
if 13 <= age < 17: # both at once: 13 <= age and age < 17
print("13-16 band: can watch PG-13")
else:
print("Outside the 13-16 band")
Output:
Outside the 13-16 band
To check a range, write the small number first, then the variable, then the big one: 13 <= age < 17. If it sounds like maths when you read it out loud, it’s right.
Snippet 3: the else that went off with another if
It’s an 18+ screening. If the person is an adult, we check whether they have a ticket; if they’re under 18, they can’t come in. With age = 15, what does it print?
age = 15
has_ticket = True
# 18+ screening: the else should be the "under 18" one
if age >= 18:
if has_ticket:
print("Can come in to the screening")
else: # which if does this else belong to?
print("Under 18: cannot come in")
print("End of check")
Real output:
End of check
No “Under 18”, nothing: only “End of check”. The else is indented 4 spaces, level with if has_ticket:, so it’s the else of that inner if, not of the first one. With age = 15, age >= 18 is False and Python skips the whole block, else included. The diagram shows which if each else pairs with in both versions:
Deciding which if an else belongs to by how it “should” work. Python decides only by indentation: an else belongs to the if at its own level.
The fix puts the else level with the first if (and, while we’re at it, gives the inner if its own else):
age = 15
has_ticket = True
if age >= 18:
if has_ticket:
print("Can come in to the screening")
else:
print("Missing a ticket")
else: # level with the first if: it is ITS else
print("Under 18: cannot come in")
print("End of check")
Output:
Under 18: cannot come in End of check
Commented solutions
Solution exercise 1
# Exercise 1 — Can I watch this movie?
age = 15
rating = "r" # as the user would type it
with_adult = False
rating = rating.upper() # "r" → "R": now we only compare capitals
# 1. Minimum age and description of each rating
if rating == "G":
min_age = 0
description = "all audiences"
elif rating == "PG":
min_age = 10
description = "under 10 with an adult"
elif rating == "PG-13":
min_age = 13
description = "not recommended under 13"
elif rating == "R":
min_age = 17
description = "not recommended under 17"
elif rating == "NC-17":
min_age = 18
description = "18 and over only"
else:
min_age = -1 # marker for "unknown rating"
description = ""
print("--- Result ---")
if min_age == -1:
print(f"Rating {rating} not recognised")
else:
print(f"Rating {rating}: {description}")
print(f"Your age: {age}")
# 2. Gets in if old enough OR with an adult (except NC-17, no exceptions)
if age >= min_age or (with_adult and rating != "NC-17"):
print("Access: ✓ You can watch this movie")
else:
print("Access: ✗ You cannot watch this movie without an adult")
Output:
--- Result --- Rating R: not recommended under 17 Your age: 15 Access: ✗ You cannot watch this movie without an adult
Why it’s done this way:
.upper()before comparing. That way we only compare with"R", not with"R"and"r". Without it,"r" == "R"isFalseand the program would say “Rating r not recognised”.- The chain only assigns. It’s the FP1 pattern: first
min_ageanddescriptionare decided; then a single access decision that works for every rating. If you put an accessprintin each branch, you’d have the same condition repeated five times. -1as the “unknown” marker. No real minimum age is negative, so-1can’t be confused with a valid rating and the variable exists in every branch (without theelse, usingmin_agelater would give aNameErrorwith an odd rating).
The key line, zoomed in:
if age >= min_age or (with_adult and rating != "NC-17"):
| Part | With 15, R, no adult | Value |
|---|---|---|
age >= min_age | 15 >= 17 | False |
with_adult | False | False |
with_adult and rating != "NC-17" | False and … (doesn’t look further) | False |
False or False | — | False → goes into the else |
The brackets aren’t decoration: they group the adult exception. Without them it would work the same (Python evaluates and before or), but with them the rule reads exactly like the statement.
Solution exercise 2
# Exercise 2 — Tax by brackets (simplified version)
salary = 28000.0
# With <= the brackets go from LOWEST to HIGHEST: the first one met is the right one
if salary <= 12450:
rate = 19
elif salary <= 20200: # here we already know salary > 12450
rate = 24
elif salary <= 35200:
rate = 30
elif salary <= 60000:
rate = 37
else:
rate = 45
tax = salary * rate / 100
net = salary - tax
monthly = net / 12
print("--- Simplified calculation ---")
print(f"Gross salary: {salary:.2f} €")
print(f"Rate applied: {rate} %")
print(f"Tax: {tax:.2f} €")
print(f"Net salary: {net:.2f} €")
print(f"Net per month (12 payments): {monthly:.2f} €")
Output:
--- Simplified calculation --- Gross salary: 28000.00 € Rate applied: 30 % Tax: 8400.00 € Net salary: 19600.00 € Net per month (12 payments): 1633.33 €
Why it’s done this way:
<=and lowest first.28000 <= 12450isFalse;28000 <= 20200isFalse;28000 <= 35200isTrue→ 30 %. When we reach eachelifwe already know the salary is above the previous bracket, so there’s no need to writesalary > 12450 and salary <= 20200.- The
elsecatches “more than 60,000”. No need to writesalary > 60000: if all the previous ones failed, it is. - The maths by hand:
28000 × 30 / 100 = 8400;28000 − 8400 = 19600;19600 / 12 = 1633.333…, which:.2fprints as1633.33.
| Comparison | Result | What happens |
|---|---|---|
28000 <= 12450 | False | Next |
28000 <= 20200 | False | Next |
28000 <= 35200 | True | rate = 30 and it leaves the chain |
28000 <= 60000 | Not evaluated | — |
Copying the grades order (highest first) when you use <=. If salary <= 60000 comes first, every salary up to 60,000 € would pay 37 %.
Solution exercise 3
# Exercise 3 — Password strength validator
password = "Python@2024"
special_chars = "!@#$%^&*"
points = 0
print("--- Password analysis ---")
# Five INDEPENDENT ifs: each criterion adds on its own (with elif only one would count)
if len(password) >= 8:
print(f"✓ Long enough ({len(password)} characters)")
points += 1
else:
print(f"✗ Too short ({len(password)} characters, minimum 8)")
if any(c.isupper() for c in password): # any capital letter?
print("✓ Has capitals")
points += 1
else:
print("✗ No capitals")
if any(c.islower() for c in password):
print("✓ Has lowercase letters")
points += 1
else:
print("✗ No lowercase letters")
if any(c.isdigit() for c in password):
print("✓ Has digits")
points += 1
else:
print("✗ No digits")
if any(c in special_chars for c in password): # any character from the list?
print("✓ Has special characters")
points += 1
else:
print("✗ No special characters")
# Now a chain: the score falls into ONE category only
if points <= 2:
strength = "Very weak 🔓"
elif points == 3:
strength = "Weak 🔐"
elif points == 4:
strength = "Strong 🔒"
else:
strength = "Very strong 🔒"
print(f"Score: {points}/5")
print(f"Strength: {strength}")
Output:
--- Password analysis --- ✓ Long enough (11 characters) ✓ Has capitals ✓ Has lowercase letters ✓ Has digits ✓ Has special characters Score: 5/5 Strength: Very strong 🔒
Why it’s done this way:
- Five independent
ifs for the criteria. A password can meet several at once, and each one adds its point. With anelifchain, as soon as the first one (length) was met the rest wouldn’t be looked at and"Python@2024"would score 1 point. - An
elifchain for the classification. Here yes: the score falls into one category only.points <= 2goes first to catch 0, 1 and 2 at once. len()inside the message."Python@2024"has 11 characters: P-y-t-h-o-n (6), @ (1) and 2-0-2-4 (4). The program counts them for you instead of you typing the number.
| Criterion | Check | Met? | points after |
|---|---|---|---|
| Length | 11 >= 8 | ✓ | 1 |
| Capitals | the P | ✓ | 2 |
| Lowercase | y, t, h… | ✓ | 3 |
| Digits | 2, 0, 2, 4 | ✓ | 4 |
| Special | the @ is in "!@#$%^&*" | ✓ | 5 |
Solution exercise 4
# Exercise 4 — Guess the number
# In your version: import random and secret_number = random.randint(1, 100)
secret_number = 69 # fixed here so the output is always the same
guesses = [50, 75, 63, 69] # what the player would type (in your version, input())
attempts = 0
guessed = False
print("=== GUESS THE NUMBER ===")
print("I'm thinking of a number between 1 and 100...")
while not guessed: # repeats until guessed (loops: next topic)
guess = guesses[attempts] # the guess for this turn
attempts += 1
print(f"Attempt {attempts}: {guess}")
if guess < secret_number:
print("→ Too low")
elif guess > secret_number:
print("→ Too high")
else: # neither lower nor higher: equal
print("→ Correct! 🎉")
guessed = True
print("--- Result ---")
print(f"You guessed it in {attempts} attempts")
if attempts <= 3:
valoracion = "Incredible 🏆"
elif attempts <= 6: # 4, 5 or 6: the elif already knows it is above 3
valoracion = "Great 👏"
elif attempts <= 10:
valoracion = "Good ✓"
else:
valoracion = "Keep practising 💪"
print(f"Rating: {valoracion}")
Output:
=== GUESS THE NUMBER === I'm thinking of a number between 1 and 100... Attempt 1: 50 → Too low Attempt 2: 75 → Too high Attempt 3: 63 → Too low Attempt 4: 69 → Correct! 🎉 --- Result --- You guessed it in 4 attempts Rating: Great 👏
Why it’s done this way:
- A three-way
if/elif/elseinside the loop. Each guess is lower than, higher than or equal to the secret: three mutually exclusive cases, so it’s a chain. Theelsedoesn’t need to sayguess == secret_number: if it’s neither lower nor higher, it’s equal. guesses[attempts]beforeattempts += 1. On the first turnattemptsis 0, andguesses[0]is the first guess. If you added first, you’d start atguesses[1]and skip the 50.- The rating with
<=in increasing order. “4 to 6” doesn’t needattempts >= 4 and attempts <= 6: if it reacheselif attempts <= 6, we already know it isn’t<= 3.
The heart of the program, zoomed in:
while not guessed: # repeats until guessed (loops: next topic)
guess = guesses[attempts] # the guess for this turn
attempts += 1
print(f"Attempt {attempts}: {guess}")
if guess < secret_number:
print("→ Too low")
elif guess > secret_number:
print("→ Too high")
else: # neither lower nor higher: equal
print("→ Correct! 🎉")
guessed = True
Turn by turn:
| Turn | guesses[attempts] | attempts after | Comparison that matches | Message | guessed |
|---|---|---|---|---|---|
| 1 | guesses[0] = 50 | 1 | 50 < 69 | Too low | False |
| 2 | guesses[1] = 75 | 2 | 75 > 69 | Too high | False |
| 3 | guesses[2] = 63 | 3 | 63 < 69 | Too low | False |
| 4 | guesses[3] = 69 | 4 | none → else | Correct! | True → leaves |
After the loop, 4 <= 3 is False and 4 <= 6 is True: “Great 👏”. The diagram shows what each hint does: cut down the range of possible numbers until only one is left.
The strategy of the sample guesses (start at 50 and split the range in half) is called binary search. With it you never need more than 7 attempts for a number from 1 to 100, because each hint throws away half.
Exam-style quiz
Now test yourself as in the exam. The FP1 quizzes look like this: 15 questions in 20 minutes (16 in 30 in the Sequences one), almost all single choice (each wrong answer subtracts a third of what the question is worth) and many «what does this code print?», with the odd fill in the gaps, matching or true or false. Here are 13 original questions on conditionals. Answer without running anything, press Check and read the explanation for each one. These questions are also the question bank for the FP1 theory mock exam, which will mix them with those from the other topics.
What does this program print? Write the exact output.
grade = 6.5
if grade >= 9:
print("Excellent")
elif grade >= 7:
print("Good")
elif grade >= 5:
print("Pass")
else:
print("Fail")Solution
Answer: Pass
The conditions are checked from top to bottom and only the first that holds is run. 6.5 does not reach 9 or 7, but it does reach 5: Pass.
How does Python know which instructions are inside an if?
- By the indentation (the spaces at the start of the line)
- By the braces
{ } - By the word
endat the end - By the brackets around the condition
Solution
Answer: By the indentation (the spaces at the start of the line)
In Python indentation is part of the syntax: the colon : opens the block and everything indented further belongs to it. If you mix indentations, you get IndentationError.
What does this program print? Write the exact output.
x = 15
c = 0
if x > 10:
c = c + 1
if x > 12:
c = c + 1
if x > 20:
c = c + 1
print(c)Solution
Answer: 2
These are three independent ifs (not elif), so all three are checked: 15 > 10 yes, 15 > 12 yes, 15 > 20 no. c ends up as 2. With elif it would only have added once.
What does this code print?
age = 17
if age >= 18:
print("Can vote")
print("End")- Only
End Can voteandEnd- Nothing
- An error
Solution
Answer: Only End
Indentation decides: print("End") is at the same level as the if, so it does not depend on the condition. Since 17 ≥ 18 is false, only End is printed.
Which is the right way to check that n is between 1 and 10 (both included)?
1 <= n <= 101 <= n or n <= 10n >= 1 and <= 10n in 1..10
Solution
Answer: 1 <= n <= 10
1 <= n <= 10 is the same as 1 <= n and n <= 10. With or the range is useless: every number is ≥ 1 or ≤ 10.
About if, elif and else:
- An
ifcan have noelse. - An
elsecan have its own condition:else x > 3:. - There can be as many
elifs as you need. - If several conditions in an
if/elifchain hold, all those blocks are run.
Solution
- T — An
ifcan have noelse. - F — An
elsecan have its own condition:else x > 3:. - T — There can be as many
elifs as you need. - F — If several conditions in an
if/elifchain hold, all those blocks are run.
else has no condition: it means «in any other case». In an if/elif/else chain only one block runs, the one of the first true condition.
What does this code print?
t = ""
if t:
print("has text")
else:
print("empty")emptyhas text- An error, because
tis not a boolean - Nothing
Solution
Answer: empty
In an if, 0, 0.0, the empty text '', the empty list [] and None count as false. Everything else is true. That is why if t: means «if t has something».
What does this program print? Write the exact output.
a, b = 4, 9
if a > b:
m = a
else:
m = b
if m % 2 == 0:
print(m // 2)
else:
print(m * 2)Solution
Answer: 18
The first if keeps the larger one: m = 9. Since 9 is odd (9 % 2 = 1), it goes to the else: 9 × 2 = 18.
Complete so that it says whether a number is positive, negative or zero:
if n > 0: prints «positive»; ____ n < 0: prints «negative»; ____: prints «zero».
Words:
- elif
- if
- while
- else
Solution
if n > 0: prints «positive»; elif n < 0: prints «negative»; else: prints «zero».
If you used another if instead of the elif, it would work, but the else would only belong to that second if. With elif the three options form a single chain.
What does the conditional expression r = 'even' if n % 2 == 0 else 'odd' do?
- It stores
'even'or'odd'inrdepending onn - It is an error: the
ifcannot go on the right of= - It always stores
'even' - It prints
evenorodd
Solution
Answer: It stores 'even' or 'odd' in r depending on n
The form is value_if_true if condition else value_if_false. It is handy for short assignments; with more than two cases, a normal if/elif is clearer.
What does this code print?
x = 7
if x > 5:
if x > 10:
print("A")
else:
print("B")
else:
print("C")BACBandC
Solution
Answer: B
It is a nested if: indentation tells you which if each else belongs to. The else of print("B") belongs to if x > 10, and the one of print("C") to if x > 5.
Put the lines in order to classify a temperature t (over 30 hot, over 15 mild, otherwise cold):
print('cold')else:elif t > 15:print('hot')print('mild')if t > 30:
Solution
Correct order:
if t > 30:print('hot')elif t > 15:print('mild')else:print('cold')
The order of the conditions matters: if you put t > 15 first, a temperature of 35 would say «mild» and never reach «hot». Always start with the most restrictive case.
What is the value of c at the end?
a, b = 50, 25
c = 0
if a > b and b > 30:
c = 1
elif a > b or b > 30:
c = 2
print(c)2103
Solution
Answer: 2
a > b and b > 30 is True and False = False. a > b or b > 30 is True or False = True, so c = 2.
Watch it step by step in Python Tutor
Snippet 3 is the hardest one to see just by reading, so watch it live. On pythontutor.com, choose Python 3 and paste this program, which has both versions one after the other (A with the badly indented else and B fixed):
age = 15
has_ticket = True
# A: the else is indented inside the inner if
if age >= 18:
if has_ticket:
print("A: can come in")
else:
print("A: under 18")
# B: the else level with the first if
if age >= 18:
if has_ticket:
print("B: can come in")
else:
print("B: missing a ticket")
else:
print("B: under 18")
The real output is a single line:
B: under 18
What to watch step by step:
- At the first
if age >= 18:(version A), the arrow jumps straight to the version B comment: withage = 15, the whole A block,elseincluded, is skipped. - Notice that in version A no
printis ever reached: that’s why no line with “A:” comes out. - In version B, the arrow goes from
if age >= 18:to theelse:near the end, because thatelseis level with the firstif. - Change
ageto20andhas_tickettoFalse: now version A prints “A: under 18” to an adult (the wrong message in the wrong branch) and B prints “B: missing a ticket”.
Cheat sheet: Python conditionals
The essentials in 30 seconds
if/elif/else: colon at the end and 4 spaces of indentation in the block.- In a chain, only the first block whose condition is
Trueruns. - With
>=, thresholds highest first; with<=, lowest first. - Independent checks → several
ifs. Exclusive cases →elif. - Ranges with
andor chained:0 <= grade <= 10. Neverx == "a" or "b". - Zero and empty are
False; everything else,True("0"too). - An
elsebelongs to theifat its own level.
I want to…
| I want to… | Code | Result |
|---|---|---|
| Do something only if it holds | if grade < 5: print("Review") | With 4.0 it prints; with 7.5, nothing |
| Choose between two | if grade >= 5: … else: … | One of the two always runs |
| Choose between several | if … elif … elif … else | Only the first True |
| Check a range | if 0 <= grade <= 10: | With 12 → False |
| Accept “s” and “S” | if answer.lower() == "s": | "S" → True |
| See if a list has anything | if submissions: | [] → False |
| Pick a value in one line | "Pass" if grade >= 5 else "Fail" | With 6.0 → "Pass" |
| See if a string contains something | if "@" in email: | True or False |
| Avoid dividing by zero | if n > 0 and total / n >= 5: | With n = 0 it doesn’t divide |
Templates from the exercises
Classify by brackets (exercises 2 and 3, the FP1 pattern):
if value <= bracket_1: # with <=, lowest first
result = "A"
elif value <= bracket_2: # we already know value > bracket_1
result = "B"
else: # everything left
result = "C"
With exercise 2, value = 28000 falls into the <= 35200 bracket and gives 30 %.
Count independent criteria (exercise 3):
points = 0
if criterion_1: # each if adds on its own
points += 1
if criterion_2:
points += 1
With "Python@2024", all five criteria add up and points reaches 5.
Decide with an exception (exercise 1):
if age >= min_age or (with_adult and rating != "NC-17"):
print("Can watch it")
else:
print("Cannot watch it")
With 15, R and no adult: False or False → “Cannot watch it”.
Symptom and likely cause
| Symptom | Likely cause |
|---|---|
SyntaxError: expected ':' | Missing colon at the end of the if, elif or else |
SyntaxError: invalid syntax. Maybe you meant '=='… | You wrote = instead of == in the condition |
IndentationError: expected an indented block | The line below the if isn’t indented |
TypeError: '>=' not supported between instances of 'str' and 'int' | You’re comparing a string (from input()) with a number: int() or float() is missing |
| A high grade comes out “Pass” | The elifs with >= go from lowest to highest |
| The condition always gets in | x == "a" or "b", or a range written with or |
| Nothing is printed | An else indented inside the wrong if, or no branch matches and there’s no else |
NameError when using a variable after the if | Some branch doesn’t assign it (the else is missing) |
| A menu always says “invalid option” | You’re comparing input() text with a number (option == 1) |
Before handing it in, ask yourself
- Have I tested each threshold with its exact value and with the one just below?
- Are my checks independent (several
ifs) or exclusive (elif)? - Is each side of my
ands andors a complete comparison? - Is every variable I use after the chain assigned in every branch?
With conditionals mastered, the next step is repeating decisions without copying code: Python loops. And if anything in this article was hard going, go back to the theory, the practice or one step further back, to Python operators.
Keep goingAll Python articlesDid this article help you? Here is how you can support SergioLearns →




What is an operating system — theory with your laptop on a study afternoon, a write() call and a CPU that never rests (and the three programs that weren’t running at the same time)