There are only 2 hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Hey pips!
Functions. There’s so much to talk about about functions. Wait. Uh…
can().talk(about = "functions", amount = "so much")
hehehehehe. When the language fails, code will illustrate unambiguously.
So, other than compartmentalisation / abstraction / whatever you wanna call it, the key purpose of functions is reusability. We can define an operation, and then use it as many times as we need to, anywhere. Even more importantly, we can define a function to take in parameters, which allow us to vary its behaviour.
def complete_homework(
subject,
date_set,
speed = "normal",
distracted = False,
time_limit = None,
):
...
return True
You can provide default values for parameters by setting them =
to one in the definition. You can then omit them when calling the function:
>>> complete_homework("maths", "25-04-02")
True
>>> complete_homework("maths", "25-04-02", distracted = True)
True
If you do, Python will just automatically fallback to the default value.
A really common pitfall with this is using a mutable object as a default value – for instance, a list
.
def update(items = []):
items.append("sup")
return items
Calling this the first time is fine:
>>> update()
["sup"]
But when we call it again…
>>> update()
["sup", "sup"]
Woah, it’s appended twice. And again?
>>> update()
["sup", "sup", "sup"]
>>> update()
["sup", "sup", "sup", "sup"]
Strange, since we only call .append()
once in the function. And yet the .append()
seems to carry over between calls.
This is because the default value of []
isn’t created every time the update()
is called, but rather when it’s defined. This means every call to the function will access the same list
object, and so any modifications to it will be reflected in other function calls too.
The workaround is to set the default value as None
and dynamically initialise a new list
if necessary:
def updated_update(items = None):
if items is None:
items = []
items.append("yo")
return items
And now:
>>> updated_update()
["yo"]
>>> updated_update()
["yo"]
Finally, you’ll often hear the words parameter and argument both used to describe what you pass into a function.
For those who care, there is a technical difference. “Parameter” refers to the particular variable being set, while “argument” refers to the actual value it’s set to.
def illustrate(drawing = "blue-corner")
... # param # argument
As such, we might talk about a “required” or “optional” parameter, but a “missing” or “invalid” argument.
illustrate(
# setting parameter
drawing = "oshi-no-ko")
# passing in argument
Not that important, but pedantics can be important o7
Further Reading
- Why are they called arguments? – StackExchange↗