Booleans and Conditions¶
In this lecture, we will exlore the boolean types True and False in Python, relational and logical operators and how they help making decisions using the if- else conditional blocks.
First, we review the notion of variable scope when calling functions.
Variable Scope¶
Local variables. An assignment to a variable within a function definition creates/changes a local variable. Local variables exist only within a function’s body, and cannot be referred to outside of it. Parameters are also local variables that are assigned a value when the function is invoked.
def myfunc (val):
val = val + 1
print('local val = ', val)
return val
val = 3
newVal = myfunc(val)
local val = 4
newVal
4
print('global val =', val)
global val = 3
Boolean Type and Relational Operators¶
True and False are of type bool in Python and naturally occur as a result of relational operators.
4 < 5
True
10 == 10
True
'a' == 'b'
False
True == 1
True
False == 0
True
1000/3 < 300
False
num1 = int(input("Enter first number: "))
num2 = int(input("Enter second number: "))
num1 <= num2
---------------------------------------------------------------------------
StdinNotImplementedError Traceback (most recent call last)
/var/folders/md/kwd9nc_d2ns0hw9wsvdrnt2c0000gn/T/ipykernel_42090/1060297538.py in <module>
----> 1 num1 = int(input("Enter first number: "))
2 num2 = int(input("Enter second number: "))
3 num1 <= num2
/usr/local/lib/python3.9/site-packages/ipykernel/kernelbase.py in raw_input(self, prompt)
1001 """
1002 if not self._allow_stdin:
-> 1003 raise StdinNotImplementedError(
1004 "raw_input was called, but this frontend does not support input requests."
1005 )
StdinNotImplementedError: raw_input was called, but this frontend does not support input requests.
num1 != num2
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/var/folders/md/kwd9nc_d2ns0hw9wsvdrnt2c0000gn/T/ipykernel_42090/2184856654.py in <module>
----> 1 num1 != num2
NameError: name 'num1' is not defined
num1 % 3 == 1
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/var/folders/md/kwd9nc_d2ns0hw9wsvdrnt2c0000gn/T/ipykernel_42090/3089261710.py in <module>
----> 1 num1 % 3 == 1
NameError: name 'num1' is not defined
Conditional Statement: If Else¶
We can ensure that some statements in the program are evaluated conditionally only if the result of a Boolean expression evaluates to True using the if statement. If the Boolean expression evalautes to False, then the control flow skips statements under the if block and evaluates the statements under the else block.
If Else Statement Syntax¶
statement 1
statement 2
if (boolean expression):
statement 3
statement 4
…
else:
statement 5
statement 6
…
statement 7
Indentation matters in Python¶
Indented statemnets form a logical block of code in Python:
If the boolean expression next to the
ifstatement evaluates toTrue, then statements3, 4,...in theifblock are executed, after which the control flow will skip over all of the statements under theelseblock, and go straight to statement7If the boolean expression next to the
ifstatement evaluates toFalse, then the control flow skips over statements3, 4,..and exectutes statements5, 6,...in theelseblock, after which the control flow goes to statement7.
Checking if Number is Even¶
Let us write a function printEven that takes a number as input. If the number is even, it prints “Even”, else it prints “Odd”.
Question. How can we check if a number is even?
3 % 2
1
10 % 2
0
17 % 2
1
9 % 2 == 0
False
Exercise. Let us write the function isEven(num) below.
def printEven(num):
"""Takes a number as input, prints Even if
it is even, else prints Odd"""
if num % 2 == 0: # if even
print("Even")
else:
print("Odd")
printEven(16)
Even
printEven(77)
Odd
Exercise. Suppose instead of printing, we want to return True if number is Even, and False if number is Odd.
Let us define an isEven(num) that does this.
def isEven(num):
"""Takes a number as input, returns True if
it is even, else returns False"""
if num % 2 == 0: # if even
return True
else:
return False
isEven(8)
True
isEven(75)
False
Else block is optional¶
An if statement does not need an else, and there are often times when removing the else block makes the program simpler.
Simplify. We can simplify the isEven function by removing the else block, and return False if the if condition fails.
def isEven(num):
"""Takes a number as input, returns True if
it is even, else returns False"""
if num % 2 == 0: # if even
return True
return False
Simplify further. We can shorten it even further if we want and just return the result of the Boolean expression.
def isEven(num):
"""Takes a number as input, returns True if
it is even, else returns False"""
return num % 2 == 0
Tracing Control Flow Through Conditionals¶
Let us look at the following example of a function zeroToOne that takes a number num as input, if the number is equal to zero, it adds one to num and returns it. Otherwise it just returns num.
Let us trace the control flow when the function is called with different values of num and see which statements are printed.
In situations like this function, it is a good idea to have a single return statement, rather than a return statement in each conditional block.
Notice: Statements above the if block and after the else block are always executed.
# adding more prints and return
def zeroToOne(num):
"""If input number num is 0, adds one and returns,
else returns num itself"""
print("You called this function with num =", num)
if num == 0:
print("Incrementing to 1")
num += 1 # update to 1
else:
print("No need to increment.")
print("Just before return")
return num
print("Just after return") # will this ever get printed?
zeroToOne(5)
You called this function with num = 5
No need to increment.
Just before return
5
zeroToOne(0)
You called this function with num = 0
Incrementing to 1
Just before return
1
Logical operators: and, or, not¶
The logical operators and, or and not in Python are used to combine Boolean values and write more complex Booleans expressions.
and¶
boolExp1 and boolExp2 evaluates to True iff both boolExp1 and boolExp2 evaluate to True.
or¶
boolExp1 or bool Exp2 evaluates to True iff at least one of boolExp1 and boolExp2 evaluate to True.
not¶
not boolExp evaluates to True iff boolExp evaluates to False.
Let us try these out.
20 < 13 and 6 == 6
False
20 < 13 or 6 == 6
True
not 20 < 13
True
not 6 == 6
False
Example 1. Check if a number is divisible by 5 and is odd.
def oddMultipleFive(num):
"Returns true if num is divisible by 5 and odd"
return num % 5 == 0 and num % 2 == 1
oddMultipleFive(55)
True
oddMultipleFive(80)
False
Example 2. Ask the user to enter a lowercase letter. Check if it is a vowel or consonent.
def isVowel(letter):
"""Takes lowercase letter as input and returns True if it is a vowel,
else returns False"""
pass
isVowel('b')
isVowel('a')
isVowel('z')
Some takeways.
We can chain together a bunch of boolean expressions (not just two).
It does not make sense to write
letter == 'a' or 'e' or 'i' or 'o' 'u': logical operators takebooltype operands, not strings.
Example 3. Write a function divide that takes two numbers num1 and num2 as input, and returns
the result of num1/num2 as long as num2 is not zero. If num2 is zero, it returns None.
def divide(num1, num2):
if not (num2 == 0): # can also write num2 != 0
return num1/num2
# do we need to say anything after this?
divide(7, 3)
2.3333333333333335
divide(9, 0)
Nested Conditionals¶
Sometimes, we may encounter a more complicated conditional structure. Consider the following example.
Write a function weather that takes as input a temperature temp value in Fahrenheit
If temp is above 80, print “It is a hot one out there.”
If temp is between 60 and 80, print “Nice day out, enjoy!”
If temp is below 60 and above 40, print “Chilly day, wear a sweater.”
If temp is below 40, print “Its freezing out, bring a winter jacket!”
Question. How can we organize this using if-else statements?
Attempt 1: Nested If Else¶
Does the following work?
def weather1(temp):
if temp > 80:
print("It is a hot one out there.")
else:
if temp >= 60:
print("Nice day out, enjoy!")
else:
if temp >= 40:
print("Chilly day, wear a sweater.")
else:
print("Its freezing out, bring a winter jacket!")
weather1(89)
It is a hot one out there.
weather1(72)
Nice day out, enjoy!
weather1(55)
Chilly day, wear a sweater.
weather1(33)
Its freezing out, bring a winter jacket!
Attempt 2: Only Ifs¶
The above function looks like a mess with so many indented blocks. What if we used only ifs? What is the trade off?
def weather2(temp):
if temp > 80:
print("It is a hot one out there.")
if temp >= 60 and temp <= 80:
print("Nice day out, enjoy!")
if temp <60 and temp >= 40:
print("Chilly day, wear a sweater")
if temp < 40:
print("Its freezing out, bring a winter jacket!")
weather2(89)
It is a hot one out there.
weather2(72)
Nice day out, enjoy!
weather2(55)
Chilly day, wear a sweater
weather2(33)
Its freezing out, bring a winter jacket!
Class Discussion¶
What is the difference between Attempt 1 and Attempt 2? Can we trace the control flow through each?
What are the pros, cons of each?
Chained if, elif, else Conditionals¶
If we only need to execute one out of several conditional branches, we can use chained (multibranch) conditionals with if, elifs, and else to execute exactly one of several branches.
If Else Statement Syntax¶
if (boolean expression a):
statement 1
…
elif (boolean epression b):
statement 2
…
else:
statement 3
statement 4
If bool expression a is True: only statement 1 and 4 are executed, regardless of the boolean exp b
If bool expression a is False and b is True: only statement 2 and 4 are executed
If bool expression a and b are both False: only statement 3 and 4 are executed
def weather3(temp):
if temp > 80:
print("It is a hot one out there.")
elif temp >= 60:
print("Nice day out, enjoy!")
elif temp >= 40:
print("Chilly day, wear a sweater.")
else:
print("Its freezing out, bring a winter jacket!")
weather3(89)
It is a hot one out there.
weather3(72)
Nice day out, enjoy!
weather3(55)
Chilly day, wear a sweater.
weather3(33)
Its freezing out, bring a winter jacket!
Takeway¶
Chained conditonals can avoid having to nest conditionals, which improves readability
Since only one of the brances in a chained
if, elif, elseconditionals evaluates toTrue, using them avoids unnecessary checks incurred by a chainedifstatements one after the other.