For Loops¶
Goal: Convert Temperatures¶
- Make a temperature conversion chart, from Fahrenheit to Centigrade, for these Fahrenheit values: 30, 40, 50, 60, 70.
- Output (approximate):
30 -1.1111111111111112
40 4.444444444444445
50 10.0
60 15.555555555555555
70 21.11111111111111
- Hint:
cent = (fahr - 32) / 9 * 5
Here is one possible Python program that solves this:
fahr = 30
cent = (fahr - 32) / 9 * 5
print(fahr, cent)
fahr = 40
cent = (fahr - 32) / 9 * 5
print(fahr, cent)
fahr = 35
cent = (fahr - 32) / 9 * 5
print(fahr, cent)
fahr = 30
cent = (fahr - 32) / 9 * 5
print(fahr, cent)
fahr = 70
cent = (fahr - 32) / 9 * 5
print(fahr, cent)
fahr = 60
cent = (fahr - 32) / 9 * 5
print(fahr, cent)
print(fahr, cent)
print(fahr, cent)
fahr = 70
cent = (fahr - 32) / 9 * 5
fahr = 70
cent = (fahr - 32) / 9 * 5
print(fahr, cent)
fahr = 70
cent = (fahr - 32) / 9 * 5
print(fahr, cent)
fahr = 70
cent = (fahr - 32) / 9 * 5
fahr = 60
cent = (fahr - 32) / 9 * 5
print(fahr, cent)
fahr = 70
cent = (fahr - 32) / 9 * 5
print(fahr, cent)
30 -1.1111111111111112 40 4.444444444444445 35 1.6666666666666665 30 -1.1111111111111112 70 21.11111111111111 60 15.555555555555555 60 15.555555555555555 70 21.11111111111111
Why would copying code to do the same/similar thing multiple times in a row be a ...
- Good (or useful) thing?
- Bad (or difficulty-inducing) thing?
for fahr in range (30, 71, 10):
cent = (fahr - 32) / 9 * 5
print(fahr, cent)
Copy and Paste Problems¶
- Error prone
- Copy-pasting in the wrong place
- Changing the wrong values
- Re-typing rather than copy/paste, causing typos
- Can take a long time (luckily this list only had 5 values in it!)
- What if …
- Modifications: I decide I want to change the output format?
- Bugs: I made a mistake in the formula?
- Readability: Is it obvious to a human reader that all 5 chunks of code are identical without looking carefully?
For each fahr
, do "this"¶
- Where "this" is:
cent = (fahr - 32) / 9.0 * 5
print(fahr, cent)
- Would be nice if we could write "this" just once
- Easier to modify
- Easier to fix bugs
- Easier for a human to read
A for
loop¶
for fahr in [30, 40, 50, 60, 70]:
cent = (fahr - 32) / 9 * 5
print(fahr, cent)
- for: Starts with the word
for
- fahr: loop/iteration variable
- [30, 40, 50, 60, 70]: A list (but can be any sequence expression).
- We will cover more about lists and other sequences later!
- Colon is required
- Loop body is indented (just like if statements!)
- Indentation is significant!
This code executes the body 5 times:
- once with
fahr = 30
- once with
fahr = 40
- ...
Loop Examples¶
Prints the value of a sequence
for num in [2, 4, 6]:
print(num)
Does not use values of a sequence
for iteration_Variable___ in [1, 2, 3]:
print("Hi there!")
Sequence is a string and prints each value (char)
"happy" + " birthday"
'happy birthday'
x = 42
y = 42
this_is_athing = 42
for char in "happy":
print(char)
h a p p y
for character in ["happy", "birthday", "I", "have", "a", "present"]:
print(character)
happy birthday I have a present
word = "happy"
for char in word:
print(char)
h a p p y
for word in ["happy", "birthday", "I", "have", "a", "present"]:
print(word)
for char in word:
print(char)
happy h a p p y birthday b i r t h d a y I I have h a v e a a present p r e s e n t
How a loop is executed: Transformation vs Direct Approach¶
Idea: convert a for
loop into something we know how to execute
Transformation Approach
- Evaluate the sequence expression
- Write an assignment to the loop variable, for each sequence element
- Write a copy of the loop after each assignment
- Execute the resulting statements
Direct Approach
- Evaluate the sequence expression
- While there are sequence elements left:
- Assign the loop variable to the next remaining sequence element
- Run the loop body
for i in [1, 2, 3]:
print(i)
i = 1
print(i)
i = 2
print(i)
i = 3
print(i)
# Transformation Approach
i = 1
print(i)
i = 4
print(i)
i = 9
print(i)
# Direct Approach
for i in [1, 4, 9]:
print(i)
The body can be multiple statements¶
Execute the whole body, then execute whole body again, etc.
for i in [3, 4, 5]:
print("Start body")
print(i)
print(i * i)
NOT:
Start body
Start body
Start body
3
4
5
9
16
25
Indentation is significant¶
- Every statement in the body must have exactly the same indentation
- That's how Python knows where the body ends
for i in [3, 4, 5]:
print("Start body")
print(i)
print(i * i)
- Compare the results of these loops:
for f in [30, 40, 50, 60, 70]:
print(f, (f - 32) / 9.0 * 5)
print("All done")
30 -1.1111111111111112 40 4.444444444444445 50 10.0 60 15.555555555555555 70 21.11111111111111 All done
for f in [30, 40, 50, 60, 70]:
print(f, (f - 32) / 9.0 * 5)
print("All done")
30 -1.1111111111111112 All done 40 4.444444444444445 All done 50 10.0 All done 60 15.555555555555555 All done 70 21.11111111111111 All done
print("1 / 2")
1 / 2
print(1 / 2)
0.5
The range function¶
A typical for loop does not use an explicit list:
for i in range(5):
... body ...
range(5)
: cycles through [0, 1, 2, 3, 4]
5
is the upper limit (exclusive)
range(1, 5)
: cycles through [1, 2, 3, 4]
1
is the lower limit (inclusive)
range(1, 10, 2)
: cycles through [1, 3, 5, 7, 9]
2
is the step (distance between elements)
Some Loops¶
# Sum of a list of values, what values?
result = 0
for element in range(5):
result = result + element
print(f"The sum is: {result}")
# Sum of a list of values, what values?
result = 0
for element in range(5, 1, -1):
result = result + element
print(f"The sum is: {result}")
# Sum of a list of values, what values?
result = 0
for element in range(0, 8, 2):
result = result + element
print(f"The sum is: {result}")
# Sum of a list of values, what values?
result = 0
size = 5
for element in range(size):
result = result + element
print("When size = " + str(size) + " result is " + str(result))
How to process a list: One element at a time¶
- A common pattern when processing a list:
result = initial_value for element in list: result = updated result use result
# Sum of a list
result = 0
for element in mylist:
result = result + element
print(result)
- initial_value is a correct result for an empty list
- As each element is processed,
result
is a correct result for a prefix of the list - When all elements have been processed,
result
is a correct result for the whole list
Examples of list processing¶
- Product of a list:
mylist = [1, 2, 3, 4, 5]
result = 1
for element in mylist:
result = result * element
print(result)
- Maximum of a list:
mylist = [5, 1, 4, 2, 3]
curr_max = mylist[0]
for element in mylist:
curr_max = max(curr_max, element)
print(curr_max)
Approximate the value 3 by
$1 + 2/3 + 4/9 + 8/27 + 16/81 + … =\\ (2/3)^0 + (2/3)^1 + (2/3)^2 + (2/3)^3 + … + (2/3)^{10}$
result = 0
for element in range(11):
result = result + (2.0 / 3.0) ** element
print(result)