The range Function

Let's say you wanted to count to 100.  It would be a pain to have list each number out.  The range function can make it much easier to create and manage a for loop.

The range function is a built-in function in Python.  We will learn more about functions in the next lesson.  For now, functions are simply reusable bits of code that can be called when needed. 

The range function helps us to create a sequence of integers.  The creation is based on information, called an argument, which you pass into the range function.

Here's an example:

Code Sequence Notes
range(3) 0, 1, 2

Start at zero and go up to, but not including, 3.

range(5) 0, 1, 2, 3, 4

Start at zero and go up to, but not including, 5.

Here we have passed the integer 3 into the range function.    When we call range(3), we get the numbers 0, 1, 2.

Note that the first item in the sequence is a zero.  And notice that the sequence goes up to, but does not include, 3.

We can use range(3) in a for loop like this:

Code Output
for n in range(3):
    print(n)
0
1
2

Launch Exercise

Launch Exercise

Of course, we don't want every sequence to begin with a zero.  The range function has other options as well, and you pass these into the function too.  Adding a second integer will allow you to control where you start and where you stop.

Code Sequence Notes
range(1, 3) 1, 2

Start at 1 and go up to, but not including, 3.

range(2, 5) 2, 3, 4

Start at 2 and go up to, but not including, 5.

When we use range(2, 5) in a for statement, we get:

Code Output
for n in range(2, 5):
    print(n)
2
3
4

Notice that the first integer passed into the range function controls the starting integer in the sequence.  The second integer passed into the range function controls the ending integer - but again, it is up to an not including that integer.

Launch Exercise

Finally, we might want to be able to skip count.  Remember as a kid?  Counting to 100 by 10s?  That was skip counting.  Python calls this the step. The third argument passed into the range function controls the step in which the sequence is incremented or decremented (because you can also go backwards!).  Here are some examples:

Code Sequence Notes
range(1, 10, 2) 1, 3, 5, 7, 9

Start at 1 and go up to, but not including, 10.  Go up in steps of 2.

range(5, 35, 4) 5, 9, 13, 17, 21, 25, 29, 33

Start at 5 and go up to, but not including, 35.  Go up in steps of 4.

When we use range(1, 10, 2) in a for statement, we get:

Code Output
for n in range(1, 10, 2):
    print(n)
1
3
5
7
9

Launch Exercise

Remember how you can go backwards?  Just start at a higher number, stop at a lower number, and use a negative step.

Code Sequence Notes
range(10, 0, -2) 10, 8, 6, 4, 2

Start at 10 and go down to, but not including, 0.  Go down in steps of 2.

Example: Countdown, Part 3

Here is how we can re-write the countdown program using the range function:

for n in range(5, 0, -1):
    print(n)

print('Blastoff!')

Output

5
4
3
2
1
Blastoff!

How it Works

Code Output Explanation
for n in range(5, 0, -1):
    print(n)
5
4
3
2
1

Range creates a sequence.  It starts at 5.  The step argument (the last one) tells us to down by 1 until, but not including, the stop argument of 0.  In other words:

[5, 4, 3, 2, 1]

The for statement then iterated through the generated sequence like normal.

print('Blastoff!') Blastoff!

We display the word Blastoff! The program is finished.

Launch Exercise

The arguments which are passed into the range function can be variables as well - just so long as they are integers.  This allows more control over your program.

Code Sequence Notes
start = 5
stop = 10
step = 2
range(start, stop, step)
5, 7, 9

Start at 5 and go up to, but not including, 10.  Go up in steps of 2.

x = 5
y = 35
z = 4
range(x, y, z)
5, 9, 13, 17, 21, 25, 29, 33

Start at 5 and go up to, but not including, 35.  Go up in steps of 4.

This means that you have your user control the countdown program as well.

The break Statement

The break statement is used to break out of a loop statement i.e. stop the execution of a looping statement, even if the loop condition has not become False or the sequence of items has not been completely iterated over.

For example, suppose you want to take input from the user until they type done. You could write:

while True:
    line = input('Are you done? ')
    if line == 'done':
        break
    print(line)

print('Done!')

The loop condition is True, which is always true, so the loop runs until it hits the break statement.

Each time through, it prompts the user with the question Are you done?  If the user types done, the break statement exits the loop. Otherwise the program echoes whatever the user types and goes back to the top of the loop. Here’s a sample run:

Are you done? not done
Are you done? done
Done!

This way of writing while loops is common because you can check the condition anywhere in the loop (not just at the top) and you can express the stop condition affirmatively ("stop when this happens") rather than negatively ("keep going until that happens").

An important note is that if you break out of a for or while loop, any corresponding loop else block is not executed.

Note that you can use break with the for statement as well.

Launch Exercise

The continue Statement

The continue statement is used to tell Python to skip the rest of the statements in the current loop block and to continue to the next iteration of the loop.

For example:

for n in [1, 2, 3]:
    if n==2:
        continue
    print(n)

When we execute this code, we get:

1
3

So even though there is clearly a 2 in our list of 1, 2, 3, the 2 is skipped.  Why?  In the body block of the for statement, there is a conditional statement.  The conditional is looking at whether n = 2.  When n = 2, the conditional uses the continue statement to skip the rest of the body block of the for statement and go straight to the next iteration.  So, the 2 is never printed.  It is skipped.

The better practice might be to leave the 2 out of your list, but it is nice to know that you can use continue if you need it.

Note that you can use continue with the while statement as well.

Launch Exercise

Nested Loops

Just as with conditional statements, you can also nest loops.  You can nest for loops in while loops and while loops in for loops.  You can nest for loops in other for loops and while loops in other while loops.  What follows are some examples and ideas for creating programs.

Example: Triangles

This code produces some pretty triangles:

for x in range(3):
    for y in range(3, 0, -1):
        print("|", " "*x, "*"*y)

Output

|  ***
|  **
|  *
|   ***
|   **
|   *
|    ***
|    **
|    *
|     ***
|     **
|     *

How It Works

Code Output Explanation
for x in range(4): None

This is the outer for loop.  It will be iterated 3 times.  The variable x will take on the values of 0, 1, 2, and 3.

    for y in range(3, 0, -1):

None

This is the inner for loop.  It will also be iterated 3 times.  The variable y will take on the values of 3, 2, and 1. 

Because the inner for loop is inside of the outer for loop, the inner for loop will completely execute a total of 3 times each time the outer for loop runs.

        print("|", " "*x, "*"*y)

This is the statement which changes during each iteration. Let's do these one at a time.

When the outer for loop runs, x = 0.  Immediately, the inner for loop runs where y = 4. Let's look at the below table to see each individual iteration.

Here are our iterations.  Since the outer loop will run 4 times and the inner loop will run 3 times, there will be 12 total iterations:

Iteration x value y value print statement Output
1 0 3 print("|", " "*0, "*"*3) |  ***
2 0 2 print("|", " "*0, "*"*2) |  **
3 0 1 print("|", " "*0, "*"*1) |  *
4 1 3 print("|", " "*1, "*"*3) |   ***
5 1 2 print("|", " "*1, "*"*2) |   **
6 1 1 print("|", " "*1, "*"*1) |   *
7 2 3 print("|", " "*2, "*"*3) |    ***
8 2 2 print("|", " "*2, "*"*2) |    **
9 2 1 print("|", " "*2, "*"*1) |    *
10 3 3 print("|", " "*3, "*"*3) |     ***
11 3 2 print("|", " "*3, "*"*2) |     **
12 3 1 print("|", " "*3, "*"*1) |     *

Launch Exercise

Debugging

As you start writing bigger programs, you might find yourself spending more time debugging. More code means more chances to make an error and more places for bugs to hide.

One way to cut your debugging time is "debugging by bisection". For example, if there are 100 lines in your program and you check them one at a time, it would take 100 steps.

Instead, try to break the problem in half. Look at the middle of the program, or near it, for an intermediate value you can check. Add a print statement (or something else that has a verifiable effect) and run the program.

If the mid-point check is incorrect, there must be a problem in the first half of the program. If it is correct, the problem is in the second half.

Every time you perform a check like this, you halve the number of lines you have to search. After six steps (which is fewer than 100), you would be down to one or two lines of code, at least in theory.

In practice it is not always clear what the "middle of the program" is and not always possible to check it. It doesn’t make sense to count lines and find the exact midpoint. Instead, think about places in the program where there might be errors and places where it is easy to put a check. Then choose a spot where you think the chances are about the same that the bug is before or after the check.