Python Quick Notes :: Part - 6


Bhaskar S 03/24/2013

Hands-on With Python - VI

Python supports the Functional Programming paradigm as well. Functional Programming has its roots from Mathematics where a computation involves evaluating one or more function(s), each of which take one or more input value(s) to produce some output value(s). The following are some of the characteristics of Functional Programming in Python:

The following is the python program named sample-29.py:

sample-29.py
#
# Name: sample-29.py
#

from functools import reduce

# ----- Functional Programmong with Python -----

# Pure function

def fact(n):
    if n <= 0:
        return 1
    return n * fact(n-1)

# Has no side effects

print("-----> Concept of Pure Functions")

n = 5

print("n (before) = ", n)
print("fact(5) = ", fact(n))
print("n (after) = ", n)

# First class object

print("-----> Concept of First Class Objects")

def func_obj(n):
    print("func_obj invoked with n = ", n)
    return

fn = func_obj

fn(5)

# Higer order function(s)

print("-----> Concept of Higher Order Functions")

def fn(arg):
    print("Invoked fn with arg: ", arg)
    return

def hofn1(fn, arg):
    print("Higher order function hofn1 called with arg: ", arg)
    fn(arg)
    return

def hofn2():
    print("Invoked hofn2")
    return fn

def filt_fn(n):
    return n % 3 == 0

def map_fn(n):
    return n*2

def red_fn(a, b):
    return a * b

hofn1(fn, 10)

myfn = hofn2()

myfn(15)

lst1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]

# Demostrate filter

print("List (before filter): ", lst1)

lst2 = list(filter(filt_fn, lst1))

print("List (after filter): ", lst2)

# Demostrate map

lst3 = list(map(map_fn, lst1))

print("List (after map): ", lst3)

# Demostrate reduce

val = reduce(red_fn, lst1)

print("Value (afetr reduce): ", val)

# Lambda function(s)

print("-----> Concept of Lambdas")

print("List (before lambda filter): ", lst1)

lst2 = [n for n in lst1 if n % 2 == 0]

print("List (after lambda filter): ", lst2)

lst3 = [n ** 3 for n in lst1]

print("List (after lambda map): ", lst3)

val = reduce(lambda a,b: a + b, lst1)

print("Value (afetr lambda reduce): ", val)

# Closure function(s)

print("-----> Concept of Closures")

def div_by(n):
    def inner(m):
        return m / n
    return inner

div_by_2 = div_by(2)

print("Invoke div_by_2(24) = ", div_by_2(24))

# List comprehensions

print("-----> Concept of List Comprehension")

lst4 = list(range(1, 11))

print("lst4 = ", lst4)

lst5 = [(n+1) for n in lst4]

print("lst5 = ", lst5)

lst6 = [n for n in lst4 if (n % 2) == 0]

print("lst6 = ", lst6)

lst7 = ['A', 'B']
lst8 = [1, 2]

lst9 = [(x, y) for x in lst7 for y in lst8]

print("lst9 = ", lst9)

Execute the following command:

python sample-29.py

The following is the output:

Output (sample-29.py)

-----> Concept of Pure Functions
n (before) =  5
fact(5) =  120
n (after) =  5
-----> Concept of First Class Objects
func_obj invoked with n =  5
-----> Concept of Higher Order Functions
Higher order function hofn1 called with arg:  10
Invoked fn with arg:  10
Invoked hofn2
Invoked fn with arg:  15
List (before filter):  [1, 2, 3, 4, 5, 6, 7, 8, 9]
List (after filter):  [3, 6, 9]
List (after map):  [2, 4, 6, 8, 10, 12, 14, 16, 18]
Value (afetr reduce):  362880
-----> Concept of Lambdas
List (before lambda filter):  [1, 2, 3, 4, 5, 6, 7, 8, 9]
List (after lambda filter):  [2, 4, 6, 8]
List (after lambda map):  [1, 8, 27, 64, 125, 216, 343, 512, 729]
Value (afetr lambda reduce):  45
-----> Concept of Closures
Invoke div_by_2(24) =  12
-----> Concept of List Comprehension
lst4 =  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
lst5 =  [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
lst6 =  [2, 4, 6, 8, 10]
lst9 =  [('A', 1), ('A', 2), ('B', 1), ('B', 2)]

The following are some of the miscellaneous concepts in Python:

The following is the python program named sample-30.py:

sample-30.py
#
# Name: sample-30.py
#

# ----- Miscellaneous concepts in Python -----

# Positional arguments

def myfunc1(*args):
    print("Invoked myfunc1() with args:")
    for a in args:
        print("\t{0}".format(a))
    return

myfunc1(1, 2, 3)

myfunc1('A', 'B', 'C', 'D', 'E')

# Keyword arguments

def myfunc2(**kwargs):
    print("Invoked myfunc2() with keywork args:")
    for key in kwargs:
        print("\t{0} = {1}".format(key, kwargs[key]))
    return

myfunc2(name='PYTHON', type='LANG', value=3)

myfunc2(a=1, b=2, c=3, d=4, e=5)

# Pre-defined __dict__ attribute

class myclass1():
    def __init__(self):
        self.name = ""
        self.price = 0.0

    def get_name(self):
        return self.name

    def set_name(self, name):
        self.name = name
        return

    def get_price(self):
        return self.price

    def set_price(self, price):
        self.price = price
        return

obj1 = myclass1()
obj1.set_name("Python")
obj1.set_price(9.99)

print("obj1.get_name() = ", obj1.get_name())
print("obj1.__dict__ = ", obj1.__dict__)

Execute the following command:

python sample-30.py

The following is the output:

Output (sample-30.py)

Invoked myfunc1() with args:
	1
	2
	3
Invoked myfunc1() with args:
	A
	B
	C
	D
	E
Invoked myfunc2() with keywork args:
	type = LANG
	name = PYTHON
	value = 3
Invoked myfunc2() with keywork args:
	a = 1
	c = 3
	b = 2
	e = 5
	d = 4
obj1.get_name() =  Python
obj1.__dict__ =  {'price': 9.99, 'name': 'Python'}

References

Python Quick Notes :: Part - 1

Python Quick Notes :: Part - 2

Python Quick Notes :: Part - 3

Python Quick Notes :: Part - 4

Python Quick Notes :: Part - 5