Deciding an appropriate course of action in my program flow
Overview
Teaching: 30 min
Exercises: 30 minQuestions
How can we make a program decide how to process an input?
Objectives
Understand the structure of a program that applies conditional logic to perform different tasks
Key Points
The
if
-elif
-else
block is a fundamental concept in all programming languages.Since Python 3.10, we can also use
match
to manage program flow.
Learning outcome
In this section, we will learn:
- How to make use of conditional logic to control program flow.
- Use
match
for structural matching to control program flow.
đ± Conditional Logic in Python
Imagine youâre planning a data. If itâs sunny, youâll take your date to the beach for a stroll. If it looks cloudy, youâll take your date to Gardens By The Bay. Otherwise, you will take your date to the shopping mall.
That decisionâmaking process is conditional logic, and in Python, we write it using ifâelifâelse
blocks.
They allow your program to make choices and take different paths depending on the situation. Instead of running the same steps every time, your code can react intelligently to different conditions.
To do this, we will make use of if-elif-else
blocks. In this section, we will go through how this can be set up. We will wrap up this section (and the day) by introducing the match
case that was introduced in the later versions of Python. With these tools, your Python programs will stop being static scripts and start becoming flexible, decisionâmaking machines.
đ Tabs, Spaces, and Why They Matter
So far, the Python code weâve written has been singleâline commands. But now that weâre learning conditional logic, weâll need to group blocks of code that only run under certain conditions.
In many programming languages, you might see {curly braces}
or other symbols marking these blocks.
But in Python, we use something much simpler â indentation (tabs or spaces).
Think of indentation as Pythonâs way of knowing what belongs inside a block.
if True:
print("This line is inside the block")
print("So is this one")
print("But this one is outside")
đ Notice that the first two print statements are indented with four spaces. That indentation tells Python:
- These lines belong to the if condition.
- When the if is True, run them together.
If you forget the spaces, Python will get confused â and remind you with an IndentationError
.
đĄ Pro tip
Use 4 spaces for indentation in Python (not the Tab key â though most editors will insert spaces automatically). This is because the
Tab
key can be interpreted differently, depending on your computer and your editor. However, most modern editors such as VSCode will automatically insert 4 spaces instead ofTab
.
Writing your first conditional flow
Remember our motivating example at the start of this episode: deciding where to take our date, depending on the weather. Conditional logic in Python allows us to write code that makes decisions â just like we do in real life. Letâs see how our decisionâmaking translates into Python:
weather = "sunny"
if weather == "sunny":
print ("Lets go to the beach")
elif weather == 'cloudy':
print ("Lets go to Gardens By The Bay")
else:
print ("Lets go shopping")
Hereâs whatâs happening:
- Python first checks the condition after the if.
- If that condition is true, the indented block runs.
- If not, Python moves on to the next condition (elif, short for else if).
- If none of the conditions match, the else block acts as a fallback.
This way, Python helps us create programs that behave differently under different circumstances â just like realâworld decisions. Note that you can use as many elif
conditions as you deem necessary, but you can only have one else
clause (since it is supposed to be the âdefaultâ action to take).
Try this
Using conditional logic, print out whether a given country is in Asia, Europe or North America:
#TODO: Fill in the blanks asia = ['singapore', 'japan', 'korea', 'indonesia', 'thailand'] europe = ['italy', 'france', 'germany', 'russia'] north_america = ['canada', 'mexico', 'united states'] country = 'france' __ country __ asia: print (_"{country} is in Asia") __ country ___ europe: print (_"{country} is in Europe") __ country ___ north_america: print (_"{country} is in North America") ______: print ("I am not sure where this country is in.") # Output: "france is in Europe"
What is going on?
What went wrong in the following code block?
#TODO: Fill in the blanks asia = ['singapore', 'japan', 'korea', 'indonesia', 'thailand'] europe = ['italy', 'France', 'germany', 'russia'] north_america = ['canada', 'mexico', 'united states'] country = 'france' if country in asia: print (f"{country} is in Asia") elif country in europe: print (f"{country} is in Europe") elif country in north_america: print (f"{country} is in North America") else: print ("I am not sure where this country is in.") # Output: "I am not sure where this country is in."
Common design patterns
if-elif-else
blocks are ubiquitous in Python programming. These are some common design patterns commonly encountered:
1. Single Decision (IfâElse)
The simplest form: two possible paths.
age = 20 if age >= 18: print("You can vote!") else: print("You are too young to vote.") đĄ Pattern: âYes/Noâ or âThis or Thatâ decisions.
2. Multiple Exclusive Choices (IfâElifâElse Chain)
Use when only one condition should run.
grade = 85 if grade >= 90: print("A") elif grade >= 80: print("B") elif grade >= 70: print("C") else: print("D or below") đĄ Pattern: Tiered decisionâmaking (ranking, thresholds).
3. Cascading Checks with a Fallback
Check multiple possibilities, but always end with a safe âelseâ.
weather = "rainy" if weather == "sunny": print("Go hiking!") elif weather == "cloudy": print("Visit a museum.") elif weather == "rainy": print("Watch a movie at home.") else: print("Stay flexible!")
đĄ Pattern: Default behavior if no earlier condition matches.
4. Nested Conditions
Sometimes decisions depend on two or more layers of logic.
age = 16 has_id = True if age >= 18: if has_id: print("Entry allowed") else: print("Bring your ID next time!") else: print("Sorry, you must be 18 or older.")
đĄ Pattern: Layered logic, though can get messy quickly. Use this with caution. It is usually the case that if you have too many layers of tests, you can probably simplify that logic.
5. Many Equalities (Candidate for Pattern Matching)
When youâre checking the same variable against many values.
day = "Saturday" if day in ["Saturday", "Sunday"]: print("Weekend!") elif day in ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]: print("Weekday!")
đĄ Pattern: Repeated comparisons â this is a prime candidate for Pythonâs match statement (structural pattern matching), which weâll explore soon.
Structual matching in Python
Sometimes, our ifâelifâelse
chains can get a little long and messy â especially when weâre checking the same variable against many possible values (see Common Design Pattern 5). Starting from PythonâŻ3.10, we have a cleaner and more powerful way to handle this: the match
statement.
Think of match
as Pythonâs version of a âswitchâ statement (like in other languages), but with superpowers: it not only checks values but can also unpack structures like lists, dictionaries, and even custom objects.
Hereâs a simple example to see how it works:
day = "Saturday"
match day:
case "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday":
print("Itâs a weekday!")
case "Saturday" | "Sunday":
print("Itâs the weekend!")
case _:
print("Not a valid day!") # The underscore (_) is the "catch-all"
đĄ Whatâs happening here?
- We tell Python: âLook at the value of day.â
- Each case checks if it matches a possibility.
|
means âor,â so one case can cover multiple values._
is a special placeholder that matches anything (like a default fallback).
Why use match instead of ifâelifâelse?
- â Cleaner and easier to read when checking many possibilities.
- â Can handle complex data structures (beyond simple values).
- â Avoids repeating if conditions over and over.
However, the match
is not only limited in testing for whether a value is in a list (as we saw above). It is also capable of handling more complex structures, as we will see next.
Pattern Matching with Unpacking
match
doesnât stop at simple values â t can also unpack data structures like tuples and lists while checking their contents. This makes it super handy for scenarios like working with coordinates or structured data.
To highlight what we mean, lets use the example of a 2D point (x, y):
point = (0, 5)
match point:
case (0, 0):
print("Origin")
case (0, y):
print(f"On the Y-axis at y={y}")
case (x, 0):
print(f"On the X-axis at x={x}")
case (x, y):
print(f"Somewhere else: x={x}, y={y}")
đ Whatâs happening here?
(0, 0)
matches exactly the origin.(0, y)
matches any point on the Y-axis, capturing the y value.(x, 0)
matches any point on the X-axis, capturing the x value.(x, y)
is the fallback â it captures any other coordinate.
So if point = (0, 5), the output will be:
On the Y-axis at y=5
This way, match doesnât just tell us what was matched â it can also extract values directly into variables while doing so.
Try this: Sorting a Mail Item
A mail item arrives at your desk in the form of a tuple:
mail = ("package", "Alice") # Instructions: Use match with unpacking to decide what message to print: # TODO: Fill in the blanks mail = ("package", "Alice") ____ mail: ____ ("package", ____): print(f"Delivering a package to {receipient}") ____ ("letter", recipient): print(________) ____ ("postcard", recipient): print(f"Delivering a postcard to {recipient}") ____ (_, recipient): print(f"Donât know what to deliver to {recipient}!")
Change mail to (âletterâ, âBobâ). What happens? Add a new rule for âmagazineâ. Try changing the last case so that it prints âUnknown itemâ without mentioning the recipient.
Try This
This is an exercise for you to exercise your new programming chops: Imagine you are building a simple command interpreter that reacts differently based on the userâs input command stored in the variable command:
command = "play"
Your task is to write a control flow that:
- Prints âPlaying musicâ if command is âplayâ
- Prints âPausing musicâ if command is âpauseâ
- Prints âStopping musicâ if command is âstopâ
- Prints âUnknown commandâ for anything else
đŻ Conclusion
Today, youâve learned how to give your Python programs the power to make decisions. From simple ifâelse checks to the more advanced match statement with unpacking, you now have the tools to make your code flexible and responsive to different situations.
Think about it â your programs are no longer just static scripts that do the same thing every time. They can now react, adapt, and even extract information on the fly when making decisions. Thatâs a huge step forward in thinking like a programmer.