Skip to content
Home / Fundamentals

Python Debugging

Introduction to Debugging

Debugging is the process of identifying and fixing errors in your code. There are three main types of errors that you might encounter while writing and running your code:

  • Syntax errors: These occur when the Python interpreter encounters code that it cannot parse. Syntax errors are usually easy to fix, as they are often caused by simple typos or missing characters.
  • Runtime errors: These occur when the Python interpreter encounters an error while executing your code. Runtime errors can be more difficult to fix, as they may be caused by a variety of issues, including incorrect data types, indexing errors, or unexpected input.
  • Logical errors: These occur when your code runs without producing any errors, but does not produce the expected output. Logical errors are usually the most difficult to fix, as they require you to carefully examine your code and understand how it is supposed to work.

Debugging Syntax Errors

To debug syntax errors, you will need to carefully examine your code and look for any typos or missing characters. Here is an example of a syntax error:

def multiply(x, y):
    result = x * y
    print(f"{x} * {y} = {result}")

def main():
    a = 5
    b = "6"
    c = a + b
    print(c)

if __name__ == "__main__":
    main()

In this example, the interpreter will raise a syntax error on the fifth line, because you cannot concatenate a string and an integer using the + operator. To fix this error, you will need to either convert a to a string or b to an integer, like this:

def multiply(x, y):
    result = x * y
    print(f"{x} * {y} = {result}")

def main():
    a = 5
    b = "6"
    c = str(a) + b  # Convert a to a string
    print(c)

if __name__ == "__main__":
    main()

Debugging Runtime Errors

To debug runtime errors, you will need to carefully examine your code and look for any issues that might cause the interpreter to raise an error. Here is an example of a runtime error:

def get_element(lst, index):
    return lst[index]

def main():
    my_list = [1, 2, 3, 4, 5]
    print(get_element(my_list, 2))  # Expects 3
    print(get_element(my_list, 5))  # Expects an index out of range error

if __name__ == "__main__":
    main()

In this example, the interpreter will raise an index out of range error on the fourth line, because the list my_list only has five elements, and the index 5 is out of range. To fix this error, you will need to either adjust the index or check whether it is within the bounds of the list, like this:

def get_element(lst, index):
    if index < 0 or index >= len(lst):
        return "Index out of range"
    return lst[index]

def main():
    my_list = [1, 2, 3, 4, 5]
    print(get_element(my_list, 2))  # Expects 3
    print(get_element(my_list, 5))  # Expects "Index out of range"

if __name__ == "__main__":
    main()

Debugging Logical Errors

To debug logical errors, you will need to carefully examine your code and try to understand why it is not producing the expected output. Here is an example of a logical error:

def get_max(lst):
    max_val = lst[0]
    for val in lst:
        if val > max_val:
            max_val = val
    return max_val

def main():
    my_list = [1, 2, 3, 4, 5]
    print(get_max(my_list))  # Expects 5

if __name__ == "__main__":
    main()

In this example, the function get_max is supposed to return the maximum value in the list lst. However, the function will always return the first element of the list, because the value of max_val is never updated. To fix this error, you will need to move the assignment of max_val to after the loop, like this:

def get_max(lst):
    max_val = None
    for val in lst:
        if max_val is None or val > max_val:
            max_val = val
    return max_val

def main():
    my_list = [1, 2, 3, 4, 5]
    print(get_max(my_list))  # Expects 5

if __name__ == "__main__":
    main()

Logical errors can be difficult to fix, because they often require you to understand how your code is supposed to work, and to think critically about why it is not producing the expected output. To help you debug logical errors, you can use tools like print statements and the Python debugger (pdb).

Best Practices

  • Test your code frequently: One of the best ways to prevent and debug errors is to test your code frequently as you are writing it. This way, you can catch errors early on, and you will have a smaller codebase to debug.
  • Use print statements to debug: Print statements are a simple and effective way to debug your code. By printing out the values of variables and expressions, you can see what your code is doing and identify where errors are occurring.
  • Write clear and organized code: Writing clear and organized code can help you avoid errors and make it easier to debug when errors do occur. Use good naming conventions, add comments to explain your code, and use clear and consistent formatting to make your code more readable.
  • Ask for help: If you are having trouble debugging your code, don't be afraid to ask for help. You can ask for help from your classmates, a tutor, or online communities like Stack Overflow.