# Functions in Python

A function is a block of organized and reusable program code that performs a single, specific and well-defined task. Python enables its programmers to break up a program into functions, each of which can be written more or less independently of the others. Therefore, the code of one function is completely insulated from the code of the other functions.

Every function interfaces to the outside world in terms of how information is transferred to it and how results generated by the function are transmitted back from it. This interface is basically specified by the function name. For example, we have been using functions such as input() to take input from the user, and print() to display some information on the screen.

## Defining a Function –

We can define a function using the keyword def followed by function name. After the function name, we should write parentheses() which may contain parameters.

The syntax of a function is given below.

def function_name(param1, param2, ...):
"""Function Doctsring"""
function statements 

For example, we can write a function to add two numbers

def sum(a, b):
"""This function finds sum of two numbers."""
c = a + b
print('sum: ', c)

Here, def represents the starting of function definition. ‘sum‘ is the name of the function. After this name, parentheses () are compulsory as they denote that it is a function and not a variable or something else. In the parentheses, we wrote two variables a and b. These variables are called parameters. A parameter is a variable that receives data from outside into a function. So, this function can receive two values from outside and those values are stored in the variables a and b.

After the parentheses, we put a colon (:) that represents the beginning of the function body. The function body contains a group of statements called suite. Generally we should write a string as the first statement in the function body. This string is called a Docstring that gives information about the function. Docstrings are generally written inside triple double quotes or triple single quotes. However these docstrings are optional. That means it is not compulsory to write them. But writing docstrings is a good programming habit.

After writing the docstring in the function, the next step is to write other statements which constitute the logic of the function. This reflects how to do the task. In our example, we want to find the sum of two numbers. Hence the logic would be.

c = a + b
print('sum: ', c)

The parameters a and b contains the values which are added and the result is stored into c. Then the result is displayed using the print() function. So this function can accept two values and display their sum.

## Calling a Function –

A function cannot run on its own. It runs only when we call it. So, the next step is to call the function using its name. While calling the function, we should pass the necessary values to the function in the parentheses as.

# calling the sum function
sum(5, 10)
#output
sum:  15

Here we are calling the sum function and passing two values 5 and 10 to that function. When this statement is executed, the Python interpreter jumps to the function definition and copies the values 10 and 15 into the parameters a and b respectively. These values are processed in the function body and result is obtained. The values passed to a function are called arguments. So 5 and 10 are arguments.

## Returning Results from a Function –

We can return the result or output from the function using the return statement in the body of the function.

For example

return c #returns c value out of function
return a, b, c # returns 3 values

When a function does not return any result, we need not write the return statement in the body of the function.

Let’s rewrite our sum() function such that it will return the sum value rather than displaying it.

def sum(a, b):
"""This function finds sum of two numbers."""
c = a + b
return c

# calling the sum function
x = sum(5, 10)
print("The sum is: ", x)
y = sum(2.5, 7.5)
print("The sum is: ", y)
#output
The sum is:  15
The sum is:  10.0

In the above program, the result is returned by the sum() function through c using the return statement

return c

When we call the function as

x = sum(5, 10)

the result returned by the function comes into the variable x. Similarly, when we call the function as

y = sum(2.5, 7.5)

The returned result will come into y.

## Returning Multiple Values from a function –

In Python, a function can return multiple values. When a function calculates multiple results and wants to return the results, we can use the return statement as

return a, b, c

Here, three values which are a, b, and c are returned. These values are returned by the function as a tuple. To grab these values, we can use three variables at the time of calling the function as

x, y, z = function()

Here, the variables x, y and z are receiving the three values returned by the function. To understand this practically, we can create a function by the name sum_sub() that takes 2 values and calculates the result of addition and subtraction. These results are stored in the variable c and d and returned as a tuple by the function.

def sum_sub(a, b):
c = a + b
d = a - b
return c, d

Since this function has two parameters, at the time of calling this function, we should pass two values as

x, y = sum_sub(10, 5)

Now, the result of addition which is in c will be stored into x and the result of subtraction which is in d will be stored into y. This is shown in the below program.

# a function that returns two results
def sum_sub(a, b):
"""This function returns results of addition
and subtraction of a and b"""
c = a + b
d = a - b
return c, d

# get the results from the sum_Sub() function
x, y = sum_sub(10, 5)

# display the results
print("Result of subtraction: ", y)

## Formal and Actual Arguments –

When a function is defined, it may have some parameters. These parameters are useful to receive values from outside of the function. They are called formal arguments. When we call the function, we should pass data or values to the function. These values are called actual arguments. In the following code a and b are formal arguments and x and y are actual arguments.

def sum(a, b): # a, b are formal arguments
c = a + b
print(c)

# call the function
x = 10
y = 15
sum(x, y) # x, y are actual arguments

The actual arguments used in a function call are of 4 types:

• Positional arguments
• keyword arguments
• Default arguments
• Variable length arguments

## Positional Arguments –

These are the arguments passed to a function in correct positional order. Here, the number of arguments and their positions in the function definition should match exactly with the number and position of the arguments in the function call.

Let’s write a function to demonstrate it.

# Positional arguments
def print_name(first, last):
"""Print the name of a person"""
name = first + " " + last
print("Name: ", name)

# call the function
print_name('Nick', 'Miller')
#output
Name:  Nick Miller

The above functions expects two strings, the first name and the last name and in that order. So, when we call this function, we are supposed to pass only two strings and in that order.

Suppose we pass the last name first and first name last then calling the function will result in different outcome that is not expected.

Also if we try to pass more than or less than 2 strings, then python will throw an error. For example, if we call this function by passing the first name, the middle name and the last name

print_name('Nick', 'Smith', 'Miller')

Then python will throw an error.

## Keyword Arguments –

Keyword arguments are arguments that identify the parameters by their names. For example, when calling the above function, we can mention which is the first name and which is the last name as shown below.

print_name(first='Nick', last='Miller')

Here Nick is assigned to first and Miller is assigned to last.

Now even if we change the order of the arguments like shown below

print_name(last='Miller', first='Nick')
#output
Name:  Nick Miller

We will get the correct output.

## Default Arguments –

Python allows users to specify function arguments that can have default values. This means that a function can be called with fewer arguments than it is defined to have. That is if the function accepts three parameters, but function call provides only two arguments, then the third parameter will be assigned the default (already specified) value.

The default value to an argument is provided by using the assignment operator ( = ). Users can specify default value for one or more arguments.

A default argument assumes a default value if a value is not provided in the function call for that argument.

Let’s write a program to demonstrate it.

def greet(name, msg='Good morning!'):
"""This function greets a person"""
print('Hi', name + ', ' + msg)

greet('Nick')
greet('Nick', 'How are you doing?')
#output
Hi Nick, Good morning!
Hi Nick, How are you doing?

In the above program, the name does not have a default value so it is mandatory to provide it’s value when calling the function. But the msg has a default value, so it is optional during function call. If a value is provided, it will overwrite the default value.

You can specify any number of default arguments in your function. If you have default arguments, then they must be written after the non-default arguments. This means that non-default arguments cannot follow default arguments. Therefore the following line of code

def greet(msg='Good morning!', name)

will produce an error

SyntaxError: non-default argument follows default argument

## Variable Length Arguments –

In some situations, it is not known in advance how many arguments will be passed to a function. In such cases, python allows programmers to make function calls with arbitrary (or any) number of arguments.

When we use arbitrary arguments or variable length arguments, then the function definition uses an asterisk ( * ) before the parameter name.

Let’s write a program to demonstrate that.

def greet(*names):
"""This function greets all people
in the names tuple."""
for name in names:
print("Hello", name)

greet('Nick','Jessica','Schmidt','Cece','Winston')
#output
Hello Nick
Hello Jessica
Hello Schmidt
Hello Cece
Hello Winston

Here we called the function with multiple arguments. It’s up to you, how many names you pass here.

The arbitrary number of arguments passed to the function basically forms a tuple before being passed into the function. Inside the called function, for loop is used to access the arguments. The variable length arguments if present in the function definition, then it should be the last in the list of formal parameters. Any formal parameters written after the variable length arguments must be keyword-only arguments.

## Local and Global Variables –

When we declare a variable inside a function, it becomes a local variable. A local variable is a variable whose scope is limited only to that function where it is created. That means the local variable value is available only in that function and not outside of that function. In the following example, the variable a is declared inside increment() and hence it is available inside that function. Once we come out of the function, the variable a is removed from memory and it is not available.

# local variable in a function
def increment():
a = 1
a += 1
print(a)

increment()
print(a) # error

The last statement in the above code result in an error – NameError: name ‘a’ is not defined, as we are trying to access a local variable outside of a function.

When a variable is declared above a function, it becomes global variable. Such variables are available are available to all the functions which are written after it.

# global variable example
a = 1 # this is global var
def myFunction():
b = 2 # this is local var
print('a= ', a) # display global var
print('b= ', b) # display local var

myFunction()
print(a) # available
print(b) # error, not available

Rating: 1 out of 5.