Lab 6: Debugging Loops

For this part of the lab, create a new file called loops.py.

Start by copying and pasting this code into your file:

def sumUpTo(top):
    """
    Returns the sum of all numbers from 1 up to and including top.
    """
    result = 0
    for n in range(top):
        result += n
        return result

This function has two bugs in it: it does NOT do what the docstring says it should. If you can spot them already, that's great, but we're going to practice a general technique that can help you spot bugs in any kind of loop. This technique is called tracing, and it involves placing extra print statements into your code so that you can see what the code is doing.

While the debugger is a great tool for running code step-by-step, it can be a lot of work to use it, and it's more complicated to use in Jupyter notebooks. Adding print statements can be used in Thonny or in Jupyter notebooks, and is a simple thing to try when something goes wrong. We call this tracing and it's a 4-step process:

  1. Add a strategic print or two to give you more info on what the code is doing.
  2. Develop a hypothesis about what your print statements should print, if the code were working correctly.
  3. Run the code, and observe what they do print. Use the difference between what was expected and what happened to deduce more about the problem.
  4. If the problem is still unclear (e.g., if nothing was printed, or there's another variable you didn't print that you now suspect), repeat steps 1-3 using additional prints to show you more information.

Step 1: Adding prints

To start with, discuss with your partner: where might it be useful to add a print statement in the sumUpTo function to figure out more about what's wrong with it?

Once you have an idea, click here to see our suggestion.

Since the function contains a loop, the most likely issue involves the loop's behavior, so adding a print statement inside the loop will probably be most informative. You'd get to see the output for each iteration of the loop, which would let you check how many iterations there are, and depending on what you print, it would let you see important values used in the loop. So to start with, add this print statement to the first line of the loop:

        print('n:', n)

The whole function should now look like this:

def sumUpTo(top):
    """
    Returns the sum of all numbers from 1 up to and including top.
    """
    result = 0
    for n in range(top):
        print('n:', n)
        result += n
        return result

Step 2: Forming a Hypothesis

Now, discuss with your partner to predict what should be printed if the function worked correctly for a call to sumUpTo(3).

Click here to show our answer.

For sumUpTo(3), the result should be 1 + 2 + 3 = 6. The loop should iterate 3 times, and the values of n should be 1, then 2, then 3. So what should be printed is:

n: 1
n: 2
n: 3

However, due to the bugs in the function, that's not what gets printed.

Step 3: Test It

Now go ahead and run the code by pasting this line into the shell (after running the code in the file):

sumUpTo(3)

Observe what was printed. Discuss with your partner: What does it tell you about how the function actually works? How might you fix the issue that is highlighted by the output you got?

Click here to show our answers.

The only thing printed will be:

n: 0

This implies two things: that n doesn't start out at 1, and that the loop only runs once instead of 3 times.

As you already know: a loop running once can be caused by an early return. Another possibility might be an incorrect loop sequence. But in this case, the return in the loop is clearly suspect! Since return stops the function, the loop will be interrupted. To fix this, change the code by removing one layer of indentation from the return line, so that it looks like this:

def sumUpTo(top):
    """
    Returns the sum of all numbers from 1 up to and including top.
    """
    result = 0
    for n in range(top):
        print('n:', n)
        result += n
    return result

After modifying your code as directed, run it again, with the print still in, once more discuss with your partner: what does the output imply about how the loop works? How can you fix the second bug?

Click here to show our answers.

The output you get now should be:

n: 0
n: 1
n: 2

After that printed output, if you're running it in the shell, it will show the result 3, even though the correct result here would be 6.

The issue is that the loop runs through 0, 1, and 2, but doesn't include 3. There are several ways to fix this. You could simply add one to the number in each iteration. You could also change the range call to produce a more correct range. That second option might look like this:

def sumUpTo(top):
    """
    Returns the sum of all numbers from 1 up to and including top.
    """
    result = 0
    for n in range(1, top + 1):
        print('n:', n)
        result += n
    return result

Once you've fixed the function so that you get 6 as the result, you can remove the print that you used for debugging, and you're ready to move on to the next part of the lab.

Note that going forward, we expect you to make an effort to debug your code using this technique before asking for help.

Table of Contents