In [ ]:
# functions
# A function is a block of code.. which can be called n number of times.
# block - function - which could be repetative.

In [1]:
# every function has a return value.
# if there is no value returned , we get None.
def myfunc():
    print "hello world!!!"

In [2]:
print myfunc()
print myfunc()


hello world!!!
None
hello world!!!
None

In [13]:
# return is not a print statement.
# return marks the end of the function.

# defin
def myfunc():
    print "hey there"
    print "how are you"
    print "hope you are fine"
    return "hello world!!!"

In [14]:
# calling the function.
print myfunc()
print myfunc()


hey there
how are you
hope you are fine
hello world!!!
hey there
how are you
hope you are fine
hello world!!!

In [19]:
# scope of function
# scope or namespaces
# any variable defined inside a function is available only during the runtime of function.
# locals -> what are the variables available to us locally for our function.


def new():
    a = 1
    print locals()
    return a

In [21]:
print new
print type(new)


<function new at 0x7fa6d429a500>
<type 'function'>

In [22]:
print new() # 1
print a


{'a': 1}
1
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-22-cb8c301ab2fa> in <module>()
      1 print new() # 1
----> 2 print a

NameError: name 'a' is not defined

In [18]:
# if i want to save the value of "a" outside the function.
# we can trap the return value

z = new()
print z


1

In [23]:
# case II
# scope resolution
# if variables are not available in local namespace, your function looks in global namespace.
# globals -> what are variables available to us globally.

y = 10

def new():
    print locals()
    return y

In [24]:
print new() # 10
print y # 10


{}
10
10

In [25]:
print globals()


{'_dh': [u'/home/tcloudost/Documents/git_repositories/python-batches/batch-61'], '__': '', '__builtin__': <module '__builtin__' (built-in)>, '_iii': u'print new() # 1\nprint a ', 'quit': <IPython.core.autocall.ZMQExitAutocall object at 0x7fa6d43e0210>, '_i9': u'# calling the function.\nprint myfunc()\nprint myfunc()', '_i8': u'# return is not a print statement.\n# return marks the end of the function.\n\n# defin\ndef myfunc():\n    print "hey there"\n    print "how are you"\n    print "hope you are fine"\n    return "hello world!!!"\n    ', '_i7': u'print myfunc()\nprint myfunc()', '_i6': u'print myfunc()\nprint myfunc()', '_i5': u'# return is not a print statement.\n# return marks the end of the function.\ndef myfunc():\n    return "hello world!!!"\n    print "hey there"\n    print "how are you"\n    print "hope you are fine"', '_i4': u'print myfunc()\nprint myfunc()', '_i3': u'def myfunc():\n    return "hello world!!!"', '_i2': u'print myfunc()\nprint myfunc()', '_i1': u'def myfunc():\n    print "hello world!!!"', 'exit': <IPython.core.autocall.ZMQExitAutocall object at 0x7fa6d43e0210>, 'get_ipython': <bound method ZMQInteractiveShell.get_ipython of <ipykernel.zmqshell.ZMQInteractiveShell object at 0x7fa6dd043950>>, '_i': u'print new() # 10\nprint y # 10', 'new': <function new at 0x7fa6d429a5f0>, '_i24': u'print new() # 10\nprint y # 10', '_i14': u'# calling the function.\nprint myfunc()\nprint myfunc()', '_i22': u'print new() # 1\nprint a ', '__doc__': 'Automatically created module for IPython interactive environment', '_i20': u'print new\nprint type(new)', '_i21': u'print new\nprint type(new)', 'myfunc': <function myfunc at 0x7fa6d433c1b8>, '_ii': u'# case II\ny = 10\n\ndef new():\n    print locals()\n    return y', '__builtins__': <module '__builtin__' (built-in)>, 'In': ['', u'def myfunc():\n    print "hello world!!!"', u'print myfunc()\nprint myfunc()', u'def myfunc():\n    return "hello world!!!"', u'print myfunc()\nprint myfunc()', u'# return is not a print statement.\n# return marks the end of the function.\ndef myfunc():\n    return "hello world!!!"\n    print "hey there"\n    print "how are you"\n    print "hope you are fine"', u'print myfunc()\nprint myfunc()', u'print myfunc()\nprint myfunc()', u'# return is not a print statement.\n# return marks the end of the function.\n\n# defin\ndef myfunc():\n    print "hey there"\n    print "how are you"\n    print "hope you are fine"\n    return "hello world!!!"\n    ', u'# calling the function.\nprint myfunc()\nprint myfunc()', u'# return is not a print statement.\n# return marks the end of the function.\n\n# defin\ndef myfunc():\n    print "hey there"\n    print "how are you"\n    print "hope you are fine"\n    print "hello world!!!"\n    ', u'# calling the function.\nprint myfunc()\nprint myfunc()', u'# calling the function.\nprint myfunc()\nprint myfunc()', u'# return is not a print statement.\n# return marks the end of the function.\n\n# defin\ndef myfunc():\n    print "hey there"\n    print "how are you"\n    print "hope you are fine"\n    return "hello world!!!"\n    ', u'# calling the function.\nprint myfunc()\nprint myfunc()', u'# scope of function\n# scope or namespaces\n\ndef new():\n    a = 1\n    return a', u'print new\nprint type(new)', u'print new() # 1\nprint a ', u'# if i want to save the value of "a" outside the function.\n# we can trap the return value\n\nz = new()\nprint z', u'# scope of function\n# scope or namespaces\n# any variable defined inside a function is available only during the runtime of function.\n# locals -> what are the variables available to us locally.\n\n\ndef new():\n    a = 1\n    print locals()\n    return a', u'print new\nprint type(new)', u'print new\nprint type(new)', u'print new() # 1\nprint a ', u'# case II\ny = 10\n\ndef new():\n    print locals()\n    return y', u'print new() # 10\nprint y # 10', u'print globals()'], '__name__': '__main__', '___': '', '_': '', '_sh': <module 'IPython.core.shadowns' from '/usr/local/lib/python2.7/dist-packages/IPython/core/shadowns.pyc'>, '_i18': u'# if i want to save the value of "a" outside the function.\n# we can trap the return value\n\nz = new()\nprint z', '_i25': u'print globals()', '_i23': u'# case II\ny = 10\n\ndef new():\n    print locals()\n    return y', '_i13': u'# return is not a print statement.\n# return marks the end of the function.\n\n# defin\ndef myfunc():\n    print "hey there"\n    print "how are you"\n    print "hope you are fine"\n    return "hello world!!!"\n    ', '_i12': u'# calling the function.\nprint myfunc()\nprint myfunc()', '_i11': u'# calling the function.\nprint myfunc()\nprint myfunc()', '_i10': u'# return is not a print statement.\n# return marks the end of the function.\n\n# defin\ndef myfunc():\n    print "hey there"\n    print "how are you"\n    print "hope you are fine"\n    print "hello world!!!"\n    ', '_i17': u'print new() # 1\nprint a ', '_i16': u'print new\nprint type(new)', '_i15': u'# scope of function\n# scope or namespaces\n\ndef new():\n    a = 1\n    return a', '_ih': ['', u'def myfunc():\n    print "hello world!!!"', u'print myfunc()\nprint myfunc()', u'def myfunc():\n    return "hello world!!!"', u'print myfunc()\nprint myfunc()', u'# return is not a print statement.\n# return marks the end of the function.\ndef myfunc():\n    return "hello world!!!"\n    print "hey there"\n    print "how are you"\n    print "hope you are fine"', u'print myfunc()\nprint myfunc()', u'print myfunc()\nprint myfunc()', u'# return is not a print statement.\n# return marks the end of the function.\n\n# defin\ndef myfunc():\n    print "hey there"\n    print "how are you"\n    print "hope you are fine"\n    return "hello world!!!"\n    ', u'# calling the function.\nprint myfunc()\nprint myfunc()', u'# return is not a print statement.\n# return marks the end of the function.\n\n# defin\ndef myfunc():\n    print "hey there"\n    print "how are you"\n    print "hope you are fine"\n    print "hello world!!!"\n    ', u'# calling the function.\nprint myfunc()\nprint myfunc()', u'# calling the function.\nprint myfunc()\nprint myfunc()', u'# return is not a print statement.\n# return marks the end of the function.\n\n# defin\ndef myfunc():\n    print "hey there"\n    print "how are you"\n    print "hope you are fine"\n    return "hello world!!!"\n    ', u'# calling the function.\nprint myfunc()\nprint myfunc()', u'# scope of function\n# scope or namespaces\n\ndef new():\n    a = 1\n    return a', u'print new\nprint type(new)', u'print new() # 1\nprint a ', u'# if i want to save the value of "a" outside the function.\n# we can trap the return value\n\nz = new()\nprint z', u'# scope of function\n# scope or namespaces\n# any variable defined inside a function is available only during the runtime of function.\n# locals -> what are the variables available to us locally.\n\n\ndef new():\n    a = 1\n    print locals()\n    return a', u'print new\nprint type(new)', u'print new\nprint type(new)', u'print new() # 1\nprint a ', u'# case II\ny = 10\n\ndef new():\n    print locals()\n    return y', u'print new() # 10\nprint y # 10', u'print globals()'], 'y': 10, '_i19': u'# scope of function\n# scope or namespaces\n# any variable defined inside a function is available only during the runtime of function.\n# locals -> what are the variables available to us locally.\n\n\ndef new():\n    a = 1\n    print locals()\n    return a', 'z': 1, '_oh': {}, 'Out': {}}

In [33]:
# local or global variable
# local variables are given more priority than global variabels.
y = 10
def new():
    print locals()
    y = 2
    print locals()
    return y

In [34]:
print new()
print y


{}
{'y': 2}
2
10

In [35]:
# global

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

In [37]:
print deposit()


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

<ipython-input-35-9eb156c782f3> in deposit()
      3 balance = 0
      4 def deposit():
----> 5     balance = balance + 1000
      6     return balance

UnboundLocalError: local variable 'balance' referenced before assignment

In [45]:
balance = 0
def deposit():
    balance = 0
    balance = balance + 1000
    return balance
def withdraw():
    balance = 0
    balance = balance - 300
    return balance

In [41]:
print deposit()


1000

In [46]:
print withdraw()


-300

In [51]:
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 [52]:
print balance
print withdraw()


0
{}
-300

In [53]:
print balance
print deposit()


-300
{}
700

In [54]:
print balance
print withdraw()
print balance


700
{}
400
400

In [60]:
# case 3
bal = 0
def deposit():
    return bal + 1000

In [62]:
print deposit()


1000

In [63]:
print bal


0

In [ ]:
# Functional Arguments

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

In [4]:
# positional arguments
print my_add(11,12)
print my_add("linux"," rocks")
print my_add("rocks"," linux")


23
linux rocks
rocks linux

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


linux rocks

In [6]:
# *,**,*args,**kwargs

In [10]:
my_names = ["linux"," rocks"]
my_names1 = ["my"," linux"," rocks"]

print my_add(my_names)


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-10-2c0da2546135> in <module>()
      2 my_names1 = ["my"," linux"," rocks"]
      3 
----> 4 print my_add(my_names)

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

In [13]:
print my_add(*my_names)
print my_add(*my_names1)


linux rocks
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-13-d38d4e3fa3e7> in <module>()
      1 print my_add(*my_names)
----> 2 print my_add(*my_names1)

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

In [20]:
# **
my_names = {'a':'linux','b':' rocks'}
my_names1 = {'a':'linux','c':' rocks'}

print my_add(**my_names)


linux rocks

In [17]:
print my_add(my_names)


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-17-9e16aa041126> in <module>()
----> 1 print my_add(my_names)

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

In [21]:
print my_add(**my_names1)


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-21-1fd724038689> in <module>()
----> 1 print my_add(**my_names1)

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

In [23]:
# *args

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 [25]:
print max(2,3,4,5,6)
print max(133,5555)


6
5555

In [26]:
def gmax(*args):
    return args

In [59]:
print gmax(2,3,4,5,6)
print gmax(133,5555)
print gmax([1,2,3,4])


6
5555
[1, 2, 3, 4]
4

In [30]:
def gmax(*args):
    big = -1
    for value in args:
         if value > big:
                big = value
    return big

In [31]:
print gmax(2,3,4,5,6)
print gmax(133,5555)


6
5555

In [33]:
print max([1,2,3,4],[5,6,7],key=len)
print max([1,2,3,4],[5,6,7],key=sum)


[1, 2, 3, 4]
[5, 6, 7]

In [41]:
def my_ip(*args):
    big = 0
    for value in args:
        my_split = int(value.split('.')[0])
        if my_split > big:
            big = my_split
            ip  = value
    return ip

In [42]:
print my_ip('1.0.0.0','2.0.0.0')


2.0.0.0

In [37]:
# TODO
# ip address
# key => max

In [ ]:
# **kwargs

In [43]:
def callme(**kwargs):
    return kwargs

In [44]:
print callme(name="kumar",gender="male")
print callme(name="kumar",account="04066758765")
print callme(name="kumar",maiden="vijaya")


{'gender': 'male', 'name': 'kumar'}
{'account': '04066758765', 'name': 'kumar'}
{'name': 'kumar', 'maiden': 'vijaya'}

In [56]:
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 'account' in kwargs:
            print "my account is {}".format(kwargs['account'])
        if 'maiden' in kwargs:
            print "my mother name is {}".format(kwargs['maiden'])
        return ''

In [57]:
print callme(name="kumar",gender="male")
print callme(name="kumar",account="04066758765")
print callme(name="kumar",maiden="vijaya")


my name is kumar
my gender is male

my name is kumar
my account is 04066758765

my name is kumar
my mother name is vijaya


In [58]:
import logging
print help(logging.basicConfig)


Help on function basicConfig in module logging:

basicConfig(**kwargs)
    Do basic configuration for the logging system.
    
    This function does nothing if the root logger already has handlers
    configured. It is a convenience method intended for use by simple scripts
    to do one-shot configuration of the logging package.
    
    The default behaviour is to create a StreamHandler which writes to
    sys.stderr, set a formatter using the BASIC_FORMAT format string, and
    add the handler to the root logger.
    
    A number of optional keyword arguments may be specified, which can alter
    the default behaviour.
    
    filename  Specifies that a FileHandler be created, using the specified
              filename, rather than a StreamHandler.
    filemode  Specifies the mode to open the file, if filename is specified
              (if filemode is unspecified, it defaults to 'a').
    format    Use the specified format string for the handler.
    datefmt   Use the specified date/time format.
    level     Set the root logger level to the specified level.
    stream    Use the specified stream to initialize the StreamHandler. Note
              that this argument is incompatible with 'filename' - if both
              are present, 'stream' is ignored.
    
    Note that you could specify a stream created using open(filename, mode)
    rather than passing the filename and mode in. However, it should be
    remembered that StreamHandler does not close its stream (since it may be
    using sys.stdout or sys.stderr), whereas FileHandler closes its stream
    when the handler is closed.

None

In [60]:
# function are first class objects

In [62]:
def extra(func,x,y):
    return func(x,y)

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

def sub(x,y):
    if x > y:
        return x - y
    else:
        return y - x

In [63]:
print extra(add,11,12)
print extra(sub,22,33)


23
11

In [64]:
print type(add)


<type 'function'>

In [67]:
# https://pyformat.info/#string_pad_align
# https://mkaz.tech/code/python-string-format-cookbook/
# termcolor

In [ ]:
# function within a function
# map,filter,lambda,reduce
# function enclosures - decorators

In [1]:
# map
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 [2]:
def square(a):
    return a * a

In [3]:
print map(square,[2,33,55,77,99,12])


[4, 1089, 3025, 5929, 9801, 144]

In [4]:
# filter
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 [21]:
# function is going to be true only when it returns a values if not called false.
def even(a):
    if a % 2 == 0:
        return 'even'

In [22]:
print even(3)


None

In [7]:
print even(4)


even

In [8]:
print filter(even,range(1,12))


[2, 4, 6, 8, 10]

In [9]:
#
print map(square,[2,33,55,77,99,12])
print filter(even,range(1,12))


[4, 1089, 3025, 5929, 9801, 144]
[2, 4, 6, 8, 10]

In [14]:
print filter(square,[2,33,55,77,99,12])
print map(even,range(1,12))


[2, 33, 55, 77, 99, 12]
['odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd']

In [15]:
# lambda

In [17]:
# nameless function.
'''
def square(a):
    return a*a
    
lambda a:a*a  (has to be used in conjunction with map,filter) 

'''
print map(square,[2,33,55,77,99,12])
print map(lambda a:a*a,[2,33,55,77,99,12])


[4, 1089, 3025, 5929, 9801, 144]
[4, 1089, 3025, 5929, 9801, 144]

In [26]:
print filter(even,range(1,12))
print filter(lambda a:a % 2 == 0,range(1,12))
print map(lambda a:a % 2 == 0,range(1,12))


[2, 4, 6, 8, 10]
[2, 4, 6, 8, 10]
[False, True, False, True, False, True, False, True, False, True, False]

In [27]:
# https://github.com/zhiwehu/Python-programming-exercises/blob/master/100%2B%20Python%20challenging%20programming%20exercises.txt
# task
'''
def add(a,b):
    return a + b
    
# use lambda along with map and filter to pass some arguments.
'''

In [28]:
# function within a function.
def upper():
    x = 10       # global value for inner,local to outer
    def inner(): # local function in upper.
        return x   # x is locally not available for inner.
    print locals()
    return inner()  # inner is called here.

print upper() # 10


{'x': 10, 'inner': <function inner at 0x7f94784a9b90>}
10

In [29]:
print x # 10


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-29-7014d7d010cf> in <module>()
----> 1 print x # 10

NameError: name 'x' is not defined

In [30]:
print inner()


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-30-faa62f522c3c> in <module>()
----> 1 print inner()

NameError: name 'inner' is not defined

In [32]:
# function closure
def upper():
    x = 10       # global value for inner,local to outer
    def inner(): # local function in upper.
        return x   # x is locally not available for inner.
    print locals()
    return inner  # we are passing the address of inner.

In [33]:
print upper


<function upper at 0x7f94784e12a8>

In [34]:
foo = upper()


{'x': 10, 'inner': <function inner at 0x7f94784e11b8>}

In [35]:
print type(foo),foo


<type 'function'> <function inner at 0x7f94784e11b8>

In [36]:
'''
def inner():
    return x
'''
print foo()


10

In [37]:
'''
* where are we getting the value of x. gloablly x is not available for me.
'''

print x


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-37-2ad60813bce5> in <module>()
      3 '''
      4 
----> 5 print x

NameError: name 'x' is not defined

In [38]:
def abc():
    return y

In [39]:
print abc()


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-39-5b4314474db5> in <module>()
----> 1 print abc()

<ipython-input-38-601c5d6bf1d4> in abc()
      1 def abc():
----> 2     return y

NameError: global name 'y' is not defined

In [ ]:
# all the variables available to a function during the defination phase - locally and globally
# will be available if you return the address of the function.
# function closure - decorators