Harika Bonthu — August 26, 2021
Beginner Programming Python

This article was published as a part of the Data Science Blogathon

Overview:

This article aims at brushing up knowledge on the Functions concept in Python in detail.

Table of Contents:

  1. What are Functions?
  2. Types of Functions
    • Built-in
    • User-defined
  3. Defining a Function
  4. Print vs Return statements
  5. Calling a Function
  6. Types of Arguments
    • Required arguments
    • Optional arguments
    • Positional arguments
    • Keyword arguments
    • Variable-length arguments ( *args, **kwargs)
  7. Nested Functions
  8. Higher-Order Functions

 

1. What are Functions?

A function in programming is a block of code organized by a set of rules to accomplish a specific task. They can be reused any number of times at any point during software development.

2. Types of Functions

Built-in functions: Every programming language has pre-defined/library functions to implement basic functionalities.

Learn more about them from Python Built-in Functions documentation.

The most frequently used function in any programming language is the print() function that prints the specified message.

It is great to have built-in functions but, what if we have a requirement that cannot be accomplished using the existing functions? We may need to create a function of our own.

The functions created by the users are called User-defined functions.

 

3. Defining a Function

Below are the steps to define a function:

The function code blocks must start with the keyword def followed by the function nameparentheses( () ), and colon(:).

Anything that is inside the parentheses is the input or parameter of the function. (The values that are passed to the function are called arguments. )

After the function declaration, we can write the description using docstring (“”” “””) that help the users understand the purpose of the function.

After the docstring comes to the code related to the functionality.

Ends with a print or return statement.

Syntax to define a function:

  1. def FunctionName(parameter):
  2. “”” This is a test function “””
  3. # code to do computation to the parameter
  4. print(output)
  5. return output

 


4. Print vs Return statements

The print() function will only print the specified message or variable given, whereas the return statement returns the message or variable to be stored into another variable when the function is called. Return statement allows us to use the output of a function.

Execution will be stopped after reaching the return statement.

You can return multiple values by separating them using commas.

 

 

5. Calling a function

A function can be called using its name. We must pass valid values to the parameters specified while defining the function.

Syntax to call a function:

functionName(argument)

Example Function: 

To implement the addition of two numbers. We will see two functions – one with a print and the other with a return statement.

Function with a print statement

def print_sum(a, b):

"""This function prints the sum of two numbers"""

output = a+b

print("Sum is: ", output)

# driver code

x = print_sum(10, 2)

print("X is: ", x)

The output of the above code is:

Sum is: 12
X is: None

Function with a return statement

def return_sum(a, b):

"""This function returns the sum of two numbers"""

output = a+b

return output

# driver code

y = return_sum(-23, 8)

print("Y is: ", y)

The output of the above code is:

Y is: -15

If we observe both the outputs, the print statement doesn’t return the output, so we cannot store it into another variable (x). The return statement returns the output, so we can store it into another variable (y).

Here a, b are called the parameters, and -23, 8 are called the arguments of the function return_sum.

 

6. Types of Arguments

Functions can be called by using the below types of arguments:

  1. Required arguments
  2. Optional arguments
  3. Positional arguments
  4. Keyword arguments
  5. Variable-length arguments (*args, **kwargs)

1. Required arguments

These are the arguments that must be passed to a function. Without them, it throws an error when the function is called.

Assume we have a function that prints the given name in the Title case.

def UpperCase(name):
formatted_name = name.title()
print("Formatted name is: ",formatted_name)

# calling student function
UpperCase()

It says the function is missing the value(argument) of the required parameter (name). To avoid such errors, we must pass a valid argument to the parameter.

UpperCase('analytics vidhya')

2. Optional arguments

Some function parameters take default values while defining the function. And there is no need to provide values for them which makes them optional arguments.

Assume we need a ’10’ multiplier function.

def multiplier(a, b=4):

return a * b

print("with default argument: ",multiplier(3))

print("Changing the default argument: ",multiplier(3, 6))

In line 4 of the above code, we are calling the multiplier function by passing only one value but it doesn’t throw an error because it is equivalent to function the arguments a=3, b=4 (default value).

In line 5, we are calling the function with the arguments a=3, b=6(charged the default value).

Before reading further, think of a minute and guess the output.

3. Positional arguments

Positional arguments are the values passed to the function in the same order as the parameters specified.

Assumes we have a function that prints full name by taking the first name, middle name, and last name.

def fullname(fname, mname, lname):

print("Full Name is: ", fname + " " +mname + " " + lname)

# Main character of Harry Potter series is "Harry James Potter"

fullname('Harry', 'James', 'Potter')

Output:

Changing the position of arguments and calling the function.

fullname('Potter', 'Harry', 'James')

Now see the reaction of Harry 👇:

So, it is important to preserve the order of the arguments. However, it would be tiresome if a function accepts more parameters.

Is there a way to not look for the order of the parameters yet passing the arguments correctly? Yes, the answer is keyword arguments.

 

4. Keyword arguments

Keyword argument is where the name of the parameter is provided while passing the function arguments.

Consider the same function fullname. Calling the function using keyword arguments.

fullname(lname='Potter', fname='Harry', mname='James')

Without looking for the order of parameters, we can get the correct Full Name. This looks great, isn’t it?

 

5. Variable-length arguments (*args, **kwargs)

*args are the non-keyword arguments/positional arguments. We can pass any number of arguments by separating them using commas or by passing a list prefixed with a * symbol (*list).

**kwargs are the keyword arguments. We can pass any number of keyword arguments directly or by using a dictionary( key, value pairs).

def variable(num1, *args, **kwargs):
    print("num1: ", num1)
    for arg in args:
        print("arg: ",arg)
    for key, value in kwargs.items():
        print("kwarg: ", value)
variable(2, 3, 4, 5, key1=6, key2=7)

The function ‘variable’ has one position argument num1 (first positional argument will always be assigned to num1), two non-keyword arguments (*args), and two keywords arguments (**kwargs).

Now, let us list and dictionary to pass *args, and **kwargs

def variable(num1, *args, **kwargs):

print("num1: ", num1)

for arg in args:

print("arg: ",arg)

for key, value in kwargs_dict.items():

print("kwarg: ", key, value)

list_of_args = [4, 5]

kwargs_dict = {

'key1':6,

'key2':7

}

variable(*list_of_args, **kwargs_dict)

The first element of the list is assigned to num1, remaining elements are assigned to *args. The elements of the dictionary are assigned to **kwargs.

7. Nested functions

The function defined inside another function is called a nested or inner function.

def mainfunction():

print("Executed Outer function")

def nestedfunction():

print('Executed Nested function')

The outer function can be called, as usual,

mainfunction()

Try calling the nestedfunction.

It threw an error saying ‘nestedfunction’ is not defined. So, we should understand that nested functions must be called inside the main function to be executed.

def mainfunction():
    print("Executed Outer function")
    def nestedfunction():
        print('Executed Nested function')
    nestedfunction()
mainfunction()

The above code executed both functions successfully.

8. Higher-order functions

A function is said to be a higher-order function if a function is passed as an argument to it.

Assume we are building a tiny calculator. Define separate functions for addition and subtraction.

  1. def add(a, b):
  2. return a + b
  3. def sub(a, b):
  4. return a – b

define a higher function calc that takes add or sub-functions are arguments in addition to a, b.

  1. def calc(func, a, b):
  2. result = func(a, b)
  3. print(“Result is :”, result)

Call the calc function by passing add, sub functions as input

calc(add, 4, 6)
calc(sub, 2, 3)

End Notes:

Thank you for reading till the conclusion. By the end of this article, we are familiar with the concept of Functions in Python.

I hope this article is informative. Feel free to share any feedback you may have.

Download the complete notebook from the GitHub repo

Other Blog Posts by me

Do check out my other blog posts from my Analytics Vidhya Profile.

You can find me on LinkedIn, Twitter in case you would want to connect. I would be glad to connect with you.

For immediate exchange of thoughts, please write to me at [email protected].

Happy Learning!

The media shown in this article are not owned by Analytics Vidhya and are used at the Author’s discretion.

Leave a Reply Your email address will not be published. Required fields are marked *