import matplotlib
if not hasattr(matplotlib.RcParams, "_get"):
    matplotlib.RcParams._get = dict.get

6.1. Error Types#

You have probably encountered errors before in your code—no one is perfect! But have you ever spent time reading through the error message to help you figure out what went wrong? This Section will give you some information that will help interpret these sometimes cryptic message to more efficiently identify the problem and fix it.

Essentially there are 3 types of errors, each of which is described below:

  • Syntax error

  • Exceptions

  • Logic error

Click –> Live Code on the top right corner of this screen and then execute the cells as you go through the page. In each case, see if you can fix the code (re-run the cell until the error is gone), as well as try to replicate the error with your own example.

In each of the examples, you should look at the error report that is printed after executing each cell and identify the type of error; in each case they should look like XxxxError, where Xxxx identifies the specific error type.

The work on this page is in part derived from work that is Copyright © University of Cape Town under CC BY-SA 4.0. Specifically, material from this page was used.

6.1.1. Syntax errors#

Syntax errors are the most common for beginner developers. Syntax errors occur when the ‘grammar’ rules of Python are broken. When this happens, Python is not able to execute your code.

Common syntax errors include:

  • missing punctuation, such as forgetting to add : after an if statement

  • unmatched parantheses, such as print((1+1)

  • misplaced keywords, such as placing the return statement outside of a function

Modern IDEs are extremely helpful for fixing these errors. They are often able to highlight these errors immediately. When an error happenes, Python parser will show in which line it is and point to it in the code with an arrow ^, like shown below:

if 5 > 3:
    print("5 is bigger than 3)
  Cell In[4], line 2
    print("5 is bigger than 3)
          ^
SyntaxError: unterminated string literal (detected at line 2)

As we can see from the error report, Python tells us directly that this is a SyntaxError. It even includes a carat (the ^ symbol) to identify the location within the line of code where it occurs. Useful, right?!

For more common syntax errors, the error message itself may even give a solutions. For instance, in the image below, we can see that in the output it not only underlines the syntax error made, but also prints out an error message with what it expected.

if x > 10
    print('Hi')
  Cell In[1], line 1
    if x > 10
             ^
SyntaxError: expected ':'

Syntax errors may often be accompanied by an IndentationError or NameError where the indentation is incorrect or a variable being used later in the code has not been defined correctly due to incorrect syntax when defining it.

6.1.2. Exceptions#

Exceptions are a general set of errors that, unlike syntax errors, appear during code execution.

6.1.2.1. Name and Scope Errors#

NameErrors and ScopeErrors are both caused by Python not being able to use a variable correctly.

  • NameErrors occur when a variable or function is used before it has been correctly defined. The underlying cause of this is often the code being carried out in the wrong order. For example, you may have encountered this error when you have jumped around in your notebook and run cells in different order.

  • A ScopeError occurs when you try to access a variable outside where it is defined (outside of scope). For instance, when you define a variable inside a function but try to access it outside of the function.

  • A UnboundLocalError is a more specific type of error. It refers to the cases where the same variable name is used both inside and outside of a function. In these cases, Python will automatically use the variable inside the function. However, if the variable is called before it is defined inside the function, it will throw this error. An example is shown below:

int = 10

def example():
    print(int)
    int = 5

example()
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
Cell In[5], line 7
      4     print(int)
      5     int = 5
----> 7 example()

Cell In[5], line 4, in example()
      3 def example():
----> 4     print(int)
      5     int = 5

UnboundLocalError: cannot access local variable 'int' where it is not associated with a value

6.1.2.2. File and Import Errors#

  • Python cannot find a file.
    These errors can be fixed by correcting the file path and ensuring that you are in the correct working directory.

  • A module has not been installed in your python environment. These errors can be fixed by installing the required packages or modules in your Python environment. In some cases, you might even have just misspelled a module name or called it using the incorrect name

6.1.2.3. Index Errors#

Index errors occurs when you try to access a position in a variable with indexes, such as a list, but the index is not available. These can be triggered by a variety of reasons:

  • An index is out of bounds, such as trying to access item number 6 in a list that only has 4 entries

  • Using a negative index, which is inherently invalid

  • When writing loops and iterating more/fewer times

  • When doing operations with matrices that have mismatched shapes.

6.1.2.4. Type and Attribute Errors#

These errors occur when you are trying to complete an operation that is not supported by the data or object type you are using.

  • TypeErrors occur when an operation or function gets the wrong data type

  • AttributeErrors occur when the object (such as a variable you have defined) does not have the method or attribute you are trying to use.

Below are two examples:

"age: " + 25
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[6], line 1
----> 1 "age: " + 25

TypeError: can only concatenate str (not "int") to str
x = 5
x.append(3)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[7], line 2
      1 x = 5
----> 2 x.append(3)

AttributeError: 'int' object has no attribute 'append'

The most common ways to fix these errors is to either convert the variable you are using into the correct data type, or to use another method. For instance, if we want x.append(3) in the example above to work, we could convert x into a list first.

6.1.3. Raising Exceptions#

If an exception stops your code from running, we often refer to this as raising an exception. Many exceptions are implemented directly in the Python code base, but it is important to recognize that anyone writing Python code can create exceptions themselves. Determining how and when to raise exceptions (i.e., “cause” the error) during code execution is a useful way to make sure code and software runs as designed; we will learn to do this later. For now we will look at several examples of exceptions that are implemented in the Python code base:

16 / 0
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
Cell In[2], line 1
----> 1 16 / 0

ZeroDivisionError: division by zero
2 + "3"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[3], line 1
----> 1 2 + "3"

TypeError: unsupported operand type(s) for +: 'int' and 'str'
2 * pi * r ** 2
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[4], line 1
----> 1 2 * pi * r ** 2

NameError: name 'pi' is not defined

As you see in the examples above, we have encountered 3 different types of exceptions - ZeroDivisionError, TypeError and NameError. A nice thing about Python is that it tells us the specific type of exception we are dealing it, making it easy for you, the developer, to figure out the cause of the raised exceptions. Although in some cases the cause of the exception is obvious, it is often useful to look up the Python documentation that describes it (especially when your code gets complex, and you are having trouble identifying the source of the problem). For example, if you look at the description of NameError, you will find:

exception NameError
Raised when a local or global name is not found. This applies only to unqualified names. The associated value is an error message that includes the name that could not be found.

The name attribute can be set using a keyword-only argument to the constructor. When set it represent the name of the variable that was attempted to be accessed.

Changed in version 3.10: Added the name attribute.

As you can see, the documentation also provides information about changes relative to older versions of Python.

For more exception types, you can have a look at the complete list here. Keep in mind that you are not required to understand the cause of every exception, but rather the importance of having different types of exceptions and that each one may require a different strategy in resolving it.

6.1.3.1. Logical errors#

Logical errors are generally the most difficult to discover, because they can be invisible to the developer. Logical errors can exist without raising an exception or an error. Particular examples of logical errors are:

  • using the wrong variable name

  • indenting a block to the wrong level

  • using integer division instead of floating-point division

  • getting operator precedence wrong

  • making a mistake in a boolean expression

  • forgetting to add an else statement to an if clause

  • off-by-one, and other numerical errors

In these cases, you need to be aware of what you would expect an output to be and analyse the code step-by-step to see where the error occurred.

distance = 10            # m
time = 3.63              # s

speed = distance / time    # m/s
print('Speed = ', speed)
Speed =  2.7548209366391188

If we use integer division by mistake, the result is incorrect:

distance = 10            # m
time = 3.63              # s

speed = distance // time    # m/s
print('Speed = ', speed)
Speed =  2.0

The difference between the 2 results is nearly 0.75, which can be very high depending on its use.

6.1.4. Summary of Error Types#

On this page we considered three types of errors. One way to help distinguish them is to recognize when they may occur:

  • Syntax error: before the code is executed

  • Exceptions: during execution

  • Logic error: code executes without error

When executing the code in the examples above, did you read the error report? It is called a traceback and it should have been useful to identify the error type. We will learn more about it in the next section.