Today we’re going to learn how to package up small chunks of code for reuse using functions.
Goal for this Tutorial:
- Create our first function to execute code multiple times.
- Learn about
range
. - Learn about function arguments.
In most of our programming, we won’t be working with a script that we’re going to run from top to bottom. Most of our time is going to be spent grouping code together in a way that makes sense to use and then combining the piece that we build up in order to create our final product. The simplest way we can package up our code is by using a function.
Python Functions are Pretty Awesome
Functions are the building block that virtually every programming language has in common, and are even the most important building block in some languages. Python functions aren’t the most important, but they are very powerful.
I like to think of functions in programming in the way that you might learn about functions in mathematics. Let’s break down a math function and turn it into a Python function:
f(x) = x + 1
Our function has the name of f
and it requires a single variable x
. We will define this function in Python using the def
keyword:
def f(x):
We follow our function name and arguments with a :
and then we will indent the actual logic of the function by 4 spaces. After the body of the function we’ll insert a blank line which will end the function.
def f(x):
x + 1
We’ve defined our function, now let’s take it for a spin:
>>> f(1)
>>>
That’s not quite right. In our math function if we use 1
for x
then the answer should be 2
, but we didn’t get anything. Our function works this way because unlike mathematical functions which always produce an output, Python functions can take an action and then return nothing to us. To make this work like the math function we need to use the keyword return
.
def f(x):
return x + 1
If we try to run the function again, we should get 2
back:
>>> f(1)
2
>>>
Beyond Math… Onto Fizz Buzz
Figuring out how to represent a math function in Python is one thing, but that really doesn’t event scratch the surface of Python functions.
Functions are not restricted to being a single line, so we can package up a series of expressions to execute. We’ll demonstrate this using a problem from programming interviews called “fizz buzz”.
For “fizz buzz” we’re going to take a number and print from 1 to that number and for each number we will print one of the following:
- “Fizz” if the number is divisible by 3
- “Buzz” if the number if divisible by 5
- “Fizz Buzz” if the number is divisible by 3 and 5
- The number itself if not divisible by 3 or 5
Here’s an example of one way we could write this function:
def fizz_buzz(limit):
for num in range(1, limit):
output = ""
if num % 3 == 0: output += "Fizz "
if num % 5 == 0: output += "Buzz"
print(output or num)
This function combines loops, conditionals, strings, conditionals, printing, and even throws in something new: range
.
A range
is a sequence of numbers, in our case it’s from 1
to whatever the passed in limit
is, excluding the limit
itself. Ranges are great for when you want to iterate through something a specific number of times or in our case where we want to do something with each number, but we don’t want to create a list ourselves.
This is a fairly complex function, and now we can run it over whatever limit we want, as many times as we want.
>>> fizz_buzz(17)
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
Fizz Buzz
16
>>>
Fizz Buzz, but Better
Our original example was a good example of creating a more complex function body, but there is more that we can do in the function declaration that can make it even better. For instance we can give limit
a default (we’re going to call this fizz_buzz2
to keep them separate):
def fizz_buzz2(limit=20):
for num in range(1, limit):
output = ""
if num % 3 == 0: output += "Fizz "
if num % 5 == 0: output += "Buzz"
print(output or num)
Now if we call fizz_buzz2
without any arguments it will automatically use 20
as the value for limit
. Pretty neat!
Let’s take this even one step forward and make the “fizz” and “buzz” messages configurable (this is fizz_buzz3
):
def fizz_buzz3(limit, fizz="Fizz", buzz="Buzz"):
for num in range(1, limit):
output = ""
if num % 3 == 0: output += fizz + " "
if num % 5 == 0: output += buzz
print(output or num)
This version of fizz buzz is the best we’re going to create. We’re now using multiple arguments, some with defaults and some without. Let’s look at some of the ways we can call this function:
>>> fizz_buzz3(7, "Red", "Blue")
1
2
Red
4
Blue
Red
>>> fizz_buzz3(7, buzz="Boom!")
1
2
Fizz
4
Boom!
Fizz
In our first example we used all positional arguments, meaning the order we passed them in would be interpreted as the order we defined them. The second time we ran it though, we used what’s known as a keyword argument. We let fizz
take its default value, but we explicitly set buzz
to be Boom!
Recap
We’re finally getting into the more exciting parts of programming. Before today, most of what we’ve learned about were the small building blocks that we’ll use to build up an individual line of code, but with functions we’re learning the tools we need to write more complex programs. From here, there are only a few more broad topics that we’ll need to cover before we can start digging into the problem solving of programming.