@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