4: Conditionals#
Learning goals:#
Write Boolean expressions based on English requirements
Explain different meta-patterns of conditional blocks (nested, chained, with alternative vs. without)
Construct various types of conditional blocks in Python
What are conditionals and why do we care about them?#
Conditionals are an example of the fundamental computational thinking concept of control flow: setting up structures in our program to control what happens when. You can think of conditionals as “forks in the road” that control what happens depending on whether some conditions are true or false.
A set of pictures might help to give the intuition:
Basically anytime you find yourself at a problem step or part of your problem where you say something like “do something based on / depending on / looking at / if some condition”, that is a signal that you need a conditional.
Here are some examples:
decide what to wear: check temperature, check if i’m going to a dress code location
shopping: check how much money i have, check quality level of the thing, what i need; decide what to buy
decide what to eat: spiciness, taste, price
What are some other real-world examples of this sort of situation that you can think of?
Anatomy of a basic conditional block in Python#
Here’s a rough diagram of a basic conditional block in Python:
And here’s what it looks like in code
# basic conditional block
if BooleanExpression:
# do something
# maybe also something more
else:
# do something else
# and maybe even more something else
The if statement
The if keyword signals that a conditional block is starting.
The Boolean expression determine where to go in the conditional block
Truegoes to the if branch;Falsegoes to the else branch
The statement needs to end in a colon to signal that the statement has ended. This is the same as with function definitions, and as we will see, with iteration loops also.
The “if” (
True) branch code: what should happen if the Boolean expression evaluates toTrue?Needs to be indented because of scope (same with functions; also will be true of loops)
The else statement:
Signals that an else branch will be specified next
Just the else keyword and a colon
The “else” (false) branch code: what should happen if the Boolean expression evaluates to
False?Also needs to be indented
Aside: indentation and branch code#
Notice the idea of branch code: it’s code that “belongs” to the branch. We only run it if we go into the branch.
In Python, we control what belongs to what with indentation. In other languages, you use things like curly braces (e.g., Java, Javascript).
Note: Unlike functions, if/else blocks do not create a new scope in Python. Variables assigned inside an if block are still accessible after the block finishes. The key thing indentation controls here is which code runs in which branch.
As an example, consider the following code: how many times do you think we will print the message “hello world”? Why?
1# if i have passed all the requirements for graduation, print graduate! otherwise, print need to do more
2# did i accumulate at least 25 credits AND earn at least a 3.0 GPA?
3n_credits = 30
4gpa = 3.95
5hello = "hello world!"
6if n_credits >= 25 and gpa >= 3.0:
7 print("Go ahead")
8 print(hello)
9else:
10 print("Take more classes")
11 print(hello)
The answer: only once! Because both print statements are indented inside a conditional branch, only one branch executes: either the if branch or the else branch, but never both.
Examples of conditionals#
Let’s look at some examples!
The following program checks if a number is even (and prints “It’s even!” if so, and “It’s odd!” if not).
1num = 3
2if num % 2 == 0:
3 print("It's even!")
4else:
5 print("It's odd!")
The following program checks if a password is correct (and prints “Come in” if so, and “Go away” if not).
1user_input = "hello"
2password = "bunny"
3# if the user input matches the password
4if user_input == password:
5 print("Come in")
6else:
7 print("Go away")
The following program implements a Waiter checking your age on your ID, and then shows beer/alcohol menu or says “have some water”
1age = 23
2drinking_age = 21
3if age >= drinking_age:
4 print("Here's the alcohol menu")
5else:
6 print("Have some water")
A closer look at Boolean expressions#
All conditional blocks depend on well-crafted Boolean Expressions, which are expressions that evaluate to (i.e., result in, produce) a Boolean value (i.e., True or False). This is what really determines the logic of the conditional control of flow. So you need to make sure you’re proficient with Booolean expressions.
Boolean Operators#
We use Boolean Operators to compare TWO pieces of data. When evaluated, they yield a Boolean value (True or False).
data1 booleanOperator data2
Here are the main ones:
==equal to / the same as!=not equal to / different from>greater than>=greater than or equal to (at least)<less than<=less than or equal to (at most)
Logical operators#
We use Logical operators to combine basic Boolean expressions into more complex ones, like “is a more than 3 and less than 5”
Here are the main ones:
and(True if all Boolean expressions are True)or(True if any Boolean expression is True)not(True if the Boolean expression is not True)
Full list of comparison and logical operators here
Practice: Construct Boolean expressions#
Let’s practice! Translate these Boolean expressions from English into Python.
Basic Boolean expressions (only Boolean operator)#
1# is the driver's speed above the limit?
2speed = 75
3limit = 45
4# boolean expression here
1# do i have a passport?
2has_passport = True # assign the value True to the passport variable
3# boolean expression here
Compound Boolean expressions (Boolean operators + Logical operators)#
1# have i passed all the requirements for graduation?
2# which is operationalized as "do i have enough credits, with enough GPA?"
3num_credits = 120 # threshold of 120
4GPA = 1.5 # threshold of 2.0
5# boolean expression here
1# did i take the prereq for the class OR get permission from the instructor?
2took_prereq = False
3have_permission = True
4# boolean expression here
1# is the driver not wearing a seat belt?
2seat_belt = False
3# boolean expression here
1# is the professor in the office and the door open more than a crack (at least 15 degrees) or there is a sign that says come on in or you have an appointment?
2prof_in_office = True
3door_angle = 5
4sign_says = "Come in"
5have_appointment = True
6# boolean expression here
Practice: construct basic conditional blocks#
Now let’s practice constructing conditional blocks! Follow along with me to translate these English instructions into conditional blocks. We basically need to 1) decide what the condition is and translate it into a Boolean expression, then 2) decide what actions go in the True or False branches.
If my speed is above the limit, print stop; otherwise, let me pass.
1# if my speed is above the limit, print stop; otherwise, let me pass
2speed = 25
3limit = 45
4# conditional block below here
If i have a passport, print come on in; otherwise, print go away
1# if i have a passport, print come on in; otherwise, print go away
2# do i have a passport?
3has_passport = False # assign the value True to the passport variable
4# conditional block below here
if i have passed all the requirements for graduation, print graduate! otherwise, print need to do more
1# if i have passed all the requirements for graduation, print graduate! otherwise, print need to do more
2# did i accumulate at least 120 credits AND earn at least a 2.0 GPA?
3# did i take the prereq for the class OR get permission from the instructor?
4num_credits = 110 # threshold of 120
5GPA = 1.9 # threshold of 2.0
6# conditional block below here
More practice: basic if/else#
Try these on your own! Each one needs a basic if/else block.
1. Freezing check#
If the temperature is below freezing (32 degrees F), print “It’s freezing!”; otherwise, print “It’s not freezing.”
1temp = 28
2# conditional block below here
2. Pass or fail#
If the student’s score is at least 60, print “Pass”; otherwise, print “Fail”.
1score = 55
2# conditional block below here
3. Number guessing game#
If the user’s guess matches the secret number, print “You got it!”; otherwise, print “Try again!”
1guess = 7
2secret_number = 4
3# conditional block below here
4. Shopping decision#
If the item is on sale AND you have enough money (i.e., money is at least the price), print “Buy it!”; otherwise, print “Maybe next time.”
1on_sale = True
2price = 25
3money = 20
4# conditional block below here
More complex conditional structures#
The if / else conditional block is the most basic and easy to understand. But often your programs may require something a bit simpler, and sometimes a bit more complex.
Conditional execution#
The else branch is actually optional. Sometimes you just want to do something if it’s true, otherwise you do nothing.
The flow looks like this:
Some examples:
Only stop someone if they’re above the speed limit
Tell me if someone is coming!
Look through the bag and only pull out the red skittles
Can you think of any others?
# generic
if booleanExpression:
# do something
1speed = 25
2limit = 30
3if speed > limit:
4 print("Stop!")
Keywords/phrases that signal that this is appropriate?
if only one “choice” (or action) is described, then probably you don’t need an else, since “doing nothing” is a default action
Practice: conditional execution (no else)#
Try these on your own! Each one only needs an if — no else needed.
1. Low battery warning#
If the battery level is below 20, print “Low battery warning!”
1battery_level = 15
2# conditional block below here
2. Dean’s list#
If the student is on the dean’s list (GPA of 3.5 or above), print a congratulations message.
1gpa = 3.8
2# conditional block below here
3. Password length check#
If the password is less than 8 characters long, print “Warning: password is too short!” Hint: you can use len() to get the length of a string, e.g., len("hello") returns 5.
1password = "abc"
2# conditional block below here
4. Free gift threshold#
If the order total is at least $50, print “Free gift added to your order!”
1order_total = 62
2# conditional block below here
5. Weekend check#
If it’s the weekend (Saturday or Sunday), print “No class today!”
1day = "Saturday"
2# conditional block below here
Chained conditionals#
Sometimes you have more than two choices of paths (branches). In that case you need an elif.
The difference from the basic conditional is something like this:
Some examples:
you have a fever if you’re above 100, hypothermia if you’re under 95; otherwise, you’re all good!
choosing an outfit depending on where you want to go (in the Spring in Maryland!).
choosing a football play depending on what you think the defense is showing.
Any other examples?
The key difference between this type of conditional block and the regular “if/else” blocks is that you need more than one Boolean expression; one for each if or elif statement.
Here’s the generic structure:
if someCondition:
# then something
elif someOtherCondition:
# then something else
else:
# some default (this is technically optional
# but if you leave it out, you may have some unexpected edge cases you didn't account for!
1gpa = 3.5
2gpa_threshold = 2.0
3required_courses = 8
4req_threshold = 10
5
6if gpa >= gpa_threshold and required_courses >= req_threshold:
7 print("graduate!")
8elif gpa >= gpa_threshold and required_courses < req_threshold:
9 print("take more required courses")
10elif gpa < gpa_threshold and required_courses >= req_threshold:
11 print("take an easy course!")
12else:
13 print("talk to an advisor")
1# example
2temp_f = 97
3if temp_f >= 100:
4 print("fever!")
5elif temp_f < 95: # need another Boolean expression
6 print("hypothermia!")
7else:
8 print("all good!")
Keywords/phrases that signal that this is appropriate?
When you see more than two conditions or choices
Practice! Let’s translate these English instructions into Python conditional blocks.
ticket pricing: if you’re under 5 or 65 and up, price is zero; if you’re theater staff, you get half price (7.50); otherwise pay normal price (15)
1# ticket pricing:
2# if you're under 5 or 65 and up, price is zero;
3# if you're theater staff, you get half price (7.50);
4# otherwise pay normal price (15)
5age = 65
6theater_staff = True
7# chained conditional block below here
help me write the grader for late assignments: if you submit before target date, you get full credit; if you submit after the target date, but before the last day of the period, you get 85% credit - if you submit on the last day of period, you get 70% credit
1# help me write the updated grader for your PCEs:
2# if you submit before target date, you get full credit;
3# if you submit after the target date, but before or equal 1 week threshold, you get 85% credit
4# if you submit after 1 week threshold, but before or equal to 2 week threshold, you get 70% credit
5# otherwise, you get no credit
6
7submission_date = 35
8target_date = 36
9one_week_threshold = target_date + 7
10two_week_threshold = target_date + 14
11score = 1
12
13# chained conditional block below here
More practice: chained conditionals#
Try these on your own! Each one needs an if/elif/else block.
1. Letter grade converter#
If the score is 90 or above, print “A”. If 80-89, print “B”. If 70-79, print “C”. If 60-69, print “D”. Otherwise, print “F”.
1score = 85
2# chained conditional block below here
2. Shipping cost calculator#
If the order weighs less than 1 lb, shipping is \(3. If it weighs 1-5 lbs, shipping is \)7. If it weighs more than 5 lbs, shipping is $12. Print the shipping cost.
1weight = 3.5
2# chained conditional block below here
3. Time of day greeting#
Using 24-hour time (0 = midnight, 13 = 1pm, etc.): if the hour is less than 12, print “Good morning!” If 12-16, print “Good afternoon!” If 17-20, print “Good evening!” Otherwise, print “Good night!”
1hour = 14
2# chained conditional block below here
4. Water state#
If the temperature (Celsius) is 0 or below, print “Solid (ice)”. If above 100, print “Gas (steam)”. Otherwise, print “Liquid (water)”.
1temp_c = 105
2# chained conditional block below here
5. BMI category calculator#
If BMI is below 18.5, print “Underweight”. If 18.5 to 24.9, print “Normal weight”. If 25.0 to 29.9, print “Overweight”. If 30.0 or above, print “Obese”.
1bmi = 22.5
2# chained conditional block below here
Planning your conditionals with decision tables#
As your conditional blocks get more complex (especially with chained conditionals), it gets harder to keep track of all the possible situations your code needs to handle. A decision table is a simple but powerful planning tool: you list out all the possible combinations of your conditions, and then decide what should happen in each case. Think of it as a spreadsheet for your logic.
Why bother?#
Consider the ticket pricing example above. The English description says:
under 5 or 65 and up → free
theater staff → half price
otherwise → full price
But what if someone is 3 years old and theater staff? Should they get free or half price? The English description doesn’t tell us! A decision table forces you to confront these situations before you write code.
How to build a decision table#
Step 1: Identify your conditions (the things you’re checking). For ticket pricing, that’s: (a) is the person under 5 or 65+? and (b) are they theater staff?
Step 2: List every combination of True/False for those conditions. With 2 conditions, you get 4 rows:
under 5 or 65+ |
theater staff |
price |
|---|---|---|
True |
True |
??? |
True |
False |
$0 |
False |
True |
$7.50 |
False |
False |
$15 |
Step 3: Fill in what should happen for each row. That ??? is exactly the kind of edge case that causes bugs! You need to make a decision: let’s say young kids and seniors always get in free, even if they’re also staff. Now the table becomes:
under 5 or 65+ |
theater staff |
price |
|---|---|---|
True |
True |
$0 |
True |
False |
$0 |
False |
True |
$7.50 |
False |
False |
$15 |
Step 4: Now your conditional block almost writes itself. Looking at the table, you can see that the age condition should be checked first, since it applies regardless of staff status:
1age = 3
2theater_staff = True
3
4if age < 5 or age >= 65:
5 price = 0
6elif theater_staff:
7 price = 7.50
8else:
9 price = 15
10
11print(f"Price: ${price}")
Notice how the order of the if/elif matters here! If we checked theater_staff first, we’d accidentally charge a 3-year-old staff member $7.50.
Practice: build a decision table#
Try building a decision table for the late assignment grader exercise above. What are the conditions? How many rows do you need? Are there any edge cases where it’s not obvious what should happen?
Nested conditionals#
Sometimes it only makes sense to check a condition if earlier conditions are true/false. This is like a garden of forking paths or choose your own adventure. Sometimes this to save time/operations. Other times, it may make your program more readable.
I like to think of it like a choose your own adventure maze:
Simple example: I want to know if x is the same, less than, or greater than y. We can represent this as a chained conditional with three conditions. But we can also group the less than or greater than conditional block by itself since that only make sense in the situation where x and y are not the same (i.e., x != y).
1x = 5
2y = 10
3
4if x == y:
5 print("x and y are equal")
6else:
7 if x < y:
8 print("x is less than y")
9 else:
10 print("x is greater than y")
Another simple example: graduation requirements: if you’ve completed the base requirements and you have a 3.0 average, then we check: do you have sufficient electives? if yes, then great! if not, take more electives. if you don’t have the core requirements done, then you need to take care of that first, we’ll worry about electives later.
1n_credits = 125
2credit_threshold = 120
3GPA = 3.5
4n_electives = 3
5electives_threshold = 4
6
7if n_credits >= credit_threshold and GPA >= 3.0:
8 if n_electives >= electives_threshold:
9 print("Ready to graduate!")
10 else:
11 print("Get more electives!")
12else:
13 print("Finish core requirements with sufficient GPA!")
Keywords/phrases that signal that this is appropriate? Something about having more than two choices, but some choices only make sense if some earlier condition is met. In other words, we have more of multiple forks, rather than a single fork.
Practice! Let’s translate these English instructions into Python conditional blocks.
Polling booth: if you don’t have an id, go away and register, then come back; if you have an id come on in! then, if you need assistance, go to the assisted booth; otherwise, go to the normal booth.
1# polling booth: if your registration doesn't match this location, go away to the right place; if yes, then come on in!
2# then, if you need assistance, go to the assisted booth; otherwise, go to the normal booth.
3registration_here = True
4need_assistance = False
5
6# nested conditional block below here
More practice: nested conditionals#
Try these on your own! Each one involves a condition that only makes sense to check after an earlier condition.
1. Online store checkout#
If the user is logged in, check if they have items in their cart: if yes, print “Proceeding to checkout”; if no, print “Your cart is empty”. If the user is not logged in, print “Please log in first”.
1logged_in = True
2items_in_cart = 0
3# nested conditional block below here
2. Amusement park ride#
If the rider is tall enough (at least 48 inches), then check their age: if they are under 12, print “You need an adult with you”; otherwise, print “Enjoy the ride!” If they are not tall enough, print “Sorry, you’re too short for this ride”.
1height = 50
2age = 10
3# nested conditional block below here
3. Job application screener#
If the applicant has a degree, check their years of experience: if 3 or more years, print “Schedule an interview”; otherwise, print “Consider for junior position”. If they don’t have a degree, check their years of experience: if 5 or more years, print “Schedule an interview”; otherwise, print “Does not meet requirements”.
1has_degree = False
2years_experience = 6
3# nested conditional block below here
4. Restaurant order#
If the restaurant is open, check if the item is on the menu. If yes, check if the item is in stock: if yes, print “Order placed!”; if no, print “Sorry, that item is sold out”. If the item is not on the menu, print “We don’t serve that here”. If the restaurant is closed, print “Sorry, we’re closed”.
1is_open = True
2on_menu = True
3in_stock = False
4# nested conditional block below here
5. Email filter#
If the email is from a known contact, print “Inbox”. If the email is not from a known contact: if it contains the word “unsubscribe”, print “Promotions”; otherwise, print “Unknown - review manually”.
1from_known_contact = False
2contains_unsubscribe = True
3# nested conditional block below here
Some people may say that sometimes this sort of code isn’t great practice, because it can be hard to understand and debug. I’m not sure I completely agree. I think it depends on the structure of your problem. I like to write nested conditionals when the underlying logic is really like a garden of forking paths or choose your own adventure game.
Common errors#
Syntax and indentation errors#
e.g., forgetting the colon, or forgetting to indent
Best recommendation is to use templates for now as you set them up.
Boolean expression errors#
Most commonly, using = (this is assigning!) instead of == (the Boolean operator you actually want)!
Semantic errors#
Not covering all your bases or mapping the wrong conditions to outcomes. These are the trickiest because your code runs without errors, but it does the wrong thing!
Common examples:
Checking conditions in the wrong order (e.g., a more general condition “catches” cases before a more specific one gets a chance)
Forgetting an edge case (e.g., what if two conditions are both true at the same time?)
Using
andwhen you meanor, or vice versa
The best defense against semantic errors is to build a decision table before you write your conditional block (see the decision tables section above). Listing out every combination of conditions and deciding what should happen in each case helps you spot gaps and conflicts in your logic before they become bugs.
Example decision table for Project 1: https://docs.google.com/spreadsheets/d/1-q5XXbMDoji8AMVWxgUf5GW5CUOJfiWQTTV6u0-DwF8/edit?usp=sharing
You can also use decision tables to debug existing code: build the table from your code by tracing through each row, and compare it to what you intended. If they don’t match, you’ve found your bug.