What to do when things go wrong
Unidata Python Workshop
This session is designed as both a workshop and group discussion. We will examine basic failures in Python and how they manifest, followed by a discussion of what sort of errors and failure cases plague you, the audience. We will try to identify things that we (Unidata) can do differently to make the software development/usage process easier for our community. We will also pool our python knowledge/experiences to try to identify common issues and potential solutions.
This is useful because, eventually, problems will arise when programming with Python. Common issues include:
- Syntax Errors
- Runtime Errors
- Unexpected Results
Identifying and correcting these issues can be difficult. However, there are strategies for preventing and mitigating many of the problems a developer may encounter.
while = 1
- Missing colon at the end of
for i in range(1,10) print('Hello world')
- Incorrect indentation. Don't mix spaces and tabs!
for i in range(1,10): x = 1 + i print(x)
- Mismatched quotation marks.
print("Some python issues are easier to find than others ')
- Unclosed brackets
print("Missing brackets can be difficult" , range(1,10) print("to find. probably not these ones however.")
Once the program is syntactically correct, it can run and now nothing will go wrong! Until it does. There are multiple ways runtime errors may manifest:
- Nothing happens.
- The program hangs.
- Infinite loop or recursion.
Debugging Runtime errors in Python with GDB¶
It's possible to debug python using
gdb. It requires the pythong debugging extensions be installed.
$ gdb python .... (gdb) run <programname>.py <arguments>
$ gdb -ex r --args python <programname>.py <arguments>
The latter case runs the program until it exits, segfaults or execution is stopped.
You can get a stack trace or python stack trace via:
Handling exceptions with
Handling exceptions may done using
try/except statements in python.
x = int(input("Please enter a number: ")) print(x)
while True: try: x = int(input("Please enter a number:")) break except ValueError: print("oops!")
Developers can create thir own exceptions by creating new exception classes derived from the Exception class.
class MyInputError(Exception): """Exception raised for errors in the input. Attributes: message -- explanation of the error """ def __init__(self,*args,**kwargs): Exception.__init__(self,*args,**kwargs) self.dError = "Internal Error 10"
try: raise MyInputError("MyInputError") raise AssertionError("Sample Assertion Error") except MyInputError as err: print('InputError caught:',err) print('dError:',err.dError) except AssertionError as err: print('Assertion error caught:',err)
Defining Clean-up Actions¶
try statement has an optional cluase which lets you define a clean-up action; this is an action executed whether an action has occured or not.
try: # raise MyInputError("New error, test finally") # except MyInputError as err: print('MyInputError:',err) print('dError:',err.dError) finally: print('Graceful Cleanup: Goodbye, world!')
Just because a program runs, we shouldn't assume that the program has generated correct output. It is important to, when possible, create software tests which test the output of your program against known good outputs.
There are services, like http://travis-ci.org, that can automate this process assuming you are using a remote repository like GitHub.