🐞 Debugging Scenarios & Solutions

Quick debugging tips:

  • Read the error message and look at the line that it refers to.
    • Sometimes the issue is at the line just ⬆ above the line that was listed in the error.
    • If enabled, pay close attention to the syntax highlighting in your editor, which can point at where the error might be happening.
  • Use print() statements to display the type and value of your variable.
  • Go back to the instructions and carefully re-read them.
  • Use Python Tutor to visualize your code.
  • Use the Rubber Duck Debugging to walk yourself through the logic of your code.
  • If you are having trouble with your output not matching what is expected, use an online text comparison tool, e.g. https://text-compare.com or https://contenttool.io/text-difference-checker.

Table of contents

  1. Common Error Messages
    1. AttributeError: '...' object has no attribute '...'
    2. EOFError: EOF when reading a line
    3. SyntaxError: unexpected EOF while parsing
    4. EOL while scanning string literal
    5. IndentationError: unexpected indent
    6. IndentationError: expected an indented block
    7. IndexError: ... index out of range
    8. KeyError: ... with a dictionary
    9. NameError: name '...' is not defined
    10. NameError with a dictionary
    11. Positional Arguments Errors
    12. RecursionError: maximum recursion depth exceeded
      1. Example erroneous code illustrating the above recursion issues
  2. Syntax Errors
    1. SyntaxError: invalid character in identifier
    2. SyntaxError: invalid syntax
    3. SyntaxError: unmatched ')'
  3. Type Errors
    1. TypeError: argument of type 'int' is not iterable
    2. TypeError: argument of type 'NoneType' is not iterable
    3. TypeError: can only concatenate str (not "int") to str
    4. TypeError: 'list' object cannot be interpreted as an integer
    5. TypeError: object of type '...' has no len()
    6. TypeError: ... takes exactly one argument (... given)
    7. TypeError: '...' not supported between instances of '...' and '...'
    8. TypeError: unsupported operand type(s) for +: 'int' and 'list'
    9. ValueError: invalid literal for int() with base 10
    10. ZeroDivisionError: division by zero
  4. Undesirable Results
    1. Output printing None
    2. Function returns None but a different value is needed
    3. Logic Errors
    4. Function address is printed <function function_name at 0x....>

Common Error Messages

AttributeError: '...' object has no attribute '...'

Example errors:

  • AttributeError: 'int' object has no attribute 'isdigit'
  • AttributeError: 'list' object has no attribute 'split'

  • Example erroneous code:
    my_int = 42
    if my_int.isdigit():
    my_float = float(my_int)
    
  • Cause: A variable of one type is trying to use a method from a different (incompatible) type.
  • Check: verify the type of the object that is listed before the . in the .method() call.
    • Either change it to the type that the method works with (see example)
    • Use another method/solution that works with the original object type (e.g., for strings stored in a list, you might need to iterate through each element of a list and use split() on the string element
  • Corrected line of code:
    my_int = "42"
    if my_int.isdigit():
    my_float = float(my_int)
    

EOFError: EOF when reading a line

  • Cause:
    • Python is expecting an input but there is no input to provide.
    • Alternatively, there might be a missing closing parenthesis (see SyntaxError: unexpected EOF while parsing).
    • If the error is produced when using a loop, check that you do not have an infinite loop. Look closely at the loop’s conditions and verify that the loop stops, especially, in the edge cases.
    • In almost all cases, input() should be included inside the main program, not inside the functions.
  • The program instructions might be providing 1 input value, but you have an extra input() in your code.
    num_items = int(input())
    item = input()
    

    but the input is just a single number, there’s no item to provide via input().

  • An infinite loop example - num_items doesn’t get updated within the loop, so the condition stays always True (unless num_items == 0 and the loop is not executed):
    num_items = int(input())
    items = []
    while num_items:
      item = input("Enter an item: ")
      items.append(item)
    

⬆️ BACK TO TOP


SyntaxError: unexpected EOF while parsing

  • Cause: Missing a closing parenthesis ).
  • Example erroneous code:
    print('Hello, World'
    
  • Corrected line of code:
    print("Hello, World")
    

⬆️ BACK TO TOP


EOL while scanning string literal

  • Cause: Missing a closing quotation mark or a mismatched quotation mark (incorrectly placed quotation can also cause it).
  • Example erroneous code:
    print('Hello, World) # missing a quotation mark
    

    or

    print('Hello, World") # mismatched quotation marks
    

⬆️ BACK TO TOP


IndentationError: unexpected indent

  • Example erroneous code:
    print("Hello world!")
    print("What a nice day!")
    
  • Cause: The code is either indented even though it is not necessary or is missing an indentation. The line number in the error points at where the mismatch happened.
  • Correct code:
    print("Hello world!")
    print("What a nice day!")
    

⬆️ BACK TO TOP


IndentationError: expected an indented block

  • Example erroneous code:
    def print_hello():
    """Print a simple greeting."""
    print("Hello!")
    
  • Cause: This error occurs if the previous line ended with a colon : and did not have a properly indented line of code underneath it. It is likely that the issue occured at the line directly above the line reported in the error.
  • Correct code (notice the indentation after the line that ends with a colon):
    def print_hello():
    """Print a simple greeting."""
    print("Hello!")
    

⬆️ BACK TO TOP


IndexError: ... index out of range

Example errors:

  • IndexError: string index out of range
  • IndexError: list index out of range

  • Example code that causes the error:
my_str = ""
print("The first symbol is", my_str[0])
print("The last symbol is", my_str[-1])
  • Cause: The string/list is being indexed at a location that does not exist.
  • Check: Print the length of the string/list to check its maximum index (remember that Python indexing starts at 0).

  • Correct code that won’t cause the error:
my_str = ""
if len(my_str) != 0: # my_str != ""
    print("The first symbol is", my_str[0])
    print("The last symbol is", my_str[-1])

⬆️ BACK TO TOP


KeyError: ... with a dictionary

This error occurs when working with dictionaries. The line above the error shows which line caused the incorrect retrieval.

  • Example erroneous code:
month_names = {
    "1": "January",
    "2": "February",
}
print("First month is", month_names[1]) # KeyError: 1

Alternatively, you wouldn’t get an error but would get an undesired output that displays None if using .get():

print("First month is", month_names.get(1)) # results in "First month is None"
  • Cause: This error occurrs when trying to retrieve a value using a key that doesn’t exist in the dictionary. Possible causes:
    • the dictionary does not store the correct key-value pairs (did you add all necessary items? what about the edge cases?)
    • the key is stored / retrieved as an incorrect type (see the example)
  • Correct code (alternative options):
...
print("First month is", month_names["1"])
print("First month is", month_names.get("1"))
print("First month is", month_names[str(1)])

⬆️ BACK TO TOP


NameError: name '...' is not defined

Python would replace the ellipsis ... with the name of the variable that it’s unable to find.

  • Cause: Generally, this error happens when a function name or a variable name
    • is misspelled
    • has not been properly defined first

For example:

NameError: name 'Print' is not defined

  • Example erroneous code:
    Print('Hello, World')
    
  • Cause: In this case, the function name is “misspelled” - an accidentally capitalized name of the function makes Python look for a variable called Print.

This error can also be caused if there is a single word (or comma-separated words) inside the print() that needed to be displayed as the literal text but does not include quotation marks around it (similar to the SyntaxError: invalid syntax).

  • Example erroneous code:
    print(Hello)
    print(Hello, World)
    

    generates the same error (NameError: name 'Hello' is not defined), since Python is now looking for a variable called Hello - it doesn’t know that we just forgot to put quotation marks around the text.

⬆️ BACK TO TOP


NameError with a dictionary

  • NameError: name 'A' is not defined
  • Example erroneous code:
    dict1 = {"A":1, "B":2, "C":3}
    print(dict1[A])
    
  • Cause: Missing quotation marks (" ") when indexing a key from the dictionary.

  • Correct code:
    dict1 = {"A":1, "B":2, "C":3}
    print(dict1["A"])
    

⬆️ BACK TO TOP


Positional Arguments Errors

Let’s first look at the case where too many arguments were provided in the function call. In that case, the error would be something like: print_name takes 0 positional arguments but 1 was given.

  • Example erroneous code:
def print_name():
    print("Sam")

if __name__ == '__main__':
    print_name("Sam")
  • Cause: The function print_name() does not take any parameters but when calling the function one parameter is being passed. This error signifies that there is a mismatch between the number of parameteres in the function defintion and the number of arguments in the function call.

  • Correct code:

def print_name():
    print("Sam")

if __name__ == '__main__':
    print_name()

This also works the other way around if you are missing arguments in the function call. For example, the function below results in an error: get_largest() missing 1 required positional argument: 'y'.

  • Example erroneous code:
def get_largest(x, y):
    return max(x, y)

if __name__ == '__main__':
    x = int(input())
    y = int(input())
    print(get_largest((x, y)))
  • Cause: The function get_largest() takes in two parameters but when calling the function only one is passed in (i.e., a tuple with two elements). This error likewise signifies that there is a mismatch between the number of parameteres in the function defintion and the number of arguments in the function call.
  • Correct code:
def get_largest(x, y):
    return max(x, y)

if __name__ == '__main__':
    x = int(input())
    y = int(input())
    print(get_largest(x, y))
  

⬆️ BACK TO TOP


RecursionError: maximum recursion depth exceeded

  • Cause: This error usually occurs due to an infinite recursion, which typically happens when there is …
    • no base case
    • an invalid base case
    • a missing base case
    • an incorrect recursive call
    • a missing return
  • Check: The following actions suggest what you can check when debugging an infinite recursion - make sure to add print() statements to each branch, so that you can trace which case is being called and with which arguments. Check the cases in the provided order:
    • No base case:
      • does the recursive function definition contain an if statement that compares if the input parameter is a specific value, which corresponds to the base case?
      • do the instructions mention any specific value that can be turned into a base case? what action needs to happen in that case?
      • Common base cases are typically: an empty list/string; a count/length of 0 or 1; a minimum/maximum allowed value;
    • An invalid base case: does the if statement compare the input parameter to the correct value of the correct type?
    • A missing base case:
      • does there need to be another if/elif statement that should check if the input parameter corresponds to an additional correct value of the correct type (remember the Fibbonacchi numbers example)?
      • Ask yourself: is there another case when the function does not need to do any computation/processing (so that it can easily produce the answer)? what action needs to happen in that case?
      • Common additional base cases: finding a match in a list/string; a single-element list/string
    • An incorrect recursive call:
      • are the arguments in the recursive function call (within the function itself) being reduced / increased so that they get closer to the value in the base case? (use print() to verify/visualize their values)
      • Plug-in the next simplest case that would occur immediately after the base case and check whether the recursive call correctly triggers the base case (e.g., if the base case is an empty list, check if the function call with a single-element list would end up calling the base case).
      • Check the instructions - are the input values supposed to be from a specific range (e.g., non-negative? is 0 included? are letters/strings accepted?)
    • A missing return: Verify that if the function is supposed to return its result, then each branch contains the return keyword. In the recursive case/branch, it is common to return the result of calling the recursive function (i.e., the recursive call).

Example erroneous code illustrating the above recursion issues

Starting from the first case, we illustrate the potential issues by building on the first example:

  • No base case
def fib(n):
    """
    param: n (int) - the ordinal value of the Fibonacchi
           sequence; expected to be > 0.
    The function recursively computes the n-th Fibonacchi
    number, starting from the 1st one.
    returns: the computed Fibonacchi value (int)
    """
    # missing a base case here - no `if` branch
    return fib(n - 1) + fib(n - 2)

if __name__ == "__main__":
    print(fib(3))
  • An invalid base case
def fib(n):
    """
    param: n (int) - the ordinal value of the Fibonacchi
           sequence; expected to be > 0.
    The function recursively computes the n-th Fibonacchi
    number, starting from the 1st one.
    returns: the computed Fibonacchi value (int)
    """
    if n == '1': # incorrect type of the base case
        return 1
    return fib(n - 1) + fib(n - 2)

if __name__ == "__main__":
    print(fib(3))
  • A missing base case
def fib(n):
    """
    param: n (int) - the ordinal value of the Fibonacchi
           sequence; expected to be > 0.
    The function recursively computes the n-th Fibonacchi
    number, starting from the 1st one.
    returns: the computed Fibonacchi value (int)
    """
    if n == 1: # correct type of the base case
        return 1 # correct return, correct value, correct type
    # need another base case, for the 2nd Fibonacchi n
    return fib(n - 1) + fib(n - 2)

if __name__ == "__main__":
    print(fib(3))
  • An incorrect recursive call
def fib(n):
    """
    param: n (int) - the ordinal value of the Fibonacchi
           sequence; expected to be > 0.
    The function recursively computes the n-th Fibonacchi
    number, starting from the 1st one.
    returns: the computed Fibonacchi value (int)
    """
    if n == 1:
        return 1
    if n == 2:
        return 1
    return fib(n) + fib(n - 2) # the first function call doesn't decrement n

if __name__ == "__main__":
    print(fib(3))
    print(fib(0)) # also, the function call is not supposed to work for n <= 0
  • A missing return
def fib(n):
    """
    param: n (int) - the ordinal value of the Fibonacchi
           sequence; expected to be > 0.
    The function recursively computes the n-th Fibonacchi
    number, starting from the 1st one.
    returns: the computed Fibonacchi value (int)
    """
    if n == 1:
        print ( 1 ) # missing a correct return
    if n == 2:
        print( 1 ) # incorrect return value
    return fib(n - 1) + fib(n - 2)

if __name__ == "__main__":
    print(fib(3))

⬆️ BACK TO TOP


Syntax Errors

SyntaxError: invalid character in identifier

  • Cause: Either quotations around the text or some other symbol is not from the standard Latin alphabet used by Python. The error typically occurs when writing code in a text processor (e.g., Word), typing on a mobile device that has autocorrect enabled, or (rarely) when accidentally switching the keyboard language layout.

  • Example erroneous code:

    print(Hello!’) # invalid quotations
    

SyntaxError: invalid syntax

This is a general error that occurs when the syntax is not correct and a “Python sentence” is broken. If enabled, pay close attention to the syntax highlighting, which can point at where the error might be happening.

Below are sample Python syntax rules:

  1. A function call must start and end with a parenthesis; the number of open and closed parentheses must match.
  2. The literal text has to be enclosed within the quotation marks.
  3. Variables must first be defined (created) before being used.


  • Cause: Missing opening quotation mark or opening parenthesis or quotations around the text.
  • Example erroneous code:
    print(Hello World')
    print'Hello World  
    print(Hello World) # see also NameError
    

⬆️ BACK TO TOP


SyntaxError: unmatched ')'

  • Cause: an extra closing parenthesis ) that does not have a matching opening paren (.
  • Example erroneous code:
    print('Hello, World'))
    

⬆️ BACK TO TOP


Type Errors

TypeError: argument of type 'int' is not iterable

Related error: TypeError: 'list' object cannot be interpreted as an integer

  • Example erroneous code:
total = 42
sum(total)

# another alternative that would case such error
for i in total: # `in` requires a range/collection, not an integer
    print(i)
  • Cause: The error usually occurs when a built-in Python function that is intended for a sequence/collection is applied to an integer instead.
  • Check: Take a look at the line that is causing an error and verify that you are using a proper collection (i.e., a list or a range).

  • Correct code:
total = [42]
sum(total)

for i in total: # `in` requires a range/collection, not an integer
    print(i)

# alternatively, if `total` needed to stay as an integer
total = 42
for i in range(total):
    print(i)

⬆️ BACK TO TOP


TypeError: argument of type 'NoneType' is not iterable

  • Example erroneous code:
val = None
if "a" in val:
    print("Found it!")
  • Cause: The error usually occurs when the in operator in trying to index a None value instead of the sequence/collection.
    • Check the type/value of the object that is used after the in operator - if that object is a result of the function’s return value, verify that the function is returning the correct object or that your if branches are set up correctly to not try to index a None.
    • Do not store the result of print() and attempt to index it. Just like the methods that modify lists directly (since lists are mutable), print() does not return anything other than None.
  • Correct code:
val = None
if val != None:
    if "a" in val:
        print("Found it!")

or

val = "aeou" # correct object provided
if "a" in val:
    print("Found it!")

⬆️ BACK TO TOP


TypeError: can only concatenate str (not "int") to str

  • Example erroneous code:
num = 6
print("I would like " + num + " tacos please.")
  • Cause: You can only concatenate a string with a string, not a numeric type. Check the types of the variables that you are using in the concatenation.

  • Correct code and alternatives:

num = 6
print("I would like " + str(num) + " tacos please.") # proper string concatenation
print("I would like", num, "tacos please.") # using print defaults
print(f"I would like {num} tacos please.") # using f-strings

⬆️ BACK TO TOP


TypeError: 'list' object cannot be interpreted as an integer

  • Example erroneous code:
total = [42]
for i in range(total):
	print(i)
  • Cause: The range() function requires an integer argument but a list is given instead.
  • Check:
  • Is the current argument given to the range() supposed to be a list? Are you trying to print its values? If so, why do you need to use a range(), which helps print indices?
  • Do you need to print indices of a list? If so, do you have len() of a list as an input to the range()?
  • Do you need to generate a bunch of numbers and you accidentally stored the total as a list, instead of as an integer?

  • Depending on what you need to do, the potential solutions to the above error could be:
# `total` needs to be an integer, not a list
total = 42
for i in range(total):
	print(i) # prints the numbers from 0 to 42 (value in total)

# or, alternatively
# `total` stays as a list but
# the range() needs to be provided a proper integer, e.g., the length of the list
total = [42]
for i in range(len(total)):
	print(i) # prints the indices of the list, which is just 0

⬆️ BACK TO TOP


TypeError: object of type '...' has no len()

Examples include the errors

TypeError: object of type 'int' has no len()
TypeError: object of type 'float' has no len()
  • Example erroneous code:
len(42)
  • Cause: The error usually occurs when you think that you are asking for a length of a collection (e.g., a list, string, dictionary) but in reality the argument is an integer. Examine the value that is being provided as an argument into the len() function.

  • Correct code:

    len([42]) 
    

⬆️ BACK TO TOP


TypeError: ... takes exactly one argument (... given)

Some examples of this error:

TypeError: len() takes exactly one argument (2 given)
  • Example erroneous code:
len(42, 33)
  • Cause: The error usually occurs when
    • a built-in Python function is being applied to an incorrect object.
    • the function is not given the required number of arguments.
  • Correct code:
    len([42, 33]) 
    

⬆️ BACK TO TOP


TypeError: '...' not supported between instances of '...' and '...'

Some specific instances of this error:

  • TypeError: '<=' not supported between instances of 'int' and 'str'
  • TypeError: '<' not supported between instances of 'str' and 'int'

Similar error: TypeError: unsupported operand type(s) ...

  • Causes: The code is trying to compare incompatible types. The listed types are on the left and ithe right side of the provided operator respectively.
  • Check: Does either or both of the operands need to be converted into a numeric type?

  • Erroneous code:
    my_var = input() 
    if my_var < 5:
     print(my_var)
    
  • Correct code:
my_var = int(input()) 
if my_var < 5:
   print(my_var)

⬆️ BACK TO TOP


TypeError: unsupported operand type(s) for +: 'int' and 'list'

Similar error: TypeError: '...' not supported between instances of 'int' and 'str'

  • Example erroneous code:
nested_list = [[5, 10, 6], [7, 8, 9]]
total_sum = sum(nested_list)
  • Cause: The error can occur when trying to apply a built-in Python method to an unsupported type, e.g., to sum up a nested list, instead of its individual elements.

  • Correct code:

nested_list = [[5, 10, 6], [7, 8, 9]]
total_sum = 0
for item in nested_list:
    item_sum = sum(item)
    total_sum += item_sum

⬆️ BACK TO TOP


ValueError: invalid literal for int() with base 10

  • Example erroneous code:
    current_year = '1792.99'
    current_year = int(current_year)
    print(current_year)
    
  • Cause: Float, represented as a string, cannot be directly converted into an integer. If you do want to pass a string representation of a float to an int, you need to convert to a float first, then to an integer.

  • Correct code:
    current_year = '1792.99'
    current_year = float(current_year)
    current_year = int(current_year)
    print(current_year)
    

⬆️ BACK TO TOP


ZeroDivisionError: division by zero

  • Example erroneous code:
    print(1 / 0)
    # or
    my_list = []
    print("The average value of the list is", sum(my_list) / len(my_list))
    
  • Cause: The denominator in a division is 0.

  • Correct code:
    my_list = []
    if my_list != []: # len(my_list) != 0
    print("The average value of the list is", sum(my_list) / len(my_list))
    

⬆️ BACK TO TOP


Undesirable Results

Output printing None

  • None is printed even though you don’t want it to be there
  • Example erroneous code:
def print_hello():
    print("hello")

if __name__ == '__main__':
    print(print_hello())
  • Cause: The function print_hello() does not return anything (it has no return statement) so when you call print(print_hello()) you are printing its return value which is None.
  • Correct code:
def print_hello():
    print("hello")

if __name__ == '__main__':
    print_hello()

⬆️ BACK TO TOP


Function returns None but a different value is needed

  • Example erroneous code:
def get_hello():
    print("hello")

if __name__ == '__main__':
    print(get_hello())
  • Cause: The function get_hello() does not return anything (it has no return statement) so when you call print(get_hello()) you are printing its return value which is None.
  • Check: Sometimes, this behavior can occur when your code has nested if/elif branches, which contain a return inside of them. If one or more of the conditions are not set up correctly, the correct return statement would not be triggered.
    • Verify the accuracy of the conditions, check the edge cases, especially with the == (e.g., is it supposed to be < or <=).
    • Note what condition needs to fail for your code to return None.
    • Debug your code by adding print statements and/or add an else: return 42 to see which branches get executed/skipped.
  • Correct code:
def get_hello():
    return "hello"

if __name__ == '__main__':
    print(get_hello())
    assert get_hello() == "hello" # to check the return value

⬆️ BACK TO TOP


Logic Errors

  • Sometimes, we get a logic error, when the output does not match what we expect.
  • Example erroneous code:
    def get_largest(x,y):
      if x > y: 
        return y
      else: 
        return x
    
  • Cause: Although the syntax of this function is correct and the function will produce no errors, the result will be incorrect. This is simply due to a logical error - an incorrect value is being returned (or, the if condition needs to be changed).

  • Correct code:
    def get_largest(x,y):
      if x > y: 
        return x
      else: 
        return y
    

⬆️ BACK TO TOP


Function address is printed <function function_name at 0x....>

  • Function Address gets printed - <function function_name at 0x....>
  • Example erroneous code:
def area(radius):
    return 3.14 * radius**2

if __name__ == '__main__':   
    radius = float(input())
    print(f"Circle has area {area} inches squared.")
  • Cause: Instead of the function call, which requires the parentheses (and the arguments, if necessary), only the name of the function is used.
  • Correct code:
    ...
    print(f"Circle has area {area(radius)} inches squared.")
    

Acknowledgement

Content on this page is adapted from Yekaterina Kharitonova