Reading documentations and using online resources#

# initialization: make numpy available
import numpy as np

As we have seen, a module like numpy may define a large number of functions, and it would be impractical to describe all of them in class. Thus, we will now discuss how to read the documentations provided by the package maintainer, so that if needed you can figure out how a function is supposed to work yourself.

In the same spirit, we will also discuss how to make use of online resources if you run into a coding problem and want to try debugging it yourself.

More on functions#

So far we have been calling functions using positional arguments. In other words, the order we supply the parameters tell python what that those parameters are used for. An example is np.linspace()

np.linspace(1, 3, 5)
array([1. , 1.5, 2. , 2.5, 3. ])

The fact that 5 is the third argument in this function call tells python that it specifies the number of elements we want the output to contain.

However, as it turns out, each of the first three arguments of np.linspace() has a name too (see the documentation here). The first argument is named start, the second stop, and the third num. So we could have called our function like so:

np.linspace(num=5, start=1, stop=3)
array([1. , 1.5, 2. , 2.5, 3. ])

Notice that when we specify the argument by keyword, the order no longer matters.

In general, a function can be called with a mix of positional and keyword arguments. However, the positional argument must come before the keyword arguments. So we could have called the np.linspace() function like so:

np.linspace(1, num=5, stop=3)
array([1. , 1.5, 2. , 2.5, 3. ])

Another concept we haven’t touched so far is the idea of an optional argument. If we read the documentation, we see that np.linspace() has a few more arguments, but we have never supplied them up to now. The reason is that these arguments have default values. For example, the endpoint argument of np.linspace() is defaulted to True, so the following are equivalent:

np.linspace(1, 3, 5)
array([1. , 1.5, 2. , 2.5, 3. ])
np.linspace(1, 3, 5, endpoint=True)
array([1. , 1.5, 2. , 2.5, 3. ])

We could, however, override the default value. The result is that the right endpoint (3) will no longer be included in the output, and the spacing is adjusted so that we still get a array of length 5:

np.linspace(1, 3, 5, endpoint=False)
array([1. , 1.4, 1.8, 2.2, 2.6])

Reading call signature of a function#

Very often, the documentation of functions start with the call signature of the functions, i.e., listing the function and its arguments. In the case of np.linspace(), we have (for numpy version 2.2.*):

numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0, *, device=None)

The way the function is written out already provides a fair amount of information. In particular:

  • The absence of the =… in the first two arguments (start and stop) indicate that they have no default values. In contrast, the rest of the arguments all have default values as indicated

  • The arguments start, stop, num, endpoint, retstep, dtype, and axis can all be called either by position or by keyword.

  • In contrast, the last argument, device, is placed after and asterisk (*), which indicates that it can only be called by keyword (The * itself is not an argument).

There are a few more conventions that are not illustrated by np.linspace(), so let’s look, e.g., at the example of np.exp(), which is documented here

numpy.exp(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature]) = <ufunc 'exp'>

Some information we can infer:

  • We again see arguments placed after the * (namely, where, casting, etc.). These are keyword-only arguments

  • We see an additional /, which, like *, is not an actual argument. What it indicates is that x, which comes before the /, is a position-only argument. That is, we can not call it using the name x

  • In contrast, the argument out can be called either by position or keyword

  • Finally, note that there is no defaults for x, but there are defaults for the rest of the arguments

Next, let’s look at the documentation for print() (which can be found here):

print(*objects, sep=' ', end='\n', file=None, flush=False)

Here we encounter a new construct, a * followed by a name (no space). This is an example of variadic positional argument. Implications:

  • *objects corresponds to a sequence of arguments you can supply by position.

  • All arguments after *objects are keyword-only.

Finally, sometimes a bunch of optional arguments are shorthanded. An example is the plt.plot() function from the matplotlib module (documented here; we’ll discuss the matplotlib module in greater details next time)

matplotlib.pyplot.plot(*args, scalex=True, scaley=True, data=None, **kwargs)

Here we again see variadic positional arguments *args. But in addition, we see the argument **kwargs:

  • **kwargs is a shorthand for “the remaining positional arguments”

The rest of the documentation#

Quite generally, the documentation of a function has a few typical sections. We have already seen a section on the call signature. Some additional sections are:

  • Description of inputs, often also called parameters or arguments

    This section is worth paying attention to if an argument’s purpose is not obvious from the call signature, or if there is potential ambiguity in how to interpret its meaning. For example, the documentation of np.sin() here clearly indicated that angle is supplied in radians

  • Description of outputs, often also called returns.

    This tells you what is returned by the function, and thus, can be assigned to a variable. For example, in the documentation of np.sin() it is said that the function returns an array-like object that is the sine of every input element.

    However, you should also pay attention to whether the functions have any side effects. These are things that happen over the course of the execution of the function and are not returns that can be assigned. For example, in the documentation of the .sort() method of list here, it is described that the method will modify the calling list object in-place and does not return anything

  • A description on how the function works, as well as caveats

  • Examples

    Which you may want to follow to get a sense of how the function works in practice.

  • Related functions (especially for a large module)

    This is useful if the function you’re reading operates close to what you want but not exactly.

Using online resources#

Sometimes, you may find the official documentation of a function too dry or too technical. Some other times, you search result produces sites that are not official documentation. At yet other times, you may find it handy to consult an AI chatbot rather than to do a search.

All of these online resources can be helpful. The key is to understand the different purposes they serve:

  • An online chatbot (e.g., chatGPT) or Q&A site (e.g., stackoverflow) are useful for answering your immediate question(s).

    However, depending on how close your problem is to the problems being asked or being trained on the AI, you may not be able to just copy-and-paste the answer.

    As a rule of thumb, you should treat these resources as the starting point of finding answers and not the ending point. If you can clearly understand how the proposed codes work and that it is directly relevant to your problem, you may be done (with perhaps changing a few variable names). However, if you are unclear about why the proposed solution works, you should keep digging even if the answer happens to work for your immediate problem.

  • An online tutorial or resource page can be helpful for understanding the concepts associated with the problem you encountered. Do note that not all online resource page are created equal and it is useful to know who to trust. In particular, I find the following sites trust-worthy most of the times:

  • Finally, once you have a good idea of how a function works in practice, it is always a good idea to check the official documentations to see if you miss any details or caveats.