Previous Lecture Lecture 4 Next Lecture

Lecture 4, Thu 01/18

Container Classes and Errors

Slides folder

Plan for today

Administrative notes

See slides for more information

Understanding container class attributes

Previously, we defined a custom class Courses, which contained Student instances.

It is important to understand and keep track of the types of the different object attributes:

UCSBCourses = Courses()

s1 = Student("Chris Gaucho", 1234567)
s2 = Student("Wilma Gaucho", 2345678)
s3 = Student("Mickey Mouse", 3456789)

UCSBCourses.addStudent("CS9", s1)
UCSBCourses.addStudent("CS9", s2)
UCSBCourses.addStudent("CS8", s3)

We can visualize the resulting object in PythonTutor: https://pythontutor.com/render.html#mode=edit

Shallow vs. Deep Equality

s1 = Student("Jane", 1234567)
s2 = Student("Jane", 1234567)
print(s1 == s2) # False, doesn’t compare values!
# Add the __eq__ method in Student.py

# s1 == s2, self is the left operand (s1), rhs is the right operand (s2)
def __eq__(self, rhs):
	return self.perm == rhs.perm
s1 = Student("Jane", 1234567)
s2 = Student("Jane", 1234567)
print(s1 == s2) # True, compares the perm values!

Python Errors

print("Start")

PYTHON!

print( Hello )
print("Start")
print( Hello )
Traceback (most recent call last):
  File "/Users/admin/Desktop/UCSB/CS9/lecture.py", line 5, in <module>
    print( Hello )
NameError: name 'Hello' is not defined

Exceptions

print("Start")
print (1/0)
Traceback (most recent call last):
  File "/Users/admin/Desktop/UCSB/CS9/lecture.py", line 5, in <module>
    print( 1/0 )
ZeroDivisionError: division by zero
print("Start")
print (‘5’ + 5)
Traceback (most recent call last):
  File "/Users/admin/Desktop/UCSB/CS9/lecture.py", line 5, in <module>
    print( '5' + 5 )
TypeError: can only concatenate str (not "int") to str

Handling Exceptions

The general rule of exception handling is:

while True:
	try:
		x = int(input("Enter an int: ")) # input() prompts user for input
		break # breaks out of the current loop
	except Exception:
		print("Input was not a number type")
	print("Let's try again...")
print(x)
print("Resuming execution")

The flow of execution is:

Catching Multiple Exceptions

Let’s slightly modify our code so another type of exception (ZeroDivisionError) may happen (in addition to entering a non-int type):

while True:
	try:
		x = int(input("Enter an int: "))
		print(x/0)
		break
	except ZeroDivisionError:
		print("Can't divide by zero")
	except Exception:
		print("Input was not a number type")
	print("Let's try again...")
print("Resuming execution")

Example of functions raising exceptions that are caught by the caller

def divide(numerator, denominator):
	if denominator == 0:
		raise ZeroDivisionError() # Change to ValueError() and observe
	return numerator / denominator

try:
	print(divide(1,1))
	print(divide(1,0))
	print(divide(2,2)) # Notice this doesn’t get executed
except ZeroDivisionError:
	print("Error: Cannot divide by zero")

print("Resuming Execution...")

Testing

Complete Test

Test Driven Development (TDD)

  1. Write test cases that describe what the intended behavior of a unit of software should. Similar to the requirements of any piece of software.
  2. Implement the details of the functionality with the intention of passing the tests - initially all tests should fail.
  3. Repeat until the tests pass.