lec-09
about these slides...
A3?
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()In this script...
⦾ the boolean type, variables
⦾ comparison operators
⦾ naming boolean variables
⦾ logical operators
SO BOOL!
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?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()!
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!
- Wikipedia
# 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!'
# 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!| Grade 12 | Python |
|---|---|
| > | > |
| < | < |
| ≥ | >= |
| ≤ | <= |
| = | == |
| ≠ | != |
careful!!!
# 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.
(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....
# 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"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?
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?
WARNING
this section is gonna be long
| 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) |
# 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 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?
# 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)
# 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!
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
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
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
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 ???
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.
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
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!
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
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)
ok = not(k >= 0 and k <= 99)
What value will ok have if k is 7? How about 100?
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
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.
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
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
What did we talk about?