In [1]:
# Function
# function is a block of code - which can be called anynumber of times.

In [2]:
def my_func():
    print "hello world!!!"

In [5]:
print type(my_func)
print my_func
my_func


<type 'function'>
<function my_func at 0x7f8adc700c80>
Out[5]:
<function __main__.my_func>

In [6]:
# every function has a return value 
# if you have no return value you get 'None'
print my_func()


hello world!!!
None

In [9]:
# return is not a print statement.
# return marks the end of the function.
def my_func():
    return "hello world!!!"
    print "hello onces"
    print "hello twice"
    print "hello thrice"

In [10]:
print my_func()


hello world!!!

In [11]:
# namespace/scope(local/global)

In [14]:
# Variables defined inside a function local variables/namespaces.
# The variables exist during the run time of the function.
# locals - inbuild function
# Use case I:
def my_func():
    print locals()
    x = 10
    print locals()
    return x

In [15]:
print my_func() # 10
print x         #


{}
{'x': 10}
10
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-15-d915979d3ea0> in <module>()
      1 print my_func() # 10
----> 2 print x         #

NameError: name 'x' is not defined

In [16]:
# globals
# we look first into locals and then into global.
# resolving happens from within the function.
# use case II:
y = 10

def my_func():
    print locals()
    return y
In [1]: y = 1 In [2]: def my_func(): ...: print locals() ...: return y ...: In [3]: print my_func() {} 1 In [4]: print y 1 In [5]: print globals() {'_dh': [u'/home/tcloudost/Documents/git_repositories/python-batches'], '__': '', '_i': u'print y', 'quit': , '__builtins__': , '_ih': ['', u'y = 1', u'def my_func():\n print locals()\n return y', u'print my_func()', u'print y', u'print globals()'], '__builtin__': , '__name__': '__main__', '___': '', '_': '', '_sh': , '_i5': u'print globals()', '_i4': u'print y', '_i3': u'print my_func()', '_i2': u'def my_func():\n print locals()\n return y', '_i1': u'y = 1', '__doc__': 'Automatically created module for IPython interactive environment', 'my_func': , '_iii': u'def my_func():\n print locals()\n return y', 'exit': , 'get_ipython': >, '_ii': u'print my_func()', 'In': ['', u'y = 1', u'def my_func():\n print locals()\n return y', u'print my_func()', u'print y', u'print globals()'], 'y': 1, '_oh': {}, 'Out': {}} In [6]: print x --------------------------------------------------------------------------- NameError Traceback (most recent call last) in () ----> 1 print x NameError: name 'x' is not defined

In [17]:
print my_func() # Novalue,10
print y # 10,10


{}
10
10

In [25]:
# use case III:

balance = 0

def deposit():
    balance = 0
    print locals()
    balance = balance + 1000
    return balance

def withdraw():
    balance = 0
    print locals()
    balance = balance - 300
    return balance

In [21]:
# provided you dont put balance=0 within function
'''
def deposit():
    print locals()
    balance = balance + 1000
    return balance

'''
print deposit()


{}
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-21-f63fab9016ab> in <module>()
----> 1 print deposit()

<ipython-input-20-f051a1fd59dd> in deposit()
      5 def deposit():
      6     print locals()
----> 7     balance = balance + 1000
      8     return balance
      9 

UnboundLocalError: local variable 'balance' referenced before assignment

In [23]:
print deposit()


{'balance': 0}
1000

In [24]:
print withdraw()


{}
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-24-c2cd67211b1e> in <module>()
----> 1 print withdraw()

<ipython-input-22-a49bb7139f2b> in withdraw()
     11 def withdraw():
     12     print locals()
---> 13     balance = balance - 300
     14     return balance

UnboundLocalError: local variable 'balance' referenced before assignment

In [26]:
print withdraw()


{'balance': 0}
-300

In [27]:
# global
balance = 0

def deposit():
    global balance
    print locals()
    balance = balance + 1000
    return balance

def withdraw():
    global balance
    print locals()
    balance = balance - 300
    return balance

In [28]:
print deposit()
print withdraw()


{}
1000
{}
700

In [29]:
# *,**,*args,**kwargs
# map,filter,lamba

In [1]:
# functional arguments
# you pass arguments as objects.
def my_add(a,b):
    result = a + b
    return result

In [4]:
# positional based arguments
print my_add(10,11)
print my_add("python","  rocks")
print my_add(" rocks","python")


21
python  rocks
 rockspython

In [7]:
# key based arguments
print my_add(a="python",b=" rocks")
print my_add(b=" rocks",a="python")


python rocks
python rocks

In [8]:
# *,**

In [10]:
my_values=[11,22]
# i want to pass my_values to my function my_add
#a,b=my_values
print my_add(*my_values)
print my_add(my_values)


33
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-10-c794235683eb> in <module>()
      3 #a,b=my_values
      4 print my_add(*my_values)
----> 5 print my_add(my_values)

TypeError: my_add() takes exactly 2 arguments (1 given)

In [19]:
# **
my_values={'a':'linux','b':'rocks'}
my_values1={'a':'linux','c':'rocks'}
# a = my_values['a']
# b = my_values['b']
print my_add(**my_values)
print my_add(**my_values1)


linuxrocks
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-19-05521372d79f> in <module>()
      5 # b = my_values['b']
      6 print my_add(**my_values)
----> 7 print my_add(**my_values1)

TypeError: my_add() got an unexpected keyword argument 'c'

In [12]:
# *args

In [13]:
print help(max)


Help on built-in function max in module __builtin__:

max(...)
    max(iterable[, key=func]) -> value
    max(a, b, c, ...[, key=func]) -> value
    
    With a single iterable argument, return its largest item.
    With two or more arguments, return the largest argument.

None

In [14]:
print max(-1,-2,-3,-4,-5) # -1
print max(11,33,44) #44
print max(22,10) #22


-1
44
22

In [17]:
# args - returns a tuple
def gmax(*args):
    big = -1
    for value in args:
        if value > big:
            big = value
    return big

In [18]:
print gmax(-1,-2,-3,-4,-5) # -1
print gmax(11,33,44) #44
print gmax(22,10) #22


-1
44
22

In [20]:
# **kwargs

In [26]:
# kwargs returns a dictionary
def callme(**kwargs):
    if 'name' in kwargs:
        print "my name is {}".format(kwargs['name'])
    if 'gender' in kwargs:
        print "my gender is {}".format(kwargs['gender'])
    if 'maiden' in kwargs:
        print "your mother maiden name is {}".format(kwargs['maiden'])
    if 'location' in kwargs:
        print "your location is {}".format(kwargs['location'])
    return True

In [27]:
print callme(name='kumar',gender='m')
print callme(name='kumar',maiden='vijaya',location='hyd')
print callme(location='hyd',gender='m')


my name is kumar
my gender is m
True
my name is kumar
your mother maiden name is vijaya
your location is hyd
True
my gender is m
your location is hyd
True

In [30]:
# default
def multi(num,limit=10):
    for value in range(1,limit+1):
        print "{0:2d} * {1:2d} = {2:3d}".format(num,value,num*value)

In [31]:
multi(5)


 5 *  1 =   5
 5 *  2 =  10
 5 *  3 =  15
 5 *  4 =  20
 5 *  5 =  25
 5 *  6 =  30
 5 *  7 =  35
 5 *  8 =  40
 5 *  9 =  45
 5 * 10 =  50

In [32]:
multi(5,limit=5)


 5 *  1 =   5
 5 *  2 =  10
 5 *  3 =  15
 5 *  4 =  20
 5 *  5 =  25

In [34]:
multi(5,5)


 5 *  1 =   5
 5 *  2 =  10
 5 *  3 =  15
 5 *  4 =  20
 5 *  5 =  25

In [35]:
# use case
#https://screenshots.en.sftcdn.net/en/scrn/20000/20678/putty-7.jpg
def putty(hostname,port=22):
    pass

In [36]:
# ssh -> putty(hostname)
# telnet -> putty(hostname,23)

In [37]:
## map,filter and lambda

In [38]:
def my_square(a):
    return a * a

In [40]:
print my_square(25)
print my_square(23)


625
529

In [41]:
print help(map)


Help on built-in function map in module __builtin__:

map(...)
    map(function, sequence[, sequence, ...]) -> list
    
    Return a list of the results of applying the function to the items of
    the argument sequence(s).  If more than one sequence is given, the
    function is called with an argument list consisting of the corresponding
    item of each sequence, substituting None for missing values when not all
    sequences have the same length.  If the function is None, return a list of
    the items of the sequence (or a list of tuples if more than one sequence).

None

In [49]:
'''
def my_square(a):
    return a * a
'''
print map(my_square,range(11,21))
print filter(my_square,range(11,21))


[121, 144, 169, 196, 225, 256, 289, 324, 361, 400]
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

In [43]:
# filter
# true function - return value
# false function - no return value

In [44]:
def my_even(a):
    if a % 2 == 0:
        return 'even'

In [45]:
print my_even(100) # even # True
print my_even(101) # None # False


even
None

In [46]:
print help(filter)


Help on built-in function filter in module __builtin__:

filter(...)
    filter(function or None, sequence) -> list, tuple, or string
    
    Return those items of sequence for which function(item) is true.  If
    function is None, return the items that are true.  If sequence is a tuple
    or string, return the same type, else return a list.

None

In [48]:
'''
def my_even(a):
    if a % 2 == 0:
        return 'even'
'''
print filter(my_even,range(11,21))
print map(my_even,range(11,21))


[12, 14, 16, 18, 20]
[None, 'even', None, 'even', None, 'even', None, 'even', None, 'even']

In [ ]:
# lambda
# creating functions on fly.

In [52]:
print map(my_square,range(11,21))
print map(lambda a:a*a,range(11,21))
print filter(my_even,range(11,21))
print filter(lambda a:a%2==0,range(11,22))


[121, 144, 169, 196, 225, 256, 289, 324, 361, 400]
[121, 144, 169, 196, 225, 256, 289, 324, 361, 400]
[12, 14, 16, 18, 20]
[12, 14, 16, 18, 20]

In [53]:
# function is a first class object.

In [54]:
def my_add(a,b):
    return a + b

def my_sub(a,b):
    return a - b

def my_extra(func,a,b):
    return func(a,b)

In [55]:
print my_extra(my_add,11,22)
print my_extra(my_sub,33,22)


33
11

In [56]:
# function within a function
def upper():
    def inner():
        x = 1
        return x
    return inner()
    
print upper() # 1,None
print inner() # 1,1


1
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-56-0e1f3e63bae8> in <module>()
      7 
      8 print upper() # 1,None
----> 9 print inner() # 1,1

NameError: name 'inner' is not defined

In [61]:
# function within a function
# function closures - All the variables available to the function during the defination of 
# function are imported automaticaly.
def upper():
    x = 1
    def inner():
        return x
    return inner

foo = upper()
print type(foo)
print foo
print x


<type 'function'>
<function inner at 0x7f65282131b8>
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-61-f7d166f6932f> in <module>()
      9 print type(foo)
     10 print foo
---> 11 print x

NameError: name 'x' is not defined

In [60]:
print foo()


1

In [ ]: