Debugging¶
Errors
Syntax
Exceptions
try
/except
Now that we’re writing functions, debugging will become really critical.
Clicker Question #1¶
Will I be able to define and execute this function?
def example_function(input_list):
running_sum = 0
for item in input_list:
running_sum = running_sum + item
special_value = input_list[3]
return running_sum + special_value
A) Yes
B) No
C) Depends on the
input_list
D) There’s no way to tell
E) I don’t know
### executing the function
example_function(['a','b','c','d'])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-4-86157b94336b> in <module>()
1 ### executing the function
----> 2 example_function(['a','b','c','d'])
<ipython-input-1-a4fb5262d9d1> in example_function(input_list)
3 running_sum = 0
4 for item in input_list:
----> 5 running_sum = running_sum + item
6
7 special_value = input_list[3]
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Errors¶
Syntax Errors¶
Syntax Errors
Indentation Errors
Syntax Error Examples¶
# will produce a syntax error
if True
print('Yep.')
File "<ipython-input-5-a91490a26c37>", line 2
if True
^
SyntaxError: invalid syntax
Python does its best to tell you:
what type of error it is
and where it thinks it occurred (
^
)
# will produce a syntax error
# and specifically an indentation error
my_list = [1, 2]
for value in my_list:
print(value)
File "<ipython-input-6-45596487aa45>", line 5
print(value)
^
IndentationError: expected an indented block
Python gives you a readout about what it was expecting and where you appear to have gone wrong.
Exceptions¶
For these, there’s nothing wrong with the syntax or structure of the code, but in your specific case and how you’re trying to use it, Python says ‘no’.
ZeroDivisionError¶
ZeroDivisionError occurs when you try to divide by zero.
# produces ZeroDivisionError
1 / 0
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-7-79e900a17bd3> in <module>()
1 # produces ZeroDivisionError
----> 2 1 / 0
ZeroDivisionError: division by zero
Python specifies:
the Exception and specific type / error
points you to where the error occurred
NameError¶
NameError occurs when you try to access a name that Python does not know.
# Define a variable
variable = 12
# If you typo a name, you will get a NameError
varaible
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-9-4acade15292f> in <module>()
1 # If you typo a name, you will get a NameError
----> 2 varaible
NameError: name 'varaible' is not defined
While it’s annoying, it’s helpful that Python doesn’t just guess that you meant ‘variable’….because sometimes Python would guess wrong. It’s better for Python to just give us the error.
# You also get a name error if you try to use the wrong operator for assignment
new_variable == 1
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-10-4f05423dede6> in <module>()
1 # You also get a name error if you try to use the wrong operator for assignment
----> 2 new_variable == 1
NameError: name 'new_variable' is not defined
IndexError¶
IndexError occurs when you try to access an index that doesn’t exist.
my_list = [1, 2, 3]
my_list[5]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-11-2c2a83518cf2> in <module>()
1 my_list = [1, 2, 3]
----> 2 my_list[5]
IndexError: list index out of range
# Relatedly, 'KeyError' occurs if you ask for a dictionary key that doesn't exist
my_dictionary = {'name1' : 1, 'name2' : 2}
my_dictionary['name3']
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-12-84a1c00e4833> in <module>()
1 # Relatedly, 'KeyError' occurs if you ask for a dictionary key that doesn't exist
2 my_dictionary = {'name1' : 1, 'name2' : 2}
----> 3 my_dictionary['name3']
KeyError: 'name3'
ValueError¶
ValueError occurs when you try to use an illegal value for something.
int('cat')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-13-1c6b28888bbe> in <module>()
----> 1 int('cat')
ValueError: invalid literal for int() with base 10: 'cat'
my_list = [1, 2, 3]
my_list.remove(0)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-14-f00634ed638b> in <module>()
1 my_list = [1, 2, 3]
----> 2 my_list.remove(0)
ValueError: list.remove(x): x not in list
TypeError¶
'a_string' + 12
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-15-57c293ee5895> in <module>()
----> 1 'a_string' + 12
TypeError: can only concatenate str (not "int") to str
Error Recap¶
Syntax Errors
SyntaxError
IndentationError
Exceptions
ZeroDivisionError
NameError
Index Errors
IndexError
KeyError
ValueError
TypeError
Clicker Question #2¶
What type of error will the following code produce?
int('six')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-16-196d25768c28> in <module>()
----> 1 int('six')
ValueError: invalid literal for int() with base 10: 'six'
A) Syntax
B) Name
C) Type
D) Index
E) Value
Clicker Question #3¶
What type of error will the following code produce?
if num > 0
print("Greater than 0")
File "<ipython-input-19-ad228ac1793f>", line 1
if num > 0
^
SyntaxError: invalid syntax
A) Syntax
B) Name
C) Type
D) Index
E) Value
Clicker Question #4¶
What type of error will the following code produce?
if num > 0:
print("Greater than 0")
A) Syntax
B) Name
C) Type
D) Index
E) Value
Stack Trace¶
The trace (log) of what Python did as it went through your code. Gets printed out if Python runs into an error.
running_sum = 0
my_list = [1, 2, 3, 4, 5]
for val in my_list:
if val % 2 == 0:
temp = val / (val - 4)
#+= allows you to add the value on the right to the variable on the left
# and assign it to the variable on the left
running_sum += temp
# equivalent to:
# running_sum = running_sum + temp
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-20-215726ba149c> in <module>()
5
6 if val % 2 == 0:
----> 7 temp = val / (val - 4)
8 #+= allows you to add the value on the right to the variable on the left
9 # and assign it to the variable on the left
ZeroDivisionError: division by zero
Sometimes these get really complex. We’re here to get better at interpreting these traces.
Note that if external functions are being used, these will get longer.
Try / Except¶
Try / Except Block¶
# Try / Except Block
try:
# Tries to do this code
pass # pass just says is not an operation; carry on
except:
# If there is an error (an exception), keep going and do this instead
pass
Try / Except Example¶
# Example: we want to get an input number from the user
my_num = input("Please type a number: ")
print('\nmy_num is: ', my_num)
Please type a number: asdlfjk
my_num is: asdlfjk
Example with Try / Except¶
try:
int(input('Number'))
except:
print("nahhh")
Number7
Try / Except within a While Loop¶
input("text")
textasdlfkj
'asdlfkj'
ask_for_num = True
while ask_for_num:
try:
my_num = int(input("Please enter a number: "))
ask_for_num = False
except ValueError:
print("Oops! That was no valid number. Try again!")
print('\nmy_num is: ', my_num)
Please enter a number: asdfasdf;lkj
Oops! That was no valid number. Try again!
Please enter a number: 5
my_num is: 5
More Try / Except¶
# define a function divide
def divide(num1, num2):
return num1 / num2
print(divide(2, 0))
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-27-0cdf54a076ec> in <module>()
----> 1 print(divide(2, 0))
<ipython-input-26-62d4f4a69b89> in divide(num1, num2)
1 # define a function divide
2 def divide(num1, num2):
----> 3 return num1 / num2
ZeroDivisionError: division by zero
# define a function safe_divide
def safe_divide(num1, num2):
try:
output = num1 / num2
except ZeroDivisionError:
output = None
return output
print(safe_divide(2, 0))
None
Raising Errors¶
Raise Exception Examples¶
raise
is a keyword that tells Python you want to create your own error.
my_int = input('An integer please: ')
if not my_int.isnumeric():
raise ValueError('I wanted a number! :(')
print('My integer is: ', my_int)
An integer please: asdf;ajsdf
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-30-df6803c14de3> in <module>()
1 my_int = input('An integer please: ')
2 if not my_int.isnumeric():
----> 3 raise ValueError('I wanted a number! :(')
4
5 print('My integer is: ', my_int)
ValueError: I wanted a number! :(
Clicker Question #5¶
Edit the code below (replacing ---
with either values or variable names) so that when executed, this cell returns None
.
num1 = 7
num2 = 0
try:
output = num1 / num2
except ZeroDivisionError:
output = None
print(output)
None
A) I did it!
B) I think I did it…
C) I’m totally lost.