Join Barron Stone for an in-depth discussion in this video Cook with functions, part of Programming Foundations: Real-World Examples.
- 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.
- Reusing functions
- Local vs. global variables
- Creating and naming custom objects
- Class inheritance
- Modules and packages
- Multidimensional lists and tuples
- Queues and stacks
- Creating and combining sets
- Storing data in dictionaries
- If/else and switch statements
- For vs. while loops
- Error handling
- Polling and event-driven programming