Previous Lecture Lecture 4 Next Lecture

Lecture 4, Tue 10/13

Exception Handling, Python Classes

Recorded Lecture: 10_13_20

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. Enter a int: ")
    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 - enter an int: ")
    except Exception:
        print("Input was not a number type. Enter a int: ")
    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()
    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...")

Python Objects and Classes

>>> x = [1,2,3]
>>> type(x)
<class 'list'>
>>> x.count(3)
1
>>> x.count(-1)
0
>>> x.append(0)
>>> x
[3, 2, 1, 0]

Student Class Example

class Student:
    ''' Student class type that contains attributes for all students '''
    def setName(self, name):
        self.name = name

    def setPerm(self, perm):
        self.perm = perm

    def printAttributes(self):
        print("Student name: {}, perm: {}" \
        .format(self.name, self.perm))

s = Student()
s.setName("Chris Gaucho")
s.setPerm(1111111)
s.printAttributes()

Default Constructor

def __init__(self):
    self.name = None
    self.perm = None

s = Student()
s.printAttributes()

Overloading Constructors

def __init__(self, name, perm):
    self.name = name
    self.perm = perm

s = Student("Richert", 1234567)
s.printAttributes()

Initializing default values in the constructor

def __init__(self, name=None, perm=None):
        self.name = name
        self.perm = perm
s = Student(perm=1234567)
s.printAttributes()

# Student name: None, perm: 1234567

Example of using objects in code

s1 = Student("Jane", 1234567)
s2 = Student("Joe", 7654321)
s3 = Student("Jill", 5555555)

studentList = [s1, s2, s3]

for s in studentList:
    s.printAttributes()

Let’s write some tests!!

# student_test.py
from Student import Student

def test_defaultStudentCreation():
    s1 = Student()
    assert s1.name == None
    assert s1.perm == None

def test_normalStudentCreation():
    s1 = Student("Richert", 1234567)
    s2 = Student("Gaucho", 7654321)

    assert s1.name == "Richert"
    assert s1.perm == 1234567
    assert s2.name == "Gaucho"
    assert s2.perm == 7654321

def test_variableStudentAttributes():
    s1 = Student(perm=5555555)
    s2 = Student("Gaucho")

    assert s1.name == None
    assert s1.perm == 5555555
    assert s2.name == "Gaucho"
    assert s2.perm == None