Construct Boolean expressions from
English descriptions.
Mentally execute (trace) code with conditionals:
that is: if, if-else, and if-multi-else statements.
Write and debug code with conditionals.
Write and debug code with conditionals inside loops.
Identify new syntactic elements related to the above.
1.0 Audio:
1.0 A simple example
Consider this program:
x = 5
y = 4
if x > y:
print('Hey, x is bigger')
print("OK, we're done")
1.1 Exercise:
In
my_ifexample.py,
type up the above and examine the output. Then,
just below the print with 'Hey' (and indented 4 spaces) add another print
to print anything. Then, change the value of y to 6 and
report the output in
module1.pdf.
Submit the program with these modifications.
Let's explain:
First, observe:
Now, at the moment the if-statement executes, the
condition is evaluated:
If the condition is true then the code that's indented below
the if-statement executes.
Consider what happens when y is 6:
1.2 Exercise:
Consider this program:
s = 0
for i in range(6):
s = s + i
if s < 15:
print('Less than 15')
print('Done')
Try to mentally execute (trace its execution in your mind)
and predict the output before typing it up in
my_ifexample2.py
to confirm.
1.1 if-else
Think of else as if's occasional partner.
Consider this example:
x = 5
y = 4
if x > y:
print('Hey, x is bigger')
else:
print('Who said x is bigger?')
print('In fact, y is bigger')
print("OK, we're done")
1.3 Exercise:
Type up the above in
my_ifexample3.py
and examine the output. Then,
change the value of y to 6. What is the output? Change
y to 5. What is the output? Report these in your module pdf.
Let's point out:
When x is indeed larger than y, the code in the if-body executes:
When the if-condition evaluates to false:
What happens when x is 5 and y is 5?
Because some of these arrows might be difficult to follow,
let's emphasize some blocks (lines) of code:
First consider when x is larger than y:
And when y is larger than x:
1.2 if-elif-else
Consider this variation:
x = 5
y = 5
if x > y:
print('Hey, x is bigger')
elif y > x:
print('Who said x is bigger?')
print('In fact, y is bigger')
else:
print('Actually, they are equal')
print("OK, we're done")
1.4 Exercise:
Type up the above in
my_ifexample4.py
and examine the output. Then, try y=6 and y=4.
Report results in your module pdf.
Let's explain:
First, consider the case x=5, y=5:
Now consider x=5, y=4:
Next: x=5, y=6:
One can have as many elif sections as one would like, for example:
x = 3
if x == 1:
print('one')
elif x == 2:
print('two')
elif x == 3:
print('three')
elif x == 4:
print('four')
else:
print('big')
Think of the whole thing as a giant if-statement:
In the above case, when x is 3, the execution path through the
giant if-statement is:
1.5 Exercise:
Type up the above in
my_ifexample5.py.
Then, try each of x=1, x=2, x=4, x=5. Draw the execution
pathways (similar to the picture above) for each case in your module pdf.
Consider this program:
x = 5
y = 4
z = 3
if x > y:
print('Hey, x is bigger')
if x > z:
print('x is bigger than z')
print('So, x must be the largest')
1.6 Exercise:
Type up the above in
my_ifexample6.py.
Try y = 6. Explain why it does not work. Then try to alter the program
without changing the print-statements
so that it works in all cases for possible values of x,y, and z.
That is, whichever of the above print-statements gets printed
correctly reflects the values of x, y and z.
1.7 Video:
1.3 Nested conditionals
Consider this program:
a = 3
b = 4
c = 5
if a < b:
if a < c:
print('a is the smallest')
else:
print('a is not the smallest')
print('Done')
This is an example of a nested conditional (nested if):
First, examine the indented structure:
The flow of execution:
Consider this variation:
a = 3
b = 4
c = 5
if a < b:
if a < c:
print('a is the smallest')
else:
print('a is not the smallest')
print('We know a is less than b')
else:
print('We know a is not less than b')
print('Done')
1.8 Exercise:
Type up the above in
my_nestedif.py.
Draw the flow of execution for the following
three cases: (1) when a=3, b=4, c=5;
(2) when a=3, b=4, c=2;
(3) when a=6, b=4, c=5.
1.9 Exercise:
In
my_smallest_of_three.py,
modify the above program so that it prints out,
appropriately, one of "a is the smallest", "b is
the smallest" or "c is the smallest", depending
on the actual values of a, b, and c.
Try different values of these variables to make
sure your program is working correctly.
1.10 Audio:
Note:
A numeric variable can be: strictly less, less than or equal to, strictly greater, greater than or equal to, or equal to another variable.
Accordingly, the different types of less/greater
comparisons are:
a < b # Strictly less than, as when a=3, b=4
a <= b # Could be less (a=3, b=5), could be equal (a=3, b=3)
a > b # Strictly greater (a=3, b=2)
a >= b # Could be greater (a=3, b=1), could be equal (a=2, b=2)
1.4 Combining conditions
Consider this program:
x = 5
y = 5
z = 5
if x == y and y == z:
print('All three are equal')
Note:
The first thing to point out is the
==
operator:
Because we've been using the equals operator
for assigning values to variables, we need something
else to test for equality.
The equality operator in Python is
==
as in:
if x == y and y == z:
Alas, the problems with limited keyboard symbols!
Important: the difference between = and ==
is very important to remember. It's easy to make a mistake one forgets.
The if-statement combines two conditions:
if x == y and y == z:
The combining occurs with the Boolean operatorand:
if x == y and y == z:
We can clarify the parts and combination thereof using parens:
if (x == y) and (y == z):
The two parts are often called clauses:
First clause (x == y):
if (x == y) and (y == z):
Second clause (y == z):
if (x == y) and (y == z):
You could have many more clauses.
The "and" operator works like this:
Boolean is pronounced "BOO lee unn".
A Boolean operator takes expressions and computes to either
true or false.
Let's go back to finding the smallest of three numbers using
conditionals:
a = 3
b = 4
c = 5
# Fill in code here ...
1.11 Exercise:
In
my_smallest_of_three2.py,
fill in code to identify which of the three variables has the
smallest value, depending
on the actual values of a, b, and c.
Use if-statements with multiple clauses.
Try different values of these variables to make
sure your program is working correctly.
1.12 Video:
As the counterpart to the and operator, there is the or
operator:
a = -2.718
if (a <= 0) or (a >= 1):
print('a is not between 0 and 1')
1.13 Exercise:
Type up the above in
my_boolean2.py.
Then try a=0.5.
Note:
We have shown how to write "less than or equal to" using
<=.
So, now we can add "equals" and "not equals"
to the numeric comparisons:
a < b # Strictly less than, like a=3 < b=4
a <= b # Could be less, could be equal (a=3, b=3)
a > b # Strictly greater (a=3, b=2)
a >= b # Could be greater, could be equal
a == b # Exactly equal
a != b # Not equal
For the or operator to evaluate to true, any one
or both of the two expressions needs to be true.
Consider:
a = 3
b = 4
if (a < 10) or (b < 10):
print('One or both of them is less than 10')
In this case both will evaluate to true, and so
the print statement executes.
Suppose we made a=3, b=11, the print statement will execute.
Suppose we change a=11, b=3, the print statement will execute.
But if a=11, b=12, the or fails (both clauses are
false), and the print won't execute.
Incidentally, let's replace or with and in the
above case, and see what we get:
a = 3
b = 4
if (a < 10) and (b < 10):
print('Both of them are less than 10')
In this case, both sub-conditions are satisfied, and so the whole
if-condition is satisfied, which means the print will execute.
But if we had
a = 3
b = 4
if (a < 10) and (b > 10):
print('Both of them are less than 10')
In this case, the second comparison fails, and the print won't
occur.
Whereas if we had or:
a = 3
b = 4
if (a < 10) or (b > 10):
print('One or both of them is less than 10')
Here, it's enough that a is less than 3, and so the print executes
even though "b greater than 10" fails.
Next, let's look at the NOT operator (written with !):
x = 5
y = 6
z = 7
if (x != y) and (x != z):
print('x is different from y and from z')
Here, read
!=
as "not equals".
1.14 Exercise:
Type up the above in
my_boolean3.py,
then change z to be 6 (same as y). What do you observe?
One can combine any number of and's, for example:
x = 5
y = 6
z = 7
if (x != y) and (x != z) and (y != z):
print('x, y, z are all different')
The difference between
!=
and
not:
We should read
!=
as "not equals"
just as we read
==
as "equals".
There is another operator called not, which
applies to Boolean expressions, as we'll see next.
The not operator
One can apply the not operator
to groups of clauses using additional parens:
x = 8
if not ( (x == 5) or (x == 6) ):
print('x is neither 5 nor 6')
Here, not is asking that whatever it applies to
be false.
Thus, consider the expression
if not ( (x == 5) or (x == 6) ):
In this case, x is 8. So, neither of
(x == 5)
nor
(x == 6)
is true.
Thus, the whole expression
( (x == 5) or (x ==6) )
is false.
Which means
not ( (x == 5) or (x ==6) )
evaluates to true.
Therefore, the print executes.
1.15 Exercise:
Suppose integer variables
a,b,c,d,e
have values a=1, b=1, c=3, d=4, e=5.
Consider the following three expressions:
( (a <= b) and (c+d > e) and (d > 1) )
( (a > c) or ( (c+1 < e) and (c-b > a) ) )
not ( (b == d-c) and (a > b) or (c < d) )
Try to evaluate each expression by hand. Then, in
my_boolean4.py,
write up each of these in an if-statement to see if the
result matches with your hand-evaluation.
1.16 Exercise:
In
my_boolean5.py,
write a program that begins with
a = -3
b = -4
and uses conditionals to print out the absolute difference between the
two numbers. In the above case, the difference is 1. In the case
of a=3, b=4, the difference is also 1. When a=-3, b=4, the difference
is 7.
1.17 Video:
1.5 Conditionals and loops
Let's write a program to loop through integers and print only
the even numbers:
n = 10
for i in range(1, n+1):
if i % 2 == 0:
print(i, 'is even')
1.18 Exercise:
In your module pdf,
trace through the iterations in the above program.
Then, in
my_oddeven.py,
modify the above program so that for every number between
n and 1, going backwards,
the program prints whether it's even or odd, as in:
10 is even
9 is odd
8 is even
7 is odd
6 is even
5 is odd
4 is even
3 is odd
2 is even
1 is odd
1.19 Audio:
1.6 Conditionals and lists
Suppose we have a list of numbers, representing daily
profits (sometimes negative, sometimes positive)
and we only want to add up the positive numbers:
earnings = [-5, 2, 3, -9, 12, 4, -30]
total = 0
for k in earnings:
if k >= 0:
total += k
print('Total profit =', total)
1.20 Exercise:
Trace through the values of total and k in your module pdf.
1.21 Exercise:
Given a list like
A = [-5, 2, 4, -9, 12, 13, -30, -21, -20]
we see that 12,13 and -21,-20 are pairs of consecutive numbers. Write
a program called
my_consecutive.py,
with loop and a conditional to identify such consecutive pairs and
print them. For the
above list, the output should be:
Next, let's write a program that asks the user to enter
a number that we then check is in a list of numbers:
# The list of numbers:
A = [-5, 2, 4, -9, 12, 13, -30]
# Receive what the user types in (as a string):
user_str = input('Enter an integer: ')
# Convert string to integer:
k = int(user_str)
# Check whether in the list:
if k in A:
print(k,'is in the list')
else:
print(k,'is not in the list')
Note:
The in operator checks member in the list:
if k in A:
1.23 Exercise:
Suppose you are given two lists like
A = [-5, 2, 4, -9, 12, 13, -30, -21, -20]
B = [2, -9, 11, 16, 13]
Notice that some elements of A (like 2) also exist in B.
In
my_twolist.py,
use the list membership idea to print those elements of A that
are also in B. For the above example, the output should be:
2 in A also found in B
-9 in A also found in B
13 in A also found in B
1.24 Audio:
1.7 More examples with lists
Consider the following program that aims
to find duplicates in a list:
A = [2, 9, 2, 6, 4, 3, 3, 2]
for k in A:
if k in A:
print('Duplicate found:', k)
In the list, we can see that 2 occurs thrice, and 3 occurs twice.
Both should be listed as duplicates. Is this the case?
1.25 Exercise:
Trace through the iterations in the above program and explain
why it does not work.
Now consider this variation:
A = [2, 9, 2, 6, 4, 3, 3, 2]
for i in range(len(A)-1):
for j in range(i+1, len(A)):
if A[i] == A[j]:
print('Duplicate found:', A[i])
1.26 Exercise:
Trace through the iterations in the above program and explain
the output. Why does the inner loop start with i+1?
1.27 Audio:
1.8 Some stats via programming
Let's now apply our practice with conditionals to solve
some problems in probability and statistics.
For example: Suppose I toss a coin 4 times and observe the face
that's up. What is the probability that I get all "tails"
(not one toss shows "heads").
Let's do this in steps.
First, let's write a program to toss a coin 4 times
import random
coin = ['heads', 'tails']
for i in range(4):
toss = random.choice(coin)
print(toss)
1.28 Exercise:
Type up the above in
my_cointosses.py
and run it a few times to see what you get.
Note:
We have made a list of strings:
coin = ['heads', 'tails']
Python has a useful way to randomly select a member of a
list:
toss = random.choice(coin)
Alternatively, we could have written:
toss = random.choice(['heads','tails'])
and avoided defining
coin.
Next, instead of printing the results, let's count the number
of heads observed:
import random
count = 0
for i in range(4):
toss = random.choice(['heads', 'tails'])
if toss == 'heads':
count = count + 1
print('Number of heads', count)
1.29 Exercise:
Type up the above in
my_cointosses2.py
and run it a few times to see what you get.
Note:
Observe how the string that's randomly selected from the list
is compared against 'heads':
if toss == 'heads':
count = count + 1
Next, what we need to do is repeat the 4-coin toss many times:
Suppose we call 4-coin tosses a single trial.
Clearly, if we ran a single trial and obtained 1 heads
(count=1) then, could we conclude that the probability of
getting all-4-tails is zero?
What we need to do is run a large number of trials
and record in how many trials we get a run of 4-tails.
We'll use the term "success" to identify a trial
in which we get all-4-tails.
Let's examine the code:
import random
trials = 10
successes = 0
for i in range(trials):
# Count number of heads in 4 tosses:
count = 0
for i in range(4):
toss = random.choice(['heads', 'tails'])
if toss == 'heads':
count = count + 1
# If the count is zero, that's a success
if count == 0:
successes += 1
# Ratio of successes to trials:
probability = successes / trials
print('probability =', probability)
1.30 Exercise:
Type up the above in
my_cointosses3.py
and run it a few times to see what you get. Then increase
the number of trials to 100000 and see. The theoretical
answer is 0.0625 (approximately 6% chance there's no heads in 4 tosses).
1.31 Exercise:
In
my_cointosses4.py,
write a program to run a large number of trials of
the following experiment:
toss a coin 10 times and record a success if you get an
equal number of heads and tails.
1.32 Audio:
Now let's solve a problem with that other favorite
manner of generating chance: dice
We'll roll two dice and add the numbers face up. We want to ask:
what are the chances we get 7 (when added up)?
Here's the program:
import random
possible_outcomes = [1,2,3,4,5,6]
trials = 100000
successes = 0
for i in range(trials):
roll1 = random.choice(possible_outcomes)
roll2 = random.choice(possible_outcomes)
if roll1 + roll2 == 7:
successes += 1
probability = successes / trials
print('probability =', probability)
1.33 Exercise:
Type up the above in
my_dice.py
and see what you get, reporting in your module pdf.
Is there a number other than 7 for which the probability is higher?
Let's also look at how one can get Python to randomly
generate real numbers, for example:
import random
trials = 100
total = 0
for i in range(trials):
x = random.uniform(5, 10)
print(x)
total += x
print('mean =', total/trials)
Note:
By using
x = random.uniform(5, 10)
we can generate a random real number between 5 and 10.
In the above program we are generating many such numbers
and calculating their average.
1.34 Exercise:
Type up the above in
my_uniform.py,
then increase the number of trials,
and see what you get as the average, reporting in your module pdf.
What is the average when you generate numbers between 25 and 30
and how does that compare with the average of the numbers 25 and 30?
Explain why this should make sense.
Before you head off to Vegas with your Python programs, let's point out:
You can use programming to explore ideas in probability
and statistics, and solve real problems as well.
It is an exciting way to learn stats that we will have more
to say about later.
1.9 Algorithmic art
Let's now use what we've learned to explore the notion of
how computers can be programmed to generate abstract art.
In our first example, we'll draw lines from one border
of a square to another:
Let's describe the main idea via some pseudocode:
In a loop we'll generate:
Set up an initial x1,y1 and x2,y2
for i in ...
Pick a random color
Draw a line from x1,y1, y2,y2
Make the current endpoint the start of the next line:
x1 = x2
y1 = y2
Pick a random border
Now pick a new random point on the next border
When we pick a border, we'll need to figure out
the coordinates.
1.35 Exercise:
Download
conditional_art.py
and
drawtool.py.
Try it out and then examine the code to confirm that
it follows the pseudocode. Try different values of n.
Can you change the choices of randomly chosen colors to
improve the result? Does it look good with just two colors?
Next, starting with Kandinsky, find an example of abstract
art that you think might be considered an analogue in
the history of art. Include a screenshot of your improved
art, and the historical painting in your module pdf.
Next, we'll explore an interesting question:
Think of random art at one end of a spectrum.
And highly-structured geometry at the other end,
generated by an algorithm.
The question: can we adjust a "knob" that
let's us generate a mix? And is that more aesthetic?
1.36 Exercise:
Download
conditional_art2.py.
Try out different values (between 0 and 1) of the
structure
parameter, for example 0.9 and 0.1.
Is there a value that provides an aesthetic mix? Try different n.
Make changes to the code and submit a screenshot of the result.
1.10 When things go wrong
In each of the exercises below, first try to identify the error
just by reading. Then type up the program to confirm, and
after that, fix the error.
1.37 Exercise:
x = 5
y = 6
if x < y
print('x is less than y')
Identify and fix the error in
my_error1.py.
1.38 Exercise:
x = 5
y = 6
if x !< y:
print('x is not less than y')
Identify and fix the error in
my_error2.py.
1.39 Exercise:
The following code intends to find the maximum number in a list:
A = [3, 1, 8, 4, 2, 5]
for k in A:
largest = 0
if k > largest:
largest = k
print(largest)
Identify and fix the error in
my_error3.py.
1.40 Exercise:
a = 2.5
# See whether a lies between 0 to 1, or 1 to 2,
# or something else
if (a > 0) and (a < 1):
print('between 0 and 1')
else if (a > 1) and (a < 2):
print('between 1 and 2')
else:
print('something else')