A common theme you have seen throughout this section is avoiding rewriting the same code multiple times. Functions are the key to achieving this in programming. A function is a way of organizing code that enables a programmer to reuse it. They are useful because once the code to complete a task has been written once, you can reuse that code to complete the same task anywhere you want with a single line that “calls” (runs) the function.
*Note: Functions are self-contained, which means any code executed within the function won’t influence anything outside the function. We call this a black box because everything inside the function is obscured from the outside code. It simply sees input go in and output come out. This is especially useful when working in teams. If programmer A writes a function and programmer B needs to use it, programmer B does not need to understand how it works. They only need to understand what inputs to give the function and what outputs come out of it; none of the inner processes or code matters to programmer B.*
Functions are composed of 4 components:
When a program reaches a function call, the program follows this order of control:
Let’s define a basic function named hello_world
that simply prints “Hello World!” and then let’s call the function.
def hello_world():
print("Hello World!")
hello_world()
> Hello World!
Common Mistake: If you run your code and nothing is happening, you might have forgotten to call your function! Defining the function does not run the code. Even experienced programmers can forget to call their function sometimes.
No parameters were being “passed into” (given to) the above function. Let’s expand it to talk about our favorite foods by adding a parameter for our favorite food and then printing it.
def hello_world(favorite_food):
print("Hello World!")
print("My favorite food is " + favorite_food + ".")
hello_world("pizza")
> Hello World!
> My favorite food is pizza.
To create and use a parameter, we first needed to give the parameter a name inside the parentheses beside the function definition header. It was favorite_food
in this case. We then used the parameter favorite_food
as a variable in the function, adding it to “My favorite food is” like a string. Notice that the function doesn’t determine the value of favorite_food.
Instead, it is the function call that determines the value.
To use the function and pass a value to the parameter, we called the function, and between the parentheses beside the function call, we specified the parameter’s value. This is when favorite_food
is given its value.
Our code would throw an error if the value of favorite_food
isn’t passed through a parameter inside the function call’s parentheses and is instead simply defined as a variable outside the function. This is shown below:
def hello_world(favorite_food):
print("Hello World!")
print("My favorite food is " + favorite_food + ".")
favorite_food = "pizza"
hello_world()
> TypeError: hello_world() missing 1 required positional argument: 'favorite_food'
However, it is possible to use a variable as the parameter instead of explicitly defining it as “pizza.”
def hello_world(favorite_food):
print("Hello World!")
print("My favorite food is " + favorite_food + ".")
favorite_food = "pizza"
hello_world(favorite_food)
> Hello World!
> My favorite food is pizza.
One last notable property of a function is using the “return” keyword that serves two purposes:
When data is returned, it is substituted for that function call. For example, we could write a function that adds two numbers and returns the result (and ignores all code after the return keyword). Then, we can store this result in a variable and print it.
def add(a, b):
return a+b
x = 2
y = 3
z = add(x,y)
print(z)
> 5
Here is one last example of a function accomplishing the more complex task of calculating the factorial of num
:
def factorial(num):
ans = 1;
for i in range(1, num + 1):
ans *= i
return ans
print(factorial(8))
> 40320
Functions are the key to abstraction (the idea that we hide unnecessary code) in computer programming. Breaking a program down into functions makes them simpler to manage, easier to test, and better to reuse. In the absence of functions, programs would contain a lot of unnecessary duplicate code, would lack separation of utility, and be a nightmare to manage, debug, and test.
Here are the primary benefits of using functions:
Note: The difference between libraries and functions is that libraries only contain very commonly used pieces of code and are uneditable. In addition, libraries are guaranteed to be relatively high-quality and previously extensively tested, whereas if you write functions, you need to test and refine them yourself.
You can play with all the code we've used in this article on Trinket: