Functions (Need)

Figure 1: From xkcd.

What to expect in this chapter

By now, you will be comfortable using functions (e.g. print(), enumerate()). In addition, I hope you are satisfied with the idea that a function is just a chunk of code that does a specific conceptual task. There is also the advantage that you can treat a function as a black box and just use it without knowing exactly what is going on in it. Sometimes this is good because too many details can be detrimental; other times it can be unwise as you do not know how an output is generated.

In this chapter, I will show you how to craft your own functions. In addition to its practicality, the modularity of functions prompts us to think of solutions about modular solutions to problems.

1 User-defined functions

print() is an example of an internal function in Python. You can also create your own functions. There are two ways to do this: named and anonymous.

1.1 Named Functions

Named functions that return

We define the function by using the keyword def as follows:

def greeting(name):
    if name == 'Batman':
        return 'Hello Batman! So, nice to meet you!'
    else:
        return f'Hello {name}!'

The function’s name is greeting and it accepts a single argument called name. We can then use the function as:

greeting("Super Man")

or

greeting(name="Super Man")

As with all structures in Python, notice the keyword def, the colon (:) and the indentation that demarcates the function’s code block. Notice also that I have used the keyword return to get an output from the function. When Python sees a return keyword it jumps out of the function with the return value. You can pick up the returned value by assigning it to a variable or even use it directly like:

greet=greeting(name='Super Man')
print(greet)

or this works too:

print(greeting(name='Super Man'))

Incidentally, you can use return only within a function.

I also like to point out that you can return almost anything! Here is an example of a function that accepts a list and returns the maximum, minimum and mean.

def basic_stats(numbers):
    np_numbers = np.array(numbers)
    my_min = np_numbers.min()
    my_max = np_numbers.max()
    my_mean = np_numbers.mean()
    return my_max, my_min, my_mean

Here is how you can use it:

list_min, list_max, list_mean = basic_stats([1, 2, 3, 4, 5])

Named functions that don’t return

A function does not have to return anything. A good example is print(), which does something but does not return a value. You will often also need functions like these, for instance, to save data to a file. I will show you a few of such functions in later chapters.

1.2 Anonymous functions

Anonymous or lambda functions are suitable for short one-liners. Let me show you two examples.

  1. This function accepts a single argument called name.

    my_short_function = lambda name: f"Hello {name}!"

    We can use it like

    my_short_function(name="Super Man")

    A lambda function always returns the value of the last statement.

  2. The above example is not a very good ‘anonymous’ one because I have used a name! So let me show you another one where things are really anonymous.

    Let’s say I want to sort the following 2D list.

    numbers=[[9, 0, -10],
             [8, 1, -11],
             [7, 2, -12],
             [6, 3, -13],
             [5, 4, -14],
             [4, 5, -15],
             [3, 6, -16],
             [2, 7, -17],
             [1, 8, -18],
             [0, 9, -19]]

    I can use the sorted() function for this. Here are three ways I can use it.

    # Sort by comparing the default key
    # (i.e., the 1st element)
    sorted(numbers)
    [[0, 9, -19]
     [1, 8, -18]
     [2, 7, -17]
     [3, 6, -16]
     [4, 5, -15]
     [5, 4, -14]
     [6, 3, -13]
     [7, 2, -12]
     [8, 1, -11]
     [9, 0, -10]]

    Notice that this sorting is based on comparing the first elements of the sub-lists.

    # Sort by comparing a custom key
    # that uses the 2nd element (index=1)
    sorted(numbers, key=lambda x: x[1])
    [[9, 0, -10]
     [8, 1, -11]
     [7, 2, -12]
     [6, 3, -13]
     [5, 4, -14]
     [4, 5, -15]
     [3, 6, -16]
     [2, 7, -17]
     [1, 8, -18]
     [0, 9, -19]]

    If I want to use some other criteria, then I need to specify a key that sorted() can be used for comparison. As you can see, I have used a lambda function for this.

    # Sort by comparing a custom key
    # that uses the sum of the elements.
    sorted(numbers, key=lambda x: sum(x))   
    [[0, 9, -19]
     [1, 8, -18]
     [2, 7, -17]
     [3, 6, -16]
     [4, 5, -15]
     [5, 4, -14]
     [6, 3, -13]
     [7, 2, -12]
     [8, 1, -11]
     [9, 0, -10]]

    This is really powerful as I can specify almost any criterion I like. For example, I can sort according to the sum of the elements of the sub-lists.

1.3 Optional arguments

Python allows us to make arguments to our function optional. To do this, we need to give the argument a default value so that it always has something to work with.

def greeting(name='no one'):
    if name == 'Batman':
        return 'Hello Batman! So, nice to meet you!'
    else:
        return f'Hello {name}!'

Now we can run this function without an argument, and it will still work without throwing an error.

greeting()
'Hello no one!'

For another example, let’s look at the documentation for print().

?print
    Docstring:
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

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

You see that print() can accept other arguments that are optional with default values. However, we can specify them if we like; here goes.

# Using default values
print('I', 'am', 'Batman!')
# Specifying an optional argument
print('I', 'am', 'Batman!', sep='---')  
I am Batman!
I---am---Batman!
Remember

Remember:

  • you can define your own functions,
  • functions can have optional arguments,
  • functions don’t always have to return anything.

1.4 The importance of functions?

An argument for functions

Now that you know a bit about creating functions, let me highlight why functions are a good idea.

Abstraction of details The most important benefit of functions goes beyond programming and relates to your ability to strategize. If you break up a complicated solution into modular chunks (i.e., functions), it becomes easier to think about it because you are not dealing with all the details all at once. As a result, it is easier to focus on your overall solution because you are not distracted by unnecessary information. This hiding of ‘stuff’ is called abstraction in computer science lingo. The concept of abstraction can be tricky to grasp. So, let me share an analogy related to driving.

A vehicle has many ‘abstracted’ systems, amongst which the engine is a good example. You do not need to know the engine’s details (e.g. electric, petrol, diesel, guineapig) to use it. You can use the engine of almost any car because you are not required to know what happens inside. This frees up your resources because you are not distracted by unnecessary details. Of course, there will be times when you want to know how an engine works to pick the best engine.

Reusability of code If you encapsulate a chunk of code in a function, it becomes straightforward to reuse it instead of copying and pasting at different places. This means your code will be shorter and more compact.

Maintainability of code With functions, your code is easier to change and maintain because you need only make changes in one place, at the function definition.

A word of caution

I have seen many instances where functions are abused; for example, by trying to do too many things or having too many arguments. They can also be overused. Having too many functions can make it difficult to read your code and also increase computational overheads. You will get a better feel for when to use functions with experience, but please bear in mind that functions can be misused.

Back to top