COMP1701-004
fall 2023
lec-11
The Fooooture






Marc Schroeder is present in class today and is conducting observations as part of an approved research study. No audio or video recording is being conducted.
His fieldnotes may record general observations about the overall nature of classroom activities and discussions. However, these will not include personal or identifying details about individuals or their participation, except for those students who are participating in other aspects of the study.
If you have any questions or concerns, then please let me know, and I’ll direct you to the appropriate resource.
RECALL
SIZE = 9
WEIGHT = 2
CARTON_CAP = 3
COST_PER_EGG = 2.0
QUIT = "quit"
p1_score = 3
p2_score = 4
num_eggs = 7
response = "QUIT"
save_complete = FalseWhat are the values and types of the following:
1. p1_score + p2_score 2. num_eggs * COST_PER_EGG 3. SIZE % WEIGHT 4. (p1_score + 1) > p2_score 5. QUIT == response or save_complete 6. len(QUIT) != int(COST_PER_EGG * 2)

let's talk about these things today:
⦾ branching
⦾ if, if-else, if-elif-else statements
⦾ common branching boo-boos
⦾ boolean-returning functions
What can a CPU do again?
-
read from an input device
-
write to an output device
-
read a value from storage
-
write a value to storage
-
"do math"
-
branch
-
loop (repeated branching)
It's branch day!
-
read from an input device
-
write to an output device
-
read a value from storage
-
write a value to storage
-
"do math"
-
branch
-
loop (repeated branching)
time to branch out
Up to now, we've written purely sequential programs
name = input("Who the heck are you? ")
print(f"Oh. Hi, {name} - I didn't recognize you.")
hair_changed = input("Have you done something with your hair?")
Wouldn't it be nice here to do something different based on the user's reply?
Of course it would.
That was a rhetorical question.
if, if-else, if-elif-else statements
if, if-else, if-elif-else statements
name = input("Who the heck are you? ")
print(f"Oh. Hi, {name} - I didn't recognize you.")
hair_changed = input("Have you done something with your hair? ")
if hair_changed == "y":
print("Well THAT explains my confusion.")
print("Enough chitty-chat. Let's grab some vitamin D.")Let's add an if
4. and a block of code to run if the condition is true
2. and a condition
1. we'll need an if, naturally
3. and a colon, 'cause Python
...and don't forget the indent!
What happens when we run this with a "y"? A not "y"?
🙋🏻♂️❓🙋🏻♀️What kind of operator is ==?
name = input("Who the heck are you? ")
print(f"Oh. Hi, {name} - I didn't recognize you.")
hair_changed = input("Have you done something with your hair? ")
if hair_changed == "y":
print("Well THAT explains my confusion.")
else:
print("Oh.")
print("This is awkward.")
print("...")
print("Enough chitty-chat. Let's grab some vitamin D.")Let's make it if-else
3. and a block of code to run when the condition is FALSE
1. add an else
2. another colon. yay.
Again, try this with a "y", then a not "y".
This dialog would sound more natural if we react to y, n, and anything else in different ways.
name = input("Who the heck are you? ")
print(f"Oh. Hi, {name} - I didn't recognize you.")
hair_changed = input("Have you done something with your hair? ")
if hair_changed == "y":
print("Well THAT explains my confusion.")
elif hair_changed == "n":
print("Oh.")
print("This is awkward.")
print("...")
else:
print("Pardon?")
print("Enough chitty-chat. Let's grab some vitamin D.")if-elif-else
Try this with a "y", then a "n", then something else.
now you try
BASE_COST = 12.00
colour = input("What tshirt colour do you wanna order? ")
if colour == "red" or colour == "blue":
discount = 0.1
elif colour == "black":
discount = 0.15
elif colour == "green":
discount = 0.05
else:
discount = 0
cost = BASE_COST * (1 - discount)What value will cost have if a user enter "blue" at the prompt?
How about "Black"?
How about "green"?

Let's take this to Python Tutor and trace it. Keep an eye on discount!
branching boo-boos
Can you spot 'em?
branching boo-boos
tank_empty = True
if tank_empty == True:
print("The tank...she be empty!")
else:
print("We got gas - let's roll!")boo-boo #1
There is NO need to do this kind of comparison - since tank_empty and happy are booleans, just use them!
...
if tank_empty:
print("The tank...she be empty!")
...happy = False
if happy == False:
print("Wassup? You look down.")
else:
print("You look pretty chipper.")...
if not happy:
print("Wassup? You look down.")
...branching boo-boos
if lives_left > 0:
print("Continue?")
else lives_left <= 0:
print("Game over!")boo-boo #2
Elses never need a condition - if the if condition doesn't trigger, into the else we go!
if lives_left > 0:
print("Continue?")
else:
print("Game over!")branching boo-boos
# want to return true if dial between 1 and 10
if 1 <= dial <= 10:
print("The dial is pleased.")
boo-boo #3
Sorry - while you can do this in math class...you can't do it here!
We want to say "if the dial is greater than/equal to 1 AND the dial is less than/equal to 10"... so use THAT instead!
# want to return true if dial between 1 and 10
if dial >= 1 and dial <= 10:
print("The dial is pleased.")
branching boo-boos
another way to write this particular case that makes thing even more obvious
# want to return true if dial between 1 and 10
if 1 <= dial and dial <= 10:
print("The dial is pleased.")
dial now looks visually between 1 and 10
branching boo-boos
# want to do something if user picks black or white
if user_choice == "black" or "white":
print("Your world is very...plain.")
boo-boo #4
It'd be awesome if we could do this...but we can't. :(
We want to say "if the choice is black OR the choice is white"... so use THAT instead!
# want to do something if user picks black or white
if user_choice == "black" or user_choice == "white":
print("Your world is very...plain.")
branching boo-boos
if amount < 0:
print("Invalid amount.")
elif amount >= 0 and amount < 40:
print("Add some stuffs.")
else:
print("Yay! Free stuffs.")boo-boo #5
Wait a sec...if we got to the elif, that means we got past the if, right?
In that case amount MUST be >= 0 already, so we don't have to check again!
if amount < 0:
print("Invalid amount.")
elif amount < 40:
print("Add some stuffs.")
else:
print("Yay! Free stuffs.")

boolean-returning functions
boolean-returning functions
I love these guys...they really go a long way towards making code expressive.
boolean-returning functions
Let's take a look at lab-10.
I wanna show you a few things.
boolean-returning functions
Task
Make a function is_factor(x, y) that returns True if x is a factor of y (and False otherwise).
Remember Polya? He's still a thing, you know - not just a one-shot.
- Understand that problem? Do you remember what "x is a factor of y" means...or at least give examples?
- Have a plan?
- Have a way to implement it?
- Know how to test it?
boolean-returning functions
Task
Make a function is_factor(x, y) that returns True if x is a factor of y (and False otherwise).
Now that you know if/if-else/if-elif-else,
you might be tempted to do this:
def is_factor(x, y):
if y % x == 0:
return True
else:
return Falseboolean-returning functions
This "works"...but is wordier than it needs to be - and a pattern you will see frequently and should be on guard for.
def is_factor(x, y):
if y % x == 0:
return True
else:
return FalseTask
Make a function is_factor(x, y) that returns True if x is a factor of y (and False otherwise).
boolean-returning functions
When that condition is False, what is returned?
def is_factor(x, y):
if y % x == 0:
return True
else:
return FalseTask
Make a function is_factor(x, y) that returns True if x is a factor of y (and False otherwise).
When the condition in the if is True, what is returned?
In this "long way" pattern:
boolean-returning functions
Use this pattern instead - and notice the behaviour of this "short way" is identical to the long way!
def is_factor(x, y):
return y % x == 0Task
Make a function is_factor(x, y) that returns True if x is a factor of y (and False otherwise).
Polya's 4th step suggests we should test our function...let me show you some easy ways to do that.
def is_factor(x, y):
if y % x == 0:
return True
else:
return False
You can import your source files into the REPL!
boolean-returning functions
One way: Use the REPL
Crude, but works!
boolean-returning functions
Another way: Use asserts

Notice however you decide to test, you need to figure out at least a few test cases yourself - that's part of programming!
Faith-based programming is NOT reliable.
boolean-returning functions
Continuing with the lab....
Task
Make a function is_even(x) that returns True if x is even (and False otherwise).
The catch: use is_factor(x, y) in your solution.
boolean-returning functions
Let's say you're a bit confused over that catch. You could still go ahead and try it without.
def is_factor(x: int, y: int) -> bool:
return y % x == 0
def is_even(num: int) -> bool:
return num % 2 == 0"divides evenly by 2" => remainder is 0.
Something is even if it divides evenly by 2, so you decide to write this:
boolean-returning functions
But to say "x divides evenly by 2" is the same as saying "2 is a factor of x" - and we have a function that does that...heck, the condition is the same!
def is_factor(x: int, y: int) -> bool:
return y % x == 0
def is_even(num: int) -> bool:
return num % 2 == 0Task
Make a function is_even(x) that returns True if x is even (and False otherwise).
The catch: use is_factor(x, y) in your solution.
boolean-returning functions
So just use is_factor!
def is_factor(x, y):
return y % x == 0
def is_even(x):
return is_factor(2, x)Task
Make a function is_even(x) that returns True if x is even (and False otherwise).
The catch: use is_factor(x, y) in your solution.
Using functions in other functions is a VERY common thing. Look for opportunities to do it yourself whenever you can!
One more.
boolean-returning functions
boolean-returning functions
Task
Make a function northern(lat_deg) that returns True if lat_deg is a northern latitude and False otherwise.
Then use that function in another function symbol_for(lat_deg), that returns "N" if lat_deg is a northern latitude, and "S" otherwise.
Assumption!
lat_deg is an int guaranteed to be in -90 ... 90 - but no 0 allowed!
A northern latitude has a latitude > 0.
boolean-returning functions
def northern(lat_deg: int) -> bool:
return lat_deg > 0Task
Make a function northern(lat_deg) that returns True if lat_deg is a northern latitude (and False otherwise).
....

🙋🏻♂️❓🙋🏻♀️Create a northern(lat_deg) function. It's got a one-line body.
Task
Make a function northern(lat_deg) that returns True if lat_deg is a northern latitude and False otherwise.
Then use that function in another function symbol_for(lat_deg), that returns "N" if lat_deg is a northern latitude, and "S" otherwise.
Let's show some different ways of finishing the second part of our task.

First, though - you try!
boolean-returning functions
Task
Make a function northern(lat_deg) that returns True if lat_deg is a northern latitude (and False otherwise).
Then use that function in another function symbol_for(lat_deg), that returns "N" if lat_deg is a northern latitude, and "S" otherwise.
def northern(lat_deg: int) -> bool:
return lat_deg > 0
def symbol_for(lat_deg: int) -> str:
if northern(lat_deg):
return "N"
else:
return "S"
Easy to follow.
Is the else necessary?
Variant 1: if/else with returns in each
boolean-returning functions
Task
Make a function northern(lat_deg) that returns True if lat_deg is a northern latitude (and False otherwise).
Then use that function in another function symbol_for(lat_deg), that returns "N" if lat_deg is a northern latitude, and "S" otherwise.
def northern(lat_deg: int) -> bool:
return lat_deg > 0
def symbol_for(lat_deg: int) -> str:
if northern(lat_deg):
return "N"
return "S"
when you return, you leave the function!
Variant 2: if with return, no else
boolean-returning functions
Task
Make a function northern(lat_deg) that returns True if lat_deg is a northern latitude (and False otherwise).
Then use that function in another function symbol_for(lat_deg), that returns "N" if lat_deg is a northern latitude, and "S" otherwise.
def northern(lat_deg: int) -> bool:
return lat_deg > 0
def symbol_for(lat_deg: int) -> str:
symbol = ""
if northern(lat_deg):
symbol = "N"
else:
symbol = "S"
return symbol
Assign a variable a temporary dummy value, then re-assign in each branch.
Finally, return the variable.
Variant 3: if/else with standard single return
boolean-returning functions
Task
Make a function northern(lat_deg) that returns True if lat_deg is a northern latitude (and False otherwise).
Then use that function in another function symbol_for(lat_deg), that returns "N" if lat_deg is a northern latitude, and "S" otherwise.
def northern(lat_deg: int) -> bool:
return lat_deg > 0
def symbol_for(lat_deg: int) -> str:
if northern(lat_deg):
symbol = "N"
else:
symbol = "S"
return symbol
Variant 4: if/else with Python-only single return
Assign value to a variable each branch.
Finally, return the variable.
Won't work in C++ or Java!
JP! Run this in PythonTutor to illustrate!
boolean-returning functions
Task
Make a function northern(lat_deg) that returns True if lat_deg is a northern latitude (and False otherwise).
Then use that function in another function symbol_for(lat_deg), that returns "N" if lat_deg is a northern latitude, and "S" otherwise.
def northern(lat_deg: int) -> bool:
return lat_deg > 0
def symbol_for(lat_deg: int) -> str:
symbol = "S"
if northern(lat_deg):
symbol = "N"
return symbol
Variant 5: if/else single return w/ default var value
Choose a default value for a shared variable. Re-assign to that variable if necessary.
Finally, return that variable.
boolean-returning functions
So which way is best?
Follow whoever is paying you.
lec-11
By Jordan Pratt
lec-11
boolean-returning functions | decisions (with if-elif-else) | decision best practices | decision gotchas
- 286