Developed by Mark Bakker
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
It happens to anyone writing code: occasionally, you make errors. It is accepted knowledge that every 1000 lines of code contain 15-50 errors (see for example here). Errors in your code, known as bugs, can be roughly divided in two kinds. The first kind are syntax errors, where Python throws an error message at you. Once you have resolved all the syntax errors, this means your code will run, but it doesn't mean, unfortunately, that you get the answer you want. There may be one or more bugs remaining in your logic. To find these bugs, it often helps to test small parts of the code separately and to write lots of print statements. There also exist tools called debuggers, which help you in stepping through the code to look at intermediate results. They do not, unfortunately, tell you what the bug is, that is still up to you, the programmer.
In this Notebook, we will discuss a number of syntax errors. Syntax errors can be very long as they provide a traceback from the function that throws the error all the way back to the code that you wrote. The strategy to find out what is going on is to read the last sentence of the error message. This error message is designed to tell you what you are doing wrong. Sometimes it is easy for Python to figure out what is wrong and the error message is very informative. Other times you make a more confusing error and Python throws an error message that doesn't help much in explaining what you did wrong. A second important piece of information is that Python shows you in what line of your code things went haywire. It prints a few lines of your code to the screen and points to the line where it thinks the error occurred with an arrow.
This Notebook is by no means exhaustive. A number of syntax errors are discussed so that you may start recognizing them and give you some practice in trying to resolve errors.
IndexError: list index out of range
¶As a first example, run the code below
x = [1, 2, 3]
for i in range(4):
print(x[i])
1 2 3
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-2-939bc4ef1842> in <module>() 1 x = [1, 2, 3] 2 for i in range(4): ----> 3 print(x[i]) IndexError: list index out of range
You will get an error message IndexError: list index out of range
and an arrow at the line of the code where this happened. This makes immediate sense, as the length of the array x
is 3 (so x[0]
, x[1]
, and x[2]
), while you are trying to print x[3]
. Fix the code and run it again.
invalid syntax
¶A common error message is invalid syntax
. This means you are trying to do something that Python doesn't understand. This could very well be a typo, which you can often spot by looking carefully at the code. For example, run the code below.
x = np.linspac(0, 10, 20)
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-3-275b52736b82> in <module>() ----> 1 x = np.linspac(0, 10, 20) AttributeError: module 'numpy' has no attribute 'linspac'
Apparently, the numpy
package doesn't have a function linspac
, which is correct, as it is called linspace
. Fix the code and run it again. Here is another syntax error that might be a bit harder to spot:
a = 7
if a = 8:
print('the value of a equals 8')
File "<ipython-input-4-de9aedde59b3>", line 2 if a = 8: ^ SyntaxError: invalid syntax
In this case, the error is that the statement a = 8
needs to have two equal signs. Fix it and run the code again.
You can also get an invalid syntax
error when you forget, for example, to add a colon after an if
statement. Python shows with the carrot (^
) where it doesn't understand what is going on.
avalue = 7
if avalue < 10
print('the value of avalue is smaller than 10')
File "<ipython-input-5-ecf569580769>", line 2 if avalue < 10 ^ SyntaxError: invalid syntax
Fix the bug and run the code again.
Other times, the syntax error may not be so obvious, for example, in the code below
plt.plot([1,2,3]
plt.title('Nice plot')
File "<ipython-input-6-5c88173b61a8>", line 2 plt.title('Nice plot') ^ SyntaxError: invalid syntax
You can stare all you want at the line plt.title('Nice plot')
but it looks perfectly good. And it is! The problem lies with the line just above it, where the closing parenthesis is missing. Python thinks that the plotting statement continuous on the next line, but the plt.title
command makes no sense in the plt.plot
function, so it throws an error message. There is not much else it can do. Fix the parenthesis and run the code again.
Error messages can be rather long, depending on where in the code the error occurs. In the code below, the error occurs in the line plt.plot(xdata, ydata)
, which calls a function in the matplotlib
package, which throws the error when it tries to plot y
vs. x
(which is a generic error message from matplotlib
; it doesn't substitute the names of the arrays you really want to plot). Run the code
def func_exp(x, a=2, b=3):
y = b * np.exp(-a * x)
xdata = np.linspace(0, 4, 10)
ydata = func_exp(xdata, b=4, a=1)
plt.plot(xdata, ydata);
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-7-9c1bb5c801bd> in <module>() 5 ydata = func_exp(xdata, b=4, a=1) 6 ----> 7 plt.plot(xdata, ydata); //anaconda/envs/python3/lib/python3.6/site-packages/matplotlib/pyplot.py in plot(*args, **kwargs) 3356 mplDeprecation) 3357 try: -> 3358 ret = ax.plot(*args, **kwargs) 3359 finally: 3360 ax._hold = washold //anaconda/envs/python3/lib/python3.6/site-packages/matplotlib/__init__.py in inner(ax, *args, **kwargs) 1853 "the Matplotlib list!)" % (label_namer, func.__name__), 1854 RuntimeWarning, stacklevel=2) -> 1855 return func(ax, *args, **kwargs) 1856 1857 inner.__doc__ = _add_data_doc(inner.__doc__, //anaconda/envs/python3/lib/python3.6/site-packages/matplotlib/axes/_axes.py in plot(self, *args, **kwargs) 1525 kwargs = cbook.normalize_kwargs(kwargs, _alias_map) 1526 -> 1527 for line in self._get_lines(*args, **kwargs): 1528 self.add_line(line) 1529 lines.append(line) //anaconda/envs/python3/lib/python3.6/site-packages/matplotlib/axes/_base.py in _grab_next_args(self, *args, **kwargs) 404 this += args[0], 405 args = args[1:] --> 406 for seg in self._plot_args(this, kwargs): 407 yield seg 408 //anaconda/envs/python3/lib/python3.6/site-packages/matplotlib/axes/_base.py in _plot_args(self, tup, kwargs) 364 # downstream. 365 if any(v is None for v in tup): --> 366 raise ValueError("x and y must not be None") 367 368 kw = {} ValueError: x and y must not be None
Again, the code looks perfectly fine, but the plt.plot
function complains that x and y must not be None
. Note that x
and y
refer to xdata
and ydata
, because the plotting statement in the code is plt.plot(xdata, ydata)
. Apparently, either xdata
or ydata
equals None
. The thing to do here is to print xdata
and ydata
to the screen.
print(xdata)
print(ydata)
[0. 0.44444444 0.88888889 1.33333333 1.77777778 2.22222222 2.66666667 3.11111111 3.55555556 4. ] None
As you see, it turns out that xdata
is indeed an array with 10 values, but ydata
is None
. The error lies in the function func_exp
that is defined. This function doesn't return the value of y
that is computed. Fix the function and run the code again.
The best way to learn how to resolve errors in your code is by practice. Consider the following code snippets. Each code snippet contains one or two syntactical errors. It is up to you to fix the error so that the code runs properly. Note that you will need to make changes to only one or two lines in each code snippet.
y = (xvalues + 2) * (xvalues - 1) * (xvalues - 2)
xvalues = linspace(-3, 3, 100)
plt.plot(xvalues, y, 'r--')
plt.plot([-2, 1, 2], [0 ,0, 0], 'bo', markersize=10)
plt.xlabel('x-axis')
plt.ylabel('y-axis')
plt.title('Nice Python figure!')
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-9-73c433d8600b> in <module>() ----> 1 y = (xvalues + 2) * (xvalues - 1) * (xvalues - 2) 2 xvalues = linspace(-3, 3, 100) 3 plt.plot(xvalues, y, 'r--') 4 plt.plot([-2, 1, 2], [0 ,0, 0], 'bo', markersize=10) 5 plt.xlabel('x-axis') NameError: name 'xvalues' is not defined
def test(x, alpha):
return np.exp(-alpha * x) * np.cos(x)
x = np.linspace(0, 10np.pi, 100)
alpha = 0.2
y = test(x)
plt.plot(x, y, 'b')
plt.xlabel('x')
plt.ylabel('f(x)')
File "<ipython-input-10-eb70911b1035>", line 3 x = np.linspace(0, 10np.pi, 100) ^ SyntaxError: invalid syntax
temperature = np.loadtxt('rome_temp.txt')
plt.plot(np.arange(1, 13), temperature, 'k--')
for i in range(len(temperature)):
if temperature[i] < 15:
plt.plot(i + 1, temperature[i], 'bo')
else
plt.plot(i + 1, temperature[i], 'ro')
plt.xlim(1, 12)
plt.xlabel('month')
plt.ylabel('temperature (Celcius)')
File "<ipython-input-11-d7828d04fa92>", line 6 else ^ SyntaxError: invalid syntax
a = np.array([2, 2, 4, 2, 4, 4])
for i in range(a):
if a[i] < 3: # replace value with 77 when value equals 2
a[i] = 77
else: # otherwise replace value with -77
a[i] = -77
print('modified a:' a)
File "<ipython-input-12-73ea85813afe>", line 8 print('modified a:' a) ^ SyntaxError: invalid syntax
y = np.zeros(20, 20)
y[8:13] = 10
plt.matshow(y)
plt.title(image of array y);
File "<ipython-input-13-119f5b34cef4>", line 4 plt.title(image of array y); ^ SyntaxError: invalid syntax
xvalues = np.linspace(-3, 3, 100) # xvalues should be placed before y. linspace should be np.linspace
y = (xvalues + 2) * (xvalues - 1) * (xvalues - 2)
plt.plot(xvalues, y, 'r--')
plt.plot([-2, 1, 2], [0 ,0, 0], 'bo', markersize=10)
plt.xlabel('x-axis')
plt.ylabel('y-axis')
plt.title('Nice Python figure!');
def test(x, alpha):
return np.exp(-alpha * x) * np.cos(x)
x = np.linspace(0, 10 * np.pi, 100) # * between 10 and np.pi
alpha = 0.2
y = test(x, alpha) # forgot to pass alpha to test
plt.plot(x, y, 'b')
plt.xlabel('x')
plt.ylabel('f(x)');
temperature = np.loadtxt('rome_temp.dat') # rome_temp.dat
plt.plot(np.arange(1, 13), temperature, 'k--')
for i in range(len(temperature)):
if temperature[i] < 15:
plt.plot(i + 1, temperature[i], 'bo')
else: # add colon
plt.plot(i + 1, temperature[i], 'ro')
plt.xlim(1, 12)
plt.xlabel('month')
plt.ylabel('temperature (Celcius)');
a = np.array([2, 2, 4, 2, 4, 4])
for i in range(len(a)): # range(len(a)) i.o. range(a)
if a[i] < 3: # replace value with 77 when value equals 2
a[i] = 77
else: # otherwise replace value with -77
a[i] = -77
print('modified a:', a) # added comma
modified a: [ 77 77 -77 77 -77 -77]
y = np.zeros((20, 20)) # add parentheses around (20, 20)
y[8:13] = 10
plt.matshow(y)
plt.title('image of array y'); # add quotes around text string