CODE WITH MARTIN

6. Functions


What Are Functions?

Functions are another major step in programming. Like variables, every programming language has functions. They allow us to group statements together with a name, then using that name, we can tell Python to run the statements that we put inside the function.

Python will then run the statements in your function and return right back where it left off at the point you asked it to go run the function.

Creating Functions

Let's take a look at some code that shows how we create a function, put statements inside of it and run it.

def greet():
    print("Hello.")
    print("Nice to meet you.")

greet()

Starting with line 1, the first word 'def' means we want to define a function. The next word 'greet' is the name of the function. We then immediately put empty round brackets '()' and a colon ':'. We'll explain what these round brackets mean shortly.

This first line of declaring a function is called the function declaration or sometimes function signature.

Just like how variables have to have unique names, functions also have to be defined with a unique name from other functions. They also can't have the same name as any defined variables. Function and variable names must be unique.

So let's take a look at lines 2 and 3. Notice anything strange about these? If you're wondering why they are indented with spaces, you've spotted the next important aspect of functions in Python. Lines 2 and 3 are statements that print text to the terminal, however, Python considers these lines as belonging to the 'greet' function because of how they are indented directly after our function declaration on line 1. There are 4 spaces before these statements on lines 2 and 3.

Python accepts indented lines starting with just 1 space. It's common for Python developers to use at least 2 spaces, but most commonly, 4 spaces. I highly recommend you stick to the standard of 4 spaces.

Visual Studio Code, your code editor, will try to help you out with these indentations and automatically start indenting your lines when it thinks you are writing a function. By default, VS code uses 2 spaces for it's indenting. To change this to 4, at the very bottom right of the window, you will see a label that says 'Spaces: 2' - click this. A menu at the top of the editor should now show some options. Click on 'Indent Using Spaces', then click the number 4 in the next list. The label at the bottom will now change to 'Spaces: 4'. When writing functions, VS code will now automatically use 4 spaces when assisting you.

When we stop using indented lines, Python stops assuming that statements belong to the function. Line 5 is a statement that does not belong to the function 'greet' because it's no longer indented.

When Python reads that you are defining a function on lines 1 to 3, it does not execute the statements belonging to the function. It does make sure that your code is valid at least, but it simply skips over those statements and only remembers that they belong to your function. Those statements inside the function will only execute when we execute the function.

To execute our defined function, we type it's name, followed by empty round brackets. Line 5 in our example executes the function.

When we execute the function, Python jumps back up to line 2, because this is the first statement belonging to the function 'greet'. It then executes the statement on line 2 and then executes the next statement in the function on line 3. There are no other statements in the function so Python comes back to line 5 where we executed the function.

You can call a function as many times as you want. Here's an example:

def greet():
    print("Hello.")
    print("Nice to meet you.")
				
greet()
greet()
greet()

Run the code and you'll see how Python has executed the function 3 times.

Functions must be defined before you can start calling them. If the code 'greet()' to execute the function appeared above the code where the function is defined, Python will complain with the error 'NameError: name 'greet' is not defined' in the terminal.

Function Parameters

Functions are a little more useful than just stuffing statements inside of them. Functions can accept data through what we call function parameters. We can declare temporary variables in the function declaration that only exist during the execution of the function.

Consider the following code:

def greet(first_name, last_name):
    print("Hello, " + first_name + " " + last_name + ".")

greet("Lex", "Luthor")

Function parameters are defined inside of the round brackets in the function declaration on line 1. Our function accepts two parameters named 'first_name' and 'last_name'. Each parameter is separated by the comma ',' character. These two names are temporary variables that only exist during the execution of the statement in the function on line 2. We use the parameter variables to print a message in the terminal.

So if the two parameters are variables for the function, what value do they have? If you look at line 4, where we execute the function, we provide two strings inside the round brackets. These two strings, separated by a comma, are the values for the variables in the function declaration. When the function executes, the variables in the function declaration are set to the values we provide.

When executing a function, we call the values we pass to it 'arguments'. So 'parameters' are what we see in the function declaration and 'arguments' are what we specify when executing functions.

Here's an example of calling the function with different arguments each time:

def greet(first_name, last_name):
    print("Hello, " + first_name + " " + last_name + ".")

greet("Lex", "Luthor")
greet("Super", "Man")
greet("Doctor", "Strange")

We can also pass variables to function calls. The values of the variables we use when executing the function are passed in to the function and set on the function parameters. The following shows this:

def greet(first_name, last_name):
    print("Hello, " + first_name + " " + last_name + ".")

first = "Lex"
last = "Luthor"

greet(first, last)

Now that you have seen how we call functions with arguments, have you noticed that the 'print' we've been using is also a function? This function has been defined for us by Python. It's one of hundreds of built in functions inside the Python language. We'll get to learn more functions provided by Python as we learn more about Python throughout the course.

Function Return Values

Another handy feature of functions is producing a result. A function result can be returned back to the line that executed the function and stored in a variable, or provided as an argument to another function call.

The following code shows a function that returns a value:

def sum(first, second):
    return first + second
	
total = sum(5, 10)
print(total)

On line 2 inside the function 'sum', we use the special Python keyword word 'return' to tell Python that we wish to return a result from the function. This function simply adds together the two parameters and returns the result.

On line 4, we define a new variable and assign it using the '=' operator to the result of the function 'sum'.

The following code shows how a function returning a value can be provided to a separate function call that accepts arguments:

def sum(first, second):
    return first + second
					
total = sum(sum(2, 3), 10)
print(total)

This might look a little confusing at first, but lets break it down. On line 4, we are assigning a value to the variable 'total'. Python can see that we are executing the sum function which we know accepts two arguments. However, for the first argument of the sum function, we are calling sum again! Python will execute the second sum statement 'sum(2,3)' first and use it's return value as an arguments for the first sum function. If this a bit confusing, consider this easier example:

def sum(first, second):
    return first + second
									
print(sum(5, 10))

In this example, we are calling the 'print' function, but it's argument is a function call to 'sum'. Python first executes the sum function and gives the result value of that to the print function.

One final mention of the 'return' keyword is that it can be used to leave a function before all of the function statements have been run. It can also be used without returning a value. The following code shows this:

def return_test():
    print("Part One")
    return
    print("Part Two")
													
return_test()

Running this code, you will notice how the second print statement does not print on line 4 due to the return statement on line 3 telling Python to return out of the function before reaching line 4.

What We Learned