Ref Part 2
Ref Part 2
2.4 Iteration
We closed Section 2.2 with the observation that most computational tasks cannot
be accomplished using branching programs. Consider, for example, writing a
program that asks the user how many time he wants to print the letter X, and
then prints a string with that number of X’s. We might think about writing
something like
numXs = int(input('How many times should I print the letter X? '))
toPrint = ''
if numXs == 1:
toPrint = 'X'
elif numXs == 2:
toPrint = 'XX'
elif numXs == 3:
toPrint = 'XXX'
#...
print(toPrint)
But it would quickly become apparent that we would need as many conditionals
as there are positive integers—and there are an infinite number of those. What
we need is a program that looks like
numXs = int(input('How many times should I print the letter X? '))
toPrint = ''
concatenate X to toPrint numXs times
print(toPrint)
When we want a program to do the same thing many times, we can use itera-
tion. A generic iteration (also called looping) mechanism is shown in the boxed-
in part of Figure 2.4. Like a conditional statement, it begins with a test. If the test
evaluates to True, the program executes the loop body once, and then goes back
to reevaluate the test. This process is repeated until the test evaluates to False, af-
ter which control passes to the code following the iteration statement.
We can write the kind of loop depicted in Figure 2.4 using a while statement.
Consider the following example:
# Square an integer, the hard way
x = 3
ans = 0
itersLeft = x
while (itersLeft != 0):
ans = ans + x
itersLeft = itersLeft - 1
print(str(x) + '*' + str(x) + ' = ' + str(ans))
CHAPTER 2. INTRODUCTION TO PYTHON 23
The code starts by binding the variable x to the integer 3. It then proceeds to
square x by using repetitive addition. The table in Figure 2.5 shows the value as-
sociated with each variable each time the test at the start of the loop is reached.
We constructed it by hand-simulating the code, i.e., we pretended to be a Python
interpreter and executed the program using pencil and paper. Using pencil and
paper might seem kind of quaint, but it is an excellent way to understand how a
program behaves.16
Test # x ans itersLeft
1 3 0 3
2 3 3 2
3 3 6 1
4 3 9 0
The fourth time the test is reached, it evaluates to False and flow of control
proceeds to the print statement following the loop. For what values of x will this
program terminate? There are three cases to consider: x == 0, x > 0, and x < 0.
Suppose x == 0. The initial value of itersLeft will also be 0, and the loop
body will never be executed.
Suppose x > 0. The initial value of itersLeft will be greater than 0, and the
loop body will be executed at least once. Each time the loop body is executed, the
value of itersLeft is decreased by exactly 1. This means that if itersLeft started
out greater than 0, after some finite number of iterations of the loop, itersLeft
16 It is also possible to hand-simulate a program using pen and paper, or even a text editor.
24 INTRODUCTION TO COMPUTATION AND PROGRAMMING USING PYTHON
will equal 0. At this point the loop test evaluates to False, and control proceeds to
the code following the while statement.
Suppose x < 0. Something very bad happens. Control will enter the loop, and
each iteration will move itersLeft farther from 0 rather than closer to it. The
program will therefore continue executing the loop forever (or until something
else bad, e.g., an overflow error, occurs). How might we remove this flaw in the
program? Initializing itersLeft to the absolute value of x almost works. The loop
terminates, but it prints a negative value. If the assignment statement inside the
loop is also changed, to ans = ans + abs(x), the code works properly.
Finger exercise: Replace the comment in the following code with a while loop.
numXs = int(input('How many times should I print the letter X? '))
toPrint = ''
#concatenate X to toPrint numXs times
print(toPrint)
prints
132 is divisible by 11 and 12
Finger exercise: Write a program that asks the user to input 10 integers, and then
prints the largest odd number that was entered. If no odd number was entered, it
should print a message to that effect.
3 SOME SIMPLE NUMERICAL PROGRAMS
Now that we have covered some basic Python constructs, it is time to start think-
ing about how we can combine those constructs to write some simple programs.
Along the way, we’ll sneak in a few more language constructs and some algo-
rithmic techniques.
For what values of x will this program terminate? The answer is, “all inte-
gers.” This can be argued quite simply.
• The value of the expression ans**3 starts at 0, and gets larger each time
through the loop.
• When it reaches or exceeds abs(x), the loop terminates.
• Since abs(x) is always positive there are only a finite number of iterations be-
fore the loop must terminate.
Whenever you write a loop, you should think about an appropriate decre-
menting function. This is a function that has the following properties:
26 INTRODUCTION TO COMPUTATION AND PROGRAMMING USING PYTHON
Now, let’s insert some errors and see what happens. First, try commenting
out the statement ans = 0. The Python interpreter prints the error message
NameError: name 'ans' is not defined
because the interpreter attempts to find the value to which ans is bound before it
has been bound to anything. Now, restore the initialization of ans, replace the
statement ans = ans + 1 by ans = ans, and try finding the cube root of 8. After
you get tired of waiting, enter “control c” (hold down the control key and the c
key simultaneously). This will return you to the user prompt in the shell.
Now, add the statement
print('Value of the decrementing function abs(x) - ans**3 is',
abs(x) - ans**3)
at the start of the loop, and try running it again. This time it will print
Value of the decrementing function abs(x) - ans**3 is 8
As you can see, even if millions of guesses are required, it’s not usually a
problem. Modern computers are amazingly fast. It takes on the order of one na-
nosecond—one billionth of a second—to execute an instruction. It’s a bit hard to
appreciate how fast that is. For perspective, it takes slightly more than a nanosec-
ond for light to travel a single foot (0.3 meters). Another way to think about this
is that in the time it takes for the sound of your voice to travel a hundred feet, a
modern computer can execute millions of instructions.
Just for fun, try executing the code
maxVal = int(input('Enter a postive integer: '))
i = 0
while i < maxVal:
i = i + 1
print(i)
See how large an integer you need to enter before there is a perceptible pause be-
fore the result is printed.
Finger exercise: Write a program that asks the user to enter an integer and prints
two integers, root and pwr, such that 0 < pwr < 6 and root**pwr is equal to the in-
teger entered by the user. If no such pair of integers exists, it should print a mes-
sage to that effect.
largest integer start + i*step less than stop. If step is negative, the last element is
the smallest integer start + i*step greater than stop. For example, the expression
range(5, 40, 10) yields the sequence 5, 15, 25, 35, and range(40, 5, -10) yields
the sequence 40, 30, 20, 10. If the first argument is omitted it defaults to 0, and
if the last argument (the step size) is omitted it defaults to 1. For example,
range(0, 3) and range(3) both produce the sequence 0, 1, 2. The numbers in the
progression are generated on an “as needed” basis, so even expressions such as
range(1000000) consume little memory.17 We will discuss range in more depth in
Section 5.2.
Less commonly, we specify the sequence to be iterated over in a for loop by
using a literal, e.g., [0, 3, 2].
Consider the code
x = 4
for i in range(0, x):
print(i)
It prints
0
1
2
3
It raises the question of whether changing the value of x inside the loop affects
the number of iterations. It does not. The arguments to the range function in the
line with for are evaluated just before the first iteration of the loop, and not
reevaluated for subsequent iterations.
To see how this works, consider
x = 4
for j in range(x):
for i in range(x):
print(i)
x = 2
17In Python 2, range generates the entire sequence when invoked. Therefore, expressions such as
range(1000000) use quite a lot of memory. In Python 2, xrange behaves the way range behaves in
Python 3.
CHAPTER 3. SOME SIMPLE NUMERICAL PROGRAMS 29
which prints
0
1
2
3
0
1
0
1
0
1
because the range function in the outer loop is evaluated only once, but the range
function in the inner loop is evaluated each time the inner for statement is
reached.
The code in Figure 3.2 reimplements the exhaustive enumeration algorithm
for finding cube roots. The break statement in the for loop causes the loop to
terminate before it has been run on each element in the sequence over which it is
iterating.
The for statement can be used in conjunction with the in operator to conven-
iently iterate over characters of a string. For example,
total = 0
for c in '12345678':
total = total + int(c)
print(total)
sums the digits in the string denoted by the literal '12345678' and prints the total.