Functions that execute a bunch of code are very well and good but often we want to get a value back 1
from a function. 2
In this lesson we're going to talk about how functions return a value and get a result back. 3
Returning a particular value is actually why we often call a function in the first place. 4
The reason we're calling the read_csv function here is because we want to pass a CSV file and get our 5
data as an output and store that data in a variable. 6
Let's look at the mechanics of returning values more closely in our get_milk example. In this case we're 7
supplying an amount of money as an input 8
and we're using our input to make a calculation. 9
This part is the same as before - we're dividing the amount of money by the price of milk to calculate 10
the litres of milk to buy. 11
So the question is - how do we return the result of this calculation? 12
And the answer is that we use a keyword - the "return" keyword, followed by the value of what we want to 13
return. 14
We write "return litres" - that would return. 15
It's actually a Python keyword. When Python hits this line of code where it says return, it will exit 16
the function and it will return whatever result comes after that keyword. 17
So in our example here get_milk is outputting the value inside litres. 18
The call to get_milk is actually the same as before - 19
we have the function name and the value for an argument, say 20.5. 20
However, if we run our Python code just like this our output is lost. 21
Our 22
get_milk function is returning a value but we're not storing this value anywhere. 23
So, what you'll typically find is that when a value is returned by a function we're gonna be storing 24
that value in a variable. In this case, our variable called amount is now holding on to 20.5 25
divided by 1.15 or around 17.8. But so much for the theory, 26
let's put this into practice. 27
Suppose you're working for a cutting edge Silicon Valley company and you're building a calculator. 28
You are the engineering lead on the team and you have been assigned the incredibly important task of 29
programming the multiplication button. As a challenge, 30
can you do the following - in the Jupyter notebook, 31
create a function called "times" and have this function take two inputs - it needs to multiply these two 32
inputs together and provide the result as an output of the function. 33
Also you need to test this function that it works. So call your function and multiply 3.14 34
and 5.09, store this value in a variable called test and print out the value of test below 35
the cell. I'll give you a few seconds to pause the video. 36
You ready? 37
Here's the solution. 38
The first thing we're gonna do is define our function. 39
So we're gonna use the keyword "def". 40
We're gonna give a function a name and call it "times". 41
Now we're going to provide the two parameters, say x and y; you can call these parameters anything you 42
want to by the way. 43
We then have the colon, hit Enter and say we want to store the result of the multiplication in a variable 44
so we'll say result = x * y and then to output the value of this function we'll go with return 45
result. 46
Notice how return is colored in green because it's a python keyword. 47
Now suppose you called your parameters a and b instead of x and y, then you've got to be consistent. 48
You've got to have a and b inside the body of the function as well. 49
So now I'm done with my function. 50
I'm going to hit Shift+Enter and I'm ready to test it. 51
So I'm going to call times(3.14, 5.09) and hit Shift+Enter. 52
Our function is working as expected. 53
Now we said we'd store the value of the output in a variable so we'd say test is equal to the times 54
function and then we can print out test. If I hit Shift+Enter now we see the value of our test variable 55
printed below the cell. 56
Now we can actually simplify the code inside our times function a little bit. 57
In fact we don't need this extra line of code right here. 58
So I can comment it out with a hashtag and instead of returning result I can return the calculation 59
directly. I can say a*b. If I hit Shift+Enter on this cell and then hit Shift+Enter again on the 60
cell below, 61
I can see that my function is working - my output is unchanged. If you've decided to write your function 62
just like this, then you're doing the calculation on the same line as the return keyword. 63
And this is absolutely fine. 64
Okay, excellent. 65
So let's continue our little story of working at the Silicon Valley tech company and connect this lesson 66
with our previous lesson on data types. Now that you've written your function, 67
you've probably submitted your calculator code by now to the project team and a few moments later your 68
boss, an accomplished python programmer, will walk over and say "Hey, I've looked at your code and I've 69
got a question for you - 70
have you watched the Monty Python movie for the quest for the Holy Grail?" 71
He then pushes you aside from your keyboard and types in times('Ni', 72
4), and after typing this code into your Jupyter notebook he smiles and walks away. 73
Let's see what happens when we run this code. 74
If I hit Shift+Enter, I see the word "Ni" displayed four times below our cell. 75
Now this is unexpected, right? 76
The times function does something completely different now. That multiplication symbol is not multiplying 77
when we're passing in a string. 78
The multiplication sign in fact is repeating a sequence. 79
And what this shows is that the python code doesn't really care about the specific data types 80
it's running on. 81
In this case, both numbers and strings support this time symbol - both numbers and strings have some sort 82
of operation that uses this multiplication symbol. 83
Now what this means in practice is that we as the developers when we're writing our Python code have 84
to run some tests and be aware of the kind of data types that we're working with and also to detect 85
errors. 86
A reasonable question to ask as well is - is this a bad thing? And why was our boss not angry when our 87
code did something really weird? 88
And the answer to that question is: Python is really all about flexibility. Ideally, Python code should 89
not really care about the types. 90
And this is in contrast to other programming languages like C++ or Java. 91
Python is meant to be flexible. 92
This is a core part of the Python philosophy in fact. Returning to our topic of functions, 93
this is a good time to review and summarize the three flavors of functions that we've encountered so 94
far. 95
We've seen functions with no inputs and no outputs. 96
We've seen functions with inputs and we've seen functions with both outputs and inputs. 97
When defining a function you always have to use that 98
"def" keyword. Then you have the name of the function followed by the parentheses and then the semicolon. 99
Also very important is that the next line, the one below the header in the body of the function is indented. 100
I recommend using four spaces, but most text editors will indent this automatically for you. 101
Now, when you have inputs or parameters, they go between the parentheses following the function name. The 102
parameters are like placeholders. 103
They're essentially a variable with a name that gets a value when the function is called. The cool thing 104
about parameters is that you can use a parameter inside the body of the function. And when you have more 105
than one parameter, you separate each parameter with a comma. Finally we encountered functions that have 106
both inputs and outputs. 107
The key here is that functions with outputs have a return statement. The output is whatever comes after 108
the return. 109
keyword. And the way to remember this is that if you're ever dating a programmer and you tell them to 110
go to a supermarket and buy some milk and they never come back it's because you haven't told them to 111
return anything. 112
So over the past couple of lessons we've worked quite a bit with different kinds of functions. Before 113
we move on, 114
let's talk a little bit about the big picture for a second. 115
I'm sure that at this point you're starting to see how functions really help with structuring code. Instead 116
of copy pasting a bunch of code, we can stick a bunch of instructions into a single function and then 117
just call that one function. 118
That's what's called code reuse and code reuse basically helps you avoid copy pasting. Also, because functions 119
can have parameters, we can call them over and over again while supplying different kinds of inputs. 120
So in scikit-learn we wrote a linear regression that looked at movie budgets and movie revenue and 121
we can run linear regressions over and over again on different kinds of data - that X and that y in that 122
fit function can have different values and we can reuse the code that fits our regression model. 123
Again this is code reuse in action. But there's also a more subtle advantage - functions allow us to split 124
up complex tasks and by splitting up a complex task we get more manageable parts. 125
For example, in this notebook, theoretically we could have had one function that, I don't know, parsed all 126
our data and then generated the graph and then did the regression but we didn't have one line of God 127
code that did everything. 128
Instead we had different functions that were responsible for different pieces of the workflow. So functions 129
are a design tool for organizing our code. 130
We've actually encountered this idea before with the packages that we looked at. 131
So our pandas package had a bunch of different files that made up the package. 132
Our pandas module did not consist of one enormous .py file. The code instead was split up into 133
a bunch of smaller files and each of these files had a specific job. 134
So as we're writing our own code we're going to be battling the same enemies as every other developer 135
out there. 136
We're gonna be fighting change and complexity. Change and complexity are the reason why good design and 137
good structure for code is key. 138
And one thing that developers have learned over the past decades is that splitting up a task into smaller, 139
more manageable parts is really important and it helps a lot. On a small scale, 140
this splitting up of different functionality is accomplished by putting code into functions. And on a 141
bigger scale, 142
this is accomplished by splitting up bits of code into different files. 143
The rationale behind both of these strategies is the same - 144
they're about managing complexity. And on that note I'm going to leave you with a little Python Easter 145
egg. In your Jupyter notebook type 146
"import this" and hit Shift+Enter. You will be greeted by the Zen of Python by Tim Peters. 147
My two favorite lines by a longshot shot are 148
"Simple is better than complex" and "Complex is better than complicated". 149
And on that bombshell I'll see you in the next lesson.