PMDS508L - Python Programming
Functions and Modules
Dr. B.S.R.V. Prasad
Department of Mathematics
School of Advanced Sciences
Vellore Institute of Technology
Vellore
[Link]@[Link] (Personal)
[Link]@[Link] (Official)
+91-8220417476
Functions 1
▶ A function is a block of code which can be run when it is called.
▶ Functions can be re-used and reduce the programming complexity.
▶ In other words, a function is a piece of code written to carry out a specified
task.
▶ To carry out that specific task, the function might or might not need multiple
inputs (arguments).
▶ When the task is carried out, the function can or can not return one or more
values.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Functions 2
▶ There are three types of functions in Python:
▶ Built-in functions, such as help() to ask for help, min() to get the minimum
value, print() to print an object to the terminal,. . . You can find an overview
with more of these functions here.
▶ User-Defined Functions (UDFs), which are functions that users create to help
them out; And
▶ Anonymous functions, which are also called lambda functions because they
are not declared with the standard def keyword.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Parameters vs Arguments 3
▶ The parameters are the variables that we can define in the function
declaration.
▶ The arguments are the variables given to the function for execution.
▶ In other words, parameters are the names used when defining a function or
a method, and into which arguments will be mapped.
▶ Arguments are the things which are supplied to any function, while the
function code refers to the arguments by their parameters.
▶ Parameters are local variables which are assigned values of the arguments
when the function is called.
▶ Parameters are known as Formal Parameters and arguments are known as
Actual Parameters.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
User-Defined Functions 4
In Python a user-defined function is defined using the following four-steps:
1. Use the keyword def to declare the function and follow this up with the
function name.
2. Add parameters to the function: they should be within the parentheses of
the function. End your line with a colon.
3. Add statements that the functions should execute.
4. End your function with a return statement if the function should output
something. Without the return statement, your function will return an object
None.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
User-Defined Functions 5
1 def my_first_function () :
2 print ( " Hellooo .. This is my first function ")
3
4 my_first_function ()
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Functions
The return Statement 6
▶ If we want to continue to work with the result of your function and try out some operations on it,
we will need to use the return statement to actually return a value, such as a String, an integer, etc.
▶ If we are only printing a message then we don’t need to return any value.
1 def hello () :
2 print (" Hello World ")
3 return (" hello ")
4
5 def hello_noreturn () :
6 print (" Hello World ")
7
8 hello () * 2 # Multiply the output of ` hello () ` with 2
9
10 hello_noreturn () * 2 # ( Try to ) multiply the output of `
hello_noreturn () ` with 2
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Funcitons
The return Statement 7
Functions immediately exit when they come across a return statement, even if it
means that they won’t return any value:
1 def test_fun () :
2 for x in range (10) :
3 if x == 5:
4 return
5 print ( " Run ! ")
6
7 test_fun ()
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Funcitons
The return Statement 8
Another thing that is worth mentioning when we’re working with the return
statement, we can use it to return multiple values.
1 # Define ' plus () '
2 def plus (a ,b):
3 sumab = a + b
4 return ( sumab , a)
5
6 # Call ' plus () '
7 sumab , a = plus (3 ,4)
8
9 print ( sumab ) # Print ' sumab '
10 print ( sumab , ' ',a) # Print ' sumab ' and 'a '
11 print ( sumab , ' ' ,b) # Error
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Functions
Function Arguments 9
We can pass arguments to functions and can evaluate them inside the function
block.
1 def addnums ( num1 , num2 ):
2 print ( " The num1 is : " , num1 )
3 print ( " The num2 is : " , num2 )
4 print ( " The sum of the two numbers is : " , num1 + num2 )
5
6 addnums (2 ,3)
7 addnums ( -5 ,6)
8 addnums (10.5 , 2.6)
9 addnums (10.5 ,2)
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Functions
Function Arguments 10
▶ By default, a function must be called with the correct number of arguments.
▶ If you try to call the function with lesser or greater arguments, the Python
returns an error.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Functions
Variable [Link] Arguments 11
▶ We can even pass the arbitrary number of arguments into a function.
▶ For this we add * before the parameter name in the function definition
▶ There are two types of variable arguments in Python.
▶ *args for Non-Keyword Arguments
▶ **kwargs for Keyword Arguments
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Functions
Variable [Link] Arguments 12
▶ The *args in Python function definitions is used to pass a non-key worded,
variable number of arguments to a function.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Functions
Variable [Link] Arguments 12
▶ The *args in Python function definitions is used to pass a non-key worded,
variable number of arguments to a function.
1 def my_function (* args ):
2 l = len ( args )
3 print ( " The number of arguments passed are : " ,l)
4 for i in range (0 , l):
5 print ( ' Argument ',i +1 , 'is : ', args [i ])
6
7 my_function (2 ,6)
8 my_function ( " a")
9 my_function (2 , "a" ,3.4)
10 my_function (2 , "a" ,[3 ,5.7 , " Test " ])
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Functions
Variable [Link] Arguments 13
▶ The **kwargs in function definitions in python is used to pass a keyworded,
variable-length argument list.
▶ We use the name kwargs with the double star.
▶ A keyword argument is where you provide a name to the variable as you pass
it into the function.
▶ One can think of the kwargs as being a dictionary that maps each keyword to
the value that we pass alongside it.
▶ As a result, we can iterate over the kwargs and perform the necessary
operations in a function call.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Functions
Variable [Link] Arguments 14
1 def my_function (** kwargs ):
2 for key , value in kwargs . items () :
3 print ( ' Key = ',key , '; Value = ' , value )
4
5 my_function ( First =" One " , Second =34.5 , Third = True )
6 my_function ( First =1)
7 my_function ( Name =" Prasad " , Degree =" PhD ")
8 my_function ( Key1 =2 , Key2 ="a" , Key3 =[3 ,5.7 , " Test " ])
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Functions
Use of *args and **kwargs 15
1 def my_function (* args , ** kwargs ):
2 print ( " args : " , args )
3 print ( " kwargs : " , kwargs )
4
5 my_function ( ' one ', 2, 3.14 , first =" Prasad " , last ="
Bhuvanagiri " , degree =" PhD ")
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Functions
Default Parameter Values 16
We can use default parameter values for a function as follows:
1 def addnums ( num1 =0 , num2 =0) :
2 print ( " The num1 is : " , num1 )
3 print ( " The num2 is : " , num2 )
4 print ( " The sum of the two numbers is : " , num1 + num2 )
5
6 addnums (2 ,3)
7 addnums (2)
8 addnums ( num2 =3)
9 addnums ( num1 =5.6)
10 addnums ()
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Functions
List of Arguments 17
We can even pass a List as an argument to Python function
1 def addnums ( myNums ):
2 numsum = 0
3 for i in myNums :
4 numsum += i
5 print ( " The sum of the numbers is : " , numsum )
6
7 addnums ([1 , 20 , 43 , 52])
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Functions
Returning a Value 18
Functions can return a value to the user:
1 def addnums ( myNums ):
2 numsum = 0
3 for i in myNums :
4 numsum += i
5 return numsum
6
7 print ( " The sum of numbers is : " , addnums ([1 , 20 , 43 ,
52]) )
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Scope of the Variables in Python Functions 19
▶ In general, variables that are defined inside a function body have a local
scope, and those defined outside have a global scope.
▶ That means that local variables are defined within a function block and can
only be accessed inside that function, while global variables can be obtained
by all functions that might be in our script.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Global vs Local Variables 20
1 # Global variable init
2 init = 1
3
4 # Define plus () function to accept a variable number of arguments
5 def plus (* args ):
6 # Local variable total
7 total = 0
8 print ( ' The initial value is : ', init )
9 for i in args :
10 total += i
11 return total
12
13 # Access the global variable
14 print ( " this is the initialized value " + str ( init ))
15
16 # ( Try to ) access the local variable
17 print ( " this is the sum " + str ( total ))
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Recursive Functions 21
▶ Recursion is a mathematical and programming concept, in which a function
calls itself.
▶ This has the benefit that one can loop through data to reach a result.
▶ Recursion is a very efficient and mathematically-elegant approach to
programming
▶ Developer/Programmer should be very careful while designing a recursion.
▶ It can be quite easy to slip into writing a recursion which never terminates, or
uses excess amounts of memory or processor power.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Recursive Functions 22
1 def my_recursion ( num ):
2 if ( num > 0) :
3 result = num + my_recursion ( num -1)
4 print ( result )
5 else :
6 result = 0
7 return result
8
9 print ( " \ nMy Recursion Example Results :")
10 finalAns = my_recursion (6)
11 print ( " \ nThe Final Answer is : " , finalAns )
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Lambda Function 23
▶ We can write our very own Python functions using the def keyword, function
headers, docstrings, and function bodies.
▶ However, there’s a quicker way to write functions on the fly, and these are
called lambda functions because you use the keyword lambda.
▶ A lambda function is a small anonymous function.
▶ A lambda function can take any number of arguments, but can only have one
expression.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Lambda Function 24
Syntax
1 fn = lambda arguments : expression
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Lambda Function 25
1 raise_to_power = lambda x , y: x ** y
2
3 raise_to_power (2 , 3)
1 myfunc = lambda a , b , c : a+b*c
2
3 print ( myfunc (2 ,3 ,5) )
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
map() function 26
The map() function executes a specified function for each item in an iterable. The
item is sent to the function as a parameter.
1 map ( function , iterables )
function: (Required) The function to execute on each item.
iterables: (Required) A sequence, collection or an iterator object.
We can send as many iterables as we like. But need to make sure
that the function has one parameter for each iterable.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
map() function 27
1 def myFunc (a , b):
2 return a + b
3
4 x = map ( myFunc , ( ' apple ', ' banana ', ' cherry ') , ( ' orange
' , ' lemon ' , ' pineapple '))
5
6 print ( x ) # returns a map object
7 print ( list ( x ) ) # convert the map into a list , for
readability
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
map() function 28
1 def myFunc ( x ) :
2 return x **2
3
4 X = map ( myFunc , [1 ,5 , -2 ,3])
5
6 print ( X ) # returns a map object
7 print ( list ( X ) ) # convert the map into a list , for
readability
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
map() function with lambda function 29
We can pass lambda function to the map() without even naming them, and in this
case, we refer to them as anonymous functions.
1 nums = [48 , 6 , 9, 21 , 1]
2
3 square_all = map ( lambda num : num ** 2, nums )
4
5 print ( square_all ) # Returns a map object
6
7 print ( list ( square_all )) # To see what the above map
object returns , we use list to turn into a list
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
filter() function 30
The filter() function returns an iterator where the items are filtered through a
function to test if the item is accepted or not.
1 filter ( function , iterable )
function: (Required) The function to execute on each item.
iterables: (Required) A sequence, collection or an iterator
object.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
filter() function 31
1 ages = [5 , 12 , 17 , 18 , 24 , 32]
2
3 def myFunc ( x ) :
4 if x < 18:
5 return False
6 else :
7 return True
8
9 adults = filter ( myFunc , ages )
10
11 for x in adults :
12 print ( x )
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
filter() function 32
1 # function that filters vowels
2 def fun ( variable ):
3 letters = [ 'a ', 'e ', 'i ', 'o ', 'u ']
4 if ( variable in letters ):
5 return True
6 else :
7 return False
8
9 sequence = [ 'b ', 'e ', 'i ', 'l ', 'k ', 's ' , 'p ' , 'a ']
10 filtered = filter ( fun , sequence ) # using filter function
11
12 print ( ' The filtered letters are : ')
13 for s in filtered :
14 print ( s)
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
filter() function with lambda function 33
1 my_list = [1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10]
2
3 # Use lambda function with ` filter () `
4 filtered_list = list ( filter ( lambda x: (x *2 > 10) ,
my_list ) )
5
6 print ( filtered_list )
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Functions with function arguments
Higher order functions 34
▶ Python functions are nothing but objects and names we define are simply
identifiers bound to these objects.
1 def first ( msg ):
2 print ( msg )
3
4 first ( " Hello ")
5
6 second = first
7 second ( " Hello ")
▶ When we run the above code both functions first and second Return the
same output as both refers to same object.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Functions with function arguments
Higher order functions 35
▶ We can even pass a function as argument to other function and these functions are called
higher order functions
1 def inc ( x ) :
2 return x + 1
3
4 def dec ( x ) :
5 return x - 1
6
7 def operate ( func , x):
8 result = func (x)
9 return result
10
11 operate ( inc , 3)
12 operate ( dec , 3)
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Nested Functions 36
▶ A function can return another function
1 def fun_called () :
2 def fun_returned () :
3 print (" Hello !.. from inner function ")
4 return fun_returned
5
6 new = fun_called () # Create the fun_called object
7
8 new () # Call the function new ()
9
10 # Output : Hello !.. from inner function
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Nested Functions 37
▶ Nested functions can access variables of the enclosing scope.
▶ Following is an example of a nested function accessing a non-local variable (a
variable which is read-only by default)
1 def outer_fn ( msg ): # Outer function
2 def inner_fn () :
3 print (" Printing from inner function with
argument passed to outer function \n"+ msg )
4 inner_fn ()
5
6 outer_fn ( " Hello !.. Argument passed to outer function
")
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Closure Functions 38
▶ Consider the following code, which is modification of above code replacing
inner_fn() call with a return inner_fn
1 def outer_fn ( msg ): # Outer function
2 def inner_fn () :
3 print (" Printing from inner function with
argument passed to outer function \n"+ msg )
4 return inner_fn
5
6 fun = outer_fn (" Hello !.. Argument passed to outer
function ")
7 fun ()
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Closure Functions 39
▶ Here, we called the outer_fn() with string "Hello!.." and the returned
function was bound to the name fun.
▶ On calling fun(), the message was still remembered although we had
already finished executing outer_fn() function.
▶ This technique by which some data (in our case the msg) gets attached to the
code is called closure in Python.
▶ This enclosing value is remembered even when the variable goes out of
scope or the function itself is removed from the current namespace.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Closure Functions 40
1 del outer_fn
2
3 fun ()
4
5 outer_fn ( " Hello !.. ")
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Criteria for Closure Function Creation in Python 41
▶ The following criteria must be met to create closure in Python:
▶ We must have a nested function (function inside a function)
▶ The nested function must refer to a value defined in the enclosing (outer)
function.
▶ The enclosing function must return the nested function.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Use of Closures in Python 42
▶ Closures can avoid the use of global values and provide some form of data
hiding.
▶ They can also provide an object oriented solution to the problem.
▶ When there are few methods (one method in most cases) to be
implemented, closures can provide an alternative and more elegant solution.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Use of Closures in Python 43
1 def multiplier_of (n):
2 def multiplier (x):
3 return x * n
4 return multiplier
5
6 # Multiplier of 3
7 times3 = multiplier_of (3)
8
9 # Multiplier of 5
10 times5 = multiplier_of (5)
11
12 print ( times3 (9) ) # Output : 27
13 print ( times5 (3) ) # Output : 15
14 print ( times5 ( times3 (2) )) # Output : 30
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Decorators 44
▶ A decorator takes in a function, adds some functionality and returns it.
▶ To understand the decorators in Python, we must recall that:
▶ Functions are objects of Python and various difference names can be bound to
the same function object.
▶ Functions can also take other functions as arguments and this type of functions
are called higher order functions.
▶ A nested function can also act as a closure function.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Decorators 45
1 def make_pretty ( func ):
2 def inner () :
3 print ("I got decorated ")
4 func ()
5 return inner
6
7 def ordinary () :
8 print ( " I am ordinary ")
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Decorators 46
1 >>> ordinary ()
2 I am ordinary
3
4 >>> pretty = make_pretty ( ordinary )
5 >>> pretty ()
6 I got decorated
7 I am ordinary
In this example, make_pretty() is a decorator.
The assignment step pretty = make_pretty(ordinary) decorates the function
ordinary() and returns a function with name pretty.
This decorator function added some new functionality to the original function.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Decorators 47
Generally, we decorate a function and reassign it as
1 ordinary = make_pretty ( ordinary )
This is a common construct for decorator functions.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Decorators 47
Generally, we decorate a function and reassign it as
1 ordinary = make_pretty ( ordinary )
This is a common construct for decorator functions. This can be simplified as:
1 @make_pretty
2 def ordinary () :
3 print ( " I am ordinary ")
which is equivalent to
1 def ordinary () :
2 print ( " I am ordinary ")
3 ordinary = make_pretty ( ordinary )
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Decorators
Illustration 48
1 def deco (f):
2 def g (* args , ** kwargs )
:
3 return f (* args , **
kwargs )
4 return g
5 def func (x):
6 return 2* x
7 func = deco ( func )
8 func (2) # Output is 4
After the assigning the result, func
https: refers to the closure g. So calling
//[Link]/closures-and-decorators-in-python-2551abbc6eb6
func(a) is like calling g(a).
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Decorators
Illustration 49
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Decorators
Illustration 49
▶ After decoration, the variable func refers to
the closure g
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Decorators
Illustration 49
▶ After decoration, the variable func refers to
the closure g
▶ Inside g, f refers to the func(x) definition.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Decorators
Illustration 49
▶ In fact, g is now acting as an
interface for the original function
func(x) which was decorated.
▶ After decoration, the variable func refers to
the closure g
▶ Inside g, f refers to the func(x) definition.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Decorators
Illustration 49
▶ In fact, g is now acting as an
interface for the original function
func(x) which was decorated.
▶ We cannot directly call func(x)
ourside g.
▶ After decoration, the variable func refers to
the closure g
▶ Inside g, f refers to the func(x) definition.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Decorators
Illustration 49
▶ In fact, g is now acting as an
interface for the original function
func(x) which was decorated.
▶ We cannot directly call func(x)
ourside g.
▶ Instead, we first call func to call g,
and then inside g we can call f to
call the original function func(x).
▶ After decoration, the variable func refers to
the closure g
▶ Inside g, f refers to the func(x) definition.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Decorators
Illustration 49
▶ In fact, g is now acting as an
interface for the original function
func(x) which was decorated.
▶ We cannot directly call func(x)
ourside g.
▶ Instead, we first call func to call g,
and then inside g we can call f to
call the original function func(x).
▶ After decoration, the variable func refers to
▶ So, we are calling the original
the closure g
function func(x) using the closure
▶ Inside g, f refers to the func(x) definition.
g.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Decorators
Examples 50
1 def smart_divide ( func ):
2 def inner (a , b):
3 print ("I am dividing " , a , " by " , b)
4 if b == 0:
5 print (" Whoops ! Denominator is Zero . Cannot divide " )
6 return
7
8 return func (a , b)
9 return inner
10
11 @smart_divide
12 def divide (a , b):
13 print (a/b)
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Decorators
Examples 51
1 >>> divide (2 ,5)
2 I am dividing 2 by 5
3 0.4
4
5 >>> divide (2 ,0)
6 I am dividing 2 by 0
7 Whoops ! Denominator is Zero . Cannot divide
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Stacked Decorators 52
1 def deco1 (f):
2 def g1 (* args , ** kwargs ):
3 print (" Calling " , f. __name__ , " using deco1 ")
4 return f (* args , ** kwargs )
5 return g1
6 def deco2 (f):
7 def g2 (* args , ** kwargs ):
8 print (" Calling " , f. __name__ , " using deco2 " )
9 return f (* args , ** kwargs )
10 return g2
11 def func (x):
12 return 2* x
13 func = deco2 ( deco1 ( func ))
14 func (2)
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Stacked Decorators 53
1 def deco1 (f):
2 def g1 (* args , ** kwargs ):
3 print (" Calling " , f. __name__ , " using deco1 ")
4 return f (* args , ** kwargs )
5 return g1
6 def deco2 (f):
7 def g2 (* args , ** kwargs ):
8 print (" Calling " , f. __name__ , " using deco2 " )
9 return f (* args , ** kwargs )
10 return g2
11 @deco2
12 @deco1
13 def func (x):
14 return 2* x
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Stacked Decorators
Example 54
1 def star ( func ):
2 def inner (* args , ** kwargs ):
3 print ("*" * 30)
4 func (* args , ** kwargs )
5 print ("*" * 30)
6 return inner
7
8 def percent ( func ):
9 def inner (* args , ** kwargs ):
10 print ("%" * 30)
11 func (* args , ** kwargs )
12 print ("%" * 30)
13 return inner
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Stacked Decorators
Example 55
1 @star def printer ( msg ):
2 @percent print ( msg )
3 def printer ( msg ): printer = star ( percent ( printer ))
4 print ( msg )
5
6 printer (" Hello ") printer ( " Hello ")
Output:
1 ******************************
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 Hello
4 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 ******************************
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Stacked Decorators
Example 56
The order in which we chain decorators matter. If we had reversed the order as,
1 @percent
2 @star
3 def printer ( msg ) :
4 print ( msg )
5
6 printer ( " Hello ")
the output would be:
1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 ******************************
3 Hello
4 ******************************
5 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Generator functions in Python 57
▶ A generator is a function that returns an (iterator) object which we can
iterate over (one value at a time).
▶ Generator function in Python is defined in the same way as the functions are
defined but with a yield statement instead of return statement.
▶ If a function contains at least one yield (it may contain other yield or
return statements), it becomes a generator function.
▶ Both yield and return will return some value from a function.
▶ The difference is that while a return statement terminates a function
entirely, yield statement pauses the function saving all its states and later
continues from there on successive calls.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Difference between Generator function and Normal func-
tion 58
▶ Generator function contains one or more yield statements.
▶ When called, it returns an object (iterator) but does not start execution
immediately.
▶ We can iterate through the items using next().
▶ Once a function yields, the function is paused and the control is transferred
to the caller.
▶ Local variables and their states are remembered between successive calls.
▶ Finally, when the function terminates StopIteration is raised automatically
on further calls.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Generator functions in Python
Example 59
1 # A simple generator function
2 def my_gen () :
3 n = 1
4 print ( ' This is printed first ')
5 # Generator function contains yield statements
6 yield n
7
8 n += 1
9 print ( ' This is printed second ')
10 yield n
11
12 n += 1
13 print ( ' This is printed at last ')
14 yield n
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Generator functions in Python
Example 60
1 >>> a = my_gen () # It returns an object but does not start execution immediately .
2
3 >>> next ( a )
4 This is printed first
5 1
6
7 >>> next (a )
8 This is printed second
9 2
10
11 >>> next ( a )
12 This is printed last
13 3
14
15 >>> next ( a )
16 Traceback ( most recent call last ):
17 ...
18 StopIteration
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Generator functions in Python 61
▶ Observe that the value of variable n is remembered between the calls.
▶ The local variables are not destroyed when the function yields. This is exactly
the opposite to how the normal functions works.
▶ Furthermore, the generator object can be iterated only once.
▶ To restart the process we need to create another generator object using
some thing like a = my_gen()
▶ We can use generators directly with for loops.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Generator functions in Python 62
1 for item in my_gen () :
2 print ( item )
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Generators with a Loop 63
1 def rev_str ( mystr ):
2 length = len ( mystr )
3 for i in range ( length -1 , -1 , -1) :
4 yield mystr [i]
5
6 for ch in rev_str (" Hello !"):
7 print ( ch )
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Generators with a Loop 63
1 def rev_str ( mystr ):
2 length = len ( mystr )
3 for i in range ( length -1 , -1 , -1) :
4 yield mystr [i]
5
6 for ch in rev_str (" Hello !"):
7 print ( ch )
This generator function not only works with strings, but also with other kinds of
iterables like list, tuple, etc
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Generator Expressions
Anonymous generator functions 64
▶ Simple generators can be easily created on the fly using generator
expressions.
▶ Generator expression create anonymous generator functions. This is similar
to lambda function, whcih create anonymous functions.
▶ The syntax of generator expression similar to that of list comprehension in
Python but, the square brackets are replaced by round parentheses.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Generator Expressions
Anonymous generator functions 64
▶ Simple generators can be easily created on the fly using generator
expressions.
▶ Generator expression create anonymous generator functions. This is similar
to lambda function, whcih create anonymous functions.
▶ The syntax of generator expression similar to that of list comprehension in
Python but, the square brackets are replaced by round parentheses.
▶ The main difference between a list comprehension and a generator
expression is that a list comprehension produces list while the generator
expression produces one item at a time.
▶ Generator expressions have lazy execution (i.e., produce items only when
needed/asked for)
▶ As a result, generator expression is much more memory efficient than an
equivalent list comprehension.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Generator Expressions
Anonymous generator functions 65
1 my_list = [2 ,4 ,6 ,8 ,10]
2 listComprehension = [x **2 for x in my_list ]
3 generator = ( x **2 for x in my_list )
4
5 print ( listComprehension )
6 print ( generator )
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Generator Expressions
Anonymous generator functions 65
1 my_list = [2 ,4 ,6 ,8 ,10]
2 listComprehension = [x **2 for x in my_list ]
3 generator = ( x **2 for x in my_list )
4
5 print ( listComprehension )
6 print ( generator )
▶ We can use generator expression as function arguments
▶ While doing so, the round parentheses can be dropped.
sum((x**2 for x in my_list))
max(x**2 for x in my_list)
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
User of Python Generators 66
1. Easy of Implement
1 def PowTwoGen ( max =0) :
2 n = 0
3 while n < max :
4 yield 2 ** n
5 n += 1
6
7 gen_fn = PowTwoGen (5)
8
9 for i in gen_fn :
10 print ( i)
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
User of Python Generators 67
2. Memory Efficient
▶ A normal function return a sequence and create the entire sequence in
memory before returning the result.
▶ If the sequence is very large then the above process drains our memory.
▶ Generator implementation of such sequences is memory friendly as it
produces one item at a time.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
User of Python Generators 68
3. Represent Infinite Stream of Data
▶ A normal function return a sequence which is finite data.
▶ Generators are excellent mediums to represent an infinite stream of data.
▶ Infinite streams cannot be stored in memory, and since generators produce
only one item at a time, they can represent an infinite stream of data.
▶ In theory, below code generates all even numbers
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
User of Python Generators 68
3. Represent Infinite Stream of Data
▶ A normal function return a sequence which is finite data.
▶ Generators are excellent mediums to represent an infinite stream of data.
▶ Infinite streams cannot be stored in memory, and since generators produce
only one item at a time, they can represent an infinite stream of data.
▶ In theory, below code generates all even numbers
1 def all_even () :
2 n = 0
3 while True :
4 yield n
5 n += 2
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
User of Python Generators 69
4. Pipelining Generators
▶ Multiple generators can be used to pipeline a series of operations.
1 def fibonacci_numbers ( nums ) :
2 x, y = 0, 1
3 for _ in range ( nums ) :
4 x , y = y , x +y
5 yield x
6
7 def square ( nums ) :
8 for num in nums :
9 yield num **2
10
11 print ( sum ( square ( fibonacci_numbers (10) )))
This example prints the sum of the squares of the first n Fibonacci numbers.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Modules 70
▶ A module is a file containing Python definitions and statements.
▶ A file containing Python code, for e.g.: [Link], is called a module and its
module name would be example.
▶ A module can define functions, classes and variables.
▶ A module can also include runnable code.
▶ Grouping related code into a module makes the code easier to understand
and use.
▶ We can define our most used functions in a module and import it, instead of
copying their definitions into different programs.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python Modules 71
Let us create a module. Type the following and save it as [Link].
1 # Python Module example
2 def add (a , b ):
3 return a + b
4
5 def subtract (a , b):
6 return a - b
7
8 def multiply (a , b):
9 return a * b
10
11 def divide (a , b):
12 return a / b
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Using a Module 72
Now we can use the module we just created, by using the import statement:
1 import myCalc
2
3 myCalc . add (2 ,3)
4 myCalc . subtract (4 ,5)
5 myCalc . multiply (3 ,5)
6 myCalc . divide (3 ,7)
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Importing a Module with Re-naming 73
We can import a module by renaming it as follows.
1 import myCalc as mc
2
3 mc . add (2 ,3)
4 mc . subtract (4 ,5)
5 mc . multiply (3 ,5)
6 mc . divide (3 ,7)
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python from...import statement 74
We can import a specific variable or function from a Module using from . . . import
...
1 from myCalc import add
2
3 add (2 ,3)
4 multiply (2 ,3) # Returns error
Note: When importing using the from keyword, do not use the module name
when referring to elements in the module.
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python in-built Modules 75
1 import math
2
3 print ( math . pi )
4 print ( math . e )
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python in-built Modules 76
1 import math as m
2
3 print ( m . pi )
4 print ( m . sin (30) ) # Prints the sin of 30 radians
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
Python in-built Modules 77
1 from math import pi , e
2
3 print ( pi )
4 print ( e )
5
6 from math import *
7
8 print ( sin (30) )
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming
The dir() function 78
▶ The dir() built-in function returns a sorted list of strings containing the
names defined by a module.
▶ The list contains the names of all the modules, variables and functions that
are defined in a module.
1 import math
2 dir ( math )
3
4 import random
5 dir ( random )
6
7 import statistics
8 dir ( statistics )
Dr. B.S.R.V. Prasad | PMDS508L - Python Programming