Today: loose ends: looking at error messages, more string functions, what is computer hardware?

Debugging

Many times you run your code and see an error message. Here are some example debug error messages and how to decode them.

These examples use our old movie.zip example, editing movie-solution.py to put in some bugs and see what they do.

Bug and Symptom

A "bug" is a flaw in the code - the code as written does not do what we wanted. Python doe s not notice the bug right away typically. Python does not know what we wanted, it just does what the lines say until it hits an error case, like a bad index or non-existent function name.

When Python hits an error and halts - we'll think of that as the "symptom" you observe. Your job is to work backwards from the symptom to figure out the underlying bug. Very often the symptom is right on the line with the bug, and so it's pretty straightforward. But sometimes it can be more complicated.

scroll_left Grid code

Here is the correct code for our scroll_left() example. Try putting in various bugs to see the error messages. Run the Doctests to see what we get.

def scroll_left(grid):
    """
    Implement scroll_left as in lecture notes.
    >>> grid = Grid.build([['a', 'b', 'c'], ['d', None, None]])
    >>> scroll_left(grid)
    [['b', 'c', None], [None, None, None]]
    """
    for y in range(grid.height):
        for x in range(grid.width):
            # Copying towards the left
            # x, y is source, copy to x-1, y
            val = grid.get(x, y)
            if x > 0 and val != None:
                grid.set(x - 1, y, val)
            grid.set(x, y, None)
    return grid

1. Bad Function Name: grid.geet()

Put a bug in scroll_left() function: grid.geet(x, y)

    for y in range(grid.height):
        for x in range(grid.width):
            # Copying towards the left
            # x, y is source, copy to x-1, y
            val = grid.geet(x, y)  # line 59

Run the Doctests, the run gets an error. Look at the bottom of the error listing first, work your way upwards. The error identifies the line with the problem, it's a line in your own code. and the error message is reasonable. This is a common, easy case - Python notices the problem right on the line with the wrong code.

      ....
      File "<doctest scroll_left[1]>", line 1, in 
        scroll_left(grid)
      File "...movie/movie-solution.py", line 59, in scroll_left
        val = grid.geet(x, y)
    AttributeError: 'Grid' object has no attribute 'geet'

2. Error In Downstream Function

Suppose a() passes bad data to b(), then b() uses the data and crashes. The error message will be in b(), but the real bug is "upstream" in a().

Bug: change x value to be wrong before grid.get() is called...

    for y in range(grid.height):
        for x in range(grid.width):
            # Copying towards the left
            # x, y is source, copy to x-1, y
            val = grid.get(x + 1000, y)   # line 59

Here is the error message - look at the bottom of the listing and work your way upwards, looking for your function (movie-solution.py) vs. some function you called (grid.py).

      ....
      File ".../movie/movie-solution.py", line 59, in scroll_left
        val = grid.get(x + 1000, y)
      File ".../movie/grid.py", line 76, in get
        return self.array[y][x]
    IndexError: list index out of range

Look at the bottom of the error listing and work up. Index-out-of-range error is not our code, it's in grid.py which we did not write. Look up one function, and we see "movie-solution.py line 59", grid.get(x + 1000, y). This is line that called get() with bad data, leading it to crash.

Or more likely, the logic just above line 59 was missing a < test, or had wrong arithmetic so it set x incorrectly, and that led to the index out of bounds error down in grid.py.