Help and Errors

Contents

Help and Errors#

Getting Help#

Reading the documentation of the programming language and software packages frequent task in programming. Nobody is expected to memorize all the details on how some function is exactly invoked and the names of all of its arguments. Therefore, it is important to quickly find the information you need to continue to be productive. The IPython interpreter that is running under the hood of Python Jupyter kernels offers a very convenient way of accessing documentation to functions, modules, packages or simply assigned variables. Put a question mark ? right after the name you want to know something about. To learn something about the print function, use

print?
Signature: print(*args, sep=' ', end='\n', file=None, flush=False)
Docstring:
Prints the values to a stream, or to sys.stdout by default.

sep
  string inserted between values, default a space.
end
  string appended after the last value, default a newline.
file
  a file-like object (stream); defaults to the current sys.stdout.
flush
  whether to forcibly flush the stream.
Type:      builtin_function_or_method

or

help(print)
Help on built-in function print in module builtins:

print(*args, sep=' ', end='\n', file=None, flush=False)
    Prints the values to a stream, or to sys.stdout by default.

    sep
      string inserted between values, default a space.
    end
      string appended after the last value, default a newline.
    file
      a file-like object (stream); defaults to the current sys.stdout.
    flush
      whether to forcibly flush the stream.

To get some information about the variable area, do

area = 5.0
area?
Type:        float
String form: 5.0
Docstring:   Convert a string or number to a floating-point number, if possible.

The information you are getting on the variable is actually the documentation of the data type of that variable.

When you start to feel comfortable using Python, it is also very beneficial to take a look at the Python documentation to get a broader and deeper understanding about the language itself.

Errors#

Errors and mistakes are an essential part of the programming process. However, one has to distinguish between mistakes you as a programmer are making and errors the users of your software might make. Let us concentrate on the first type of mistake: coding errors (or bugs).

Do not be disappointed if your code does not work at the first time. It almost never does, either because your syntax is not correct (a syntax error) or your code tries to do something that is not well-defined (an exception) Most languages, and also Python, do have some mechanism to deal with errors that occur during the runtime of the program. If the Python interpreter encounters some error it raises an exception. An exception raised due to a syntax error may look like this

a = 5 when 3 < 9
  Cell In[3], line 1
    a = 5 when 3 < 9
          ^
SyntaxError: invalid syntax

This code raises a SyntaxError exception, since Python does not know a when key word. The ^ symbol in the output points to the exact location where the syntax is wrong. This greatly helps to find typos in your code.

But there are a lot more exceptions, such as arithmetic exceptions, raised if an invalid operation occurs:

a = 1
b = 0
c = a / b
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
Cell In[4], line 3
      1 a = 1
      2 b = 0
----> 3 c = a / b

ZeroDivisionError: division by zero

Here we try to divide by zero which is a not well-defined mathematical operation. Hence, the interpreter complains and in the output the ----> marks the line in the code where the interpreter raised the exception. Note that in many cases, unlike in this simple example, the occurrence of an exception depends on the conditions at runtime, i.e. when the program is executed. Such conditions could be the data that are fed into the program, which may be different for each execution.

Often, when we use functions or packages, the exception is raised inside some function that may not even be part of our own code. To still be able to identify the origin of the issue, the Python interpreter provides a traceback, that is a list of all lines that are executed until the program went wrong.

def outer(a, b):
    c = inner(a, b)
    return c

def inner(a, b):
    return a / b

result = outer(1, 0)
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
Cell In[2], line 8
      5 def inner(a, b):
      6     return a / b
----> 8 result = outer(1, 0)

Cell In[2], line 2, in outer(a, b)
      1 def outer(a, b):
----> 2     c = inner(a, b)
      3     return c

Cell In[2], line 6, in inner(a, b)
      5 def inner(a, b):
----> 6     return a / b

ZeroDivisionError: division by zero

In this example, two functions, outer and inner are defined where outer is simply calling inner with it’s own parameters. In the last line, we call outer with the parameters 1 and 0. In the last block of the traceback, we can see that the exception has been raised within the function inner. The second last block tells us, that the function inner has been called within the function outer. And finally, in the first block we see that the function outer has been called in the eighth line of the cell with the arguments 1 and 0. Hence, a traceback is best read backwards, allowing to trace the occurrence of an error back to it’s origin.

Note that for the syntax error, the output looks different. The reason is that the syntax error is raised while the interpreter reads the source code and before the code is executed. All other exceptions are raised during the execution of the program. See the Pyhon documentation to learn more about errors and exceptions and how to deal with them.