Skip to content

Commit 8feceae

Browse files
InonSInonS
InonS
authored and
InonS
committedFeb 17, 2014
Create Python276tutorial-FunctionalProgramming.py
1 parent 344c212 commit 8feceae

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed
 
+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
#! /usr/bin/python
2+
3+
# In Python, and other languages, functions are "first class citizens":
4+
# They are objects which can be treated as you would a variable or any other object
5+
# (passed as argument to another function, returned by a function, and so on).
6+
#
7+
# A function which takes or returns a function is called a functional, or higher-order function
8+
# (e.g. an integral takes a function as an argument).
9+
#
10+
# Use of these properties is called the functional programming paradigm.
11+
#
12+
# The origin for (and simplest instance of) a functional object is the labmda expression.
13+
14+
#http://docs.python.org/release/2.7.6/tutorial/
15+
16+
#==============================================
17+
18+
# 4.7.5 Lambda expressions (c.f. C function pointers)
19+
# "Lambda expression" here is a small, anonymous function;
20+
# used whenever a function is required to be represented as an object.
21+
# Syntactically restricted to a single expression...
22+
23+
# Lambda expression returning unevaluated function object
24+
add = lambda a,b: a+b
25+
print add(1,2) # evaluate function object
26+
argsList=[2,3]
27+
print apply(add,argsList) # using non-essential 'apply()' function
28+
29+
# Lambda expresssion referrencing value from containing scope (like nested function definitions)
30+
def make_incrementor(n):
31+
return lambda x: x+n # given parameter 'n' and taking argument 'x', return the value 'x+n'
32+
f=make_incrementor(42) # 'f' is now a function object with n=42
33+
print "f(0)= ", f(0) # print the evaluated function for x=0
34+
print "f(1)= ", f(1) # print the evaluated function for x=1
35+
36+
# Sort list according to a key, where the key is a lambda expression
37+
pairs=[(1,'one'),(2,'two'),(3,'three'),(4,'four')]
38+
print "Before sort: ", pairs
39+
pairKey=lambda pair: pair[1] # Lambda expression which, given an object 'pair', returns the [1] element (i.e. the second elemnt in the tuple)
40+
pairs.sort(key=pairKey) # Sort pairs according to the name of the number (i.e. alphabetically)
41+
print "After sort: ", pairs
42+
43+
#==============================================
44+
print
45+
46+
# 5.1.3 Functional programming (functional = higher-order function)
47+
48+
# Filter (aka C++ <algorithm> remove_copy_if() , etc.)
49+
50+
# Example: filter out Capital letters, punctuation marks, and spaces
51+
stringEx="Hello World!"
52+
print stringEx
53+
def someBoolFunction(x):
54+
return (ord(x) > 97) # is the ASCII value of the character x greater than 97?
55+
print filter(someBoolFunction,stringEx) # returns only string, tuple or list (depending on input)
56+
57+
# Example: compute a sequence of numbers not divisible by 2 or 3
58+
def notDiv2or3(x):
59+
return (0 != x % 2) and (0 != x % 3)
60+
print filter(notDiv2or3, range(2,25)) # recall that range is inclusive of 'from' argument and exclusive of 'to' argument
61+
62+
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
63+
print
64+
65+
# Map (aka C++ <algorithm> transform()
66+
67+
# Example: "do for each" return cube
68+
def cube(x):
69+
return x*x*x
70+
print map(cube, range(1,10))
71+
72+
# Example: map multiple sequences (e.g. lists)
73+
def add2(a,b):
74+
## if int(a) and int(b): return a+b
75+
## elif int(a): return a # i.e. ! int(b)
76+
## else: return b # int(b) but ! int(a)
77+
## if (type(a) is IntType) and (type(b) is IntType): return a+b # requires 'from types import *'
78+
return a+b if (type(a)== type(b)) else 'undefined'
79+
seq1=range(0,8)
80+
seq2=range(-6,4) # note that len(seq2) > len(seq1)
81+
print map(add2,seq1,seq2)
82+
83+
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
84+
print
85+
86+
# Reduce (aka Fold, C++ <numeric> accumulate()
87+
# see also python 3 'compose' and Haskell 'scan'
88+
89+
# serial composition of binary function (takes two arguments at a time) from left to right:
90+
91+
# leftFold(f;a,b,c,d) = f( f( f(a,b) ,c) ,d)
92+
print "((2/3)/4)/5 = 1/30",
93+
def div(x,y): return float(x)/float(y)
94+
l=range(2,6)
95+
print reduce(div,l)
96+
97+
# can take initial value argument:
98+
print "((((1)/2)/3)/4)/5 = 1/120",
99+
initVal=1
100+
print reduce(div,l,initVal)
101+
102+
# rightFold(f;a,b,c,d) = f(a , f(b, f(c,d) ) )
103+
print "2/(3/(4/5)) = 8/15",
104+
def vid(x,y):
105+
return div(y,x) # reverse function object
106+
lRev=reversed(range(2,6)) # reverse argument list (compose d,c, then b, then a ...)
107+
print reduce(vid,lRev)
108+
109+
# Example: sum numbers from 1 through 10 (inclusive)
110+
def add(x,y): return x+y
111+
print reduce(add,range(1,11))
112+
113+
114+
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
115+
print
116+
117+
# Example: Parralelization of search for all multiples of 'q' in the range [a:b]
118+
# 1) Split range [a:b] to n sub-ranges.
119+
# 2) MAP multiple-finding function to each sub-range, and execute in parallel.
120+
# 3) REDUCE result lists back to a single list.
121+
122+
123+
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
124+
print
125+
126+
# Creating a list using functional programming
127+
# specifically, using map()...
128+
129+
squaresLambda=map(lambda x: x**2, range(3))
130+
print squaresLambda
131+
132+
133+
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
134+
print
135+
# 5.1.4 listcomp: List comprehension
136+
# Concise way of creating a list in which each element is the result of some opperation, applied to each member of another sequence or iterable.
137+
138+
squaresExplicit=[] # create empty list
139+
for x in range(3):
140+
squaresExplicit.append(x**2)
141+
print squaresExplicit
142+
143+
squaresListcomp=[x**2 for x in range(3)] #concise expression, using list compehension
144+
print squaresListcomp
145+
146+
147+
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
148+
print
149+
# More complex list comprehension (more than one 'for' and additional 'if' clauses)
150+
# For example, the sequence of subsequences of non-negative integers,
151+
# such that each subsequence is shorter than 6 integers long (including zero)
152+
seqOfsubSeq=[x for y in range(10) for x in range(y) if y<6]
153+
print seqOfsubSeq

0 commit comments

Comments
 (0)
Failed to load comments.