Learning objectives:
An expression with value true or false is called a boolean expression. Example expressions for what you would write mathematically as $C=40$, $C\ne40$, $C\ge40$, $C\gt40$ and $C\lt40$ are:
C == 40 # Note: the double == checks for equality!
C != 40 # This could also be written as 'not C == 4'
C >= 40
C > 40
C < 40
We can test boolean expressions in a Python shell:
C = 41
print("C != 40: ", C != 40)
print("C < 40: ", C < 40)
print("C == 41: ", C == 41)
C != 40: True C < 40: False C == 41: True
Several conditions can be combined with the special 'and' and 'or' keywords into a single boolean expression:
Examples:
x=0; y=1.2
print (x >= 0 and y < 1)
False
Add a comment to the code below to explain the outcome of each of the boolean expressions:
C = 41
print("Case 1: ", C == 40)
print("Case 2: ", C != 40 and C < 41)
print("Case 3: ", C != 40 or C < 41)
print("Case 4: ", not C == 40)
print("Case 5: ", not C > 40)
print("Case 6: ", C <= 41)
print("Case 7: ", not False)
print("Case 8: ", True and False)
print("Case 9: ", False or True)
print("Case 10: ", False or False or False)
print("Case 11: ", True and True and False)
print("Case 12: ", False == 0)
print("Case 13: ", True == 0)
print("Case 14: ", True == 1)
Case 1: False Case 2: False Case 3: True Case 4: True Case 5: False Case 6: True Case 7: True Case 8: False Case 9: True Case 10: False Case 11: False Case 12: True Case 13: False Case 14: True
Suppose we want to make a table of Celsius and Fahrenheit degrees:
-20 -4.0
-15 5.0
-10 14.0
-5 23.0
0 32.0
5 41.0
10 50.0
15 59.0
20 68.0
25 77.0
30 86.0
35 95.0
40 104.0
```
How do we write a program that prints out such a table?  We know from the last lecture how to make one line in this table:
C = -20
F = 9.0/5*C + 32
print(C, F)
-20 -4.0
We can just repeat these statements:
C=-20; F=9.0/5*C+32; print(C,F)
C=-15; F=9.0/5*C+32; print(C,F)
C=-10; F=9.0/5*C+32; print(C,F)
C=-5; F=9.0/5*C+32; print(C,F)
C=0; F=9.0/5*C+32; print(C,F)
C=5; F=9.0/5*C+32; print(C,F)
C=10; F=9.0/5*C+32; print(C,F)
C=15; F=9.0/5*C+32; print(C,F)
C=20; F=9.0/5*C+32; print(C,F)
C=25; F=9.0/5*C+32; print(C,F)
C=30; F=9.0/5*C+32; print(C,F)
C=35; F=9.0/5*C+32; print(C,F)
C=40; F=9.0/5*C+32; print(C,F)
-20 -4.0 -15 5.0 -10 14.0 -5 23.0 0 32.0 5 41.0 10 50.0 15 59.0 20 68.0 25 77.0 30 86.0 35 95.0 40 104.0
So we can see that works but its very boring to write and very easy to introduce a misprint.
You really should not be doing boring repetitive tasks like this. Spend one time instead looking for a smarter solution. When programming becomes boring, there is usually a construct that automates the writing. Computers are very good at performing repetitive tasks. For this purpose we use loops.
A while loop executes repeatedly a set of statements as long as a boolean (i.e. True / False) condition is True
while condition:
<statement 1>
<statement 2>
...
<first statement after loop>
Note that all statements to be executed within the loop must be indented by the same amount! The loop ends when an unindented statement is encountered.
At this point it is worth noticing that blank spaces may or may not be important in Python programs. These statements are equivalent (blanks do not matter):
v0=3
v0 = 3
v0= 3
# The computer does not care but this formatting style is
# considered clearest for the human reader.
v0 = 3
Here is a while loop example where blank spaces really do matter:
counter = 0
while counter <= 10:
counter = counter + 1
print(counter)
11
Let's take a look at what happens when we forget to indent correctly:
counter = 0
while counter <= 10:
counter = counter + 1
print(counter)
File "<ipython-input-8-d65e9710371e>", line 3 counter = counter + 1 ^ IndentationError: expected an indented block
Let's use the while loop to create the table above:
C = -20 # Initialise C
dC = 5 # Increment for C within the loop
while C <= 40: # Loop heading with condition
F = (9.0/5)*C + 32 # 1st statement inside loop
print(C, F) # 2nd statement inside loop
C = C + dC # Increment C for the next iteration of the loop.
-20 -4.0 -15 5.0 -10 14.0 -5 23.0 0 32.0 5 41.0 10 50.0 15 59.0 20 68.0 25 77.0 30 86.0 35 95.0 40 104.0
Write a program that prints out a table with Fahrenheit degrees 0, 10, 20, ..., 100 in the first column and the corresponding Celsius degrees in the second column.
Hint: $C = \frac{5}{9}(F-32)$
Many people use an approximate formula for quickly converting Fahrenheit ($F$) to Celsius ($C$) degrees: $C \approx \hat{C} = \frac{F − 30}{2}$ Modify the program from the previous exercise so that it prints three columns: $F$, $C$, and the approximate value $\hat{C}$.
So far, one variable has referred to one number (or string). Sometimes however we naturally have a collection of numbers, say degrees −20, −15, −10, −5, 0, ..., 40. One way to store these values in a computer program would be to have one variable per value, i.e.
C1 = -20
C2 = -15
C3 = -10
# ...
C13 = 40
This is clearly a terrible solution, particularly if we have lots of values. A better way of doing this is to collect values together in a list:
C = [-20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40]
Now there is just one variable, C, holding all the values. Elements in a list are accessed via an index. List indices are always numbered as 0, 1, 2, and so forth up to the number of elements minus one:
mylist = [4, 6, -3.5]
print(mylist[0])
print(mylist[1])
print(mylist[2])
print(len(mylist)) # length of list
4 6 -3.5 3
Here are a few example of operations that you can perform on lists:
C = [-10, -5, 0, 5, 10, 15, 20, 25, 30]
C.append(35) # add new element 35 at the end
print(C)
[-10, -5, 0, 5, 10, 15, 20, 25, 30, 35]
C=C+[40,45] # And another list to the end of C
print(C)
[-10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45]
C.insert(0, -15) # Insert -15 as index 0
print(C)
[-15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45]
del C[2] # delete 3rd element
print(C)
[-15, -10, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45]
del C[2] # delete what is now 3rd element
print(C)
[-15, -10, 5, 10, 15, 20, 25, 30, 35, 40, 45]
print(len(C)) # length of list
11
print(C.index(10)) # Find the index of the list with the value 10
3
print(10 in C) # True only if the value 10 is stored in the list
True
print(C[-1]) # The last value in the list.
45
print(C[-2]) # The second last value in the list.
40
You can also extract sublists using ":"
print(C[5:]) # From index 5 to the end of the list.
[20, 25, 30, 35, 40, 45]
print(C[5:7]) # From index 5 up to, but not including index 7.
[20, 25]
print(C[7:-1]) # From index 7 up to the second last element.
[30, 35, 40]
print(C[:]) # [:] specifies the whole list.
[-15, -10, 5, 10, 15, 20, 25, 30, 35, 40, 45]
You can also unpack the elements of a list into seperate variables:
somelist = ['Curly', 'Larry', 'Moe']
stooge1, stooge2, stooge3 = somelist
print(stooge3, stooge2, stooge1)
Moe Larry Curly
Step 1: Write a program that generates all odd numbers from 1 to n. Set n in the beginning of the program and use a while loop to compute the numbers. (Make sure that if n is an even number, the largest generated odd number is n-1.).
Step 2: Store the generated odd numbers in a list. Start with an empty list and use the same while loop where you generate each odd number, to append the new number to the list.
Finally, print the list elements to the screen.
We can visit each element in a list and process the element with some statements using a for loop, for example:
degrees = [0, 10, 20, 40, 100]
for C in degrees:
print('list element:', C)
print('The degrees list has', len(degrees), 'elements')
list element: 0 list element: 10 list element: 20 list element: 40 list element: 100 The degrees list has 5 elements
Notice again how the statements to be executed within the loop must be indented! Let's now revisit the conversion table example using the for loop:
Cdegrees = [-20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40]
for C in Cdegrees:
F = (9.0/5)*C + 32
print(C, F)
-20 -4.0 -15 5.0 -10 14.0 -5 23.0 0 32.0 5 41.0 10 50.0 15 59.0 20 68.0 25 77.0 30 86.0 35 95.0 40 104.0
We can easily beautify the table using the printf syntax that we encountered in the last lecture:
for C in Cdegrees:
F = (9.0/5)*C + 32
print('%5d %5.1f' % (C, F))
-20 -4.0 -15 5.0 -10 14.0 -5 23.0 0 32.0 5 41.0 10 50.0 15 59.0 20 68.0 25 77.0 30 86.0 35 95.0 40 104.0
It is also possible to rewrite the for loop as a while loop, i.e.,
for element in somelist:
# process element
can always be transformed to a while loop
index = 0
while index < len(somelist):
element = somelist[index]
# process element
index += 1
```
Taking the previous table example:
Cdegrees = [-20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40]
index = 0
while index < len(Cdegrees):
C = Cdegrees[index]
F = (9.0/5)*C + 32
print('%5d %5.1f' % (C, F))
index += 1
-20 -4.0 -15 5.0 -10 14.0 -5 23.0 0 32.0 5 41.0 10 50.0 15 59.0 20 68.0 25 77.0 30 86.0 35 95.0 40 104.0
Rather than just printing out the Fahrenheit values, let's also store these computed values in a list of their own:
Cdegrees = [-20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40]
Fdegrees = [] # start with empty list
for C in Cdegrees:
F = (9.0/5)*C + 32
Fdegrees.append(F) # add new element to Fdegrees
print(Fdegrees)
[-4.0, 5.0, 14.0, 23.0, 32.0, 41.0, 50.0, 59.0, 68.0, 77.0, 86.0, 95.0, 104.0]
In Python for loops usually loop over list values (elements), i.e.,
for element in somelist:
...process variable element
However, we can also loop over list indices:
for i in range(0, len(somelist), 1):
element = somelist[i]
... process element or somelist[i] directly
```
The statement range(start, stop, inc) generates a list of integers start, start+inc, *start+2*inc, and so on up to, but not including, stop. We can also write range(stop)* as an abbreviation for range(0, stop, 1):
print(range(3)) # same as range(0, 3, 1)
range(0, 3)
print(range(2, 8, 3))
range(2, 8, 3)
Consider this example where we compute two lists in a for loop:
n = 16
Cdegrees = []; Fdegrees = [] # empty lists
for i in range(n):
Cdegrees.append(-5 + i*0.5)
Fdegrees.append((9.0/5)*Cdegrees[i] + 32)
print("Cdegrees = ", Cdegrees)
print("Fdegrees = ", Fdegrees)
Cdegrees = [-5.0, -4.5, -4.0, -3.5, -3.0, -2.5, -2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5] Fdegrees = [23.0, 23.9, 24.8, 25.7, 26.6, 27.5, 28.4, 29.3, 30.2, 31.1, 32.0, 32.9, 33.8, 34.7, 35.6, 36.5]
As constructing lists is a very common requirement, the above way of doing it can become very tedious to both write and read. Therefore, Python has a compact construct, called list comprehension for generating lists from a for loop:
n = 16
Cdegrees = [-5 + i*0.5 for i in range(n)]
Fdegrees = [(9.0/5)*C + 32 for C in Cdegrees]
print("Cdegrees = ", Cdegrees)
print("Fdegrees = ", Fdegrees)
Cdegrees = [-5.0, -4.5, -4.0, -3.5, -3.0, -2.5, -2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5] Fdegrees = [23.0, 23.9, 24.8, 25.7, 26.6, 27.5, 28.4, 29.3, 30.2, 31.1, 32.0, 32.9, 33.8, 34.7, 35.6, 36.5]
The general form of a list comprehension is:
somelist = [expression for element in somelist]
# Using for loop
# Using list comprehension
# Using the function range