@extends('template')
@section('title')
Lab 6: Debugging Loops
@stop
@section('head')
@stop
@section('content')
# 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:
```py
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 `print`s
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:
```py
print('n:', n)
```
The whole function should now look like this:
```py
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:
```txt
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):
```py
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:
```txt
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:
```py
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:
```txt
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:
```py
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.
@include('/labs/lab06/_toc')
@stop