Debugging

CSCI 1012

Announcements

  • Homework 11 (debugging) is due Sunday, 13 Apr 11:55 PM
  • Next week (4/14): Modules and Classes
  • Following week (4/21): Review
  • Unit 2 Exam is April 28 (in 3 weeks)
  • Optional Final Exam is May 5 (5:20-7:20pm)

In-Class Exercises

  • File names:
    • ex1.py
    • ex2.py
    • ex3.py
  • Turn in on the submit server before the end of lecture for credit
  • Turn in one .zip with all the .py files
    • Unlimited attempts during lecture
  • We’ll provide solutions – pay attention!

Common Errors

  • Incorrect file names:
    • check_even.py vs. checkEven.py
  • Incorrect function name
    • def check_even(x): vs. def check_evens(x):
  • Spacing errors
    • 1 2 3 vs. 1 2 3

Read your autograder output!

Today

  • Debugging
    • Making sense of common errors
    • Using print statements to find mistakes

Strings

  • Ordered collections of characters
  • They are immutable
  • You can access elements using the syntax s[INDEX] (where s is the string and INDEX is the integer index you are trying to access)
  • You can loop over them

Lists

  • Ordered collections of items
  • They are mutable
  • You can access elements using the syntax L[INDEX] (where L is hte list and INDEX is the integer index you are trying to access)
  • You can loop over them
  • Contents can include: ints, floats, lists, dictionaries, tuples, booleans, etc. and any combination thereof

Tuples

  • Ordered collections of items
  • They are immutable
  • You can access elements using T[INDEX] (where T is the tuple and INDEX is the integer index you are trying to access)
  • You can loop over them

Dictionaries

  • Unordered collections of key/value pairs
  • You can access them using the keys: D[KEY] (where KEY is the key whose value you are trying to access)
  • You can loop over them (but you can’t use range() syntax)
  • Keys: ints, floats, tuples, strings, but not lists or dictionaries (because they are mutable)
  • Values: can be anything we’ve seen so far, including ints, floats, tuples, booleans, strings, lists, dictionaries, etc.

Warmup: Exercise 1

Write a function ex1 that takes a list of integers as its only argument. Your function will return a dictionary with two keys: even whose value is a list of all of the even numbers in the input list (in the order they appeared), and odd whose value is a list of all of the odd numbers in the input list (in the order they appeared).

  • ex1([1,2,3,4]) returns {'even': [2, 4], 'odd': [1, 3]}
  • ex1([4,2,2,1]) returns {'even': [4, 2, 2], 'odd': [1]}
  • ex1([1,5,7,3]) returns {'even': [], 'odd': [1,5,7,3]}
  • ex1([]) returns {'even': [], 'odd': []}

Submit as ex1.py.

Debugging

  • Debugging: The process of finding and fixing errors (or bugs) in code so that it works as intended
  • Sometimes code will produce an error message.
    • These errors exist to help us find bugs
  • Other times, code won’t produce an error message, but will not give the correct answer

Common Errors


print("hello, world!')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  print("hello, world!')
        ^

SyntaxError: unterminated string literal (detected at line 1)
  • The error message tells us what’s wrong:
    • Python was reading a string
    • The string started with quotations of some sort
    • But Python never found the ending quotations
  • The carat ^ and line number tell us where in the code the error was found

Common Errors


z = 2
y == z + 4
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'y' is not defined


D = {'a': 1, 'e': 5, 'z': 26}
print(D[z])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'z' is not defined
  • We have tried to use the variables y and z before assigning anything to them
  • For y, we should define it first, or change == to = (depending on what we want to do)
  • For z, we should use 'z' instead

Common Errors: Not Subscriptable


y = [4, 3, 2, 1]
print(len[y])
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: 'builtin_function_or_method' object is not subscriptable
  • We have tried to index something ([ ]) that can’t be indexed
  • len[y]: Python trying to index len, but this can’t be interpreted logically
    • Should be len(y)

Common Errors: Not Subscriptable

y = 2
x = y[0]
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: 'int' object is not subscriptable
  • We have tried to index something ([ ]) that can’t be indexed
  • x = y[0]: Python trying to access the 1st element of y
    • This works if y is a string, list, tuple, but can’t be interpreted when y is an int

Common Errors: Not Callable


t = (1, 2, 3, 4, 5)
print(t(0))
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: 'tuple' object is not callable
  • not callable means we tried to call something as if it were a function
    • t is not a function, it’s a tuple, so it can’t be called
    • Should be t[0] instead (i.e., square brackets, instead of parentheses)

Common Errors: Item Assignment


s = 'string'
s[0] = 'p'
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: 'string' object does not support item assignment


t = (1, 2, 3, 4)
t[0] = 2
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: 'tuple' object does not support item assignment
  • Strings and tuples are immutable

Common Errors: Key Errors

D = {'a': [4,3,2,1], 'b': [4, 1, 3]}
del D['b']
print(D['b'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'b'

Common Errors: IndexError


L = [1,2,4]
for i in range(len(L)):
  if L[i] > L[i+1]:
    print("The list is not in strictly ascending order")
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
IndexError: list index out of range
  • When we are in the last iteration of the for-loop, i is 2.
  • We try to compare L[i] (L[2]) against L[i+1] (L[3])`
  • But there is no 4th element in the list, so we get an index error
  • We are try to access something that does not exist

Tracebacks

  • Error messages in Python trace
def function_A(x, y):
  return function_B(x, y)

def function_B(x, y):
  return x + y

print(function_A('3', 1))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in function_a
  File "<stdin>", line 2, in function_b
TypeError: can only concatenate str (not "int") to str

In-class Exercise 2

Code is provided for the following prompt, but it doesn’t run. Your task is to edit it by testing the code, reading the error messages, and fixing the bugs. Submit your edited version as ex2.py.

Access the code

Write a function ex2 that takes one argument: a dictionary that has lists of integers as its values. Your function should return the maximum value in any of the lists. You may not use the built-in max function.

  • ex2({'hello': [2, 34, 5, 1, 0, 2], 'goodbye': [1, 2, 3, 99]}) returns 99.
  • ex2({'a': [2, 34], 'b': [1, 2], 'c': [-24]}) returns 34.

Example: Calculating total value in list

A = [3, 1, 0, 2, 3, 1]
total = 0
for j in A:
  total += A[j]
print("Final total is", total)

Example: Calculating total value in list of lists

def get_total(x):
  total = 0
  for L in x:
    for num in L:
      total += num
    return total

x = [[1,3], [0], [2,4]]
print("Final total is", get_total(x))

In-Class Exercise 3

Code is provided for the following prompt, but it doesn’t yield the intended answer. Your task is to edit it by testing the code, and using print statements to identify the issue(s). Submit your edited code as ex3.py.

Access the code

Write a function ex3 that takes one argument: a dictionary that has student names as keys and their grades (0-100) as integers. Your function should return the number of A’s in the class (as an int; where an A is defined as any grade 90 or above).

  • ex3({'Julie': 95, 'Anna': 99, 'Oscar': 85}) returns 2.
  • ex3({'Julie': 95, 'Anna': 99, 'Oscar': 95}) returns 3.
  • ex3({'Julie': 85, 'Anna': 79}) returns 0.

Summary: Debugging

  • Writing code with bugs (errors) is inevitable
  • Being able to test, diagnose, and identify bugs is an important part of programming
  • Error messages can help identify what the error is
  • The visualizer and print statements can help us track what the program is doing and find the line(s) where things go wrong.
  • When all else fails, sitting down and explaining it to someone else can help you find an error

Next week: Tuples & File System

  • Read Python for Data Analysis Chapter 4
    • Through “Boolean Indexing”