Reading Errors

Sometimes when you write a bug in your Python program, it will crash! Crashing is actually a good thing since it usually tells you exactly (or almost exactly) what the error is! For example, consider the following program stored in module.py.

def add(a, b):
    return a + b


def main():
    print(add(1, 2))
    print(add(3, '4'))


if __name__ == '__main__':
    main()

If we try running this program (i.e. with python module.py in the terminal), we would see the following output. Notice that the first value it printed was 3 (because the first add was successful), and the remainder of the output describes an error.

# python module.py
3
Traceback (most recent call last):
  File "module.py", line 11, in 
    main()
  File "module.py", line 7, in main
    print(add(3, '4'))
  File "module.py", line 2, in add
    return a + b
TypeError: unsupported operand type(s) for +: 'int' and 'str'
There are two very important things to note about this output (and it requires you to read the output backwards):

  1. The last line of the output tells you what type of error was encountered (TypeError) and then it will usually try to give some explanation (unsupported operand type(s) for +: 'int' and 'str').
  2. The lines before that show a stack trace. This helps you figure out where the error comes from. You would read it in the following order:
    1. The error happened with the line return a + b. The line of output before that tells you where in the program this is (Line 2 of module.py in the add function).
    2. The call to the add function that caused the error was print(add(3, '4')). The line of output before that tells you where in the program this is (Line 7 of module.py in the main function).
    3. The call to the main function that caused the error was main(). The line of output before that tells you where in the program this is (Line 11 of module.py).

    Usually the first line of an error is not very informative because it just says it happens in the main method. Reading this backwards is very helpful because it not only tells us what the error is (a TypeError) but also which call of the function caused that error (add(3, '4')). Now that you have these two key facts, you can start putting together a plan to fix the error!

    Types of Errors

    The remainder of this page gives some example error types and what they mean (in alphabetical order).

    AttributeError

    Description: Accessing a member of an object which doesn’t exist.

    Example Cause: Referring to obj.foo when obj‘s class does not have a foo field.

    Additional Notes: Check whether you are trying to access a local variable or a field.

    FileNotFoundError

    Description: Opening a file which doesn’t exist.

    Example Cause: Writing open('file.txt') when file.txt is not a file that exists.

    Additional Notes: Perhaps, you are missing a path or the file is in the wrong location.

    IndexError

    Description: Tying to access an element of a list outside the bounds.

    Example Cause: Accessing my_list[10] when my_list = [1, 2].

    Additional Notes: Be careful what you’re indexing into. Can occur if you are modifying a list while looping over it. It is always a good idea to print out the list for debugging.

    KeyError

    Description: Trying to access an element not in a dict, set, pandas object.

    Example Cause: Accessing d['tacos'] when d = {'queso': 1}.

    Additional Notes: For pandas: Check if you are accessing a column from a Series or if the column doesn’t exist.

    NameError

    Description: Accessing a variable which was never defined.

    Example Cause: print(my_var) when my_var hasn’t been defined.

    Additional Notes: Many times, we forget the self before our field: self._my_var.

    TypeError

    Description: Passing a function the wrong type of variable as a parameter, indexing into a structure (mostly DataFrames or lists of dictionaries) with the wrong index type, or just using some type incorrectly.

    Example Cause: Calling sum('hello') when sum doesn’t take strings. Indexing into a list of dictionaries using list_of_dict['Column Name'] or a DataFrame using df[0].

    Additional Notes: Also occurs when you pass the wrong number of parameters to a function.

    ValueError

    Description: Passing a function an invalid value as a parameter.

    Example Cause: print(my_var) when my_var hasn’t been defined.

    Additional Notes: sqrt(-5) as sqrt only takes positive numbers.