Debugging#
1) Using a Python Traceback#
(Also called a slacktrace)
blue box - Type of error
green box - Error message
red line - The specific line that caused the error
yellow box - The files and functions/methods where the error occured
Key point:
Read a Python traceback from bottom to top
metadata = {
'location': 'Nairobi',
'quality_flag': 5
'zenith': 60,
'clouds': True,
'data_center': ['LPDAAC', 'ASDC'],
}
metadata['Zenith"] == '7'
rotated_zenith = metadata['zenith'] + 90
print(rotated_zenith)
Cell In[1], line 8
metadata['Zenith"] == '7'
^
SyntaxError: unterminated string literal (detected at line 8)
Indentify the parts of the slacktrace in the error message above.
Python Error Messages#
Python error messages are shown at the bottom of a Traceback. This is the first thing you often read in the traceback.
IndexError
#
An IndexError
occurs when you try to access a value using an index and that index does not exist in the object.
pollutants = ['co', 'co2', 'no2', 'o3']
pollutants[50]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-11-f05b51aac7dc> in <module>
1 pollutants = ['co', 'co2', 'no2', 'o3']
----> 2 pollutants[50]
IndexError: list index out of range
KeyError
#
A KeyError
occurs when you are trying to access a named value of an object (a key) that does not exist. This is common in dictionaries and pandas DataFrames.
metadata = {
'location': 'Nairobi',
'quality_flag': 5,
'zenith': 60,
'clouds': True,
'data_center': ['LPDAAC', 'ASDC'],
}
metadata['start_date']
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-4-e954e279728c> in <module>
----> 1 metadata['start_date']
KeyError: 'start_date'
NameError
#
A NameError
occurs when you try to use a variable that doesn’t exist.
len(max_no2)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-10-8c7930fd591b> in <module>
----> 1 len(max_no2)
NameError: name 'max_no2' is not defined
SyntaxError
#
A SyntaxError
occurs when you have typed something that breaks the grammar rules of the core Python language. This could be extra parenthesis, mismatching quotes, backwards brackets, or a variety of other things.
len(pollutants
File "<ipython-input-12-06668746c5e8>", line 1
len(pollutants
^
SyntaxError: unexpected EOF while parsing
metadata['zenith"]
File "<ipython-input-13-feb0a3922969>", line 1
metadata['zenith"]
^
SyntaxError: EOL while scanning string literal
TypeError
#
A TypeError
is raised when you try to do something to an object, for example using a function, method, or operator, that the object can’t handle.
max_o3 = 95
len(max_o3)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-16-fbedace2e0dc> in <module>
1 max_o3 = 95
----> 2 len(max_o3)
TypeError: object of type 'int' has no len()
AttributeError
#
An AttributeError
occurs when you try to get information from an object and the type of information you are looking for doesn’t exist on that type of object.
pollutants = ['co', 'co2', 'no2', 'o3']
pollutants.keys()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-25-4c211af94241> in <module>
1 pollutants = ['co', 'co2', 'no2', 'o3']
----> 2 pollutants.keys()
AttributeError: 'list' object has no attribute 'keys'
ValueError
#
A ValueError
is raised when a function/method gets an input value that has the right type but the value is not appropriate. It is a very broad reaching error so it sometimes isn’t obvious what the problem is if you get a ValueError
.
float('8') # This is fine
float('pineapples') # This isn't
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-48-37db5a3fe5f5> in <module>
1 float('8') # This is fine
----> 2 float('pineapples') # This isn't
ValueError: could not convert string to float: 'pineapples'
Sometimes it’s mixed#
At times the error message you get won’t be the most helpful thing to lead to you to the solution. Keep this in mind - while the error message is a very useful place to start your debugging be open to considering additional avenues of error.
# Sometimes error messages are more cryptic
metadata['data_center'['LPDAAC']]
<>:2: SyntaxWarning: str indices must be integers or slices, not str; perhaps you missed a comma?
<>:2: SyntaxWarning: str indices must be integers or slices, not str; perhaps you missed a comma?
<ipython-input-24-22f4cb02bbce>:2: SyntaxWarning: str indices must be integers or slices, not str; perhaps you missed a comma?
metadata['data_center'['LPDAAC']]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-24-22f4cb02bbce> in <module>
1 # Sometimes error messages are more cryptic
----> 2 metadata['data_center'['LPDAAC']]
TypeError: string indices must be integers
Libraries#
Additional libraries will have their own custom errors that you will learn as you use them. Read the error message type to become familiar with the terminology then move on to reading the error message.
import rasterio
rasterio.open('./my_favorite_file.tif')
---------------------------------------------------------------------------
CPLE_OpenFailedError Traceback (most recent call last)
rasterio\_base.pyx in rasterio._base.DatasetBase.__init__()
rasterio\_shim.pyx in rasterio._shim.open_dataset()
rasterio\_err.pyx in rasterio._err.exc_wrap_pointer()
CPLE_OpenFailedError: ./my_favorite_file.tif: No such file or directory
During handling of the above exception, another exception occurred:
RasterioIOError Traceback (most recent call last)
<ipython-input-21-cce27133433b> in <module>
----> 1 rasterio.open('./my_favorite_file.tif')
~\.conda\envs\lessons\lib\site-packages\rasterio\env.py in wrapper(*args, **kwds)
433
434 with env_ctor(session=session):
--> 435 return f(*args, **kwds)
436
437 return wrapper
~\.conda\envs\lessons\lib\site-packages\rasterio\__init__.py in open(fp, mode, driver, width, height, count, crs, transform, dtype, nodata, sharing, **kwargs)
218 # None.
219 if mode == 'r':
--> 220 s = DatasetReader(path, driver=driver, sharing=sharing, **kwargs)
221 elif mode == "r+":
222 s = get_writer_for_path(path, driver=driver)(
rasterio\_base.pyx in rasterio._base.DatasetBase.__init__()
RasterioIOError: ./my_favorite_file.tif: No such file or directory
An Example#
Take a few minutes to debug the following block of code. Keep note of what strategies you use to find and fix errors.
How do you know when something isn’t working?
How do you decide what to try?
# Goal: Set a new value of 7 to the zenith then print the `rotated_zenith` value
# The output value should be 97.
metadata = {
'location': 'Nairobi',
'quality_flag': 5
'zenith': 60,
'clouds': True,
'data_center': ['LPDAAC', 'ASDC'],
}
metadata['Zenith"] == '7'
rotated_zenith = metadata['zenith'] + 90
print(rotated_zenith)
File "<ipython-input-4-780111995053>", line 6
'zenith': 60,
^
SyntaxError: invalid syntax
Example 2 (pandas)#
import pandas as pd
# Import example WAS data
was_2020_filepath = "./data/SARP 2020 final.xlsx"
was_2020 = pd.read_excel(was_2020_filepath, "INPUT", skipfooter=7)
was_2020['Box'] = was_2020['Box'].astype(str)
The goal of the following piece of code is to show all ~20 rows where CH4 was greater than 1 from box 37.
was_2020[(was_2020['Box'] == 37) & (was_2020['CH4 (ppmv height)'] > 1)]['i-Pentane (E/B)'].plot())
File "<ipython-input-55-2c466c8d93fe>", line 1
was_2020[(was_2020['Box'] == 37) & (was_2020['CH4 (ppmv height)'] > 1)]['i-Pentane (E/B)'].plot())
^
SyntaxError: unmatched ')'
3) Reading Documentation#
Remembering arguments (args
) and keyword arguments (kwargs
)#
pollutants = ['co', 'co2', 'no2', 'o3']
# 'ch4' is an argument
pollutants.append('ch4')
# reverse=False is a key word argument
pollutants.sort(reverse=False)
pollutants
['ch4', 'co', 'co2', 'no2', 'o3']
Example with rasters: matplotlib.plot.imshow
#
import matplotlib.pyplot as plt
matrix = np.array([[3, 5, 7], [0, np.nan, 10], [np.nan, 4, 4]])
print(matrix)
[[ 3. 5. 7.]
[ 0. nan 10.]
[nan 4. 4.]]
plt.imshow(matrix)
<matplotlib.image.AxesImage at 0x2a0e29dc610>
plt.imshow(matrix, cmap='BuGn')
<matplotlib.image.AxesImage at 0x2a0e19bf100>
Example with pandas
: .plot.scatter()
#
import pandas as pd
# Import example WAS data
was_2020_filepath = "./data/SARP 2020 final.xlsx"
was_2020 = pd.read_excel(was_2020_filepath, "INPUT", skipfooter=7)
was_2020.plot.scatter(x='i-Butane (E/B)', y='n-Butane (E/B)')
<AxesSubplot:xlabel='i-Butane (E/B)', ylabel='n-Butane (E/B)'>