<jupyter_start><jupyter_text>Exploratory Computing with Python*Developed by <NAME>*  Notebook<jupyter_code>import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline<jupyter_output><empty_output><jupyter_text>It happens to anyone writing code: occasionally, you make errors. 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, unfortunatley, 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 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<jupyter_code>x = [1, 2, 3]
for i in range(4):
    print(x[i])<jupyter_output><empty_output><jupyter_text>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<jupyter_code>a = 7 
if a = 8:
    print('the value of a equals 8')<jupyter_output><empty_output><jupyter_text>Similarly, if you forget to add a colon, you get a `invalid syntax` error. Python shows with the carrot (`^`) where it doesn't understand what is going on.<jupyter_code>avalue = 7 
if avalue < 10
    print('the value of avalue is smaller than 10')<jupyter_output><empty_output><jupyter_text>In this case, the error is that the statement `a = 8` needs to have two equal signs. Fix it and run the code again.  Other times, the syntax error may not be so obvious, for example, in the code below<jupyter_code>plt.plot([1,2,3]
plt.title('Nice plot')<jupyter_output><empty_output><jupyter_text>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.   Longer error messagesError messages can be rather long, depending 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<jupyter_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);<jupyter_output><empty_output><jupyter_text>Again, the code looks perfectly fine, but `matplotlib` complains that `x and y must not be None`. Note that `x` and `y` refer to `xdata` and `ydata`, because that is the statement in the code. Apparently, either `xdata` or `ydata` equals `None`. The thing to do here is to print `xdata` and `ydata` to the screen.<jupyter_code>print(xdata)
print(ydata)<jupyter_output><empty_output><jupyter_text>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.   ExercisesThe 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.   Exercise 1<jupyter_code>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!')<jupyter_output><empty_output><jupyter_text>Answer to Exercise 1  Exercise 2<jupyter_code>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)')<jupyter_output><empty_output><jupyter_text>Answer to Exercise 2  Exercise 3<jupyter_code>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)')<jupyter_output><empty_output><jupyter_text>Answer to Exercise 3  Exercise 4<jupyter_code>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)<jupyter_output><empty_output><jupyter_text>Answer to Exercise 4  Exercise 5<jupyter_code>y = np.zeros(20, 20)
y[8:13] = 10
plt.matshow(y)
plt.title(image of array y);<jupyter_output><empty_output><jupyter_text>Answers to the exercises Answer to Exercise 1<jupyter_code>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!');<jupyter_output><empty_output><jupyter_text>Back to Exercise 1Answer to Exercise 2<jupyter_code>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)');<jupyter_output><empty_output><jupyter_text>Back to Exercise 2Answer to Exercise 3<jupyter_code>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)');<jupyter_output><empty_output><jupyter_text>Back to Exercise 3Answer to Exercise 4<jupyter_code>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<jupyter_output><empty_output><jupyter_text>Back to Exercise 4Answer to Exercise 5<jupyter_code>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<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10308450865726408, 'fraction_numerical': 0.019837174635936247, 'mean_word_length': 4.5660497766432675, 'pattern_counts': {'":': 0, '<': 75, '<?xml version=': 0, '>': 70, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '17', 'dir': 'jupyter-structured-clean-dedup', 'id': '194418', 'license': 'CNRI-Python', 'n_tokens_mistral': 3003, 'n_tokens_neox': 2787, 'n_words': 1197, 'path': 'src/exploratory_py/notebook7_bugs/py_exploratory_comp_7.ipynb', 'repo_name': 'c-w-m/learning_python', 'size': '8726'}