- One of the first things that everybody is taught
when learning to program
is how to create a function.
The syntax for functions may vary from language to language
but the general concept is always the same.
A function is a routine or procedure
that may or may not take some input values,
it performs some sort of processing
and then possibly returns an output value.
Every programming course will teach you
how to create functions in that specific language
but what often gets overlooked is the question of
why should you create a function
and when should you or should you not
turn a specific process into a function.
The short answer is
function should be created for commonly used routines.
To demonstrate that concept,
let's go to the kitchen
and look at a routine I do every day.
Good morning.
Every day when I wake up,
I like to cook myself a hearty breakfast
to kick-start the day.
There are a lot of steps involved in cooking that breakfast.
I always make coffee,
might scramble some eggs, make some toast,
and, of course, I finally eat.
Each of those steps in the breakfast-making process
is comprised of many more smaller steps.
For example, the process of making coffee
involves measuring the coffee beans,
grinding the coffee beans,
putting the ground coffee beans into the filter,
measuring the water,
starting the coffee maker,
and finally, pouring the coffee.
There were a lot of steps in that process,
but those steps would be exactly the same
every time I make coffee.
And that's why I've decided to combine those steps
into a mental function.
Now, when I decide to make coffee,
my brain goes into autopilot and I do all of those things
without having to explicitly think about each step.
Mmm.
Making coffee is just one part of my breakfast routine
that I've turned into a mental function.
Let's break down another breakfast process,
making an omelette.
To make an omelette, I start by mixing my ingredients
together in a bowl,
I pour that mixture into a frying pan,
I cook the omelette on one side,
I flip it,
I cook the other side,
and the output of that process
is an omelette.
It's nothing fancy but I'm a computer programmer,
not a chef.
Just like with making coffee,
I've also functionalized the process for making an omelette.
That means if my wife, Olivia,
wants me to make an omelette for breakfast,
she doesn't have to tell me each of those steps,
mixing the ingredients,
pouring them into the frying pan and so on,
all she has to say is
- Make me an omelette,
please?
- And I know exactly what to do.
Let's look at that omelette-making process
as a function in Python.
I have the IDLE Python editor
open to the start_01_01_breakfast_function script
which I'll use to assemble the tools
to make a functional breakfast.
Right now, the script is simply a series of print statements
which represent each of the steps
in my omelette-making process.
Python can do a lot of things
but it can't actually make a real life omelette
so we'll need to use a bit of imagination.
The steps in the omelette-making process
include mixing the ingredients,
pouring the mixture into a frying pan,
cooking the first side, flipping it,
and then cooking the other side.
At the end of the process, I create a new string object
to represent the tasty omelette I just cooked
and I assign it to the variable name omelette.
I'll run this script in IDLE by going to Run, Run Module.
And that will bring up the interactive Python shell.
As you can see, the script printed out those five steps
in the omelette-making process.
If I type omelette to access that variable,
I get back the string object describing the tasty omelette,
just what I expected.
So that was an omelette for me to eat.
But what if Olivia wants an omelette for breakfast too?
In that case, I'll need to repeat all of those steps again
to create a second omelette for Olivia.
One way I could accomplish that would be to type out
all of those steps in the process again,
but for the sake of time, I'll just copy and paste.
And I'll modify the variable names to be omelette1
and omelette2
so I can tell them apart.
Now, when I save and run this script,
it goes through the steps to make an omelette twice.
And if I type omelette1,
you can see that it's a tasty omelette.
And the same goes for the variable omelette2.
That script successfully cooked breakfast
for Olivia and myself,
but what if I needed to make more than just two omelettes?
Let's say I decided to invite a bunch of friends over
for breakfast.
If I kept manually copying all of the steps
every time I wanted to make an omelette,
my script would end up being really long.
And the longer the script gets,
the more likely I am to make a mistake.
Since I'm performing the exact same actions
every time I want to make an omelette,
this is the perfect scenario for us to combine those steps
into a single function.
So let's do that now.
Before I can use a function, I need to define it first.
So at the top of the script, I'll type D-E-F
which is the keyword to let Python know
that I'm defining a new function.
I'll give the function a name, make_omelette,
and then create open and close parentheses
followed by a colon.
The specific syntax for defining a function
will vary if you're programming in a different language,
but this is how it's done in Python.
Now, I need to put all of those steps for making an omelette
into my new make_omelette function.
Python uses indentation to show that a specific line of code
exists within something else,
like a function definition,
so I'll indent all of these print statements
to make them part of the make_omelette function.
I'll also delete the second set of print statements
since I won't be needing it anymore.
At this point, I've created a function called make_omelette,
and whenever I use it, it'll print out those steps
and create a new string describing a tasty omelette.
But there's one more thing I need to do.
I don't just want the string describing a tasty omelette
to exist inside of this function.
When I call the make_omelette function,
I want to get that string back as an output.
To do that, I can add the statement return omelette
at the end of the function
and I'll also change the variable name from omelette1
back to just omelette.
As this function executes,
when it gets to the return statement,
it'll exit the function and pass that string
describing the tasty omelette as output.
Now, our function is complete so let's use it.
To make an omelette for myself,
I can type omelette1 = make_omelette
with open and close parentheses afterwards.
This will execute the make_omelette function
which performs all of the necessary omelette-making steps
and returns the tasty omelette string
which I then assign to the variable name omelette1.
I should also be nice and make an omelette for Olivia
and I can do that the same way
by simply typing omelette2 = make_omelette.
Now, when I save and run this script,
it'll perform the steps to make two omelettes
just like before.
And we can check to see that the variable omelette1
is a tasty omelette.
And so is omelette2.
Perfect.
Now, we have an omelette-making function,
we've tested it and we know it works.
We can use it over and over
to create as many omelettes as we want.
I can even use it here in the interactive shell.
If I type make_omelette and hit enter,
it'll execute the necessary steps
and the function returns the string "a tasty omelette"
which gets printed out automatically by the Python shell.
This demonstrates one benefit
of organizing code into functions,
code reuse.
I wrote my omelette-making function once
and now I can easily use it over and over.
The function performs all of the intermediate steps of
mixing, cooking, and flipping the omelette
so I don't have to worry about any of those steps
whenever I use the function.