# Getting Loopy¶

See also

Text, Chapter 5

Loops are a general tool used any time there is some task to do over and over. Your job as a programmer is to find those places in your problem where a loop is needed, then figure out how to set up the loop to do the job.

## Kinds of Loops¶

Python, and most modern programming languages, has several different kinds of loops you can use. Why more than one is just a matter of convenience. You can get away with fewer, in fact only one, but life is easier when we have options.

The basic kinds of loops we will study are these:

### While loop¶

While some condition is true, do something. In Python, this looks like this:

```
while x > 0:
# do something here
```

The something we want to do is any sequence of Python statements indented as shown in the comment above. That sequence is called the loop body. The flow chart diagram for this looks like this:

Of all the loops we will study, this is the one I would keep if I had to choose.
Another name for this kind of loop is the `pre-test loop`

because we test the
condition before we process the loop body. It may be that we never process the
loop body, if the condition comes up `False`

the first time we test:

```
num = 5
while num > 5:
print(num)
```

We will not see any output from this sequence since the condition is initially
`False`

.

### Do Until loop¶

The next loop is similar, but waits to ask the question until after you do the task. This one is not used as much, and Python does not provide a loop of this kind.

This kind of loop is also called the `post-test loop`

because the condition
is evaluated after the loop body is processed. The minimum number of times we
will process the loop body is once, since we do that before ever checking the
condition.

### Counted loop¶

Both of the above loops run until something happens to stop them. If you think about it, that something must happen inside the loop so the condition we are checking causes the loop to stop.

The counted loop, does something exactly the right number of times. The basic Python counted loop looks like this:

```
for count in range(1,10):
print(count)
```

The only annoying thing about this loop is how that `range`

function works.
Formally, it produces a list of numbers starting with the first number and
going up to `but not including`

the last number. So we see this:

```
>>> for count in range(1,10):
... print(count)
...
1
2
3
4
5
6
7
8
9
>>>
```

Note

We have not studied the `list`

in Python yet, so for now, just think of it
this way. `count`

is a `loop variable`

that is automatically set to a
value from the sequence of values produced by `range`

each time the loop
is processed. On the first time through the loop, the value is 1, on the
second pass, the value is 2 and so on.

Counted loops are used most often when you know exactly how many times you want
the loop body to be processed. If that number of times is not known, we
probably need to use the `while`

loop above.

## Learning when to use loops¶

The big challenge new programmers face is seeing a loop as part of the solution. Each problem has its own issues, bu the key thing you need to see is that you are doing some set of things over and over. Let’s look at a simple example.

I need to add up a bunch of numbers the user will type in from the console. Is that a place for a loop.

Absolutely! As stated, I do not even know how many numbers I might need to add up, and even if I did know the number, it is still a looping opportunity. To see this more clearly, we need to think about how we would add up the numbers manually.

### Summing by hand¶

If you were given this problem to do by hand, you would probably write down the
entire list of numbers on a piece of paper and start adding all of the digits
in the `ones`

column, writing down the result and copying the `carry`

into
the next column. You know the drill. This does not seem like a loop at all, but
it can be recast as one if we think about how we would do it with a calculator!

What you do now is first, clear the `accumulator`

(the number on the
display). You enter the first number, then hit the plus key. You see the first
number on the display. That number is actually the starting value (0) plus the
number you just entered. Hitting the `plus`

key tells the calculator to add
in whatever number you type in next. Keep doing the sequence (enter number,
then hit the plus key) until all numbers have been entered, then hit the
`equals`

key to see the final result.

All those steps were pretty much identical, with a few exceptions, so we are actually doing the same thing multiple times.

We can translate this process into Python code as follows.

First we need to create a variable that will hold the sum. Let’s call it
`sum`

for convenience. The initial value for this variable should be zero,
since we have not added in anything yet. (This is the same step as clearing the
calculator display!).

Now, our loop involves getting a new number and adding it in. Let’s try this:

```
sum = 0
new_number = int(input("Enter the next number"))
```

Well, durn. I wanted to use a loop, but I am stuck. How am I going to control the loop? I need to be able to say NO!, I do not want to enter another number.

The solution to this dilemma is to figure out a possible number that you never expect to enter, and ask the user to enter than number to stop the process of adding in new numbers. (If you know how many numbers to add, this will not be necessary, as we shall see in a bit.

Let’s assume that we only want to add up positive numbers (perhaps including zero). We could ask the user to enter a negative number to stop the loop:

```
sum = 0
new_number = int(input("enter a number (negative to quit)"))
while new_number >= 0:
sum = sum + new_number
```

So far we have our first number added in, but running this loop will not be a
good idea. We never get another number since the input function was called
outside of the loop. We need to get another number. The solution is to get that
next number by repeating the input line, but this time `inside`

the loop
body. Like this:

```
sum = 0
new_number = int(input("enter a number (negative to quit)"))
while new_number >= 0:
sum = sum + new_number
new_number = int(input("enter a number (negative to quit)"))
```

We need to see the final sum, so we need one more statement, this one to print
out the final value for `sum`

. That one is not in the loop, so we do not
indent it. Here is the final code:

```
sum = 0
new_number = int(input("enter a number (negative to quit)"))
while new_number >= 0:
sum = sum + new_number
new_number = int(input("enter a number (negative to quit)"))
print("The sum of the input numbers is", sum)
```

Here is a sample run:

```
Enter a number (negative to quit)10
Enter a number (negative to quit)20
Enter a number (negative to quit)30
Enter a number (negative to quit)40
Enter a number (negative to quit)-10
The sum of the input numbers is 100
```

Looks like it works.

### Summing a known number of numbers¶

If we know how many numbers we want to add up, the code is easier. We will use
a `for loop`

to do this one:

```
for count in range(1,6):
new_number = int(input("Enter value",count)
```

This loop just asks for exactly five numbers (why?). It does no work. Let’s add those numbers up by using some of the logic we used before:

```
sum = 0
for count in range(1,6):
new_number = int(input("Enter value",count)
sum = sum + new_number
print("The total of the numbers input is",sum)
```

See how this one works. We did not need to start off by reading a number, then checking it since we knew exactly how many numbers we would input.

### Replacing the for loop with a while loop¶

We have seen this problem before, time to look at how you should have done it.

The `for loop`

sets up a counter and gives it an initial value. That value is
the lower number we set up in the range. The `range`

generates a sequence of
numbers as we saw earlier. We want our `while loop`

to process code exactly
the same number of times, with a new value in loop each pass. Here is how that
might be done:

```
count = 1
while count < 6:
print(count)
count = count + 1
```

What do you expect to see? The answer should be the same set of numbers we saw earlier.

In this code, we needed to generate the right sequence of values for `count`

ourselves, and we did this by adding one each pass. Make sure you see that this
does the job!

Note

I will leave it as an exercise to add in the rest of the summing logic to add up the same set of numbers.

## Infinite loops¶

There is an interesting kind of loop that never stops! Sounds kind of useless, but it turns out to be handy in some cases. Here is what it looks like:

```
count = 1
while True:
print(count)
count += 1
```

Note

Whoa! What was that last line?

Python lets you be lazy (remember, good programmers are lazy) any time you
want to add something to a variable and put it back in the same variable.
The `+=`

notation is just a short form for `count = count + 1`

. We can
also do these:

- count += 2 # add two each pass
- count /= 2 # divide the value in half each time

Neat! (I bet you can think up a few more variations)

Back to our infinite loop, running this example will never end. Try it and see what happens.

Eventually, the number might get so bit that Python will pitch a fit, but that
will take a while. You can press `Ctrl-C`

on the PC to stop the program. If
all else fails, close the console window!

### Escaping from this prison¶

What do you do when you wanr to escape from prison? Break out, of course (NO!, I do not condone such behavior!)

Python has a nice escape statement that will get you out of any loop you are in at the moment. Here is what it looks like:

```
count = 1
while True:
print(count)
if count > 10:
break
print("I am free!!")
```

The `break`

statement will only be executed when the value in the `count`

variable gets to a value of 11. The `break`

will exit the infinite loop and
we will continue processing on the statement after the loop.

## Combining loops¶

We cah have loops inside other loops with no problems, just indent properly and you are good!

Suppose you want to print out that old multiplication table from elementary school. Here is some code that might do the job:

```
# generate the multiplication table
for row in range(1,11):
for col in range(1,11):
value = row * col
print(value, end=' ')
print()
```

The new stuff at the end of the print function forces Python to add a space after each thing it prints, but not to add a newline. The result is that the numbers have spaces between them, and we do not generate a newline until we want one. I want one after each row is complete, so I add a print statement after displaying a complete row,

Running this code give this:

```
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
```

Well, that is close to what I want to see, but it is ugly. Can’t we do something about the way things do not line up? The answer is yes, but we need a trick we have not studied yet:

```
# generate the multiplication table
for row in range(1,11):
for col in range(1,11):
value = row * col
print("%3d" % value, end=' ')
print()
```

See that funny stuff in the print statement. The `"%3d"`

says print something
here that will be a decimal number three characters wide. The `% val`

right
after that says to use the current value stored in the `val`

variable as the
thing to display. Before we added this code, Python printed things any way it
chose to, and we got ugly, but readable output.

Here is what we get now:

```
.
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
```

Note

ignore that funny dot at the beginning, I had to put that in to force my note system to display the output correctly.

We will learn more about all this later in the course.

One last try:

```
# generate the multiplication table
# display a header row at the top
for row in range(11):
if row == 0:
print(" ",end='')
else:
print("%3d" % row, end=' ')
print()
print(" ","____"*10)
for row in range(1,11):
for col in range(1,11):
if col == 1:
print("%3d" % row," |", end='')
value = row * col
print("%3d" % value, end=' ')
print()
```

This has logic in it that is trying to display the header row and column to complete the table.

```
;
1 2 3 4 5 6 7 8 9 10
________________________________________
1 | 1 2 3 4 5 6 7 8 9 10
2 | 2 4 6 8 10 12 14 16 18 20
3 | 3 6 9 12 15 18 21 24 27 30
4 | 4 8 12 16 20 24 28 32 36 40
5 | 5 10 15 20 25 30 35 40 45 50
6 | 6 12 18 24 30 36 42 48 54 60
7 | 7 14 21 28 35 42 49 56 63 70
8 | 8 16 24 32 40 48 56 64 72 80
9 | 9 18 27 36 45 54 63 72 81 90
10 | 10 20 30 40 50 60 70 80 90 100
```

Looks more like what we expect, right?