Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

4.3 Functions

Functions are essential in programming as they allow you to encapsulate and reuse code efficiently. By breaking down complex problems into smaller, manageable parts, functions enhance code organization and readability. As we already saw you can use built-in functions or import them from specialized modules. Quite often it is also useful for you to define your own functions. In Python, this can be done by using the def keyword followed by a function name:

I'm a custom function!

Function arguments and returns

Functions can accept inputs that modify their behaviour. Strictly speaking, the names listed in the function definition are called parameters, while the actual values you pass when calling the function are called arguments (in practice, the two terms are often used interchangeably). For example, if we want to add two numbers, we can pass both of them as arguments and return the result to the caller:

3

Required and optional parameters

Function parameters can either be required or optional. Required parameters do not have a default value and must be provided, otherwise the function will throw an error. In the previous example, both a and b are required parameters, and the function would not know what to do if any of them were missing. Optional parameters on the other hand are assigned a default value in the function definition. This means that the function knows what to do even if the user does not explicitly provide a value for that parameter.

As an example, let’s create a function that checks whether a reaction time is valid. This is a common step when cleaning data from psychological experiments, as you might want to exclude trials in which participants responded unrealistically fast (e.g. anticipations) or very slowly (e.g. lapses of attention). Only the reaction time rt is required, while the lower and upper limits of the valid range are optional:

Help on function is_valid_rt in module __main__:

is_valid_rt(rt, min_rt=150, max_rt=1000)
    Checks whether a reaction time lies within a valid range.

    Parameters
    ----------
    rt : float
        The reaction time in milliseconds.
    min_rt : float, optional
        The fastest reaction time that is still considered valid.
        Default: 150
    max_rt : float, optional
        The slowest reaction time that is still considered valid.
        Default: 1000

    Returns
    -------
    bool
        True if the reaction time lies within the valid range,
        False otherwise.

If we now call this function by just providing a reaction time, it will still work as expected by using the default range of 150 to 1000 ms:

True
False

Positional and keyword arguments

When calling a function, there are two ways of passing arguments. Positional arguments are matched to the parameters by their position, while keyword arguments are matched by their name (e.g. max_rt=1500). If your task allows for slower responses, you can simply pass a new upper limit as a keyword argument. As keyword arguments are identified by their name, you can provide them in any order you like, as long as all positional arguments come before them.

True

You can also pass all arguments (including rt) by name, in which case their order does not matter at all

True

or pass all of them by position:

False

However, the last example gives a different result than the previous one! As no names are provided, Python matches the arguments to the parameters in the order in which they are defined in the function, so they are interpreted as rt=1200, min_rt=1500 and max_rt=200. With these limits, no reaction time could ever be valid. Keyword arguments are therefore a good way of making your code both clearer and less error-prone.

Variable numbers of arguments

Another feature of Python is the ability to write functions that accept an arbitrary number of arguments by using *args and **kwargs. While we will not cover this topic here, I want to mention it for completeness. If you are interested or encounter it in practice, feel free to explore this topic on your own (e.g., here).