Learning Python 3 with the Linkbot/Debugging

What is debugging?

 * "As soon as we started programming, we found to our surprise that it wasn't as easy to get programs right as we had thought.  Debugging had to be discovered.  I can remember the exact instant when I realized that a large part of my life from then on was going to be spent in finding mistakes in my own programs." &mdash; Maurice Wilkes discovers debugging, 1949

By now if you have been messing around with the programs you have probably found that sometimes the program does something you didn't want it to do. This is fairly common. Debugging is the process of figuring out what the computer is doing and then getting it to do what you want it to do. This can be tricky. It surprisingly common to spend weeks tracking down and fixing a bug that was caused by someone putting an  where a   should have been.

This chapter will be more abstract than previous chapters.

What should the program do?
The first thing to do (this sounds obvious) is to figure out what the program should be doing if it is running correctly. Come up with some test cases and see what happens.

For instance, lets try to write a program that rolls a Linkbot-I with two wheels forward one rotation while making the LED green, and then rolls the Linkbot backward with the LED red. Here's a first try at this program:

At first glance, the above program may appear to be correct. When you actually try it though, you'll see that the robot never turns its LED green, and it never moves forward. It immediately changes its LED red and moves backward. What happened to the two lines that are supposed to make the robot roll forward and turn the LED green?

One easy and powerful method of debugging problems like this is to use the  function to track the progress of the program while it's running. Lets try adding some print statements to our original program and see if we can track down the problem:

When you run this program, pay attention not only to what it's printing, but also how and when it's printing. When you run the program, the output you should get is: Moving forward... Done. Setting LED to green... Done. Moving backward... Done. Setting LED to red... Done. However, you'll notice that all of those statements print immediately; there is no delay between the commands that tell the robot to move forward and the commands that tell it to move backward. That should immediately give us an indication for what is wrong: the program should wait until the robot is finished moving forward before moving backward and turning red. You'll notice that we used non-blocking movement functions in our program so that we can move and change the LED color at the same time. However, we also know that Python doesn't stop and wait at non-blocking and "set" functions. From the previous chapter, we also have a function that makes Python wait until a non-blocking motion is completed called. Lets try fixing our broken program:

A  statement has been added in-between the two steps. This forces Python to wait until the robot is done moving forward before telling it to move backward and set the LED color to red.

Without the  statement, Python will go through all of those statements so fast that the robot rolling forward and green LED won't be noticeable to human eyes and ears. Only the last commands, rolling backward and the red LED, "stay" on the robot and are observable, making it seem like Python was skipping the moving forward and green LED altogether.

General Tips

 * 1) This may sound obvious, but the first thing to ensure is that you know what the program is supposed to do.
 * 2) Check to make sure the program flow is correct by using   statements.
 * 3) Check to make sure variable values are correct using   statements.
 * 4) For complex programs that might use loops and variables, try "stepping" through the program, line by line, keeping track of variable values and program outputs using pen and paper.
 * 5) If you have a long program that does many calculations on a variable and the value of the variable is wrong at the end of the program, try using the "binary-search" method to find the bug: Use a   statement to check the value of the variable in the middle of the program. If the value is correct, you know the bug is somewhere in the second half of your program. Put another   statement in the middle of the second half of the program and check its value. Repeat until you've found the incorrect line of code that is incorrectly setting the variable's value. This technique is highly useful for finding where a bug might be occurring, and it is useful for many types of bugs.