@extends('template') @section('title') Lab 8: Part 1. Tracing & Debugging Loops @stop @section('content') # Lab 8: Part 1. Tracing & Debugging Loops **Tracing** refers to keeping track of the values used by a program as it runs. This can be achieved through printing, by using the debugger, or even using a pencil and paper or just your imagination. Writing an iteration table is a kind of tracing. **Debugging** refers to finding and fixing errors to make something work correctly. **Testing** (which we'll delve into in the following section) refers to setting up examples and establishing expectations so that we can see if something really works or not. Again it can be done by hand, or by using a program or library. ## Tracing with `print` The most straightforward way to trace code is to add `print` function calls to the code itself, so that as it runs, it prints out the information you need to know. This takes a bit of work, but it always saves time compared to simply guessing what the problem might be and trying different things.
Partner A
In **the provided starter file `tracing.py`**, there is a copy of the `hasCGBlock` function from the genetics problem set task (there are also several broken copies numbered `hasCGBlock1` through `hasCGBlock3`). Your job is to add `print` calls so that it prints out the trace information shown in these examples (note that the provided version works correctly): ```txt >>> hasCGBlock('CGAU') base C True run 1 base G True run 2 base A False run 0 base U False run 0 no blocks False ``` ```txt >>> hasCGBlock('CGCAGGGCCUAGC') base C True run 1 base G True run 2 base C True run 3 base A False run 0 base G True run 1 base G True run 2 base G True run 3 base C True run 4 base C True found it True ``` ## Debugger limitations Next, we'll use Thonny's built-in debugger to trace our code, which requires less setup than using `print`s, and can tell us more information at once. Recall that [we introduced the debugger back in lab 2](/labs/lab02/debugger). If you don't remember how it works, briefly review the "Using the debugger" section of that lab which explains how the different buttons work. The main ones we will use are the "start debugging" button, the "step into" button, and the "resume" button. Before we get started, we also need to be aware of two important limitations: 1. The debugger will only run code in your file, not code that you put into the shell. So your file itself must call the function that you want to debug. 2. The debugger slows things down, even when a breakpoint is set up, because it has to record every step of your program. Sometimes, when we provide very large data files, trying to import these will take forever in the debugger. In cases like this, it's best to temporarily comment out any imports for very large Python files while using the debugger, if you can. If that's not possible, you may have to rely on simpler methods like `print`s to trace your code. ## Tracing with the debugger The debugger can be set up to pause at certain points in the code, instead of running step by step. These are called "breakpoints." To set a breakpoint, double-click on the margin of Thonny where the line numbers are written, and a red dot should appear next to the line number you double-clicked on, which will look like this: ![A screenshot of part of the Thonny window showing the first few lines of the hasCGBlock definition from the provided tracing.py file. A breakpoint has been set on line 20, which is the if statement on the first line of the for loop.](breakpoint.png) When any breakpoints are set, running the debugger will fast-forward until it reaches a line with a breakpoint on it (and it will run to completion if it never reaches such a line). It will pause at that point, and you can use the normal stepping buttons to keep running step-by-step, or you can also use the resume button to continue until the next breakpoint is hit. By setting a breakpoint on the very first line inside of a for loop, we can use the resume button to step through each iteration of the loop. And in the function call frame window that pops up, the local variables of the function will be displayed, so we can watch the values update on each iteration, as shown in this picture: ![A screenshot of Thonny showing the debugger paused on the first line of the loop in hasCGBlock, and indicating the function call frame window that's open, the yellow box in Thonny highlighting the if/else block which is about to execute, and the local variables pane at the bottom showing the value of each local variable, including base ('C'), run (0), and sequence ('CGAGGGCCUC').](debugger_open.png) Take a moment to step through the `hasCGBlock` loop and watch the values update so you're familiar with how to use the debugger before moving on to the next part of this lab. Remember to add a function call to the file so that it will actually run when you start it in debug mode. @include('/labs/lab08/_toc') @stop