7 > 3
True
Introduction to Software Engineering (CSSE 1001)
The following are the basic operands of logic.
or
,and
,not
.which are functions into the bool
type. Functions that return True
or False
, such as these, are called predicates.
For instance, greater than is a predicate which takes two numbers and returns True
when the first larger than the second.
7 > 3
True
The binary predicate and
is used to test that both of two predicate statements are True
.
An expressions with and
is True
only when both of its inputs are True
.
False and False
False
False and True
False
True and False
False
True and True
True
The binary predicate or
is used to test that at least one of two predicate statements is True
.
An expressions with or
is False
only when both of its inputs are False
.
False or False
False
False or True
True
True or False
True
True or True
True
3>7 or 7>3
True
3>7 and 7>3
False
0 < 3 and 3 < 8
True
There is a nice shorthand for statements like 0 < 3 and 3 < 8
.
0 < 3 < 8
True
Consider that
True or False and False
is ambiguous because left-bracketing gives
True or False) and False (
False
but right-bracketing gives
True or (False and False) == True
True
and thus an order of operations is necessary to resolve ambiguities.
Observe
True or False and False
True
and thereby and
has precedence over or
.
Exercise 1 Bracket the following boolean expression so that it evaluates to False
.
False and False or True and False or False or True
How many different bracketings can you find?
The logical statement not
is the negation of logical statement:
not(False)
True
not(True)
False
= 6, 7 a, b
== 6 a
True
== 6 and b == 5 a
False
not(a == 7 and b == 5)
True
!= 7 and not b != 7 a
True
Exercise 2 Add a single not
to
False and False or True and False or False or True
so that it evaluates to False.
Python is a lazy programming language which means it does not perform computation unless it absolutely must. The consequence of this is that expressions may not get executed when and
-ing and or
-ing them.
For instance, we do not throw a division by zero error in the following because Python does not both evaluating 1/0
because the outcome of that expressions has no bearing on the outcome (True or ANYTHING
is True
).
True or 1/0
True
We do however, throw it here because Python needed to check if 1/0
is True
because the first input was False
.
False or 1/0
ZeroDivisionError: division by zero
The following is fine because Python never gets around to checking if non_existent_variable
has a value.
True or non_existent_variable
True
The following it not fine because it is not in Python’s language – it does not satisfy the syntax rules.
True or !
True or !
^
SyntaxError: invalid syntax
Python needs to check if 1/0
is truthy to determine the outcome of the following. This is the point at which the error occurs.
True and 1/0
ZeroDivisionError: division by zero
False and 1/0
False
Keep in mind that the result of comparison operators can be stored in memory.
= 3
a == 3
a != 3 a
False
= (a != 3)
b b
False
Exercise 3 Determine what outputs.
= True + 2
a a
= 7*False
b b
= not a != b
c c
Values in Python that bool
converts to True
are called truthy.
Example 1 Non-zero numbers, non-empty strings, and non-empty lists are all truthy.
bool(1), bool(-10), bool("Hello"), bool([1,2,3])
(True, True, True, True)
Conversely, values in Python that bool
converts to True
are called falsy.
Example 2 Zero, the empty string, and the empty list are all falsy.
bool(0), bool(""), bool([])
(False, False, False)
Exercise 8 Which of the following expressions evaluate to True
?
bool(not [] and "hello")
bool(True or 1/0)
bool(" ")
bool(1 > False)
The functions and
and or
do not always return True
and False
as we may expect. In Python, and
returns its first falsy input and or
its first truthy input. In the case no such value exists, the last input is returned.
0 or 2
2
0 or 0
0
or [1] or [1, 2] []
[1]
1, 2] or [1] or [] [
[1, 2]
0 and 2
0
1 and 2
2
and [1] and [1, 2] []
[]
1, 2] and [1] and [] [
[]
Given a condition \(C\) (i.e. a predicate that evaluates to True or False) an if-statement is a control structure that executes a block of code when \(P\) is True (and skips it otherwise).
if <cond>:
<code executed when cond == True> ␣␣␣␣
In Python spaces matter — only code indented within an if-statement gets executed.
= 0
x if False:
= x + 1
x x
0
= 0
x if True:
= x +1
x x
1
= 0
x if x:
= x + 1
x x
0
= 1
x if x:
= x +1
x x
2
def foo(x):
if x > 0:
print("Positive")
if x > 10**5:
print("Large positive")
= foo(10**6) ans
Positive
Large positive
type(ans)
NoneType
def bar(x):
if x > 0:
return "Positive"
if x > 10**5:
return "Large positive"
= bar(10**6) ans
type(ans)
str
ans
'Positive'
Take care when defining variables inside if-statements.
if False:
= 0
ans ans
NameError: name `ans' is not defined
The code in the if-statement is skipped and therefore ans
does not get set.
In this case it is best to define a default value for ans
.
Consider that writing
if balance >= 0:
= True
in_the_black = False
in_the_red
if balance < 0:
= False
in_the_black = True int_the_red
makes our code longer and checks the condition twice.
Here is the general framework for working with if-then
statements.
if <cond>:
<code>
else:
<code>
if balance >= 0:
= True
in_the_black = False
in_the_red else:
= False
in_the_black = True int_the_red
if-else
does not allow you to skip code, but rather lets us pick between two instruction sets.
Here is the general framework for working with if-elif
statements.
= 60
age
if age >= 18:
= "cheap beer"
beverage elif age >= 30:
= "standard beer"
beverage elif age >= 50:
= "expensive beer"
beverage
beverage
'cheap beer'
This code does not work as intended!
We could specify lower and upper bounds on the age .
= 60
age
if 18 <= age < 30:
= "cheap beer"
beverage elif 30 <= age < 50:
= "standard beer"
beverage elif 50 <= age:
= "expensive beer"
beverage
beverage
'expensive beer'
Notice for this fix we did not need elif
statements because the following is equivalent to what we just wrote.
= 60
age
if 18 <= age < 30:
= "cheap beer"
beverage
if 30 <= age < 50:
= "standard beer"
beverage
if 50 <= age:
= "expensive beer"
beverage
beverage
'expensive beer'
If we revese the way we check for age and re-introduce the elif
we can simplify the code somewhat.
= 60
age
if age >= 50:
= "expensive beer"
beverage elif age >= 30: # Guaranteed `age < 50`
= "standard beer"
beverage elif age >= 18: # Guaranteed `age < 50 and age < 30`
= "cheap"
beverage
beverage
'expensive beer'
Here is the general framework for working with if-elif-else
statements.
if <cond0>:
<code>
elif <cond1>:
<code>
.
.
.elif <condN>:
<code>
else:
<code>
Exercise 7 What will beverage
evaluate to after this code is run?
= 9
age
if age >= 50:
= "expensive beer"
beverage elif age >= 30:
= "standard beer"
beverage elif age >= 18:
= "cheap"
beverage
beverage
In computer science factoring means breaking a complex problem into parts that are easier to conceive, understand, program, and maintain.
Code refactoring is the process of restructuring existing computer code – changing the factoring – without changing its behavior.
Here are a list of common scenarios where refactoring could be done.
Example 3 Nested if-statements should be avoided by using and
because
if x>1:
if y>2:
if z>3:
print("hello")
is equivalent to
if x>1 and y>2 and z>3:
print("hello")
Example 4 No need for an if-statement in the following code because
def foo(x):
if x > 0:
return True
else:
return False
is equivalent to
def foo(x):
return x > 0
Example 5 No need for an if-statement in the following code because
if x > 0:
= True
y else:
= False y
is equivalent to
= x > 0 y
Example 6 No need to equality check on True
because
if x > y == True:
= 1 z
is equivalent to
if x > y:
= 1 z
Example 7 No need to equality check on False
because
if x > y == False:
= 1 z
is equivalent to
if not x > y:
= 1 z
Exercise 4 Are the following pieces of code equivalent?
#Block 1
if x > 0:
print("A")
elif x <= 0 and x % 2 == 0:
print("B")
if x > 0:
print("A")
elif x % 2 == 0:
print("B")
Exercise 5 Are the following pieces of code equivalent?
if x > 0:
print("A")
if x <= 0 and x % 2 == 0:
print("B")
if x > 0:
print("A")
if x % 2 == 0:
print("B")
Exercise 6 Refactor the code.
def foo(x, y):
if x > 100 and y > 0:
if y > 100 and x > 0:
return "A"
elif y > 100 or x > 0:
return "A"
else:
return "B"
elif y <= 0 or x <= 0:
if x == y:
return "A"
if x <= y and x >= y:
return "B"
if y < x and x < y:
return "C"
else:
return "A"
else:
if x <= 100 and y > 0:
return "A"
if x > 100 or y <= 0:
return "B"
else:
return "D"
The following will always print.
if x == 1 or 2 or 3:
print("hello")
It is not equivalent to
if x == 1 or x == 2 or x == 3:
print("hello")
which we will eventually refactor as
if x in [1,2,3]:
print("hello")
This is because
== 1 or 2 or 3 x
is evaluated like
== 1) or (2) or (3) (x
which is equivalent to
== 1) or True or True (x
which is always True
.
The following is not an error per-se, but is common student code and should not be done.
if x:
pass
else
print("Hello World")
is equivalent to
if not x:
print("Hello World")
Blocks of code can be skipped using if
statements. This control flow depends on the evaluation of predicate statements.
Next Iteration!