exceptions copyright © software carpentry 2010 this work is licensed under the creative commons...

74
Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution Lice See http://software-carpentry.org/license.html for more informati Testing

Upload: ashley-craig

Post on 18-Jan-2018

222 views

Category:

Documents


0 download

DESCRIPTION

TestingExceptions Things go wrong External

TRANSCRIPT

Page 1: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Exceptions

Copyright © Software Carpentry 2010This work is licensed under the Creative Commons Attribution LicenseSee http://software-carpentry.org/license.html for more information.

Testing

Page 2: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Things go wrong

Page 3: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Things go wrongExternal

Page 4: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Things go wrongExternal– Missing or badly-formatted file

Page 5: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Things go wrongExternal– Missing or badly-formatted fileInternal

Page 6: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Things go wrongExternal– Missing or badly-formatted fileInternal– Bug in code

Page 7: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Things go wrongExternal– Missing or badly-formatted fileInternal– Bug in code

Page 8: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Things go wrongExternal– Missing or badly-formatted fileInternal– Bug in codeHandling errors sensibly is easy

Page 9: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Option #1: return status code

Page 10: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Option #1: return status codeparams, status = read_params(param_file)if status != OK: log.error('Failed to read', param_file) sys.exit(ERROR)

grid, status = read_grid(grid_file)if status != OK: log.error('Failed to read', grid_file) sys.exit(ERROR)

Page 11: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Option #1: return status code

This is what we really care about

params, status = read_params(param_file)if status != OK: log.error('Failed to read', param_file) sys.exit(ERROR)

grid, status = read_grid(grid_file)if status != OK: log.error('Failed to read', grid_file) sys.exit(ERROR)

Page 12: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Option #1: return status code

The rest is error handling

params, status = read_params(param_file)if status != OK: log.error('Failed to read', param_file) sys.exit(ERROR)

grid, status = read_grid(grid_file)if status != OK: log.error('Failed to read', grid_file) sys.exit(ERROR)

Page 13: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Hard to see the forest for the trees

Page 14: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Hard to see the forest for the trees

Expectedflow of control

Page 15: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Hard to see the forest for the trees

Expectedflow of control

Errorhandling

Page 16: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Hard to see the forest for the trees

Expectedflow of control

Errorhandling

So people don't even try to handle errors

Page 17: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Hard to see the forest for the trees

Expectedflow of control

Errorhandling

So people don't even try to handle errorsWhich makes them harder to find and fix whenthey do occur

Page 18: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Option #2: use exceptions

Page 19: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Option #2: use exceptionsSeparate "normal" operation from code thathandles "exceptional" cases

Page 20: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Option #2: use exceptionsSeparate "normal" operation from code thathandles "exceptional" casesMake both easier to understand

Page 21: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Rearrange this...

params, status = read_params(param_file)if status != OK: log.error('Failed to read', param_file) sys.exit(ERROR)

grid, status = read_grid(grid_file)if status != OK: log.error('Failed to read', grid_file) sys.exit(ERROR)

Page 22: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

...to put "normal" code in one place...

params, status = read_params(param_file)if status != OK: log.error('Failed to read', param_file) sys.exit(ERROR)

grid, status = read_grid(grid_file)if status != OK: log.error('Failed to read', grid_file) sys.exit(ERROR)

params = read_params(param_file) grid = read_grid(grid_file)

Page 23: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

...and error handling code in another

params, status = read_params(param_file)if status != OK: log.error('Failed to read', param_file) sys.exit(ERROR)

grid, status = read_grid(grid_file)if status != OK: log.error('Failed to read', grid_file) sys.exit(ERROR)

params = read_params(param_file) grid = read_grid(grid_file)

log.error('Failed to read', filename) sys.exit(ERROR)

Page 24: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

...and error handling code in another

params, status = read_params(param_file)if status != OK: log.error('Failed to read', param_file) sys.exit(ERROR)

grid, status = read_grid(grid_file)if status != OK: log.error('Failed to read', grid_file) sys.exit(ERROR)

Only need one copy of the error handling code

params = read_params(param_file) grid = read_grid(grid_file)

log.error('Failed to read', filename) sys.exit(ERROR)

Page 25: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Join the two parts with try and except

params, status = read_params(param_file)if status != OK: log.error('Failed to read', param_file) sys.exit(ERROR)

grid, status = read_grid(grid_file)if status != OK: log.error('Failed to read', grid_file) sys.exit(ERROR)

try: params = read_params(param_file) grid = read_grid(grid_file)except: log.error('Failed to read', filename) sys.exit(ERROR)

Page 26: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

You have seen exceptions before

Page 27: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

You have seen exceptions before>>> open('nonexistent.txt', 'r')IOError: No such file or directory: 'nonexistent.txt'

Page 28: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

You have seen exceptions before>>> open('nonexistent.txt', 'r')IOError: No such file or directory: 'nonexistent.txt'

>>> values = [0, 1, 2]>>> values[99]IndexError: list index out of range

Page 29: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Use try and except to deal with them yourself

Page 30: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Use try and except to deal with them yourself>>> try:... reader = open('nonexistent.txt', 'r')... except IOError:... print 'Whoops!'

Whoops!

Page 31: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Use try and except to deal with them yourself>>> try:... reader = open('nonexistent.txt', 'r')... except IOError:... print 'Whoops!'

Whoops! Blue indicates regular output

Page 32: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Use try and except to deal with them yourself>>> try:... reader = open('nonexistent.txt', 'r')... except IOError:... print 'Whoops!'

Whoops! Try to do this...

Page 33: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Use try and except to deal with them yourself>>> try:... reader = open('nonexistent.txt', 'r')... except IOError:... print 'Whoops!'

Whoops! ...and do this ifan IO error occurs

Page 34: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Use try and except to deal with them yourself

...and do this ifan IO error occurs'IOError' is how Pythonreports 'file not found'

>>> try:... reader = open('nonexistent.txt', 'r')... except IOError:... print 'Whoops!'

Whoops!

Page 35: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Can put many lines of code in a try block

Page 36: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Can put many lines of code in a try blockAnd handle several errors afterward

Page 37: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Can put many lines of code in a try blockAnd handle several errors afterward

try: params = read_params(param_file) grid = read_grid(grid_file) entropy = lee_entropy(params, grid) write_entropy(entropy_file, entropy)except IOError: log_error_and_exit('IO error')except ArithmeticError: log_error_and_exit('Arithmetic error')

Page 38: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Try to do this

try: params = read_params(param_file) grid = read_grid(grid_file) entropy = lee_entropy(params, grid) write_entropy(entropy_file, entropy)except IOError: log_error_and_exit('IO error')except ArithmeticError: log_error_and_exit('Arithmetic error')

Can put many lines of code in a try blockAnd handle several errors afterward

Page 39: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

try: params = read_params(param_file) grid = read_grid(grid_file) entropy = lee_entropy(params, grid) write_entropy(entropy_file, entropy)except IOError: log_error_and_exit('IO error')except ArithmeticError: log_error_and_exit('Arithmetic error')

Handle I/Oerrors here

Can put many lines of code in a try blockAnd handle several errors afterward

Page 40: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

try: params = read_params(param_file) grid = read_grid(grid_file) entropy = lee_entropy(params, grid) write_entropy(entropy_file, entropy)except IOError: log_error_and_exit('IO error')except ArithmeticError: log_error_and_exit('Arithmetic error')

and numericalerrors here

Can put many lines of code in a try blockAnd handle several errors afterward

Page 41: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

try: params = read_params(param_file) grid = read_grid(grid_file) entropy = lee_entropy(params, grid) write_entropy(entropy_file, entropy)except IOError: log_error_and_exit('IO error')except ArithmeticError: log_error_and_exit('Arithmetic error')

These messagesaren't very helpful

Can put many lines of code in a try blockAnd handle several errors afterward

Page 42: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Python 2.6

try: x = 1/0except Exception, error: print error

Page 43: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Python 2.6

try: x = 1/0except Exception, error: print error

Stores information about what went wrong

Page 44: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Python 2.6

try: x = 1/0except Exception, error: print error

Stores information about what went wrongDifferent information for different kinds of errors

Page 45: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Python 2.6

try: x = 1/0except Exception, error: print error

Python 2.7

try: x = 1/0except Exception as error: print error

More readable

Page 46: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Better error messages

Page 47: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

try: params = read_params(param_file) grid = read_grid(grid_file) entropy = lee_entropy(params, grid) write_entropy(entropy_file, entropy)except IOError as err: log_error_and_exit('Cannot read/write' + err.filename)except ArithmeticError as err: log_error_and_exit(err.message)

Better error messages

Page 48: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

try: params = read_params(param_file) grid = read_grid(grid_file) entropy = lee_entropy(params, grid) write_entropy(entropy_file, entropy)except IOError as err: log_error_and_exit('Cannot read/write' + err.filename)except ArithmeticError as err: log_error_and_exit(err.message)

Better error messages

Page 49: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

try: params = read_params(param_file) grid = read_grid(grid_file) entropy = lee_entropy(params, grid) write_entropy(entropy_file, entropy)except IOError as err: log_error_and_exit('Cannot read/write' + err.filename)except ArithmeticError as err: log_error_and_exit(err.message)

Better error messagesHelp user figure outwhich file

Page 50: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

try: params = read_params(param_file) grid = read_grid(grid_file) entropy = lee_entropy(params, grid) write_entropy(entropy_file, entropy)except IOError as err: log_error_and_exit('Cannot read/write' + err.filename)except ArithmeticError as err: log_error_and_exit(err.message)

Better error messages

No worse thanthe default

Page 51: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

A question of style

Page 52: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

A question of style

try: grid = read_grid(grid_file)except IOError: grid = default_grid()

Page 53: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

A question of style

if file_exists(grid_file): grid = read_grid(grid_file)else: grid = default_grid()

try: grid = read_grid(grid_file)except IOError: grid = default_grid()

Page 54: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

try: grid = read_grid(grid_file)except IOError: grid = default_grid()

A question of style

if file_exists(grid_file): grid = read_grid(grid_file)else: grid = default_grid()

Use exceptions for exceptional cases

Page 55: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Another question of style

Page 56: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Another question of styleBut first...

Page 57: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Exceptions can be thrown a long way

Page 58: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

try: params = read_params(param_file) grid = read_grid(grid_file) entropy = lee_entropy(params, grid) write_entropy(entropy_file, entropy)except IOError as err: log_error_and_exit('Cannot read/write' + err.filename)except ArithmeticError as err: log_error_and_exit(err.message)

Exceptions can be thrown a long way

Page 59: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

try: params = read_params(param_file) grid = read_grid(grid_file) entropy = lee_entropy(params, grid) write_entropy(entropy_file, entropy)except IOError as err: log_error_and_exit('Cannot read/write' + err.filename)except ArithmeticError as err: log_error_and_exit(err.message)

These arefunction calls

Exceptions can be thrown a long way

Page 60: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Any errorsthey don'tcatch...

Exceptions can be thrown a long way

try: params = read_params(param_file) grid = read_grid(grid_file) entropy = lee_entropy(params, grid) write_entropy(entropy_file, entropy)except IOError as err: log_error_and_exit('Cannot read/write' + err.filename)except ArithmeticError as err: log_error_and_exit(err.message)

Page 61: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

Exceptions can be thrown a long way

try: params = read_params(param_file) grid = read_grid(grid_file) entropy = lee_entropy(params, grid) write_entropy(entropy_file, entropy)except IOError as err: log_error_and_exit('Cannot read/write' + err.filename)except ArithmeticError as err: log_error_and_exit(err.message)

...are caughtand handledhere

Page 62: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

"Throw low, catch high"

Page 63: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

"Throw low, catch high"Many places where errors might occur

Page 64: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

"Throw low, catch high"Many places where errors might occurOnly a few where they can sensibly be handled

Page 65: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

"Throw low, catch high"Many places where errors might occurOnly a few where they can sensibly be handledA linear algebra library doesn't know how itscallers will want to report errors...

Page 66: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

"Throw low, catch high"Many places where errors might occurOnly a few where they can sensibly be handledA linear algebra library doesn't know how itscallers will want to report errors......so it shouldn't try to handle them itself

Page 67: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

You can raise exceptions yourself

Page 68: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

You can raise exceptions yourselfshould

Page 69: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

You can raise exceptions yourselfshould

def read_grid(grid_file): '''Read grid, checking consistency.'''

data = read_raw_data(grid_file) if not grid_consistent(data): raise Exception('Inconsistent grid: ' + grid_file) result = normalize_grid(data)

return result

Page 70: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

You can raise exceptions yourselfshould

def read_grid(grid_file): '''Read grid, checking consistency.'''

data = read_raw_data(grid_file) if not grid_consistent(data): raise Exception('Inconsistent grid: ' + grid_file) result = normalize_grid(data)

return result

Page 71: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

You can define new types of exceptions too

Page 72: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

You can define new types of exceptions tooshould

Page 73: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Exceptions

You can define new types of exceptions tooshould

Need to understand classes and objects first

Page 74: Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

July 2010

created by

Greg Wilson

Copyright © Software Carpentry 2010This work is licensed under the Creative Commons Attribution LicenseSee http://software-carpentry.org/license.html for more information.