Functions in Python are like Coffee Machines - a coffee cup on a desk with computers

Functions in Python are Like a Coffee Machine

Functions in Python are one of those topics for beginners! Most understand what functions are at a basic level. However, there’s much more detail and nuance to defining and calling functions in Python.

As with most things in coding and Python, there’s nothing better than a good analogy to picture what’s happening behind the scenes.

In this article, you’ll read how functions in Python are like coffee machines. You’ll read about:

  • parameters and arguments
  • defining and calling functions
  • moving data out of a function using a return statement

Time to make yourself a cup of coffee, sit down (or stand if, like me, you use a standing desk), and enjoy both the coffee and the article.

What Does A Coffee Machine Need?

There are many different types of coffee machines, of course. I’ll use the one I have on my kitchen bench as an example. Here it is:

Coffee machine making coffee

But the analogy works for other types of coffee machines, too!

The coffee machine’s instruction manual will tell you the things you’ll need before you can make your coffee:

  • water
  • electricity
  • ground coffee or coffee pods

Let’s look at a pseudo-function signature—the line you’d write when defining a “coffee machine” function:

def make_coffee(water, electricity, coffee):

The function definition has three parameters. This means that for this function to work, it will need something to fill these three placeholders.

Defining the function is not enough. Access to a function definition, whether you write your own or import from a module, is the equivalent of buying the coffee machine, unpacking it, and finding a place to put it in your kitchen.

You need to turn it on…

Turning On The Coffee Machine — Calling A Function in Python

Before you turn on the coffee machine, you must put in the ingredients. The machine has a place ready for these. These placeholders are:

  • the tank where the water will go
  • the plug to supply electricity
  • the holder for the coffee pod

These are the parameters. They’re the placeholders which were present since you bought the machine—or defined the function.

Now you need to put the things needed in the machine.

You may use tap water, or filtered water, or bottled water (really?!) in the water tank. And if you use coffee pods, you may have a selection to choose from.

Whatever you choose will be the argument when you call the function.

Here’s what a function call could look like:

make_coffee(
    tap_water,
    electricity_from_wall_socket,
    blue_espresso_pod,
)

Calling the function is the equivalent of turning the machine on and pressing the button to make the coffee.

The brackets you use when you call a function are the “on” button of a function in Python. In fact, there’s a resemblance between the typical “on” button on most devices and the brackets or parentheses ( ):

Do You Know How The Coffee Machine Works?

If you just want to use the coffee machine to make coffee, you don’t need to know how the coffee machine works on the inside. Does it have motors? What about the electronics? You don’t really care as long as you can put the water in the tank, put the coffee pod in its holder, plug in the machine and turn it on.

When you use a function, whether it’s one that you or someone else wrote, you don’t need to know what’s inside the function definition.

As long as you know how to use the function, you don’t need to know what code is written within. You need to know what arguments are needed and what the function returns, but not how the function performs the actions it does.

In the coffee machine analogy, the instruction manual doesn’t tell you how the machine works on the inside. It just tells you how to use it.

However, if you’re an engineer building a coffee machine, or you’re tempted to open your coffee machine to fix it or (perhaps) improve it, then you need to know how it works. You need to know the code inside the function definition—especially if you’re the one writing it!

Making The Coffee and Making Sure You Don’t Waste It!

So, you’ve put in the water and the coffee pods and plugged the machine into the wall socket.

You turn it on.

You hear a whizzing sound, and a short second later, the coffee starts pouring out of the nozzle at the top of the machine…

And the coffee pours straight into the drainage tray at the bottom, eventually overflowing and making a mess on your kitchen bench.

Oops!

We’ll return to this problem shortly.

What Does The Machine Return?

Functions return data. Even those functions in Python that “don’t return anything” return the object None. A Python function cannot return nothing. Instead, it returns None when there’s nothing else to return.

However, many functions do return some data. Let’s look at this example:

import random

def do_something(first, second):
    result = first + second + random.randint(-5, 5)
    return result

The eagle-eyed reader may notice that the variable result is not needed in this function, but I’ve included it for the purposes of the discussion coming next.

What does this function return? Here’s the pedantic answer, but the pedantry is important in this case.

The function does not return result. It does not return a variable named result. It returns the contents of the local variable result.

If a variable is a box containing the data and the variable name is the label on the outside of the box, a function doesn’t return the box but it tips it over and returns its contents.

This is why the following code returns a NameError:

import random

def do_something(first, second):
    result = first + second + random.randint(-5, 5)
    return result

do_something(3, 5)
print(result)

The error says that name 'result' is not defined. In the main scope of this program, the name result has never been created. It only exists as a local variable within the confines of the function do_something().

So what’s happened to the coffee? You turned the coffee machine on with a call that could have looked like this:

make_coffee(
    tap_water,
    electricity_from_wall_socket,
    blue_espresso_pod,
)

The function returns the liquid coffee, which pours out of the machine’s nozzle. But you didn’t create a variable to collect the coffee returned by the function. You’re not storing the data that’s returned. Just like the coffee, the data returned by a function will be lost if you don’t use it right away or store it somewhere.

You can try the following:

coffee_cup = make_coffee(
      tap_water,
      electricity_from_wall_socket,
      blue_espresso_pod,
)

Now, you’re collecting the coffee returned in a variable named coffee_cup.

A transparent coffee cup with coffee using in the Coffee Machine Functions in Python analogy

Time to make another coffee?

Final Words

The coffee machine analogy is one of my favourites in programming. Like all analogies, it’s not perfect, and there’s a limit on how far you can take it. You probably need to “give up coffee” when you move to default arguments or *args and **kwargs, say.

However, it gives a good picture of the distinction between defining and calling a function in Python, and between parameters and arguments. It also provides a good visualisation of what happens when a function returns data and how you need to collect those data in a variable when you call the function.

Further Reading

  • If you like analogies, here’s another perspective of functions in Python through The Function Room analogy, part of The White Room analogy.
  • And you can also read the full White Room analogy which accounts for more parts of a computer program.

Get the latest blog updates

No spam promise. You’ll get an email when a new blog post is published


Leave a Reply