What to do when things go wrong

Unidata Logo

What to do when things go wrong

Unidata Python Workshop


Server on fire

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.

Syntax Errors

Syntax errors usually occur when python is translated from source code into byte code. This is typically identified by a message similar to:

SyntaxError: invalid syntax

Common syntax errors include:

  • Using a reserved python keyword for a variable name.
In [ ]:
while = 1

  • Missing colon at the end of for, while, if, def statements.
In [ ]:
for i in range(1,10) print('Hello world')

  • Incorrect indentation. Don't mix spaces and tabs!
In [ ]:
for i in range(1,10):
  x = 1 + i
    print(x)

  • Mismatched quotation marks.
In [ ]:
print("Some python issues are easier to find than others ')

  • Unclosed brackets
In [ ]:
print("Missing brackets can be difficult" , range(1,10)
print("to find. probably not these ones however.")

Runtime errors

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:

  1. Nothing happens.
  2. The program hangs.
  3. 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.

Running gdb interactively:

   $ gdb python
   ....
   (gdb) run <programname>.py <arguments>

Running gdb Automatically:

   $ 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:

   (gdb) bt

or

   (gdb) py-bt

Handling exceptions with try/except

Handling exceptions may done using try/except statements in python.

In [ ]:
x = int(input("Please enter a number: "))
print(x)
In [ ]:
while True:
    try:
        x = int(input("Please enter a number:"))
        break
    except ValueError:
        print("oops!")
            

User-defined exceptions

Developers can create thir own exceptions by creating new exception classes derived from the Exception class.

In [ ]:
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"
In [ ]:
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)
In [ ]:
?type

Defining Clean-up Actions

The 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.

In [ ]:
try:
    # raise MyInputError("New error, test finally")
    # 
except MyInputError as err:
    print('MyInputError:',err)
    print('dError:',err.dError)
finally:
    print('Graceful Cleanup: Goodbye, world!')
    

Unexpected Results

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.