Skip to content

Commit da60b36

Browse files
committed
Added error notebook and images
1 parent 878c8b0 commit da60b36

File tree

3 files changed

+295
-0
lines changed

3 files changed

+295
-0
lines changed

Python Lessons/Python/Errors.ipynb

Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# A Bit about Errors\n",
8+
"\n",
9+
"This short notebook is to briefly discuss some types of errors and give you some ideas on how to look for and fix your own. Or how to ask us for help :) \n",
10+
"Ultimately, there are three types of errors, two of which Python will give you warnings for, and the more elusive logical error."
11+
]
12+
},
13+
{
14+
"cell_type": "markdown",
15+
"metadata": {},
16+
"source": [
17+
"# Error Debugging\n",
18+
"\n",
19+
"During the workshop, you may well find that your code gets errors. If not, congratulations! But if you need help from us resolving it, here's what to do.\n",
20+
"\n",
21+
"Copy your error into the QnA chatbox, particularly the last two lines that show the erroring line, and the type/description of error. \n",
22+
"Then copy in your code as well, so we can see where the error might lie if it's not immediately visible in the error message itself. \n",
23+
"That's it! From there one of the helpers should be able to give you a hand no trouble :)\n",
24+
"\n",
25+
"Let's now talk a bit about some of the types of errors you're likely to see. Hopefully some of this gives you an idea about how to look for errors. Some will be extremely direct, some will require a bit of lateral thinking to see where you've gone wrong."
26+
]
27+
},
28+
{
29+
"cell_type": "markdown",
30+
"metadata": {},
31+
"source": [
32+
"# Syntax Errors\n",
33+
"\n",
34+
"This is the most basic type of error, meaning that you've typed something wrong and Python doesn't understand it."
35+
]
36+
},
37+
{
38+
"cell_type": "code",
39+
"execution_count": 1,
40+
"metadata": {},
41+
"outputs": [
42+
{
43+
"ename": "SyntaxError",
44+
"evalue": "invalid syntax (<ipython-input-1-17192a779b39>, line 1)",
45+
"output_type": "error",
46+
"traceback": [
47+
"\u001b[1;36m File \u001b[1;32m\"<ipython-input-1-17192a779b39>\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m while True print('Hello, world!')\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
48+
]
49+
}
50+
],
51+
"source": [
52+
"if True print('Hello, world!')"
53+
]
54+
},
55+
{
56+
"cell_type": "markdown",
57+
"metadata": {},
58+
"source": [
59+
"If you run the code above, you should get a `SyntaxError`. The parser will display the line that caused the issue and give a little pointer arrow at the first place it found the error. \n",
60+
"What this means is that the arrow points at the first thing *after* the broken syntax.\n",
61+
"\n",
62+
"Here, it's expecting a colon, new line, and indentation after the `if True` statement. So it gets to print, realises those are missing, and gives you an error."
63+
]
64+
},
65+
{
66+
"cell_type": "code",
67+
"execution_count": 4,
68+
"metadata": {},
69+
"outputs": [
70+
{
71+
"name": "stdout",
72+
"output_type": "stream",
73+
"text": [
74+
"Hello, world!\n"
75+
]
76+
}
77+
],
78+
"source": [
79+
"if True:\n",
80+
" print('Hello, world!')"
81+
]
82+
},
83+
{
84+
"cell_type": "markdown",
85+
"metadata": {},
86+
"source": [
87+
"# Exceptions\n",
88+
"\n",
89+
"Something can be correct grammatically (as far as Python grammar is concerned) but still not valid, and give you a different type of error. \n",
90+
"There are way too many to discuss here, but I'll discuss a few of the more common examples that you're likely to run into.\n",
91+
"\n",
92+
"**NameError**: when a referenced name is not defined. You'll often see this by mistyping a variable name, or only defining it in a condition or function but using it elsewhere.\n",
93+
"\n",
94+
"**TypeError**: occurs when you try to perform an operation on something that is not the expected type. For example, you can 'add' strings to each other, and you can add integers together, but you can't add strings and integers together.\n",
95+
"\n",
96+
"**IndentationError**: when an indentation is expected but not present. The pointer will point directly at the thing that is indented incorrectly.\n",
97+
"\n",
98+
"**ZeroDivisionError**: don't divide by zero."
99+
]
100+
},
101+
{
102+
"cell_type": "code",
103+
"execution_count": 5,
104+
"metadata": {},
105+
"outputs": [
106+
{
107+
"ename": "NameError",
108+
"evalue": "name 'foo' is not defined",
109+
"output_type": "error",
110+
"traceback": [
111+
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
112+
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
113+
"\u001b[1;32m<ipython-input-5-9112f1c5a9f8>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mFalse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mfoo\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m8\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfoo\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
114+
"\u001b[1;31mNameError\u001b[0m: name 'foo' is not defined"
115+
]
116+
}
117+
],
118+
"source": [
119+
"# NameError: you can't print foo because I haven't defined foo. Even if that statement was sometimes True, you'd get an error whenever it wasn't.\n",
120+
"if False:\n",
121+
" foo = 8\n",
122+
"print(foo)\n",
123+
"\n",
124+
"# This could be really subtle, though. If I tried to `print(graphlookup)` when I've only defined `graphLookup` I will get a NameError.\n",
125+
"# Talking from experience there! Keep an eye on your letter cases. This is why short variable names are easier to work with."
126+
]
127+
},
128+
{
129+
"cell_type": "code",
130+
"execution_count": 6,
131+
"metadata": {},
132+
"outputs": [
133+
{
134+
"ename": "TypeError",
135+
"evalue": "can only concatenate str (not \"int\") to str",
136+
"output_type": "error",
137+
"traceback": [
138+
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
139+
"\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
140+
"\u001b[1;32m<ipython-input-6-59c862ee3b35>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# TypeError: adding strings and integers.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[1;34m'2'\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
141+
"\u001b[1;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str"
142+
]
143+
}
144+
],
145+
"source": [
146+
"# TypeError: adding strings and integers.\n",
147+
"'2' + 2"
148+
]
149+
},
150+
{
151+
"cell_type": "code",
152+
"execution_count": 8,
153+
"metadata": {},
154+
"outputs": [
155+
{
156+
"name": "stdout",
157+
"output_type": "stream",
158+
"text": [
159+
"dict_keys(['dictionary', 'two keys'])\n"
160+
]
161+
},
162+
{
163+
"ename": "TypeError",
164+
"evalue": "'dict_keys' object is not subscriptable",
165+
"output_type": "error",
166+
"traceback": [
167+
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
168+
"\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
169+
"\u001b[1;32m<ipython-input-8-2c7edd6281a7>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[0md\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m{\u001b[0m\u001b[1;34m'dictionary'\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'has keys and items'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'two keys'\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'two items'\u001b[0m\u001b[1;33m}\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0md\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mkeys\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0ma\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0md\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mkeys\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;31m# [0] should give the first key, 'dictionary', right?\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 5\u001b[0m \u001b[1;31m# Nope, the dict_keys object returned by d.keys() cannot be accessed in that way. TypeError.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
170+
"\u001b[1;31mTypeError\u001b[0m: 'dict_keys' object is not subscriptable"
171+
]
172+
}
173+
],
174+
"source": [
175+
"# Another TypeError: attempting to access a not-list object in a way that\n",
176+
"d = {'dictionary': 'has keys and items', 'two keys': 'two items'}\n",
177+
"print(d.keys())\n",
178+
"a = d.keys()[0] # [0] should give the first key, 'dictionary', right?\n",
179+
"# Nope, the dict_keys object returned by d.keys() cannot be accessed in that way. TypeError."
180+
]
181+
},
182+
{
183+
"cell_type": "code",
184+
"execution_count": 9,
185+
"metadata": {},
186+
"outputs": [
187+
{
188+
"ename": "ZeroDivisionError",
189+
"evalue": "division by zero",
190+
"output_type": "error",
191+
"traceback": [
192+
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
193+
"\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
194+
"\u001b[1;32m<ipython-input-9-1f9050bc5837>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# ZeroDivisionError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[1;36m10\u001b[0m\u001b[1;33m/\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
195+
"\u001b[1;31mZeroDivisionError\u001b[0m: division by zero"
196+
]
197+
}
198+
],
199+
"source": [
200+
"# ZeroDivisionError\n",
201+
"10/0"
202+
]
203+
},
204+
{
205+
"cell_type": "markdown",
206+
"metadata": {},
207+
"source": [
208+
"Python is pretty helpful here. It will point you exactly at what line is causing the error. If you're getting a NameError, check for typos and that the variable you're accessing is always defined. A TypeError suggests you haven't converted that integer to a string when you're trying to print it, perhaps. `str()` is your friend!"
209+
]
210+
},
211+
{
212+
"cell_type": "markdown",
213+
"metadata": {},
214+
"source": [
215+
"# Logical Errors"
216+
]
217+
},
218+
{
219+
"cell_type": "markdown",
220+
"metadata": {},
221+
"source": [
222+
"A logical error works a bit differently. These won't give you an exception and won't halt your program. They're syntactically correct, but an error on the part of the programmer that gives an unexpected result. An example:"
223+
]
224+
},
225+
{
226+
"cell_type": "code",
227+
"execution_count": 10,
228+
"metadata": {},
229+
"outputs": [
230+
{
231+
"name": "stdout",
232+
"output_type": "stream",
233+
"text": [
234+
"x is neither 1 nor 0\n"
235+
]
236+
}
237+
],
238+
"source": [
239+
"x = input(\"Enter 1 or 0\")\n",
240+
"if x == 1:\n",
241+
" print('x is 1')\n",
242+
"elif x == 0:\n",
243+
" print('x is 0')\n",
244+
"else:\n",
245+
" print('x is neither 1 nor 0')"
246+
]
247+
},
248+
{
249+
"cell_type": "markdown",
250+
"metadata": {},
251+
"source": [
252+
"This code will always say that 'x is neither 1 nor 0', no matter what you type. This is because `input()` saves the response as a string, but the `if` statements are checking that x is equal to the integer 1 or 0. The code will run but it won't give the output you're expecting, making it a logical error. \n",
253+
"\n",
254+
"\n",
255+
"Here's a real-life example from my own work:"
256+
]
257+
},
258+
{
259+
"cell_type": "markdown",
260+
"metadata": {},
261+
"source": [
262+
"<img src=\"images/lowercaseName.png\" alt=\"A code snippet, showing a database fetch method referring to a field called 'name'. It has a lowercase n.\" />\n",
263+
"\n",
264+
"This code works fine to fetch database objects, and is grammatically correct, but in this case it's not going to find any ancestors, and just completely not work, because it's looking for a field that doesn't exist! Note the case of the 'n' in each image.\n",
265+
"\n",
266+
"<img src=\"images/uppercaseName.png\" alt=\"Database objects with the 'Name' attributed highlighted. It has an upper case N.\" /> "
267+
]
268+
}
269+
],
270+
"metadata": {
271+
"interpreter": {
272+
"hash": "b859d9bcf8d7d89e11e38465defecfc8ebdb585d978d9823e0b6eeac5dc038a0"
273+
},
274+
"kernelspec": {
275+
"display_name": "Python 3.8.3 32-bit",
276+
"language": "python",
277+
"name": "python3"
278+
},
279+
"language_info": {
280+
"codemirror_mode": {
281+
"name": "ipython",
282+
"version": 3
283+
},
284+
"file_extension": ".py",
285+
"mimetype": "text/x-python",
286+
"name": "python",
287+
"nbconvert_exporter": "python",
288+
"pygments_lexer": "ipython3",
289+
"version": "3.8.3"
290+
},
291+
"orig_nbformat": 4
292+
},
293+
"nbformat": 4,
294+
"nbformat_minor": 2
295+
}
15.5 KB
Loading
10.6 KB
Loading

0 commit comments

Comments
 (0)