# Functions in Python

So far in this course, we have been using built-in functions that come with Python. In this lesson, we will learn how we can create our own functions. But before we do that, let’s spend some time learning why we even need them in the first place.

Suppose you want to create a program which allows users to calculate the sum between two numbers. At this point, you shouldn’t have any problem writing such programs; anyway, your code might look this:

This program calculates the sum of all numbers from `10` to `30`. If we want to calculate the sum of numbers from `100` to `200`, we would need to update the program as follows:

As you can see both versions of the program is nearly identical, the only difference is in the values of the `start` and `end` variables. So everytime we want to calculate the sum of two numbers, we would need to update the source of the program. It would be good if we somehow just reuse the entire code without doing any modification. We can do that using functions.

## What is a Function?

A function is named group of statements, which perform a specific task. The syntax of defining a function is as follows:

A function consists of two parts: header and body. The function header starts with the `def` keyword, followed by name of the function, followed by arguments and ends with a colon (`:`).

The `def` is a reserved keyword, so you shouldn’t use it as a variable or function name in your programs. `function_name` can be any valid identifier. After the function name, we have a list of arguments inside parentheses separated by a comma (`,`). We use these arguments to pass the necessary data to the function. A function can take any number of arguments or none at all. If a function doesn’t accept any argument then the parentheses is left empty.

In the next line, we have a block of statements or function body. The function body contains statements which define what the function does. As usual, Python uses indentation of statements to determine when block starts and ends. All the statements in the body of the function must be equally indented otherwise you will get a syntax error.

Pay special attention to the last statement in the function body i.e `<return statement>`. The `return` statement is used to return a value from the function. The `return` statement is not mandatory, some function return values while others don’t. If a function doesn’t have `return` statement in the body then a reserved keyword `None` is returned automatically. `None` is actually an object of a built-in type `NoneType`. Don’t worry if you find `return` statement confusing; they are not, we will discuss `return` statement in detail in the upcoming section.

Here is a small function which prints current date and time along with a greeting:

python101/Chapter-13/first_function.py

The `greet()` function doesn’t accept any arguments, that’s why parentheses are left empty. The function body contains two `print()` statements. These two statements will be executed when we call `greet()` function. The `greet()` function doesn’t return any value.

## Function Call

A function definition does nothing by itself. To use a function we must call it. The syntax of calling a function is as follows:

If a function doesn’t accept any arguments then use the following syntax:

The following code calls `greet()` function:

python101/Chapter-13/calling_first_function.py

Output:

The function call must appear after the function is defined otherwise, you will encounter `NameError` exception. For example:

python101/Chapter-13/call_before_definition.py

Output:

When a function is called the program control jumps to that function definition and executes the statements inside the function body. After executing the body of the function, the program control jumps back to the part of the program which called the function and resumes execution at that point.

The following example demonstrates what happens when a function is called.

python101/Chapter-13/transfer_of_control.py

Output:

In lines 3-5, we have defined a `greet()` function. The `print()` statement in line 7, prints string `"Before calling greet()"` to the console. In line 8, we are calling `greet()` function. At this point, the execution of statements following the call to `greet()` halts and program control jumps to the definition of the `greet()` function. After executing the body of the `greet()` function program control again jumps back to the point where it left off and resumes the execution from there. Our previous program has only function. It is not unusual for programs to have hundreds or even thousands of functions. In python, it a common convention to define a function called `main()` which gets called when the program start. This `main()` function then goes on to call other function as needed. The following program demonstrates the flow of program control when we have two functions in a program.

python101/Chapter-13/two_func_program_control.py

In lines 3-5, and 7-10, we have defined two functions `greet()` and `main()`. The `greet()` function is now updated to accept an argument called `name`, which it then uses in the next line to greet the user.

The `main()` function doesn’t accept any arguments and has three statements inside the body.

The statement in line 12, calls the `main()` function. The program control jumps to the body of the `main()` function. The first statement inside the `main()` prints string `"main() function called"` to the console. The statement in line 9, calls the `greet()` function with an argument `"Jon"` which will be assigned to the variable `name` in the function header. At this point, execution of statements following the call to `greet()` halts and program control jumps to the body of the `greet()` function. After executing the body of the `greet()` function, program control jumps back to where it left off and executes the `print()` statement in line 10. As there are no more statements left to execute in the `main()` function and program control jump again back to where it left off to execute statements after the function call (line 12).

## Local Variables, Global Variables and Scope

Variable Scope: The scope of a variable refers to the part of the program where it can be accessed.

The variable we create inside the function is called a local variable. Local variables can only be accessed inside the body of the function in which it is defined. In other words, the scope of a local variable starts from the point they are defined and continues on until the end of the function. Local variables are subject to garbage collection as soon as the function ends. As a result, trying to access a local variable outside of its scope will result in an error.

On the other end of the spectrum, we have Global variables. The Global variables are variables that are defined outside of any functions. The scope of a global variable starts from the point they are defined and continues on until the program ends.

Now consider the following examples:

Example 1:

python101/Chapter-13/variable_scope.py

Output:

In line 1, we have created a global variable named `global_var`. It is then accessed in line 12, inside the `func()` function and in line 16, outside the function. We have also declared a local variable named `local_var` inside the function `func()`. It is then accessed inside the function in line 9.

Let’s see what happens, if we try to access a local variable outside the function. To do so, uncomment the code in line 18 and run the program again.

Output:

The error `NameError: name 'local_var' is not defined` tells us that there is no variable named `local_var` exists in this scope.

What if we have local and global variables of the same name? Consider the following program.

Example 2:

python101/Chapter-13/same_global_and_local.py

Output:

Here we have a global variable `num` in line 1 and a local variable of the same name inside the function in line 4. Whenever there is a conflict between a local and global variable inside the function, the local variable gets the precedence. This is the reason why `print()` function (line 5) prints the value of the local `num` variable. However, outside the function, `num` refers to the global `num` variable.

We can also use the same variable names in different function without conflicting with each other.

python101/Chapter-13/same_variable_names_in_different_functions.py

Output:

## Passing Arguments

An argument is nothing but a piece of data passed to the function, when it is called. As said before, a function can take any number of arguments or none at all. For example, `print()` function accepts one or more arguments but `random.random()` function accepts none.

If you want a function to receive arguments, when it is called, we must first define one or more parameters. A parameter or parameter variable is simply a variable in the function header which receives an argument when the function is called. Just like local variables, the scope of parameter variables is only limited to the body of the function. Here is an example of a function which accepts a single argument:

When function `add_100()` is called with an argument, the value of the argument is assigned to the variable `num` and the `print()` statement prints the value of `num` after adding `100` to it.

The following program demonstrates how to call a function with an argument.

python101/Chapter-13/function_argument.py

Output:

In line 5, function `add_100()` is called with an argument `100`. The value of the argument is then assigned to the parameter variable `num`.

Example 2: Function to calculate the factorial of a number.

python101/Chapter-13/factorial.py

Output:

The factorial of a number `n` is defined as multiplication of all digits from `1` to `n`.

where `n!` denotes factorial of `n`. Here are some examples:

Now, let’s see how the for loop works when the value of `n` is `4`:

Before for loop starts `i` not defined `f = 1` `n = 4`
After 1st iteration `i = 4` `f = n * f = 4 * 1 = 4` `n = 3`
After 2nd iteration `i = 3` `f = n * f = 3 * 4 = 12` `n = 2`
After 3rd iteration `i = 2` `f = n * f = 2 * 12 = 24` `n = 1`
After 4th iteration `i = 1` `f = n * f = 1 * 24 = 24` `n = 0`

After the 4th iteration loop terminates and `print()` function prints the factorial of the number.

Example 3: Passing multiple arguments to the function

python101/Chapter-13/multiple_arguments.py

Output:

When `calc()` function is called in line 8, the argument `10` is passed to parameter variable `num1` and `20` is passed to parameter variable `num2`.

The order of arguments passed while calling the function must match the order of parameters in the function header, otherwise, you may get unexpected results.

## Pass by Value

Recall that everything in Python is an object. So a variable for an object, is actually a reference to the object. In other words, a variable stores the address where an object is stored in the memory. It doesn’t contain the actual object itself.

When a function is called with arguments, it is the address of the object stored in the argument is passed to the parameter variable. However, just for the sake of simplicity, we say the value of an argument is passed to the parameter while invoking the function. This mechanism is known as Pass By Value. Consider the following example:

Output:

Notice that the `id` values are same. This means that variable `arg1` and `para1` references the same object. In other words, both `arg1` and `para1` points to the same memory location where `int` object (`100`) is stored. This behavior has two important consequences:

1. If arguments passed to function is immutable, then the changes made to the parameter variable will not affect the argument.
2. However, if the argument passed to the function is mutable, then the changes made to the parameter variable will affect the argument.

Let’s examine this behavior by taking some examples:

Example 1: Passing immutable objects to function.

python101/Chapter-13/passing_immutable_objects.py

Output:

In line 7, `func()` is called with an argument `arg1` (which points to an immutable object `int`). The value of `arg1` is passed to the parameter `para1`. Inside the function value of `para1` is incremented by `100` (line 2). When the function ends, the print statement in line 8 is executed and the string `"After function call, arg1 = 100"` is printed to the console. This proves the point that no matter what function does to `para1`, the value of `arg1` remains the same.

If you think about it this behavior makes perfect sense. Recall that the contents of immutable objects can’t be changed. So whenever we assign a new integer value to a variable we are essentially creating a complete new `int` object and at the same time assigning the reference of the new object to the variable. This is exactly what’s happening inside the `func()` function.

Example 2: Passing mutable objects to function

python101/Chapter-13/passing_mutable_objects.py

Output:

The code is almost the same, but here we are passing a list to the function instead of an integer. As the list is a mutable object, consequently changes made by the `func()` function in line 2, affects the object pointed to by variable `arg1`.

## Positional and Keyword Arguments

Arguments to a function can be passed in two ways:

1. Positional argument.
2. Keyword argument.

In the first method, we pass arguments to a function in the same order as their respective parameters in the function header. We have been using this method to pass arguments to our functions. For example:

python101/Chapter-13/pythagorean_triplets.py

The statement `is_pythagorean_triplet(3, 4, 5)` passes `3` to `base`, `4` to `height` and `5` to `perpendicular`, and prints `"Numbers passed are Pythagorean Triplets"`. However, the statement `is_pythagorean_triplet(3, 5, 4)`, passes `3` to base, `5` to `height` and `4` to `perpendicular` and prints `"Numbers passed are not Pythagorean Triplets"`, which is wrong. So when using positional arguments always make sure that order of arguments in function call and order of parameters in function header matches. Otherwise, you may get expected results.

The other way to pass arguments to a function is to use Keyword arguments. In this method we pass each argument in the following form:

where `parameter_name` is the name of the parameter variable in the function header and `val` refers to the value you want to pass to the parameter variable. Because, we are associating parameter name with values, the order of arguments in the function call doesn’t matter.

Here are some different ways in which we can call `is_pythagorean_triplet()` function using keyword arguments:

Keyword arguments are a little bit flexible because we don’t have to remember the order of parameters in the function header.

## Mixing Positional and Keyword arguments

We can also mix positional arguments and keyword arguments in a function call. In doing so, the only requirement is that positional arguments must appear before any keyword arguments. It means that the following two calls are perfectly valid because in both calls positional arguments are appearing before keyword arguments.

However, we can’t do this:

The problem here is that the positional argument (`5`) is appearing after the keyword argument (`height=4`). Trying to call `is_pythagorean_triplet()` in this way results in the following error:

## Returning Values

Up to this point, we have been creating functions which don’t return any values, such functions are also known as void functions.

To return value from a function we use `return` statement. It’s syntax is:

The square brackets (`[]`) around the `expression` indicates that it is optional. If omitted a special value `None` is returned.

When `return` statement is encountered inside a function, the function terminates and the value of the `expression` followed by the `return` keyword is sent back to the part of the program that called the function. The `return` statement can appear anywhere in the body of the function. The functions which returns values are known as value-returning functions.

Here is an example:

A function can be called in two ways, depending upon whether they return value or not.

If a function returns a value then a call to such a function can be used as an operand in any expression in the program. For example:

In the above expression, we are first calling the `add()` function, and then assigning the return value of the function to the `result` variable. Had we not used the `return` statement in the `add()` function, we wouldn’t be able to write this code. Here are some other ways in which we can call `add()` function.

We are not bound to use the return value from the function. If we don’t want to use the return value, just call the function as a statement. For example:

In this case, the return value of `add()` is simply discarded.

Let’s rewrite our factorial program to return the factorial instead of printing it.

python101/Chapter-13/return_factorial.py

Output:

In the above example, we are returning an integer value from the function, but we can use any type of data `int`, `float`, `str`, `bool`; you name it. The following program demonstrates how to return `bool` type from the function:

python101/Chapter-13/is_even_or_odd.py

1st run Output:

2nd run Output:

If expression followed by `return` keyword is omitted then a special value `None` is returned.

python101/Chapter-13/returning_none.py

Output:

We can also use `return` statement multiple times inside the function but as soon as the first `return` statement is encountered the function terminates and all the statements following it are not executed. For example:

First run output:

Second run output:

## Void Function returns None

In Python, void functions are slightly different than functions found in C, C++ or Java. If the function body doesn’t have any `return` statement then a special value `None` is returned when the function terminates. In Python, `None` is a literal of type `NoneType` which used to denote the absence of a value. It is commonly assigned to a variable to indicate that the variable does not points to any object.

The following program demonstrates that the void functions return `None`.

python101/Chapter-13/void_function.py

Output:

Sure enough! `add()` function indeed returns `None`. So we can say that in Python, all functions return value whether you use `return` statement or not. However, this doesn’t mean that you can use void functions just like a value-returning function. Consider the following example:

python101/Chapter-13/using_void_function_as_non_void_function.py

Output:

In line 4, we are trying to add value returned from `add()` i.e `None` to the integer `100`, but the operation failed because `+` operation can’t add `NoneType` to `int`.

That’s why a void function is generally invoked as a statement like this:

## Returning Multiple Values

To return multiple values from a function just specify each value separated by a comma (`,`) after the `return` keyword.

When calling a function returning multiple values, the number of variables on the left side of `=` operator must be equal to the number of values returned by the `return` statement. So if a function returns two values then you must use 2 variables on the left side of `=` operator. Here is an example:

python101/Chapter-13/returning_multiple_values.py

Output:

Notice how values are assigned while calling the function. The statement:

assigns the smaller number to variable `number1` and greater number to variable `number2`.

## Default Arguments

In Python, we can define a function with default parameter values, this default value will be used when a function is invoked without any argument. To specify a default value for the parameter just specify the value using the assignment operator followed by parameter name. Consider the following example:

python101/Chapter-13/setting_default_values.py

Output:

In line 7, we are calling function `calc_area()` without any arguments, so default values `2` and `3` will be assigned to `length` and `width` parameters respectively.

In line 8, we are calling `calc_area()` by passing `4` to `length` and `6` to `width`. As values to both the parameters are provided while calling the function, the default value will not be used in this case. The same is true for `calc_area()` call in line 9, except here we are using keyword arguments.

In line 10, we are only providing value to `length` parameter using keyword argument, as a result, the default value for `width` parameter will be used.

### 2 thoughts on “Functions in Python”

1. “The statement is_pythagorean_triplet(3, 4, 5) passes 3 to base, 4 to height and 5 to base, and prints ”

I believe there is an error here. 5 is being passed to perpendicular and not base

• Code Updated.