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.