# Topic covered
* Functions
* User Defined Functions
* Return Statement
* Parameters & Arguments
    * Positional arguments
    * Keyword arguments
    * Default arguments
    * Variable length arguments

9. Functions

If a group of statements is repeatedly required then it is not recommended to write these statements everytime separately.

We have to define these statements as a single unit, and we can call that unit any number of times based on our requirement without rewriting. This unit is nothing but function.

  • The main advantage of functions is code Reusability.
  • Python supports 2 types of functions
    1. Built-in Functions
    2. User Defined Functions

9.1 Built-in Functions

The functions which are coming along with Python software automatically, are called built-in functions or pre-defined functions

Eg:
id() , type(), input(),
map(), reduce(), filter(), lambda(), eval()

9.2 User Defined Functions

The functions which are developed by programmer explicitly according to business requirements, are called user defined functions.

# Syntax
def function_name(parameters):
    """ doc string"""
    ----
    -----
    return value

9.3 Return Statement

Function can take input values as parameters and executes business logic, and returns output to the caller with return statement.


def add(x,y):
    return x+y

result=add(10,20)
print("The sum is",result)
# Returning multiple values
def sum_sub(a,b):
    sum=a+b
    sub=a-b
    return sum,sub
x,y=sum_sub(100,50)
print(x,y)

9.4 Parameters

Parameters are inputs to the function. If a function contains parameters, then at the time of calling, compulsory we should provide values otherwise, otherwise we will get error.

A parameter is the variable defined within the parentheses during function definition.

# Here a,b are the parameters
def sum(a,b):
    print(a+b)
sum(1,2)

9.5 Arguments

An argument is a value that is passed to a function when it is called. It might be a variable, value or object passed to a function or method as input. They are written when we are calling the function

def f1(a,b):
    ------
    ------
    ------
f1(10,20)

There are 4 types are actual arguments are allowed in Python.

  1. Positional arguments
  2. Keyword arguments
  3. Default arguments
  4. Variable length arguments

Positional arguments

The number of arguments and position of arguments must be matched. If we change the order then result may be changed.

def sub(a,b):
    print(a-b)
sub(100,200)  # -100
sub(200,100)  # 100

Keyword arguments

Here the order of arguments is not important but number of arguments must be matched.

def wish(name, msg):
    print("Hello", name, msg)

wish(name="Amrit", msg="Good Morning")
# Hello Amrit Good Morning

wish(msg="Good Morning", name="Amrit")
# Hello Amrit Good Morning

We can use both positional and keyword arguments simultaneously. But first we have to take positional arguments and then keyword arguments, otherwise we will get syntax-error.

def wish(name, msg):
    print("Hello", name, msg)

wish("Amrit", "GM")  # valid
wish("Amrit", msg="GM") # valid

wish(name="Amrit", "GM") # invalid
# SyntaxError: positional argument follows keyword argument

Default Arguments

Sometimes we can provide default values for our positional arguments.

def wish(name="Guest"):
    print("Hello", name, "GoodMorning")

wish("Amrit")
# Hello Amrit Good Morning

wish()
# Hello Amrit Good Morning
  • SyntaxError: non-default argument follows default argument
def wish(name="Guest", msg="Good Morning"): # valid
def wish(name, msg="Good Morning"):      # valid

def wish(name="Guest", msg):  # Invalid

Variable length arguments

Sometimes we can pass variable number of arguments to our function, such type of arguments are called variable length arguments.

We can declare a variable length argument with * symbol as follows

def sum(*n):
    total=0
    for i in n:
        total=total+i
    print(total)

sum()  # 0
sum(10)  # 10
sum(10, 20)  # 30
sum(10, 20, 30, 40)  # 100

We can mix variable length arguments with positional arguments.

def f1(n1,*s):
    print(n1, s)

f1(10)      # 10 ()
f1(10,20)   # 10 (20,)
f1(10, "A", 30) # 10 ('A', 30)

We can declare key word variable length arguments also. For this we have to use **.

def display(**kwargs):
    print(kwargs)

display(n1=10)
# {'n1': 10}

display(rno=100,name="Amrit")
# {'rno': 100, 'name': 'Amrit'}
  • Using both *args and **kwargs in Python to call a function
def test7(*args , **kwargs) : 
    return args , kwargs

test7(2,3,4,5,a= 34, b = 98)
# ((2, 3, 4, 5), {'a': 34, 'b': 98})