5.5 Write more complex functions - Video Tutorials & Practice Problems
Video duration:
11m
Play a video:
<v ->So now let's look at writing some more complex functions.</v> So, let's go back to our Scratch.py and we already know how to define a function. Let's say, greeting and print("Hello") and then how to call that function. So, greeting and then call it by putting the parentheses there. So I can run this and hopefully embiggen it. Oh, there we go. And it prints out, "Hello". And we know how to take in some parameters, so like name, and then now we're getting this like warning here, parameter name unfilled, and we have to put in a name. So, how do we write functions that are a little bit more flexible? 'Cause right now we have to pass in a value for every parameter that's in the function definition. So, I could say something like, "shout", and then if I put "true", and say, "if shout", "print", we'll make this f-string, and then make it "uppercase". Or else, don't make it "uppercase". So we can run this, we can pass in "false", but now what if we want to just have this "shout" be optional? So we can add a default value between, say, that default, by default it's "false", so this still works. I can pass in "false" if I want. I can pass in "true" if I want. But if I don't pass anything in, then it assumes that it's "false." So what happens if I don't pass a name in? It's missing one required positional argument, named "name". So yeah, if "greeting" doesn't make sense without "name", then make it required by not putting in a default value. Or if we wanted to make it optional, we can say that this defaults to none and we can say if "name", then greeting equals "hello name". else greeting equals "hello". And then we can print the greeting here. So now we can pass in "hello", and we can also pass in "shout" equals "true". So, this is getting into some weird stuff because now we're not passing "name" in, now we're passing "shout". But if we passed in just "true", it would say "hello true", because these also have a position. So if you don't specify which parameter this value refers to, so if it's "name" or "shout", it'll assume that it's ordered and just plug it into the first one. Okay, so if we want to pass nothing in for "name", but we want to put something in for "shout", we can give it a keyword and then say what the value is. So this is getting into some stuff that is, you know, you'll probably see it in some Python libraries and you'll be like, what is going on? What is this? So that's something called star-args, and star-star-kwargs. So you might see this in some function definitions and be like, I have no idea what they're talking about here. So this is a catch-all thing that you can say, like, I do want to accept these things into this function, but also you can pass in any number of extra arguments and any number of extra keyword arguments. So let's see what happens here. If I run this, I've got multiple values of arguments for "shout." Because I'm passing that in here. Or like, it's expecting this to be "shout" and this also to be "shout". So let's just, like, okay so what I can do is say, like, I want "name" to equal "Arianne", and then "shout" equals "false". And then I want to pass in a bunch of values here. So this works. Let's say "shout" equals "true". So this works. And if I wanted to see what extra arguments I was passing in, I could like go print-args, and it passes in a tuple and if I wanted to get a specific arg, I can get the index of it. So args, I find, less useful but kwargs, I think, are more useful. So kwargs refer to keyword arguments and so I can give it a keyword name and a value, keyword and another value, and then I can also print kwargs. And it passes in a dictionary with some keys and some values. And if I wanted to get a specific key, I can access it. And if I'm not sure if that key actually exists in here, I can say get "a", and if it's not passed in, if it's passed in, it'll get the value, and if it's not passed in, it'll just return none. So this is definitely more complicated. But I wanted to show it to you because it's something that you'll see often in some more advanced Python libraries and it takes some while to figure out like why these are useful. You know, you might have a function that takes some things and then passes all the other values into another function, and it keeps like pulling different values out. And then lastly for functions, I wanted to show you nested functions. So that is something that we can do that, like, puts a function inside of another one. So for example, if we wanted to make this get greeting a new function, I can define a function inside of here. Oh actually these shouldn't be the same names. This should be "greet". Okay. So I can say, def greeting, and then I can pass in, "name", and then nest these inside of here for example and return. I can just return this if name was passed in, or else I can return this. And then, so this is a function called "greeting", and it lives within this function called "greet". And then, if I want to use it, I can call it in this outer function. So this would be the inner function, this would be the outer function. So to call a function, I can use these parentheses and pass "name" in 'cause it's expected. So it'll say, "hello Pete", and I can pass this shouting in and, yeah, everything works. Actually I don't even have to pass this name in because, since this function is inside this one, it has access to all of the same variables as long as those variables are defined up here before this function is defined.