Hello, and welcome to Chapter Four,
Functions, in the book Python for Informatics.
As always, these slides and this audio and
this video are copyright Creative Commons Attribution.
Now we are to the point, you know, Chapter Four, we're sort of well into the class.
So I figure I should introduce myself a little bit, let you know a little bit.
As I said before, I think in the beginning,
we're tape, I'm taping this in a
wonderful building at the University of Michigan called the North Quad.
It's a relatively new building, it's got some
residential sections and some academic sections and some
classrooms, and one of the classrooms that
I typically teach in is actually 2255 North Quad.
It's a really beautiful room
with great ways for people to interact, and so sometimes
I'm teaching, you know, little tiny Dr. Chuck down here.
With a smile on the face.
And sometimes my students are taking me on, taking my
classes on campus and sometimes students are watching me through lecture.
And so this building is really beautiful and if
you ever get a chance to come to Ann Arbor
and look at it, maybe walk through it, it's really, it's really quite nice.
One of the things I like about it is
that I think it's really highly inspired by Harry Potter.
The kind of, of course, Oxford and Cambridge are
the real inspiration for Harry Potter, but our, our cafeteria,
for example, it kind of looks like the four tables
in Hogwarts and you can kind of imagine a snowy owl
flying around and a Sorting Hat at the, at the front sorting people.
And so the nickname, the nickname for the place is Quadwarts, because it's North Quad
Quadwarts, that's like Hogwarts and North Quad kind of jammed together.
And of course, given that we sort of think
of ourselves a little bit as Harry Potter,
people when they first come in September often sort of decide
to sort themselves and a few years back
when we first started the building the students
decided that I did not get to be in Gryffindor.
As a matter of fact, it's probably time for me to to
show you who I am, and who I've been sorted to be.
So the students decided that I couldn't be in Griffindor.
That I had to be in Slitherin,
and that's because of my name, Charles Severance.
And sever is snake.
What's even cooler, of course,
is given that I teach Python, Slitherin's house is
a snake, right? So it makes a lot of sense, I even have
this really fancy Slitherin teacup that I use to drink tea during lectures.
Sometimes I drink coffee, and
sometimes I drink tea. Oh wow, this thing itches.
So let me just get rid of it.
If I had any hair, that would mess my hair up.
So let me get rid of this for the rest of the lecture.
So there I am, okay. Enough of that, back to,
back to Dr. Chuck. [CLAP]
So, with that sort of brief, brief interlude, the topic of
the actual topic of this lecture is Functions. And so storing and
reusing is basically an idea that
we will often have a series of steps that we will
want to use over and over in a program, increasingly complex.
The things that we'll use in this lecture are kind of silly because
I have to keep them short so the slides don't get too long.
But a good example of, you know, the kind of work is maybe I am going to use
Google's geocoding service and I am going to send some unstructured
data and get a GPS coordinate back.
And that's a service that I want to call and it would
maybe be about this much lines of, this many lines of code.
And I'm going to want to do that all over the place.
So do I want to put this many lines of code 40 places in my program?
Or do I want to put it one place and
then call it in the various places that I need it?
And so that's why I call it the store and the reuse function.
So if we take a look at the simple syntax here.
These things are called functions and in some languages it's called subprograms,
but we call them functions in Python. And the keyword
that we're really going to focus on is def, which stands for
define, and what happens here is when Python sees this def keyword
it actually doesn't run the code.
It says, oh, you're going to make a function and you're
going to kind of turn on a recorder and start recording this code.
So it has a colon at the end of it.
So it has an indented block afterwards.
And so the indented block becomes recorded.
So instead of running the code, like if we just
put print hello and print fun, it would run it.
Instead it says, hey don't run it right now, name it hello.
We give it a name.
It's kind of like a variable. We choose the name.
We've chosen hello as the name of this.
Define it as hello, have it have these two
lines of Python in it, and we'll use it later, okay?
And so that's the function definition.
That's the store phase.
That is it's sort of like, it doesn't really run those lines.
It sort of makes a variable called hello
that actually contains Python code
rather than containing like 12 or a string or something like that
that we've worked with before.
So this is the store part, and then the reuse part is, we then have extended Python.
We now can call our bit of code. So we say, hello, hello name is what we came up with,
parentheses, and then that says, remember that code that I
put in there under the name hello?
Run it now and, so, so, so if I
start looking at that and then it just continues.
So let me kind of clear this and start over again.
And, so if I watch what Python does from the beginning as
it reads here and it goes oh, you're defining a function named hello.
Great, I will sort of remember, remember.
I got that remembered for you, let's continue on.
Oh, hello!
You want me to run that stuff that
you just got done storing under the name hello.
So then it kind of goes and runs it and out comes Hello Fun.
Then after that it runs to the print and out comes print Zip.
And we say, you know what?
I want to reuse that again.
I stored it once, I can reuse it as many times as I want.
And now, hello, and then these two lines of code run a second time.
So we stored them once, gave them a name, and then
ran them twice, in the context of wherever it is we wanted.
Now this is not sort of a profound
a profound reason to use it in this.
I'm just trying to give you the notion that there's a
way to store and name code that then you can retrieve later.
That's really what's going on here.
There's two kind of functions inside of Python, and
we've actually been using them almost from the very first lecture.
And that is there are built-in functions that Python provides
to us like float, raw_input, int, those kinds of functions.
Those are just part of Python but we call them as functions.
The difference is we don't write them.
And then there's user-defined functions, functions that we write.
Functions that create functionality that we want to make use of.
Like encapsulating the ability to compute pay for time and a half for overtime.
And so, we name these things and we
treat them as new reserved words that we've created.
They're kind of an extension to the language
as it were.
So when we're coming along, we define a function with the def keyword, right?
The def keyword
is a reserved word. It's one of the many reserved words back in Chapter One
that we talked about, and it indicates to Python the beginning of a function.
We define it, and then when we call it, which is called invoking,
it's like, we're building it, and then we're invoking it.
And you can build it once, and then invoke it many, many times.
So for example, here is a built-in function called max that
finds the largest character, the sort
of lexicographically largest character, in a string.
And so it's like okay, tell me the maximum character.
And so max is not some code that we've
written but we are invoking a function here and we're
passing in an argument to that.
So the argument is this stuff in between the parentheses.
So the max function can find the maximum of many different things.
At this moment we want it to find the maximum of that particular string.
The highest character
in that particular string. So, this is a left, a right-hand side of
an assignment statement too. So that has to be evaluated to a value.
So it goes into the function,
does whatever things the function wants to do,
and then the function gives us back a value
that becomes the value for max parentheses Hello world.
And that value in this case is the letter w, okay?
Because the letter w was decided to be
the highest letter and that's what max gives us back.
And then when we're done with that, then that w ends up being assigned.
The assignment statement completes.
And so you can think of the function evaluation
as happening as part of the right-hand side expression calculation.
There could a plus here and other stuff
and it's just, at some point, a big expression.
And this one, it's a simple expression with just one function call.
Now if we look at this, there is some code somewhere.
Somebody wrote some code.
It's part of Python.
You didn't write it. There's a max function somewhere.
And you can think of a function as having some input.
It's kind of like a program, that's why
some languages call these things subprograms.
Because they have an input, they do some kind of useful works, whatever
that useful work happens to be, and then they produce some kind of an output.
Right? So Hello world
is the input, a string, the arguments, the thing we're passing in.
Hello world is what's being passed in to the function.
The function is running and then something comes back and is sent back.
So it has input, processing, and output.
Input, processing, and output. So that's how a function.
Some stored code, whether we wrote it or not,
they work the same when we call
functions, right?
So you could think of this as, somewhere inside of the Python library
is some code that maybe has a little def in there, and the name,
they named the function max, and it takes a single parameter.
And it does some blah, blah, blah, blah,
loopy blah, blah stuff, whatever max wants to do.
Whatever we need max to do based on
the specifications that max is supposed to support.
But somewhere
there is code inside of Python
that actually represents the function definition.
It's a built-in function because it comes with Python
and we didn't have to do anything to add it.
So some common built-in functions that we have
been using all along, good examples are the float, which
takes as input anything and
returns you a floating point number version of that.
Type, which takes a parameter of a variable or a constant
and says, what is the type of this.
Float, again converting.
Type, again, and float.
So these are all things that, we've been calling functions all along.
And it passes the input value into the function, the
function runs and then gives us back a return value
which then participates in the rest of the expression on the right-hand side.
You can think of it's pausing the calculation
on the right-hand side, calling the function,
getting the result of the function back,
and then continuing the evaluation of the right-hand side.
Then coming up with whatever value and then printing that value out.
Okay? Another thing that we've done
is we've done string conversions. Right?
So we've converted, in this case, a string to an integer.
And asked what type it is.
We've converted a string to an integer. So, int converts its argument,
whatever that happens to be, into an integer.
So that's just some of the built-in
functions that we have talked about so far.
Now, this becomes more interesting
when we can make our own, own functions.
Oops, there goes my teabag right in the middle of the thing.
Got to take the teabag out, I think it's, whoa, hang on, be right back.
Teabag, okay, there's my tea. So, so we want to make a new function.
Like I said in the other example, we use the def keyword,
the def keyword here, and then we have some indented bit.
We create a name for it and then have some parentheses.
These parentheses will later tell the inputs
that we're going to pass in, but this
function has no input, so we just go parenthesis, parenthesis and then the
all-important colon character which indicates the beginning of an
indented block of Python, that then is, this detects the function.
So, it's important to remember
that while this is executing when Python first
looks at this, it doesn't run these lines of code.
It just remembers them, and names them print lyrics.
So it doesn't cause any printout, it just causes Python to remember.
I probably said that a few too many times. So, so here is
a difficult problem, and I'll let you think about
it for a while.
I want you to kind of mentally go through and execute this code.
And ask what, ask yourself what the output of this program would produce.
How many lines?
How many lines of output would this program produce?
So, how many of you said three?
How many of you said five? Well, the right answer
is actually three. You see five print statements, two, three,
four, five, but two of the print statements are sitting inside of this.
And we never called, we never invoked a function down here, okay?
So, this one,
let's clear this. This one prints, these two get skipped,
this one prints, and this one prints.
So that that's why there are three statements that print.
There is stored, but we never used, a function called print lyrics.
And it's got two statements in it, but we never used it.
So the output of this is Hello Yo 7, and that's because we
never actually invoked it.
We had to say print lyrics parentheses or whatever to cause it to call this.
Okay? That's just to emphasize that as it
looks at it, it does not execute these lines.
So once we've defined a function, once we have given it a name, given it
code that is a part of it, then we can invoke it or call it as many times as we like.
So now,
our little example works a little better if we actually call our function.
Python really doesn't care if you don't call your function.
It's like you told me to make one, I made one.
You didn't use it. There you go.
But if you look at this one now, so here we go, x equals 5.
print Hello, out comes Hello.
Define.
Nothing happens here. Nothing happens here.
It's just remembering.
Okay? Then it says, print Yo.
Then it calls the function print lyrics, which sort of stops us here,
runs these two lines of code. So out comes that and that.
Then it sort of finishes this and it comes back, x equals x plus 2, then it prints x.
That must mean that x is 7, and so out that comes.
And so, again, it's on the first time through.
No, go back, go back, go back.
On the first time through, it doesn't print.
But then when it hits this,
it prints.
You could say print lyrics several more times and
it would run this as many times as it did,
and it needed to, as many times as you want, and it would make output for you.
So you can invoke this is the definition, let's clear this.
This is the definition. This is the call or invoke.
So we are invoking the function, we're calling the function,
we're causing the function to execute.
Here we're just causing the function to be looked at and defined,
but not actually executed. Hope that's clear.
Now, when we pass data into a function, and functions
that don't take data are not as useful as they could be.
There are plenty of things that do, times
that you build a function doesn't take data.
But the most interesting functions are the ones
that you could hand them something to work on and
they could do their work and then come back with whatever.
So this max function is a good example of this, one that's taking an argument.
We call the things in between the parentheses
when we're invoking the function,
we call the things in between the parentheses arguments, okay?
So that's passing into the function.
Feeding data into the function. So we put arguments in between them.
So for example, here we have a little program.
That
that is, it's a function named greet, and now we are
going to define this function and we're going to say, you know what?
I would like to take a parameter, let's take a parameter.
Let's have one parameter come in.
And we need kind of a placeholder for that
parameter, so within the function we're going to use lang.
Now this isn't actually a real variable.
It's kind of like a, it's a placeholder variable.
So this first parameter, whatever it is,
when it's called, is going to be lang.
And so if that first parameter is equal to es,
we're going to print Hola.
And else if it's equal to fr we'll print Bonjour.
And otherwise, we'll print Hello.
So there's apparently three languages in the world, Spanish, French, and English.
And if it's not Spanish or French, then it must be English.
But, I, you have to keep this kind of small, so my screen doesn't get too big.
So this is again just the definition and if you type this
into the interactive thing it gives you this dot dot dot prompt.
And so we now have this thing called greet
and now we've extended Python to add our own function to Python.
And now we can say greet en and so it runs this code
except that en is lang and so that comes, and then it prints Hello.
So out comes Hello. Now later we can say, oh,
I would to do a greeting, but this time I'm going to pass es in as it.
So lang becomes, for this execution, es. And then, so it prints out Hola.
And then the next execution, lang is fr. So it executes this three times but
lang is different each time because we've passed in different parameters each time.
So that's how we can kind of write general-purpose code
inside the function and then reuse that general-purpose code in different ways.
Okay? It's a real powerful, powerful mechanism
that makes functions far more useful.
Now, functions don't necessarily just have to do stuff.
A real powerful mechanism in a function is what we call a return value.
So a function can take its arguments, do some work.
We've seen that.
And then it can return a value. And the key to the return value is, when we call the
function, like we were calling max,
it gives us back some value like the little w, okay?
So here we're going to make a function called greet that takes no parameters.
Doesn't take parameters, but it has another keyword.
It's another reserved word in Python
and whatever we put on this
return statement shows up as the replacement in this expression.
So, whatever greet is, it runs greet and
then the return is kind of a residual value.
So if we say print greet, comma, Glenn.
it says Hello Glenn, because the return value
for the greet function is the string Hello.
And if we say greet Sally,
it says Hello Sally.
And so, and it's run the code twice and the return function, return value has
been put in here instead. And so the Hello came there and the Hello came there,
so we get the two lines.
So, return is a statement that both terminates the
execution of the function and defines the value of
what will be replaced when the function call comes back,
in the line that the function was called from.
So here is a little smarter version of our greet function.
It's very similar, it's called greet still, takes lang as a parameter.
And if the language is es, then it returns the string Hola.
If the language is French, it returns Bonjour.
Otherwise, it returns Hello.
So we're not actually doing the print, if you
go back on the other slides, we were printing.
But now we're just returning a string. Okay?
And so now, I can call print greet, and pass en in,
so then that runs the code once, with lang equal to en.
And I get back Hello, and then comma, Glenn.
Then I call it again and I pass es in. And then
that time it returns, the return value here becomes Hola, a string Hola.
Hola Sally. And then Michael, I'll pass in one more time.
Lang is now fr,
the string fr, and so it returns a Bonjour and
so the, the residual that is here is Bonjour, and so out comes Bonjour Michael.
So there is lot to this, right?
You're passing stuff in.
You have this kind of placeholder variable.
And you have this return that sort of appears where it was called from.
This goes in, does its work, it comes back, and there's sort of the
residual value that sits here.
You don't have to have a return in a function, but if you want to
do something with the value, then you have to have a return in the function.
We call the functions that produce values
fruitful, and the other ones are called void.
[LAUGH] So, that's a good name for them.
So, to review sort of this, arguments,
parameters, and results, if we look at max,
the original thing, where it's looking for the largest, lexicographically
largest letter, it looks Hello world is the argument that's passed in.
We have this sort of formal parameter here called inp which is not really a
variable, it just happens to refer to whatever is the
first argument in any particular call.
And then it does its little thing and runs loops and does all these things and
at some point it returns w, so that the thing that comes out when the function
quits that becomes the replacement value here is a lowercase w string.
And then that is the w that goes over in the big.
So the return is what defines what comes back here.
Because you think of this as, it's looking at this. It suspends for the moment.
It runs this code.
It's holding.
It's holding itself here.
It's running this code and then it comes back to here.
Okay?
And the return value is what defines coming back.
So, of course you can have more than one parameter and they are in order.
So here we have an a and a b.
These, the name of these things doesn't really matter.
They're just relevant inside of the function definition.
So we are going to add two numbers together
by taking a + b, and then returning the sum.
The added variable is just kind of local to this function.
And now we can say, you know, addtwo, 3, comma, 5.
And then this will come back as 8, and then 8 will get assigned
into x, and so that will print out 8.
And so you can have as many of these as you want
and the order matters and there is a one-to-one correspondence.
3 goes to a and 5 goes to b
when the thing is called.
And then the return value again comes back.
Okay? So that's, sort of, arguments.
And like I said, not all functions have to return values.
We call them void functions when they don't return anything.
It's totally fine for that to be the case.
So at this point you might be thinking to yourself, okay, great, well I still
don't quite get why to use functions.
And in reality, in the first 10, 11 chapters of this book, other than
using lots of functions, we're not really going to spend a lot
of time making functions because most of our programs are going to kind of be
that long and we're not going to do a lot reuse in the program.
And there'll be a time when your programs become complex enough.
You'll be like, oh, thank heaven for functions.
I think it's premature to say you must use functions, even though
there are some exercises that just say, hey, do this with a function.
Just so you kind of get the understanding of a function.
You will find soon enough,
as your programs grow, you'll go like, oh,
I keep doing this same thing over and over again.
Let me pull it up into a function and pass
a parameter in, have a return value, and away you go.
Or, you might find that you're moving from
one program to another and you have this common thing
that you want to do, so you make yourself a library that you drag along.
And we will do lots of libraries.
The book in the second half does lots and lots of library
stuff, doing things like parsing XML and this, that, and the other thing.
So, so don't feel like you need to use functions on every
assignment, because they're a natural thing when a program gets big enough.
So, so just kind of understand them on a
mechanical level, but
it'll come to you at the right time
when it's time to start building your own functions.
So in this class, we kind of, you know, talked about functions.
Just got you started.
Talked about parameters, talked about built-in functions,
talked about return values, the store and reuse pattern.
So, the problems at the end of the
chapter for this particular chapter are relatively straightforward,
in that, like I said, we don't have a real strong
need to do functions yet in this class because the programs aren't large enough.
But I just said okay, take, take one
of your previous assignments and refactor the code
so that at the top there is a def computepay, and you put like the if
and whatever in here, and then later on
you do your code and then you call computepay.
So you took code that you already had, you
move it up into a function, and make a function.
And I've also online got sort of a
sample of this, because it's, it's a little complex.
And so you should be able to find, on Python Learn or on the course site,
you should be able to find a good example,
because I really want you to sort of get this.
Like I said, there will come a time
when functions will make the most sense to you.
But coming up next, of course, is Chapter Five, and that's loops.
And loops are going to rock the house, And so we really, that's our
fourth major pattern is loops and and I'm looking forward to it.
So we'll we'll see you at the next lecture.