CS 112 Intro to Programming Exceptions

28
CS 112 Intro to Programming Exceptions George Mason University

description

CS 112 Intro to Programming Exceptions. George Mason University. Exception Handling: Basic Syntax. try : #watch for exceptions here try_suite except : #exception handling code except_suite. A piece of code that is potential to crash in runtime. 2. Exceptions Hierarchy. BaseException - PowerPoint PPT Presentation

Transcript of CS 112 Intro to Programming Exceptions

Page 1: CS 112 Intro to Programming Exceptions

CS 112Intro to Programming

Exceptions

George Mason University

Page 2: CS 112 Intro to Programming Exceptions

Exception Handling: Basic Syntax

try:#watch for exceptions

heretry_suite

except:#exception handling codeexcept_suite

2

A piece of code that is potential to crash in

runtime

Page 3: CS 112 Intro to Programming Exceptions

Exceptions Hierarchy

BaseException +-- KeyboardInterrupt +-- Exception +-- ArithmeticError | +-- ZeroDivisionError +-- EnvironmentError | +-- IOError +-- EOFError +-- LookupError | +-- IndexError | +-- KeyError +-- NameError +-- SyntaxError +-- SystemError +-- TypeError +-- ValueError

• There are many exception classes organized into a hierarchy→ using inheritance (parent and child class relationships)

(found at http://docs.python.org/3.2/library/exceptions.html )Whenever a runtime error occur in ‘try’, the ‘except’ will handle this

specific exception (event)

Page 4: CS 112 Intro to Programming Exceptions

Validating Input

e4.pyneed_input = Truewhile need_input: x = eval(input("#: ")) need_input = False

print ("successfully got x: "+str(x))

Loop continues to execute, raising and handling exceptions, until user

complies.

Page 5: CS 112 Intro to Programming Exceptions

Validating Input

e4.pyneed_input = Truewhile need_input: try: x = eval(input("#: ")) need_input = False except Exception as e: print(e)print ("successfully got x: "+str(x))

Loop continues to execute, raising and handling exceptions, until user

complies.demo$ python3 e4.py#: 5successfully got x: 5#: asdfname 'asdf' is not defined#: 3/0division by zero

Exception1

Exception2

Page 6: CS 112 Intro to Programming Exceptions

Exception HandlingThere are three basic choices when handling exceptions:

•handle it •defer it up the calling chain •do both: handle it, but also defer it to the caller.

Example:•if method A calls method B, and then B calls method C, and C raises an exception:

• C can handle it• C can defer it to B (the caller of C)

→ B, and in turn, A, then have the same choices• C can handle it and then re-raise it

6

Page 7: CS 112 Intro to Programming Exceptions

Exception Handling

7

Method A(Function A)

Method B

Method C

Exception(error)

I will handle it

Propagate(report the error)

Page 8: CS 112 Intro to Programming Exceptions

Validating Input

e4.pyneed_input = Truewhile need_input: try: x = eval(input("#: ")) need_input = False except Exception as e: print(e)print ("successfully got x: "+str(x))

Loop continues to execute, raising and handling exceptions, until user

complies.demo$ python3 e4.py#: 5successfully got x: 5#: asdfname 'asdf' is not defined#: 3/0division by zero

Exception1

Exception2

Page 9: CS 112 Intro to Programming Exceptions

Exception Handling

9

Method A

Method B

Method C

Exception

Ouch!

defer

I will handle it

Page 10: CS 112 Intro to Programming Exceptions

Deferring Exceptions

10

e12.pydef buggy (): x = int(input("#? ")) return 5/xdef main(): try: print(buggy()) except ZeroDivisionError as e: print("sadly, we cannot do zero division.")main()

demo$ python3 e12.py #? 100.5demo$ python3 e12.py #? 0sadly, we cannot do zero division.demo$ python3 e12.py #? asdfTraceback … ValueError…

• exception raised in buggy crashes (propagates) out to whatever called it: main, in this case.

• main catches the exception.

Page 11: CS 112 Intro to Programming Exceptions

Exception Handling

11

Method A

Method B

Method C

Exception

Ouch!

defer

I will handle itPropagate

(report the error)

Page 12: CS 112 Intro to Programming Exceptions

Exception Handling

12

Method A

Method B

Method C

Exception

I will handle some

Defer the rest

I will handle some

Defer the rest

Page 13: CS 112 Intro to Programming Exceptions

Deferring Some Exceptions

13

e13.pydef buggy (): try: x = int(eval(input("#? "))) return 5/x except ValueError as e: print ("didn't get an int!") return 0def main(): try: print(buggy()) except ZeroDivisionError as zde: print("sadly, we cannot do zero division.")main()

demo$ python3 e13.py#? 31.6666666666666667demo$ python3 e13.py#? "hello"didn't get an int!0demo$ python3 e13.py#? 0sadly, we cannot do zero division.demo$ #? (1,2,3)Traceback … TypeError…

• ValueErrors caught in buggy.• ZeroDivisionErrors propagated to main, caught there.• TypeErrors propagated all the way, crashing entire

program.

Page 14: CS 112 Intro to Programming Exceptions

Deferring - another example

14

e14.pydef find(): try: d = {1:'a',2:'b',3:'c'} v = int(input("#? ")) return d[6/v] except KeyError as verr: return "red herring"def main(): try: print(find()) except ZeroDivisionError as zde: print("sadly, we cannot do zero division.")main()

demo$ python3 e14.py#? 6ademo$ python3 e14.py#? 4red herringdemo$ python3 e14.py#? 0 sadly, we cannot do zero division.demo$ python3 e14.py#? asdfTraceback…ValueError…

• KeyError handled in find()• ZeroDivisionError deferred in find(), then handled in main()• ValueErrors unhandled.

Page 15: CS 112 Intro to Programming Exceptions

Exception Handling

15

Method A

Method B

Method C

Exception

I will handle some

Defer the rest

I will handle some

Defer the rest

If the exception is handled by C, then B

will not notice it

Verify the password

Count failed times

Login bank account

Page 16: CS 112 Intro to Programming Exceptions

Exception Handling

16

Method A

Method B

Method C

Exception

I will handle it

Re-raise

I will handle it, too

Verify the password

Count failed times

Login bank account

After the exception is handled by C, we will manually inform B

Page 17: CS 112 Intro to Programming Exceptions

Raising Exceptions• We can generate an exception on purpose

(and hopefully catch it somewhere else!)• done with a raise statement, which needs an

expression of some Exception type. This usually means calling a constructor (__init__). Examples:• raise Exception("boo!")

raise ArithmeticError ("this doesn't add up!")raise ValueError("needed a positive number")

• except IOError as e: print ("catching it, re-raising it.") raise e

Page 18: CS 112 Intro to Programming Exceptions

Exceptions Hierarchy

BaseException +-- KeyboardInterrupt +-- Exception +-- ArithmeticError | +-- ZeroDivisionError +-- EnvironmentError | +-- IOError +-- EOFError +-- LookupError | +-- IndexError | +-- KeyError +-- NameError +-- SyntaxError +-- SystemError +-- TypeError +-- ValueError

• There are many exception classes organized into a hierarchy→ using inheritance (parent and child class relationships)

(found at http://docs.python.org/3.2/library/exceptions.html )Build-in exception, everyone know what

they means

Page 19: CS 112 Intro to Programming Exceptions

Raising ExceptionsReusing/raising a few specific exception types is useful:• Exception for general issues (but a bit vague)• TypeError, when the supplied arg. was the

wrong type• ValueError when your code only should be run

on some batch of values and the wrong one was given

• Any of them can be reused if it suits your purpose, just call their constructor (see examples on previous slide)

Then you can raise them and catch them as before.→ but you can also make brand new types of exceptions!

Page 20: CS 112 Intro to Programming Exceptions

Re-raising the Same Exception

20

We can directly re-raise the caught exception object.• To force this exception propagate, since by default

exception only get handled once• No need to construct an exception value-we already

have an exception object.e15.pydef get_input(): try: return float(eval(input("#: "))) except ValueError as e: print("in get_input: "+str(e)) raise edef main(): try: print( get_input()) except (TypeError, ValueError) as e: print ("in main: "+str(e))main()

demo$ python3 e16.py#: 'a'in get_input: could not convert string to float: 'a'in main: could not convert string to float: 'a'

note the quotes!

Page 21: CS 112 Intro to Programming Exceptions

Re-raising Another Exceptions

21

• Initialize an exception ourselves• We want to customized the error

information to the caller

e15.pydef get_input(): try: return float(eval(input("#: "))) except ValueError as e: print("in get_input: "+str(e)) raise (ValueError("ERR"))def main(): try: print( get_input()) except (TypeError, ValueError) as e: print ("in main: "+str(e))main()

demo$ python3 e15.py #: 'asdf'in get_input: could not convert string to float: 'asdf'in main: ERRdemo$ python3 e15.py #: (1,2,3)in main: float() argument must be a string or a numberdemo$ python3 e15.py #: asdfTraceback…NameError…

note the quotes!

Page 22: CS 112 Intro to Programming Exceptions

Exception Handling

22

Method A

Method B

Method C

Exception

I will handle it

Re-raise

I will handle it, too

Verify the password

Count failed times

Login bank account

After the exception is handled by C, we will manually inform B

Page 23: CS 112 Intro to Programming Exceptions

Did you find initialization of an exception looks the same as initialization of an object of a class?Actually exceptions are just a kind of class:

Exceptions and Classes

e15.pydef get_input(): try: return float(eval(input("#: "))) except ValueError as e: print("in get_input: "+str(e)) raise (ValueError("ERR"))def main(): try: print( get_input()) except (TypeError, ValueError) as e: print ("in main: "+str(e))main()

Class (web page) Exception

Driven by user behavior

Driven by runtime error

Click a link or button

Through out an exception

Open a new web page

Initialize an exception object

Page 24: CS 112 Intro to Programming Exceptions

Exceptions Hierarchy

BaseException +-- KeyboardInterrupt +-- Exception +-- ArithmeticError | +-- ZeroDivisionError +-- EnvironmentError | +-- IOError +-- EOFError +-- LookupError | +-- IndexError | +-- KeyError +-- NameError +-- SyntaxError +-- SystemError +-- TypeError +-- ValueError

• There are many exception classes organized into a hierarchy→ using inheritance (parent and child class relationships)

(found at http://docs.python.org/3.2/library/exceptions.html )Inheritance relations

We usually define customized exception

as child class of build-in ones

Page 25: CS 112 Intro to Programming Exceptions

User-Defined ExceptionsWe can create our own types of exceptions.They can be raised, propagated, and caught just like any other exception types.

25

e10.pyclass Disallowed (Exception): def __init__(self, value): self.value = value

Page 26: CS 112 Intro to Programming Exceptions

26

e11.pyfrom e10 import Disallowedtry: x = int(input("#? ")) if x==13: raise Disallowed("that's unlucky!") print(x*10)except Disallowed as dis: print("uhoh: "+dis.value)except Exception as e: print(e)

demo$ python3 e11.py#? 550demo$ python3 e11.py#? 13uhoh: that's unlucky!demo$ python3 e11.py#? asdfinvalid literal for int() with base 10: 'asdf'

• raise keyword used with a call to our exception's constructor

• except-block used with our new type of exception

User-Defined Exceptions

Raise an exception just like:

If want to trigger this event, then raise this exception

Page 27: CS 112 Intro to Programming Exceptions

• A class can use exceptions within its methods, just like we've done before.

e17.pyclass LongNameException(Exception): def __init__(self, text="too long!"): self.text = text

class Artist(object): def __init__(self, name="None"): self.__name = name def set_name (self, name): try: if (len(name))>10: raise LongNameException() else: self.__name = name except LongNameException as e: print(e.text)

Example: using exception handling in

classes

demo$ python3 -i e17.py>>> alice = Artist()>>> alice.set_name("Alice Cooper")too long!

Page 28: CS 112 Intro to Programming Exceptions

e18.pyclass LongNameException(Exception): def __init__(self, text="too long!", data=""): self.text = text self.data = data

class Artist(object): def __init__(self, name="None"): self.__name = name def set_name (self, name): try: if (len(name))>10: raise LongNameException(data=(len(name))) else: self.__name = name except LongNameException as e: print(e.text+" ("+str(e.data)+")")

Example: using instance variables in exceptions

demo$ python3 -i e18.py>>> alice = Artist()>>> alice.set_name("Alice Cooper")too long! (12)

Our exceptions are objects, and they can

have/use instance variables like data.