- Hello! Welcome to the Path to Programming; the audio supplementary materials for introduction to computer science! - I am a former student that took this introductory course and today I want to talk to you about functions! - You might have heard of functions in a mathematical sense, and in a higher conceptual sense functions in programming work in the same way. Just like in math, functions have variables that go in, and a result that comes out. - So a function in computer science takes a certain input (or several inputs) and returns an output based on the input. - Last week we talked about built-in functions, like print, max, min, int and more. These are built-in functions that already exist in Python. - There can be different outcomes from a function: it can have a result, and it could also have one or more side effects. Functions that don't have a result value instead have side effects. - Some of the built in functions we have talked about so far, like print and input, have side effects, namely, displaying text to whoever is running the program, who we call "the user." - One rule of thumb is that if a function only has side effects and no result value, you won't store the result in a variable (because there is no result). - Functions like print fall into this category, and they generally make something apparent to the user, whether that's text, graphics, or audio. - On the other hand, when you use a function like max, min, int, float or str (string) which has a result value, you do need to store the result in a variable. These functions don't have side effects, and their purpose is to generate their result values that some other part of the program will further modify or make apparent to the user. - Basically when you use a function that has a side effect there will be something displayed, but if you use a function that only produces a result, nothing will be displayed unless you store that result in a variable and later use that variable with a side-effect function. - Of course, there are some complicated functions, like input, which have both side effects and results. Input displays text, but also asks the user to enter their own text, and it makes that text available for use in your program as its result value, which is why despite having a side effect, you can store the result of input in a variable. - Now that we know the difference between side effects and result values, let's talk more about functions, but instead of talking about the built-in functions let's talk about user defined functions! - Functions are ways that you can store instructions to be used later, and they're quite powerful. Once you can define your own functions you will be able to perform a variety of different operations that are not in the library of the programming language you are using. - By capturing common patterns you can write so many functions. So let's dive into the nuts and bolts of how you can come up with your own user defined function. - The first thing you must do when writing your own function is to define it! - To do this in Python you would use the def keyword. When you define a function you can name the function whatever you want, but make sure to pick a name that makes sense to everyone else that would use the code you wrote and not just you. - Once you have a name then you may specify one or more parameters. A parameter is basically a slot that you can use to give information to your function when you call it. - Each time anyone calls your custom function, they must supply an argument value for each parameter that you set up when you defined the function. - For example if you define a function with one parameter named 'x,' whoever calls that function will need to supply one argument, and whatever value they supply will be called 'x' within your code. - After defining your parameters, you have to define how your function will actually work, and this is done in the body of your function. - This is the meat of the function and tells the computer what exactly your function will do, and it's made up of Python code statements just like the code you've already been writing. For example if you are writing a square function the body is where you would tell it to multiply the number with itself. - When you call a function, Python executes each line of code that you wrote in the function body, until it reaches a return statement. - If that return statement has an expression after it, Python will simplify that expression and the resulting value will become the result value of the function. - If the return statement doesn't have an expression after it, or if Python reaches the end of your function body without seeing a return statement, the result value of your function will be the special value None, which is Python's way of saying "there's no actual value here." - Either way, whoever called the function will get back the result value, which they can store in a variable or use as part of an expression, just as you've already been doing with built-in functions. - An important thing to pay attention to when writing the body of your function is to indent. - Indentation is a part of Python and tells the computer how to read what you have written: code that shares the same indentation level will be treated as part of the same group, for example, as the body of a function. - If you don't use indentation correctly the computer will get confused, and won't know how to read what you have written. If you don't indent correctly you will get an indentation error so make sure that you are indenting it correctly and consistently! - Last week we also touched on the memory model and how useful it will become and functions are a place where you can use the memory model to really understand what is going on behind the scenes! The application of the memory model to a function is called the Function Call Model. - By following the function call model rules we can figure out the result value of a function. - We already talked about how you can write your own function by using the def keyword, using parameters to accept arguments and specifying what will happen using a function call body. - When you call a function, behind the scenes Python creates something that is called a function call frame. - You can think of the function call frame as a box or special zone that can store temporary variables which will only be available during the processing of that function call. - So this all happens behind the scenes and you don't really interact with the function call frame as a programmer, but Python or the programming language you are using uses the function call frame to be able to execute a custom function without interfering with any other variables that might exist. - The function call frame contains the name of the function, the parameters, each filled with their corresponding argument values; and the body of the function. The function call frame evaluates the body of the function using the arguments that were provided as the value of each parameter, and running every line of code in the function body from the top to the bottom. - The frame is important conceptually because it is not something that you can really see at work when you are coding because it is discarded after the result value is determined and returned. - This means that variables within a function, including its parameters, are thrown away when we get to the end of the function, and they are not accessible within other functions: only the result value is. - Just to go over what we talked about in even more detail, when you define a new function, which you do just once, you set up the parameters and specify what code should execute. - Then each time that function is called, a new function call frame is created so that Python can process that specific function call (which might have different argument values than another function call to the same function). - The function call frame is a special zone where the behind the scenes work takes place with temporary variable reassignments etc. - Eventually, when the function is finished, the function call frame is discarded, and only the result value is returned to the code where the function call was made (which can now continue). - As a concrete example, imagine that you write a function named 'square' with one parameter named 'x,' and a single line of code in its body which read 'return x times x.' - If you call that function by writing 'square parenthesis five close parenthesis', you are providing 5 as the argument value for that function call, and so x will be 5 in the function call frame that is created. - With x assigned to 5, the return expression which was 'x times x' will evaluate to 25. So wherever you wrote your function call, that part of the code will simplify to the value 25. - Note that if there are multiple parameters, there must be the same number of arguments, and each argument is assigned to be the value of one parameter based on the ordering of the parameters and arguments: first with first, second with second, etc. - Now that we know what goes on behind the scenes when you call your function with the function call frame, let's talk about more nitty gritty things. - First we already mentioned that there can be multiple parameters in a function. The function call frame is able to take care of this by matching up each argument value with a single parameter as we mentioned. - Besides having multiple parameters you can also call other functions within a function that you have defined. Calling a function basically means that you can use it in the body of the function that you are currently writing. - The only condition required to call a function is that it either has to be built-in or you must have previously defined it, essentially it must exist before you call a function that uses it (but not necessarily before that other function is defined). - Calling multiple functions can be useful when you are trying to make more complicated calculations. - Another concept about functions that we will touch on is the local variable. A local variable only exists in the body of the function, which is where you define how your function will work in case you forgot! You can not reference a local variable outside of the body of a function. - Parameters are also a kind of local variable. They are assigned a value when the function is invoked (which is another word for calling a function). They also cannot be referred outside the function. - Finally I want to touch in the difference between using a print statement or a return statement in the body of your function. - This concept will tie into fruitfulness which I will touch on more in a minute, but fruitfulness will become very important as you start writing more complicated functions. - A return statement in the body specifies the result of the function invocation whereas a print statement causes characters to be displayed on the screen while your function is running. - Think back to the beginning of this episode when we mentioned that the print statement has a side effect, which displays something on your screen. - Be careful to not confuse print and return statements, as they have different uses. - A return statement creates a result value calculated from the function call frame, and that result gets returned to whoever called the function, so it can be used elsewhere in your program. - On the other hand, a print statement displays text to the user, but this text does not become accessible for further operations in Python. - Typically you will assign the result of a function which has a return value to a variable so that you can use it later on, but if a function just uses print to display text and does not have a return value, you will not really do that. - As we mentioned before if your function does not have a return statement the function will return the special value 'None'. - If a function has a return value other than None than it is called fruitful. - If a function does not have a return value then it is non-fruitful. - For example the print function does not have a return value (as we mentioned it displays text as a side effect) and therefore it is a non-fruitful function. - That was our introduction to functions! - Make sure from this episode you take away the basic ideas of what a function is, how you define a function using a name, parameters and a body and how when you call a function, Python executes it using the function call model. - Once you understand these basics you can think about more complicated scenarios such as a function with multiple parameters, or a function that calls another function. - Finally make sure you understand the difference between a fruitful and non fruitful function. - Thank you for joining me on your path to Programming! I hope your journey is going well.