Computer Science 15-112, Spring 2012
Class Notes: Loops
- Required
Reading
-
"for" loop over a range
-
Range from 0 to y: use xrange(y+1)
-
Range from x to y: use
xrange(x, y+1)
-
Range from x to y with step z: use
xrange(x, y+1, z)
-
Range in reverse (use a negative step)
- xrange versus range
- Nested
"for" loops
- The
"while" statement
- Examples of "while" Loops
- Read Until a Sentinel
- Read Until a Condition
- Find the Nth Positive Integer with
Some Property
- Misuse: Iterate Over a Range of
Integers
- break and
continue
-
Infinite "while" loop with break
- Practice Problems
- Tracing
- Mystery
Method(s)
-
Sum the numbers from 1 to N
-
Sum the odd numbers from 1 to N
- Using "if"
-
Using a different increment
-
Sum the first N odd numbers
- isPrime
- fasterIsPrime
- nthPrime
Loops
- Required
Reading
-
Python Language Reference, Ch 7.2 (The while statement)
-
Python Language Reference, Ch 7.3 (The for statement)
Think of the targetList as a single variable. Plus, you may
ignore the note on the subtlety.
-
The Python Tutorial, Ch 4.2-4.5
-
"for" loop over a range
-
Range from 0 to y: use
xrange(y+1)
# print the numbers from 0 to 4 (not 5)
for x in
xrange(5):
print x
-
Range from x to y: use
xrange(x, y+1)
# print the numbers from 10 to 14 (not 15)
for x in
xrange(10, 15):
print x
-
Range from x to y with step z: use
xrange(x, y+1, z)
# print the even numbers from 10 to 14 (not 15)
for x in
xrange(10, 15, 2):
print x
-
Range in reverse (use a negative step):
# print the even numbers from 14 to 10 (not 9)
for x in
xrange(14, 9, -2):
print x
- xrange
versus range:
# xrange is
usually a little more efficient
# xrange may work on larger ranges without running out of memory
# range
creates an actual list (which we will learn about next week)
-
Nested "for" loops
n = int(raw_input("How many rows? "))
for row in
xrange(n):
for col in xrange(row+1):
print "*",
print
- The "while" statement
while
(test):
body
For example:
def
powersOfTwo(upperLimit):
n = 1
while (n < upperLimit):
print n
n *= 2
print "After loop, n = ", n
And a similar example:
def
dividingByTwo(n):
count = 0
while (n > 0):
print n
n /= 2
count += 1
print "After loop, n=", n, " and count=", count
- Examples of "while" Loops
- Read Until a Sentinel
# Keep reading names until the user enters "done"
count = 0
sentinel = "done"
input = None
print "Keep entering names. To quit, enter", sentinel
while (input != sentinel):
input = raw_input("Enter name #" + str(count+1) + ": ")
if (input != sentinel):
count += 1
print "You entered", count, "names!"
- Read Until a Condition
# keep reading numbers until their sum exceeds 10
sum = 0.0
while (sum < 10):
print "Sum = " + str(sum) + ". ",
input = float(raw_input("Next number --> "))
sum += input
print "Final sum = ", sum
- Find the Nth Positive Integer with
Some Property
# find the nth number that is a multiple of either 4 or 7
def isMultipleOf4Or7(x):
return ((x % 4) == 0) or ((x % 7) == 0)
def nthMultipleOf4Or7(n):
found = 0
guess = -1
while (found <= n):
guess += 1
if
(isMultipleOf4Or7(guess)):
found += 1
return guess
input = None
while (input != -1):
input = int(raw_input("Enter a # (or -1 to quit): "))
if (input != -1):
print " nthMultipleOf4Or7(", input, ") =",
nthMultipleOf4Or7(input)
print "Bye!"
- Misuse: Iterate Over a Range of
Integers
# sum numbers from 1 to 10
# note: this works,
but you should not use "while" here.
# instead, do this with "for" (once you know how)
sum = 0
counter = 1
while (counter <= 10):
sum += counter
counter += 1
print "The sum from 1 to 10 is", sum
Once again, but with a bug!:
#
sum numbers from 1 to 10
# warning: buggy
version!
sum = 0
counter = 0
while (counter <= 10):
counter += 1
sum += counter
print "The sum from 1 to 10 is", sum
And once more, using a "for" loop (the right way!):
# sum
numbers from 1 to 10
sum = 0
for counter in xrange(1,11):
sum += counter
print "The sum from 1 to 10 is", sum
- break and
continue
for n in xrange(20):
if (n % 3 == 0):
continue # skips rest of this pass
elif (n == 10):
break # skips rest of entire loop
print n # prints 1, 2, 4, 5, 7, 8 (skips 3, 6, 9, then
breaks)
-
Infinite "while" loop with break
while (True):
response = raw_input("Enter a string (or 'done' to quit): ")
if (response == "done"):
break
print " You entered: ", response
print "Bye!"
- Practice Problems
-
Tracing
# trace
this code by hand, then run it to confirm your prediction
x = 13
y = 1
while (y < x):
print x,y
x -= 2
y += 3
print x,y
- Mystery Method(s)
# State
what this function does, in just a few words of plain English.
# Do not state line-by-line what it does at a low level. Find the
general pattern.
# Also note that there is a clearer, faster, better way to do the same
thing!
def mysteryA(x, y):
# assume x and y are non-negative integers
c = 0
while (x > 0):
c += y
x -= 1
return c
-
Sum the numbers from 1 to N
def sumFrom1ToN(n):
sum = 0
for i in
xrange(n+1):
sum += i
return sum
# let's see it in action...
for n in
xrange(-2,6):
print n, sumFrom1ToN(n)
- Sum the odd numbers from 1 to N
- Using "if"
def sumOddsFrom1ToN(n):
sum = 0
for i in
xrange(n+1):
if (i % 2 == 1):
sum += i
return sum
# let's see it in action...
for n in
xrange(-2,6):
print n, sumOddsFrom1ToN(n)
- Using a different increment
def sumOddsFrom1ToN(n):
sum = 0
for i in
xrange(1, n+1, 2):
sum += i
return sum
# let's see it in action...
for n in
xrange(-2,6):
print n, sumOddsFrom1ToN(n)
- Sum the first N odd numbers
def sumOfFirstNOdds(n):
sum = 0
for i in
xrange(n):
sum += 2*i+1
return sum
# let's see it in action...
for n in
xrange(6):
print n, sumOfFirstNOdds(n)
Or...
def sumOfFirstNOdds(n):
sum = 0
for i in
xrange(1,2*n+1,2):
sum += i
return sum
Or...
def sumOfFirstNOdds(n):
sum = 0
nextOdd = 1
for i in
xrange(n):
sum += nextOdd
nextOdd += 2
return sum
Once more, this time with a bug...
def sumOfFirstNOdds(n): # This version has a bug!
sum = 0
for i in
xrange(n):
sum += 2*n+1
return sum
- isPrime
#Note: there are faster/better ways. We're just going for clarity and simplicity here.
def isPrime(n):
if (n < 2):
return False
for factor in
xrange(2,n):
if (n % factor == 0):
return False
return True
# And take it for a spin
for n in
xrange(500):
if isPrime(n):
print n,
- fasterIsPrime
#Note: this is still not the fastest way, but it's a nice improvement.
def fasterIsPrime(n):
if (n < 2):
return False
if (n == 2):
return True
if (n % 2 == 0):
return False
maxFactor = int(round(n**0.5))
for factor in
xrange(2,maxFactor+1):
if (n % factor == 0):
return False
return True
# Verify these are the same
for n in
xrange(1000):
if (isPrime(n) != fasterIsPrime(n)): print n
assert(isPrime(n) == fasterIsPrime(n))
print "They seem to work the same!"
# Now let's see if we really sped things up
import time
bigPrime = 499 # Try 1010809, or 10101023, or 102030407
print "Timing isPrime(",bigPrime,")",
time0 = time.time()
print ", returns ", isPrime(bigPrime),
time1 = time.time()
print ", time = ",(time1-time0)*1000,"ms"
print "Timing fasterIsPrime(",bigPrime,")",
time0 = time.time()
print ", returns ", fasterIsPrime(bigPrime),
time1 = time.time()
print ", time = ",(time1-time0)*1000,"ms"
- nthPrime
def nthPrime(n):
found = 0
guess = 0
while (found <= n):
guess += 1
if (isPrime(guess)):
found += 1
return guess
# and let's see a list of the primes
for n in
xrange(10):
print n, nthPrime(n)
carpe diem -
carpe diem - carpe diem - carpe diem
- carpe diem - carpe diem -
carpe diem - carpe diem - carpe
diem