Reading: Practical Programming, rest of Chapter 7.
We already started using ranges in last lecture, but we will go over them in detail here.
A range is a function to generate a list of integers. For example,
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Notice this is up through and not including the last value specified!
If we want to start with something other than 0, we provide the starting values
>>> range(3,8)
[3, 4, 5, 6, 7]
We can create increments. For example,
>>> range(4,20,3)
[4, 7, 10, 13, 16, 19]
starts at 4, increments by 3, stops when 20 is reached or surpassed.
We can create backwards increments
>>> range(-1, -10, -1)
[-1, -2, -3, -4, -5, -6, -7, -8, -9]
We can use the range to generate the list of values in a for loop. Our first example is printing the contents of the planets list
planets = [ 'Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter',
'Saturn', 'Uranus', 'Neptune', 'Pluto' ]
for i in range(len(planets)):
print planets[i]
The variable i is variously known as the “index” or the “loop index variable” or the “subscript”.
We will modify the loop in class to do the following:
Sometimes the loop index should not go over the entire range of indices, and we need to think about where to stop it “early”, as the next two examples show.
Example: Returning to our example from Lecture 1, we will briefly re-examine our solution to the following problem: Given a string, how can we write a function that decides if it has three consecutive double letters?
def has_three_doubles(s):
for i in range(0, len(s)-5):
if s[i] == s[i+1] and s[i+2] == s[i+3] and s[i+4] == s[i+5]:
return True
return False
We have to think carefully about where to start our looping and where to stop!
Generate a range for the positive integers less than 100. Use this to calculate the sum of these values, with and without a for loop.
Use a range and a for loop to print the even numbers less than a given integer n.
Suppose we want a list of the squares of the digits 0..9. The following does NOT work
squares = range(10)
for s in squares:
s = s*s
Why not? Write a different for loop that uses indexing into the squares list to accomplish our goal.
The following code for finding out if a word has two consecutive double letters is wrong. Why? When, specifically, does it fail?
def has_two_doubles(s):
for i in range(0, len(s)-5):
if s[i] == s[i+1] and s[i+2] == s[i+3]:
return True
return False
A local maximum, or peak, in a list is a value that is larger than the values next to it. For example,
L = [ 10, 3, 4, 9, 19, 12, 15, 18, 15, 11, 14 ]
has local maxima at indices 4 and 7. (Note that the beginning and end values are not considered local maxima.) Write code to print the index and the value of each local maximum.
Some problems require “iterating” over either
As an example, here is code to print all of the products of digits:
digits = range(10)
for i in digits:
for j in digits:
print "%d x %d = %d" %(i,j,i*j)
How does this work?
We will look at finding the two closest points in a list.
Suppose we are given a list of point locations in two dimensions, where each point is a tuple. For example,
points = [ (1,5), (13.5, 9), (10, 5), (8, 2), (16,3) ]
Our problem is to find the two points that are closest to each other.
The natural idea is to compute the distance between any two points and find the minimum.
We will work through the approach to this and post the result on the Piazza site.
The following simple exercise will help you understand loops better. Show the output of each of the following pairs of for loops. The first two pairs are nested loops, and the third pair is formed by consecutive, or “sequential”, loops.
# Version 1
sum = 0
for i in range(10):
for j in range(10):
sum += 1
print sum
# Version 2
sum = 0
for i in range(10):
for j in range(i+1,10):
sum += 1
print sum
# Version 3
sum = 0
for i in range(10):
sum += 1
for j in range(10):
sum += 1
print sum
dimensional array. This is similar to a list of lists, but is written slightly differently: we use pix[i,j] instead of pix[i][j] to access a point at location (i,j) of the image.
Here is a code that copies one image to another, pixel by pixel.
im = Image.open("bolt.jpg")
w,h = im.size
newim = Image.new("RGB", (w,h), "white")
pix = im.load() ## creates an array of pixels that can be modified
newpix = newim.load() ## creates an array of pixels that can be modified
for i in range(0,w):
for j in range(0,h):
newpix[i,j] = pix[i,j]
newim.show()
Modify the above code so that:
If you want some additional challenge, try these:
We can terminate a loop immediately upon seeing the 0 using Python’s break:
sum = 0
while True:
x = int( raw_input("Enter an integer to add (0 to end) ==> "))
if x == 0:
break
sum += x
print sum
outside the current loop, and
The while condition of True essentially means that the only way to stop the loop is when the condition that triggers the break is met.
Suppose we want to skip over negative entries in a list. We can do this by telling Python to continue when it sees a blank line:
for item in mylist:
if item < 0:
continue
print item
When it sees continue, Python immediate goes back to the while condition and re-evaluates it, skipping the rest of the loop.
Any while loop that uses break or continue can be rewritten without either of these.
This particular example is probably better without the continue.
One important danger with while loops is that they may not stop!
For example, it is possible that the following code runs “forever”. How?
n = int(raw_input("Enter a positive integer ==> "))
sum = 0
i = 0
while i != n:
sum += i
i += 1
print 'Sum is', sum
How might we find such an error?
We will practice with the Wing IDE debugger in class, using it to understand the behavior of the program. We will explain the following picture
and note the use of
Given two lists L1 and L2 measuring the daily weights (floats) of two rats write a while loop to find the first day that the weight of rat 1 is greater than that of rat 2.
Do either of the following examples cause an infinite loop?
import math
x = float(raw_input("Enter a positive number -> "))
while x > 1:
x = math.sqrt(x)
print x
import math
x = float(raw_input("Enter a positive number -> "))
while x >= 1:
x = math.sqrt(x)
print x
Many numerical simulations, including many video games involve random events.
Python includes a module to generate numbers at random. In particular,
import random
# Print three numbers randomly generated between 0 and 1.
print random.random()
print random.random()
print random.random()
# Print a random integer in the range 0..5
print random.randint(0,5)
print random.randint(0,5)
print random.randint(0,5)
We’d like to use this to simulate a “random walk”:
Many variations on this problem appear in physical simulations.
We can simulate a steps in two ways:
We’ll write the code in class, starting from the following:
import random
# Print the output
def print_platform( iteration, location, width ):
before = location-1
after = width-location
platform = '_'*before + 'X' + '_'*after
print "%4d: %s" %(iteration,platform),
raw_input( ' <enter>') # wait for an <enter> before the next step
#######################################################################
if __name__ == "__main__"
# Get the width of the platform
n = int( raw_input("Input width of the platform ==> ") )