Professional Documents
Culture Documents
FUNCTIONS
Similar to these functions, a programmer can also create his own functions which which are called ‘user-defined’ functions.
Advantages:
1. Once a function is written, it can be reused as and when required.
2. Functions provide modularity for programming. which makes it easy.
3. Code maintenance will become easy because of functions. When a new feature has to be added to the existing software, a new
function can be written and integrated into the software.
4. When there is an error in the software, the corresponding function can be modified without disturbing the other functions in the
software. Thus code debugging will become easy.
5. The use of functions in a program will reduce the length of the program.
localhost:8888/notebooks/Functions.ipynb# 1/36
3/6/2021 Functions - Jupyter Notebook
localhost:8888/notebooks/Functions.ipynb# 2/36
3/6/2021 Functions - Jupyter Notebook
y = sum_sub(10, 5)
print(y)
In [ ]: #Returning a list
s_d= sum_sub(18, 5)
print(s_d)
In fact when we create a function, the Python interpreter internally creates an object.
Since functions are objects, we can pass a function to another function just like we pass an object (or value) to a function.
Also, it is possible to return a function from another function. This is similar to returning an object (or value) from a function.
In [ ]: def display(str):
pass
localhost:8888/notebooks/Functions.ipynb# 4/36
3/6/2021 Functions - Jupyter Notebook
print(display("Krishna"))
def message():
return 'How are U? '
In [ ]: def fun1(str):
return str
def fun2(str):
return str
localhost:8888/notebooks/Functions.ipynb# 5/36
3/6/2021 Functions - Jupyter Notebook
Pass by value represents that a copy of the variable value is passed to the function and any modifications to that value will not reflect
outside the function.
Pass by reference represents sending the reference or memory address of the variable to the function. The variable value is modified by
the function through memory address and hence the modified value will reflect outside the function also.
Neither of these two concepts is applicable in Python. In Python, the values are
sent to functions by means of object references.
When we pass values like numbers, strings, tuples or lists to a function, the references of these objects are passed to the function.
x= 10
modify(x)
print("x outside the funcion", x, id(x))
From the output, we can understand that the value of ‘x’ in the function is 15 and that is not available outside the function.
When we call the modify() function and pass ‘x’ as: modify(x) we should remember that we are passing the object reference to the
modify() function. The object is 10 and its reference name is ‘x’.
localhost:8888/notebooks/Functions.ipynb# 6/36
3/6/2021 Functions - Jupyter Notebook
Inside the function, we are using: x = 15. This means another object 15 is created in memory and that object is referenced by the name
‘x’.
In Python integers, floats, strings and tuples are immutable. That means their data cannot be modified. When we try to change their
value, a new object is created with the modified value.
On the other hand, lists and dictionaries are mutable. That means, when we change their data, the same object gets modified and new
object is not created.
In the next program, we are passing a list of numbers to modify() function. When we append a new element to the list, the same list is
modified and hence the modified list is available outside the function also.
localhost:8888/notebooks/Functions.ipynb# 7/36
3/6/2021 Functions - Jupyter Notebook
In [ ]: # A Python program to create a new object inside the function does not modify outside object.
#passing a list to a function
def modify(lst):
""" to create a new list """
lst = [1,2,3,4]
print(lst, id(lst))
#call modify() and pass lst
lst = [1,2,3,4]
modify(lst)
print(lst, id(lst))
In [ ]: a=[1,2,3];print(id(a))
b=[1,2,3]; print(id(b))
localhost:8888/notebooks/Functions.ipynb# 8/36
3/6/2021 Functions - Jupyter Notebook
localhost:8888/notebooks/Functions.ipynb# 9/36
3/6/2021 Functions - Jupyter Notebook
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 argument in the function call.
Keyword Arguments
Keyword arguments are arguments that identify the parameters by their names.
For example, the definition of a function that displays grocery item and its price can be written as:
At the time of calling this function, we have to pass two values and we can mention which value is for what. For example,
localhost:8888/notebooks/Functions.ipynb# 10/36
3/6/2021 Functions - Jupyter Notebook
grocery(item='Sugar', price=50.75)
Here, we are mentioning a keyword ‘item’ and its value and then another keyword ‘price’ and its value. Please observe these keywords
are nothing but the parameter names which receive these values. We can change the order of the arguments as:
grocery(price=88.00, item='Oil')
Default Arguments
Let’s take the definition of grocery() function as:
Here, the first argument is ‘item’ whose default value is not mentioned. But the second argument is ‘price’ and its default value is
mentioned to be 40.00.
At the time of calling this function, if we do not pass ‘price’ value, then the default value of 40.00 is taken. If we mention the ‘price’ value,
then that mentioned value is utilized.
localhost:8888/notebooks/Functions.ipynb# 11/36
3/6/2021 Functions - Jupyter Notebook
The variable length argument is written with a ‘ * ’ symbol before it in the function definition as:
A keyword variable length argument is an argument that can accept any number of values provided in the format of keys and values.
localhost:8888/notebooks/Functions.ipynb# 12/36
3/6/2021 Functions - Jupyter Notebook
Here ‘kwargs’ is called keyword variable argument. This argument internally represents a dictionary object. A dictionary stores
data in the form of key and value pairs. It means, when we provide values for ‘kwargs’, we can pass multiple pairs of values using
keywords as: display(5, rno=10)
Here, 5 is stored into ‘farg’ which is formal argument. ‘rno’ is stored as key and its value ‘10’ is stored as value in the dictionary that is
referenced by ‘kwargs’.
localhost:8888/notebooks/Functions.ipynb# 13/36
3/6/2021 Functions - Jupyter Notebook
def myfunction():
a=1 #this is local var a+=1 #increment it
print(a) #displays 2
myfunction()
print(a) #error, not available
myfunction()
print('a=', a) #display global var
When the programmer wants to use the global variable inside a function, he can use the keyword ‘global’ before the variable in the
beginning of the function body as:
global a
In this way, the global variable is made available to the function and the programmer can work with it as he wishes.
localhost:8888/notebooks/Functions.ipynb# 14/36
3/6/2021 Functions - Jupyter Notebook
In [ ]: # A Python program to access global variable inside a function and modify it.
#accessing the global variable inside a function
a=1 #this is global var
def myfunction():
global a #this is global var
print('global a=', a) #display global var
a=2 #modify global var value
print('modifed a=', a) #display new value
myfunction()
print('global a=', a) #display modified value
When the global variable name and local variable names are same, the programmer will face difficulty to differentiate between them
inside a function. For example there is a global variable ‘a’ with some value declared above the function. The programmer is writing a
local variable with the same name ‘a’ with some other value inside the function. Consider the following code:
Now, if the programmer wants to work with global variable, how is it possible? If he uses ‘global’ keyword, then he can access only global
variable and the local variable is no more available.
The globals() function will solve this problem. This is a built in function which returns a table of current global variables in the form of a
dictionary. Hence, using this function, we can refer to the global variable ‘a’, as: globals()['a']. Now, this value can be assigned to another
variable, say ‘x’ and the programmer can work with that value.
localhost:8888/notebooks/Functions.ipynb# 15/36
3/6/2021 Functions - Jupyter Notebook
myfunction()
print('global var a=', a)
Recursive Functions
A function that calls itself is known as ‘recursive function’.
factorial(3) = 3 * factorial(2)
Now, if we know that the factorial(0) value is 1, all the preceding statements will evaluate and give the result as:
factorial(3) = 3 * factorial(2)
= 3 * 2 * factorial(1)
= 3 * 2 * 1 * factorial(0) = 3 * 2 * 1 * 1 = 6
From the above statements, we can write the formula to calculate factorial of any number ‘n’ as:
factorial(n) = n * factorial(n-1)
localhost:8888/notebooks/Functions.ipynb# 16/36
3/6/2021 Functions - Jupyter Notebook
def factorial(n):
""" to find factorial of n """
if n==0:
result=1
else:
result=n*factorial(n-1)
return result
It is believed that this game helps to develop intelligence of the children who play it.
In this game, there will be a group of disks on a pole ‘A’ such that the biggest disk will be at the bottom and the smaller disks will be on its
top. One is supposed to transfer all these disks from pole ‘A’ to another pole, let’s say ‘C’ in minimum number of steps.
While moving these disks from ‘A’ to ‘C’, we can take the help of an intermediate pole ‘B’. But, the rule is that while moving the disks from
one pole to another, we should never place a bigger disk on a smaller disk.
For example, to transfer 3 disks from the pole ‘A’ to ‘C’ with the help of an intermediate pole ‘B’, we can use the steps shown below:
localhost:8888/notebooks/Functions.ipynb# 17/36
3/6/2021 Functions - Jupyter Notebook
localhost:8888/notebooks/Functions.ipynb# 18/36
3/6/2021 Functions - Jupyter Notebook
localhost:8888/notebooks/Functions.ipynb# 19/36
3/6/2021 Functions - Jupyter Notebook
Here, the ‘function’ represents a function name that may return either True or False; and ‘sequence’ represents a list, string or tuple.
The ‘function’ is applied to every element of the ‘sequence’ and when the function returns True, the element is extracted otherwise it is
ignored.
localhost:8888/notebooks/Functions.ipynb# 20/36
3/6/2021 Functions - Jupyter Notebook
In [ ]: # A Python program using filter() to filter out even numbers from a list.
def is_even(x):
if x%2==0:
return True
else:
return False
Passing lambda function to filter() function is more elegant. We will rewrite the Program using lambda function.
localhost:8888/notebooks/Functions.ipynb# 21/36
3/6/2021 Functions - Jupyter Notebook
lst = [1, 2, 3, 4, 5]
When the same program is rewritten using lambda function, it becomes more elegant.
It is possible to use map() function on more than one list if the lists are of same length. In this case, map() function takes the lists as
arguments of the lambda function and does the operation.
localhost:8888/notebooks/Functions.ipynb# 22/36
3/6/2021 Functions - Jupyter Notebook
In [ ]: # A Python program to find the products of elements of two different lists using lambda function.
#Lambda that returns products of elements of two lists
lst1 = [1, 2, 3, 4, 5]
lst2 = [10, 20, 30, 40, 50]
lst3 = list(map(lambda x, y: x*y, lst1, lst2))
print(lst3)
Function Decorators
A decorator is a function that accepts a function as parameter and returns a function.
A decorator takes the result of a function, modifies the result and returns it.
Thus decorators are useful to perform some additional processing required by a function.
localhost:8888/notebooks/Functions.ipynb# 23/36
3/6/2021 Functions - Jupyter Notebook
2. We should define a function inside the decorator function. This function actually modifies or decorates the value of the function
passed to the decorator function.
To apply the decorator to any function, we can use the ‘@’ symbol and decorator name just above the function definition. For example, to
apply our decor() function to the num() function, we can write @decor statement above the function definition as:
It means decor() function is applied to process or decorate the result of the num() function. When we apply the decorator in this way, we
need not call the decorator explicitly and pass the function name. Instead, we can call our num() function naturally as:
In [ ]: print(num())
localhost:8888/notebooks/Functions.ipynb# 24/36
3/6/2021 Functions - Jupyter Notebook
To apply the decorators to num() function using ‘@’ symbol, we can rewrite the above program
localhost:8888/notebooks/Functions.ipynb# 25/36
3/6/2021 Functions - Jupyter Notebook
pp y () g @ y p g
Generators
Generators are functions that return a sequence of values. A generator function is written like an ordinary function but it uses ‘yield’
statement.
localhost:8888/notebooks/Functions.ipynb# 26/36
3/6/2021 Functions - Jupyter Notebook
g = mygen(5, 10)
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))
# print (next(g))
# print (next(g))
In [ ]: for i in g:
print(i, end=' ')
Once the generator object is created, we can store the elements of the generator into a list and use the list as we want. For example, to
store the numbers of generator ‘g’ into a list ‘lst’ we can using list() function as:
In [ ]: lst=list(g); print(lst)
If we want to retrieve element by element from a generator object, we can use next() function as:
localhost:8888/notebooks/Functions.ipynb# 27/36
3/6/2021 Functions - Jupyter Notebook
In [ ]: a = range(5)
list(a)
In [ ]: def infinite_sequence():
num = 0
while True:
yield num
num += 1
In [ ]: for i in infinite_sequence():
print(i, end=" ")
In [ ]: gen = infinite_sequence()
next(gen)
In [ ]: next(gen)
localhost:8888/notebooks/Functions.ipynb# 28/36
3/6/2021 Functions - Jupyter Notebook
In [ ]: next(gen)
Detecting Palindromes
localhost:8888/notebooks/Functions.ipynb# 29/36
3/6/2021 Functions - Jupyter Notebook
localhost:8888/notebooks/Functions.ipynb# 30/36
3/6/2021 Functions - Jupyter Notebook
In [ ]: def is_palindrome(num):
# Skip single-digit inputs
if num // 10 == 0:
return False
temp = num
reversed_num = 0
while temp != 0:
reversed_num = (reversed_num * 10) + (temp % 10)
temp = temp // 10
if num == reversed_num:
return num
else:
return False
In [ ]: for i in infinite_sequence():
pal = is_palindrome(i)
if pal:
print(pal)
For this purpose, structured programming is the strategy used by programmers in general.
In structured programming, the main task is divided into several parts called sub tasks and each of these sub tasks is represented by one
or more functions.
To understand this concept, let’s take an example where we are supposed to calculate the net salary of an employee.
Every employee will have some basic salary. The company may provide some benefits like dearness allowance (da) and house rent
allowance (hra), which when added to basic salary will give the gross salary. So, Gross salary = basic salary + da + hra.
localhost:8888/notebooks/Functions.ipynb# 31/36
3/6/2021 Functions - Jupyter Notebook
( ) y g g y y y
The net salary or take home salary is calculated based on gross salary. After making deductions like provident fund and income tax from
the gross salary, the remaining amount is called net salary.
So, Net salary = gross salary - pf – income tax. Hence, in a program to calculate the net salary, we need to calculate the following: da,
hra, pf and income tax. All these will come under sub tasks and to represent these sub tasks, we can write functions.
Finally, using these functions we can calculate the net salary of the employee.
localhost:8888/notebooks/Functions.ipynb# 32/36
3/6/2021 Functions - Jupyter Notebook
#this is the main program #calculate gross salary of employee by taking basic
basic = float(input('Enter basic salary:'))
In Python, we have several built-in modules like sys, io, time etc. Just like these modules, we can also create our own modules and use
them whenever we need them.
Now, we can create our own module by the name ‘employee’ and store the functions da(), hra(), pf() and itax() in that module. The
module can subsequently be imported in any program to use these functions. Remember we can also store classes and variables etc. in
the same manner in any module.
This variable stores information regarding whether the program is executed as an individual program or as a module.
When the program is executed directly, the Python interpreter stores the value ‘__ main __’ into this variable.
When the program is imported as a module into another program, then Python interpreter stores the module name into this variable.
Thus, by observing the value of the variable __ name __, we can understand how the program is executed.
In [ ]: numbers = [1, 2, 3]
letters = ['a', 'b', 'c']
zipped = zip(numbers, letters)
print(zipped) # Holds an iterator object
list(zipped)
localhost:8888/notebooks/Functions.ipynb# 34/36
3/6/2021 Functions - Jupyter Notebook
In [ ]: numbers = "abcd"
letters = "def"
zipped = zip(numbers, letters)
print(zipped) # Holds an iterator object
list(zipped)
In [ ]: numbers = (1, 2, 3)
letters = ('a', 'b', 'c')
zipped = zip(numbers, letters)
print(zipped) # Holds an iterator object
list(zipped)
In [ ]: tup = ('a',0),('b',1)
for l, n in tup:
print(f'Letter: {l}')
print(f'Number: {n}')
In [ ]: c=1,2; c
localhost:8888/notebooks/Functions.ipynb# 35/36
3/6/2021 Functions - Jupyter Notebook
You can also update an existing dictionary by combining zip() with dict.update().
localhost:8888/notebooks/Functions.ipynb# 36/36