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 FalseFalse
False and TrueFalse
True and FalseFalse
True and TrueTrue
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 FalseFalse
False or TrueTrue
True or FalseTrue
True or TrueTrue
3>7 or 7>3 True
3>7 and 7>3 False
0 < 3 and 3 < 8True
There is a nice shorthand for statements like 0 < 3 and 3 < 8.
0 < 3 < 8True
Consider that
True or False and Falseis ambiguous because left-bracketing gives
(True or False) and False False
but right-bracketing gives
True or (False and False) == TrueTrue
and thus an order of operations is necessary to resolve ambiguities.
Observe
True or False and FalseTrue
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 TrueHow many different bracketings can you find?
The logical statement not is the negation of logical statement:
not(False)True
not(True)False
a, b = 6, 7 a == 6 True
a == 6 and b == 5 False
not(a == 7 and b == 5) True
a != 7 and not b != 7 True
Exercise 2 Add a single not to
False and False or True and False or False or Trueso 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.
a = 3
b = (a != 3)
bFalse
Exercise 3 Determine what outputs.
a = True + 2
ab = 7*False
bc = not a != b
cValues 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 22
0 or 00
[] or [1] or [1, 2][1]
[1, 2] or [1] or [][1, 2]
0 and 20
1 and 22
[] 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.
x = 0
if False:
x = x + 1
x 0
x = 0
if True:
x = x +1
x 1
x = 0
if x:
x = x + 1
x 0
x = 1
if x:
x = x +1
x 2
def foo(x):
if x > 0:
print("Positive")
if x > 10**5:
print("Large positive")
ans = foo(10**6) Positive
Large positive
type(ans) NoneType
def bar(x):
if x > 0:
return "Positive"
if x > 10**5:
return "Large positive"
ans = bar(10**6) type(ans) str
ans 'Positive'
Take care when defining variables inside if-statements.
if False:
ans = 0
ansNameError: 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:
in_the_black = True
in_the_red = False
if balance < 0:
in_the_black = False
int_the_red = Truemakes 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:
in_the_black = True
in_the_red = False
else:
in_the_black = False
int_the_red = Trueif-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.
age = 60
if age >= 18:
beverage = "cheap beer"
elif age >= 30:
beverage = "standard beer"
elif age >= 50:
beverage = "expensive beer"
beverage 'cheap beer'
This code does not work as intended!
We could specify lower and upper bounds on the age .
age = 60
if 18 <= age < 30:
beverage = "cheap beer"
elif 30 <= age < 50:
beverage = "standard beer"
elif 50 <= age:
beverage = "expensive beer"
beverage 'expensive beer'
Notice for this fix we did not need elif statements because the following is equivalent to what we just wrote.
age = 60
if 18 <= age < 30:
beverage = "cheap beer"
if 30 <= age < 50:
beverage = "standard beer"
if 50 <= age:
beverage = "expensive beer"
beverage 'expensive beer'
If we revese the way we check for age and re-introduce the elif we can simplify the code somewhat.
age = 60
if age >= 50:
beverage = "expensive beer"
elif age >= 30: # Guaranteed `age < 50`
beverage = "standard beer"
elif age >= 18: # Guaranteed `age < 50 and age < 30`
beverage = "cheap"
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?
age = 9
if age >= 50:
beverage = "expensive beer"
elif age >= 30:
beverage = "standard beer"
elif age >= 18:
beverage = "cheap"
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 Falseis equivalent to
def foo(x):
return x > 0Example 5 No need for an if-statement in the following code because
if x > 0:
y = True
else:
y = Falseis equivalent to
y = x > 0Example 6 No need to equality check on True because
if x > y == True:
z = 1is equivalent to
if x > y:
z = 1Example 7 No need to equality check on False because
if x > y == False:
z = 1is equivalent to
if not x > y:
z = 1Exercise 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
x == 1 or 2 or 3is evaluated like
(x == 1) or (2) or (3)which is equivalent to
(x == 1) or True or Truewhich 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!