COMP1701-004
fall 2023
lec-09
about these slides...
Looking Ahead


A3?
RECALL
def undo(x):
print("undoing....")
def vamp_in_the_middle(left: str, right: str) -> None:
return f'{left}vamp{right}'
def lazy_and_rude(something):
flip(something)
print(something)
def flip(invert_this: int) -> int:
return -1 * abs(invert_this)
def proclaim() -> None:
print("yea, verily!")
def main():
input("Yes or no: this is pointless? ")
s = vamp_in_the_middle("make my", "bed")
lazy_and_rude(4)
undo(s)
main()- Name all the void functions.
- Which functions return something?
- How many function calls are there?
- How many arguments altogether?
- How many parameters altogether?
- How many function definitions?
In this script...

let's talk about these things today:
⦾ the boolean type, variables
⦾ comparison operators
⦾ naming boolean variables
⦾ logical operators
SO BOOL!
boolean type & variables
boolean type & variables
what types have we used so far?
- int (like 4, 0, -1_532_873)
- float (like 5.12, 0.0, -153.00012)
- string (like "foo", 'bar', f"{12:10}")
boolean type & variables
meet the bool type - unlike its cousins, it only has 2 possible values!
TrueFalse
and
careful with those caps, folks!
# REPL time!
type(True) # type() is useful!
type(False)
type(true) # whoops!
type(F) # nope
type("True") # careful now
type(bool("False")) # yay?put type() in your toolkit
type(bool("False")) # yay?Here there be dragons.
Life isn't as rosy as you think.
# predict these
bool("True")
bool("False") # wait...what?
bool("Argle Bargle Snargle") # ???
bool(" ")
bool("")
bool(0)
bool(1)
bool(153.12)Takeaway:
Be careful using bool()!
btw...why "bool"?

Meet George.
George Boole.
“Boolean algebra has been fundamental in the development of digital electronics, and is provided for in all modern programming languages.”
Way to go, George!
boolean type & variables
- Wikipedia
Just like we can store ints, floats, and strings in variables...
boolean type & variables
# int variables
num_pie_pieces = 17
length_of_name = len("JP") # 2, since 2 characters
# float variables
anger_buildup_rate = 89123.99
area_of_circle = round(math.pi * 7, 2)
# string variables
user_name = "Ms. Bindersmoot"
greeting = f'Why, hi there, {user_name}!' # 'Why, hi there, Ms. Bindersmoot!'
...we can store bools in variables, too.
# bool variables
has_weak_heart = False
is_screaming = "STOP SHOUTING!".isupper() # huh...that's new
is_boolean = type(has_weak_heart) is bool # huh...that's new, too!comparison operators
comparison operators
What operators have we used so far?
- assignment (=)
- math (like +, -, //, %, *, /, **)
- string (like +, *)
comparison operators
Meet the comparison operators - they do what their name suggests: compare 2 things
| Grade 12 | Python |
|---|---|
| > | > |
| < | < |
| ≥ | >= |
| ≤ | <= |
| = | == |
| ≠ | != |
careful!!!
Let's kick some tires on these operators with some ints
# REPL time!
4 > 3 # True
-1 > 0 # False
-8 < 1 # True
1 < 1 # False
8 >= 8 # True
100 >= 1000 # False
(6 + 2) <= 8 # True
-4 <= -5 # False
100 == (2 * 50) # True
0 == "0" #False
4 != 3 # True
1_789 != 1789 # False| Grade 12 | Python |
|---|---|
| > | > |
| < | < |
| ≥ | >= |
| ≤ | <= |
| = | == |
| ≠ | != |
Careful - working with negatives hurts the brain.
Evaluate bracketed expression first
# REPL time!
"a" < "b" # True
'Z' >= 'A' # True
"Z" < "a" # sayWHATnow?!?!
"apple" == "apple" # True
"apple" == "Apple" # oh, great
'I am a wild party' != 'I am a wild party' # False
"" != " " # Careful there...Moral of the story: string comparisons kinda work like you expect, with some gotchas.
Let's try these operators with some strings
comparison operators
We don't talk about Bruno floats
(0.1 + 0.2) == 0.3 # True?
(0.3 * 3) + 0.1 == 1.0 # True?🙋🏻♂️❓🙋🏻♀️How is data represented in memory?
Takeaway:
Avoid using comparison operators with floats.
This being said, you'll still see float comparisons being used out there...including in labs, on tests, in assignments....
comparison operators
Since the results of comparisons are bools, we can store them in variables!
# REPL time!
statement = "K"
confusingly_short = len(statement) < 2
temp_in_c = 99
is_boiling = temp_in_c >= 100
response = input("Continue? ")
wants_to_continue = response == "Y"comparison operators
now you try
a = 7 >= 8
b = (3 + 4) < (8 - 1)
c = "pear" >= "pear"
d = len("foo") != 3
e = (8 % 4) == (2 // 3)
What values are in a through e?



naming boolean variables
naming boolean variables
best practices for naming your boolean variables (or your "bool vars", as the cool kids would say)
JP's rule of thumb:
If you can say "If [your variable]" and it sounds kind of Englishy, you're OK!"
valid_input
input
"if valid input..."
"if input..."
is_valid_input
"if is valid input..."
maybe a bit off?
logical operators
WARNING
this section is gonna be long
logical operators
Meet the logical operators - they only work with boolean expressions (things that evaluate to True or False)
| operator | example | description |
|---|---|---|
| and | x and y | True only if x AND y are both True |
| or | x or y | True as long as at least ONE of x and y is True |
| not | not x | The inverse of x. (not True == False) (not False == True) |
logical operators
Let's meet and
# let's use the debugger here
some_text = "ARRRRRRG"
very_screamy = len(some_text) > 2 and some_text.isupper() # T and T => T
some_text = "AR"
very_screamy = len(some_text) > 2 and some_text.isupper() # F and T => F
some_text = "ARRrrrrg"
very_screamy = len(some_text) > 2 and some_text.isupper() # T and F => F
some_text = "a"
very_screamy = len(some_text) > 2 and some_text.isupper() # F and F => F🙋🏻♂️❓🙋🏻♀️There's an important pattern here - do you see it?
isupper() tells you weather a given string is ALL IN UPPERCASE. Note how it's called! <<<
Let's meet or
# let's use the debugger here
energy_level = 3
hungry = True
should_take_break = energy_level <= 3 or hungry # T or T => T
energy_level = 3
hungry = False
should_take_break = energy_level <= 3 or hungry # T or F => T
energy_level = 15
hungry = True
should_take_break = energy_level <= 3 or hungry # F or T => T
energy_level = 59
hungry = False
should_take_break = energy_level <= 3 or hungry # F or F => F🙋🏻♂️❓🙋🏻♀️There's an important pattern here - do you see it?
logical operators
Let's meet not
# REPL time
wind_speed = 80
windmill_turning = not (wind_speed <= 20) # not F => T
wind_speed = 20
windmill_turning = not (wind_speed <= 20) # not T => Funary operator (because it only takes ONE operand)
logical operators
not can hurt
# REPL time
wind_speed = 80
windmill_turning = not (wind_speed <= 20) # ow
wind_speed = 20
windmill_turning = not (wind_speed <= 20) # ow# REPL time
wind_speed = 80
windmill_turning = wind_speed > 20 # ah...
wind_speed = 20
windmill_turning = wind_speed > 20 # ...much better!Takeaway:
Avoid using not - if you can.
Flip the operators!
logical operators
compound expressions
take_umbrella = (raining and not driving) or i_like_umbrellas
valid_e = (e < 10 and e * 4 >= 20) or e == -1
life gets "interesting" when we start making more complicated expressions out of all of these conditional and logical operators
logical operators
compound expressions
busy = True sleepy = True ok_to_take_nap = not busy and sleepy
let's try one
1. evaluate any boolean variables / expressions
ok_to_take_nap = not True and True
3. evaluate result
2. flip any nots to make it hurt less
ok_to_take_nap = False
ok_to_take_nap = False and True
Remember:
If you use and, if either operand is False, the result is False
compound expressions
hunger_level = 4 food_spoiled_probability = 0.3 im_a_rat = False eat_it = (hunger_level > 3 and not food_spoiled_probability > 0.5) or im_a_rat
let's try a harder one
1. evaluate any boolean variables / expressions
3. simplify
eat_it = (True and not False) or False
2. flip any nots to make it hurt less
eat_it = (True and True) or False
eat_it = True or False
4. evaluate result
eat_it = True
Remember:
If you use or, if either operand is True, the result is True
compound expressions
x = 3
y = 0
grrr = x == 1 or x != 3 and not x == y and not y > 1
let's try an even harder one
1. evaluate any boolean variables / expressions
grrr = False or False and not False and not False
2. flip any nots to make it hurt less
grrr = False or False and True and True
Uh oh. No brackets to guide us here.
grrr = (False or False) and (True and True) ???
grrr = False or (False and (True and True)) ???
grrr = ((False or False) and True) and True ???
order of operations
if you don't have brackets to guide you, you need to know NAO: not > and > or
1. nots first, left to right
2. ands next, left to right
3. ors next, left to right
We've already been doing this.
compound expressions
x = 3
y = 0
grrr = x == 1 or x != 3 and not x == y and not y > 1
pick up where we left off
2. flip any nots to make it hurt less
grrr = False or False and True and True
3. bracket ands left-to-right
grrr = False or ((False and True)and True)
4. simplify
grrr = False or (False and True)
grrr = False or False
5. evaluate result
grrr = False
logical operators
Naturally, YOU will be nice and not cause suffering like this, right?
Bracket expressions to avoid confusion.
Better yet, avoid making these kind of complex expressions in the first place!


logical operators
compound expressions
e = 4
valid_e = (e < 10 and e * 4 >= 20) or e == -1
One more. Need to make sure you're still alive.
1. evaluate any boolean variables / expressions
valid_e = (True and False) or False
2. simplify
valid_e = False or False
3. evaluate result
valid_e = False
logical operators
keep an eye out for this pattern
not(k >= 0 and k <= 99)
not(speed < 4 or in_control)
When you not a compound expression using and/or, you can use De Morgan's Laws
not(k >= 0 and k <= 99)
not(speed < 4 or in_control)
(k < 0 or k > 99)
(speed >= 4 and not in_control)
logical operators
now you try
ok = not(k >= 0 and k <= 99)
What value will ok have if k is 7? How about 100?

logical operators
now you try
CUTOFF = 100
will_buy = price <= CUTOFF or not(cash < price or out_of_print)
What value will will_buy have if
- price is 100
- cash = 10
- out_of_print = True

logical operators
short-circuit evaluation
CUTOFF = 100
will_buy = price <= CUTOFF or not(cash < price or out_of_print)
What value will will_buy have if
- price is 100
- cash = 10
- out_of_print = True
Something interesting happened here...did you notice it?
True
Something
But True or ANYTHING is True!
So Python - and you - don't even need to figure out what Something is -
just evaluate the right-hand side of the assignment to True!
This "shortcutting" is called short-circuit evaluation.
logical operators
short-circuit evaluation
can_continue = not(energy == 0 or shield == 0) and not hull_breached
What value will can_continue have if
- energy is 0
- shield = 100
- hull_breached = False
Another example (with and this time).
True
Something
Short-circuiting happens twice here!
False
Something
WARNING about short-circuit evals
logical operators
now you try
a = not x > 5 or y < 20 and x + y > 10
b = x <= 5 and not y - 1 > 1 or y == x and x - y != 5
What value will a and b have if x is 5 and y is 10?
Re-write the right-hand sides of the assignment statements, removing the nots and adding brackets, to make the precedences explicit!

if you have any brain-juice left
RECAP RECAP
What did we talk about?
lec-09
By Jordan Pratt
lec-09
boolean types, variables | comparison operators | logical operators | boolean variable naming
- 254