Notes
Notes
Notes
19ISE36
UNIT 2
Functions and Scoping : Functions and Scoping, Function calls, Type conversion, Type
coercion, Math functions, Functions as Objects ,Composition ,Variables and parameters are
local, global, Recursion, Modules, Files Handling, Directories
FUNCTIONS:
A function is a block of organized, reusable code that is used to perform a single, related
action. It is a named sequence of statement used to perform a specific task.
➢
Once a function is written, it can be reused as and when required. So, functions are
also called reusable code.
➢
Functions provide modularity for programming. A module represents a part of the
program. Usually, a programmer divides the main task into smaller sub tasks called
modules.
➢
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.
➢
When there is an error in the software, the corresponding function can be modified
without disturbing the other functions in the software.
➢
The use of functions in a program will reduce the length of the program.
Python has many built-in functions like sqrt( ), etc. but you can also create your own
functions. These functions are called user-defined functions.
Objectname.methodname()
Classname.methodname()
Defining a Function
Rules to define a function in Python.
Function blocks begin with the keyword def followed by the function name and
parentheses ( ).
Any input parameters or arguments should be placed within these parentheses. You
can also define parameters inside these parentheses.
The code block within every function starts with a colon (:) and is indented.
A function that performs some task, but do not return any value to the calling function
is known as void function.
Syntax:
def functionname (parameters):
body of the function
return [expression]
Example:
def add(a,b):
"""This function sum the numbers"""
c=a+b
print c
return
Calling Function:
A function cannot run by its own. It runs only when we call it. While calling the function, we
should pass the necessary values to the function in the parentheses as:
add(5,12)
Example:
add(2,3)
add(2.3, 4.5)
add(a=2.3, b=4.5)
add(b=4.5, a=2.3)
Out: 5
Out: 6.8
Out: 6.8
Out: 6.8
x,y,z=calc(5,8)
print ("Addition=",x)
print ("Subtraction=",y)
print ("Multiplication=",z)
Map function
Map is built-in function that takes a function and applies it to a list..map() function returns a
list of the results after applying the given function to each item of a given iterable (list, tuple)
Syntax :
map(fun, iter)
Parameters :
fun : It is a function to which map passes each element of given iterable.
iter : It is a iterable which is to be mapped.
Each element in the list is used a parameter for len() and the results form a list. Notice that len
is passed and not len(). This is because, we are not calling len. We are just passing len to
map. map will internally call it
def add(a,b):
return a+b
print(list(map(add, [1,2,3,4], [10,20,30,40])))
def cube(number):
return number**3
print(list(map(cube, range(10))))
In Python, functions are considered as first class objects. It means we can use functions as
perfect objects. 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. The following possibilities are:
def first(msg):
print(msg)
first("Hello")
second = first
second("Hello")
Output
Hello
Hello
def display(f):
return "hai"+f
def message():
return " how r u?"
fun=display(message())
print(fun) Output: hai how r u?
def inc(x):
return x + 1
def dec(x):
return x - 1
def operate(func, x):
result = func(x)
return result
>>>func(inc,3)
>>>4
Output: how r u?
def display(st):
def message():
return "how r u? "
res=message()+st
return res
x=display("ISE")
print(x)
Pass by Object Reference in Python
In Python, we can observe both pass by value and pass by reference behaviour while passing
the actual parameters to the function definition. Python supports pass by object reference
unlike in C, C++.
Pass by Value:
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. In python, the values are sent
to functions by means of object references. If we store a value into a variable as:
x=10
So, 10 is the object and x is the name of that object. Also, objects are created on heap memory
which is a very huge memory that depends on the RAM of our computer system.
This means another object 15 is created in memory and that object is referenced by the name
„x‟. The reason why another object is created in the memory is that the integer objects are
immutable (not modifiable). So in the function, when we display „x‟ value, it will display 15.
Once we come outside the function and display „x‟ value, it will display numbers of „x‟ inside
and outside the function, and we see different numbers since they are different objects.
Pass by Reference:
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. In python, lists and dictionaries are
mutable. That means, when we change their data, the same object gets modified and new
object is not created.
Example: A Python program to pass a list to a function and modify it.
def modify(a):
a.append(5)
print("inside",a,id(a))
a=[1,2,3,4]
modify(a)
print("outside",a,id(a))
Output:
inside [1, 2, 3, 4, 5] 45355616
outside [1, 2, 3, 4, 5] 45355616
Inside the function, we are appending a new element „5‟ to the list. Since, lists are mutable,
adding a new element to the same object is possible. Hence, append( ) method modifies the
same object.
a) Positional Arguments:
These are the arguments passed to a function in correct positional order. Here, the number of
arguments and their position in the function definition should match exactly with the number
and position of argument in the function call.
def attach(s1,s2):
s3=s1+s2
print (s3)
attach("New","Delhi") #Positional arguments
b) 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:
def grocery(item, price):
At the time of calling this function, we have to pass two values and we can mention which
value is for what. For example,
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’)
def grocery(item,price):
print "item=",item
print "price=",price
grocery(item="sugar",price=50.75) # keyword arguments
grocery(price=88.00,item="oil") # keyword arguments
Output:
item= sugar
price= 50.75
item= oil
price= 88.0
c) Default Arguments:
We can mention some default value for the function parameters in the definition.
def grocery(item, price=40.00)
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. So, a default argument is an
argument that assumes a default value if a value is not provided in the function call for that
argument.
Example: def grocery(item,price=40.00):
print("item=",item)
print("price=",price)
grocery(item="sugar",price=50.75)
grocery(item="oil")
Output:
item= sugar
price= 50.75
item= oil
price= 40.0
Example:
def print_series(n=5):
for i in range(n):
print(i)
print ('calling with 3 as parameter')
print_series(3)
print ('calling without an actual parameter')
print_series()
Output:
Out: calling with 3 as parameter
Out: 0
Out: 1
Out: 2
Out: calling without an actual parameter
Out: 0
Out: 1
Out: 2
Out: 3
Out: 4
Example:
def add(farg,*args):
sum=0
for i in args:
sum=sum+i
print("sum is",sum+farg)
add(5,10)
add(5,10,20)
add(5,10,20,30)
Output: sum is 15
sum is 35
sum is 65
Example:
def max(*numbers):
result = -1
for number in numbers:
if number > result:
result = number
print(result)
Out: max(12,3,19,1)
19
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.
Example-1:
def myfunction():
a=10
print("Inside function",a) #display 10
myfunction()
print("outside function",a) # Error, not available
Output:
Inside function 10
outside function
NameError: name 'a' is not defined
When a variable is declared above a function, it becomes global variable. Such variables are
available to all the functions which are written after it.
Example-2:
a=11
def myfunction():
b=10
print("Inside function",a) #display global var
print("Inside function",b) #display local var
myfunction()
print("outside function",a) # available
print("outside function",b) # error
Output:
Inside function 11
Inside function 10
outside function 11
outside function
NameError: name 'b' is not defined
Sometimes, the global variable and the local variable may have the same name. In that case,
the function, by default, refers to the local variable and ignores the global variable. So, the
global variable is not accessible inside the function but outside of it, it is accessible.
Example-1:
a=11
def myfunction():
a=10
print("Inside function",a) # display local
myfunction()
print("outside function",a) # display global variable
Output:
Inside function 10
outside function 11
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
a=11
def myfunction():
global a
a=10
print("Inside function",a) # display global variable myfunction()
print("outside function",a) # display global variable
Output:
Inside function 10
outside function 10
Recursive Functions:
A function that calls itself is known as recursive function.
factorial(n) = n * factorial(n-1)
Example-1:
def factorial(n):
if n==0:
result=1
else:
result=n*factorial(n-1)
return result
for i in range(1,5):
Print("factorial of ",i,"is",factorial(i))
Output:
factorial of 1 is 1
factorial of 2 is 2
factorial of 3 is 6
factorial of 4 is 24
These functions are called anonymous because they are not declared in the standard
manner by using the def keyword. You can use the lambda keyword to create small
anonymous functions.
Lambda forms can take any number of arguments but return just one value in the form of
an expression. They cannot contain commands or multiple expressions.
An anonymous function cannot be a direct call to print because lambda requires an
expression.
Lambda functions have their own local namespace and cannot access variables other than
those in their parameter list and those in the global namespace.
Although it appears that lambda's are a one-line version of a function, they are not
equivalent to inline statements in C or C++, whose purpose is by passing function stack
allocation during invocation for performance reasons.
The syntax is:
lambda argument_list: expression
Example:
Normal function
f=lambda x:x*x
value = f(5) def square(x):
print (value) return x*x
Usage of lambda function with map() Function
The advantage of the lambda operator can be seen when it is used in combination with the
map() function. map() is a function with two arguments:
def fahrenheit(T):
return ((float(9)/5)*T + 32)
def celsius(T):
return (float(5)/9)*(T-32)
temp = (36.5, 37, 37.5,39)
F = list(map(fahrenheit, temp))
C =list(map(celsius, F))
By using lambda, we wouldn't have had to define and name the functions fahrenheit() and
celsius(). You can see this in the following interactive session:
map() can be applied to more than one list. The lists have to have the same length. map() will
apply its lambda function to the elements of the argument lists, i.e. it first applies to the
elements with the 0th index, then to the elements with the 1st index until the n-th index is
reached:
>>> a = [1,2,3,4]
>>> b = [17,12,11,10]
>>> c = [-1,-4,5,9]
>>> map(lambda
x,y:x+y,a,b) [18, 14, 14, 14]
>>> map(lambda
x,y,z:x+y+z,a,b,c) [17, 10, 19, 23]
Filter function
The function filter(function, list) offers an elegant way to filter out all the elements of a list,
for which the function function returns True. The function filter(f,l) needs a function f as its
first argument. f returns a Boolean value, i.e. either True or False. This function will be
applied to every element of the list l. Only if f returns True will the element of the list be
included in the result list.
reduce()
The reduce(fun,seq) function is used to apply a particular function passed in its argument to all
of the list elements mentioned in the sequence passed along. This function is defined in
“functools” module.
At first step, first two elements of sequence are picked and the result is obtained. Next step is
to apply the same function to the previously attained result and the number just succeeding the
second element and the result is again stored. This process continues till no more elements are
left in the container. The final returned result is returned and printed on console.
import functools
lis = [ 1 , 3, 5, 6, 2, ]
# using reduce to compute sum of list
print ("The sum of the list elements is : ",end="")
print (functools.reduce(lambda a,b : a+b,lis))
Output:
The sum of the list elements is : 17
The maximum element of the list is : 6
Function composition
Function composition is a way of combining functions such that the result of each function is
passed as the argument of the next function. For example, the composition of two functions f
and g is denoted f(g(x)) .
Output: 22
Modules:
A module is a file containing Python definitions and statements. The file name is the module
name with the suffix.py appended. Within a module, the module‟s name (as a string) is
available as the value of the global variable __name__. For instance, use your favourite text
editor to create a file called fibo.py in the current directory with the following contents:
Now enter the Python interpreter and import this module with the following command:
This does not enter the names of the functions defined in fibo directly in the current symbol
table; it only enters the module name fibo there. Using the module name you can access the
functions:
>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>>fibo.__name__
'fibo'
from statement:
Each module has its own private symbol table, which is used as the global symbol table by
all functions defined in the module. Thus, the author of a module can use global variables
in the module without worrying about accidental clashes with a user‟s global variables. On
the other hand, if you know what you are doing you can touch a module‟s global variables
with the same notation used to refer to its functions, modname.itemname.
Modules can import other modules. It is customary but not required to place all import
statements at the beginning of a module (or script, for that matter). The imported module
names are placed in the importing module‟s global symbol table.
mymodule .py
def greeting(name):
print("Hello, " + name)
person1 = {
"name": "John",
"age": 36,
"country": "Norway"
}
import mymodule as mx
a = mx.person1["age"]
print(a)
mx.greeting(“Tom”)
There is a variant of the import statement that imports names from a module directly into
the importing module‟s symbol table. For example:
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
This does not introduce the module name from which the imports are taken in the local
symbol table (so in the example, fibo is not defined). Only fib() is imported.There is even a
variant to import all names that a module defines:
>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
Built-in modules
import platform
x = platform.system()
print(x)
A Python statement can access variables in a local namespace and in the global
namespace. If a local and a global variable have the same name, the local variable
shadows the global variable.
Each function has its own local namespace. Class methods follow the same scoping
rule as ordinary functions.
Python makes educated guesses on whether variables are local or global. It assumes
that any variable assigned a value in a function is local.
Therefore, in order to assign a value to a global variable within a function, you must
first use the global statement.
The statement global VarName tells Python that VarName is a global variable. Python
stops searching the local namespace for the variable.
For example, we define a variable Money in the global namespace. Within the
functionMoney, we assign Money a value, therefore Python assumes Money as a local
variable. However, we accessed the value of the local variable Money before setting it,
so an UnboundLocalError is the result. Uncommenting the global statement fixes the
problem.
Math functions
Python has a math module that provides most of the familiar mathematical functions.
>>> degrees = 45
>>> radians = degrees / 360.0 * 2 * math.pi
>>> math.sin(radians)
0.707106781187
>>>math.cos(45*math.pi/180)
0.7071067811865476
>>> math.tan(45*math.pi/180)
0.9999999999999999
Directories
In a computer system, files are organized into directories. These may contain subdirectories
and files. We should import the OS module to be able to access the method.
>>> import os
To get the contents of a directory into a python list, we use the listdir() method.
>>> os.listdir()
['All Users', 'Default', 'Default User', 'desktop.ini', 'Public', 'TEMP', 'vandana']
>>>os.path.abspath(".\rpc.py")
'C:\\Users\\vandana\\Anaconda3\\Lib\\idlelib\\.\rpc.py'
>>> os.path.isdir("rpc.py")
False
>>> os.path.isdir("..\idlelib")
True
>>> os.path.isfile("rpc.py")
True
>>> os.path.isfile("..\idlelib")
False
>>>os.getcwd()
'C:\\Users\\vandana\\Anaconda3\\Lib\\idlelib
To get the path of current working directory as a bytes object, we use the method getcwdb().
>>>os.getcwdb()
b'C:\\Users\\vandana\\Anaconda3\\Lib\\idlelib'
>>> print(os.getcwd())
C:\Users\vandana\Anaconda3\Lib\idlelib
>>> os.chdir("C:\\Users")
>>> os.getcwd()
'C:\\Users'
>>> os.mkdir("ptest")
>>>os.rmdir('dirname')
>>> os.rename("ptest","python-test")
>>>os.remove('C:\\Users\\lifei\\Desktop\\Christmas 2017\\Readme.txt')
>>> os.path.exists('C:\\Users\\lifei\\Desktop\\Myfolder')
Pickling in Python
Pickle is used for serializing and de-serializing Python object structures, also called
marshalling or flattening. Serialization refers to the process of converting an object in memory
to a byte stream that can be stored on disk or sent over a network. Later on, this character
stream can then be retrieved and de-serialized back to a Python object. Any object in python
can be pickled so that it can be saved on disk.
Pickle “serialises” the object first before writing it to file. Pickling is a way to convert a
python object (list, dict, etc.) into a character stream. The idea is that this character stream
contains all the information necessary to reconstruct the object in another python script.
The pickle module implements binary protocols for serializing and de-serializing a
Python object structure. “Pickling” is the process whereby a Python object hierarchy is
converted into a byte stream, and “unpickling” is the inverse operation, whereby a byte stream
(from a binary file or bytes-like object) is converted back into an object hierarchy.
Application:
1) Saving a program's state data to disk so that it can carry on where it left off when restarted
(persistence)
4) Converting an arbitrary python object to a string so that it can be used as a dictionary key
(e.g. for caching & memoization).
5) Pickle is very useful for when you're working with machine learning algorithms, where you
want to save them to be able to make new predictions at a later time, without having to rewrite
everything or train the model all over again
Example:
import pickle
a = ['test value','test value 2','test value 3']
fileObject = open(“test_file”,'wb')
pickle.dump(a,fileObject)
fileObject.close()
fileObject = open(“test_file”,'r')
b = pickle.load(fileObject)
print(b)
print(a==b, type(b))
Output
['test value','test value 2','test value 3']
True <class ‘list’>