the building blocks of functional computing data, sequences conditionals recursion cs 121 today list...

27
The building blocks of functional computing data, sequences conditional s recursion CS 121 today List Comprehensions map and applications

Upload: scot-kelley

Post on 03-Jan-2016

228 views

Category:

Documents


2 download

TRANSCRIPT

The building blocks of

functional computing

data, sequences

conditionals

recursion

CS 121 today

List Comprehensions

map and applications

functional programming

>>> 'fun' in 'functional'True

Key ideas in functional programming

• create small building blocks (functions)

• leverage self-similarity (recursion)

• representation via list structures (data)

Compose these together to solve or investigate problems.

elegant and concisenot maximally efficient for

the computer…vs.

return to recursion

Composing functions into specific applications

Creating general functions that will be useful everywhere (or almost…)

return to recursion

Composing functions into specific applications

Creating general functions that will be useful everywhere (or almost…)

building blocks with which to compose…

sum, range

def sum(L):

""" input: a list of numbers, L

output: L's sum

"""

sum, range

def sum(L):

""" input: a list of numbers, L

output: L's sum

"""

if len(L) == 0:

return 0.0

else:

return L[0] + sum(L[1:])

Base Caseif the input

has no elements, its sum is zero

Recursive Case

if L does have an element, add

that element's value to the sum of the REST of the

list…

This input to the recursive call must be "smaller" somehow…

sum, range

def range(low,hi):

""" input: two ints, low and hi

output: int list from low up to hi

"""

excluding hi

sum, range

def range(low,hi):

""" input: two ints, low and hi

output: int list from low up to hi

"""

if hi <= low:

return []

else:

return

excluding hi

sum, range

def range(low,hi):

""" input: two ints, low and hi

output: int list from low up to hi

"""

if hi <= low:

return []

else:

return [low] + range(low+1,hi)

excluding hi

Recursion: Good News/Bad News

Recursion is common (fundamental) in functional programming

def dblList(L):

""" Doubles all the values in a list.

input: L, a list of numbers """

if L == []:

return L

else:

return [L[0]*2] + dblList(L[1:])

But you can sometimes hide it away!

Map: The recursion "alternative"

def dbl(x):

return 2*x

def sq(x):

return x**2

def isana(x):

return x=='a’

>>> map( dbl, [0,1,2,3,4,5] )[0, 2, 4, 6, 8, 10]

>>> map( sq, range(6) )[0, 1, 4, 9, 16, 25]

>>> map( isana, 'go away!' )[0, 0, 0, 1, 0, 1, 0, 0]

Hey… this looks a bit False to me!

(1) map always returns a list

(2) map(f,L) calls f on each item in L

Map !

def dblList(L): """ Doubles all the values in a list. input: L, a list of numbers """ if L == []: return L else: return [L[0]*2] + dblList(L[1:])

Without map

def dbl(x): return x*2

def dblList(L): """ Doubles all the values in a list. input: L, a list of numbers """ return map(dbl, L)

With map!

Map: a higher-order function

In Python, functions can take other functions as input…

def map( f, L ):

KeyConcep

t Functions ARE data!

Why use map?

Why use map?

Faster execution in Python – map optimized for operations in lists

More elegant / shorter code, “functional in style”

Avoid rewriting list recursion (build once, use lots)

Mapping without map: List Comprehensions

>>> [ dbl(x) for x in [0,1,2,3,4,5] ][0, 2, 4, 6, 8, 10]

>>> [ x**2 for x in range(6) ][0, 1, 4, 9, 16, 25]

>>> [ c == 'a' for c in 'go away!' ][0, 0, 0, 1, 0, 1, 0, 0]

Anything you want to happen to each element of a list

output

output

output

input

input

input

name that takes on the value of each element

in turnthe list (or string)

any name is OK!

Mapping without map: List Comprehensions

>>> [ dbl(x) for x in [0,1,2,3,4,5] ][0, 2, 4, 6, 8, 10]

>>> [ x**2 for x in range(6) ][0, 1, 4, 9, 16, 25]

>>> [ c == 'a' for c in 'go away!' ][0, 0, 0, 1, 0, 1, 0, 0]

def dbl(x):

return 2*x

def sq(x):

return x**2

def isana(x):

return x=='a’

>>> map( dbl, [0,1,2,3,4,5] )[0, 2, 4, 6, 8, 10]

>>> map( sq, range(6) )[0, 1, 4, 9, 16, 25]

>>> map( isana, 'go away!' )[0, 0, 0, 1, 0, 1, 0, 0]

List Comprehensions

def len(L): if L == []: return 0 else: return 1 + len(L[1:])

len(L)

implemented via raw recursion

sScore(s)

sajak(s)

def sajak(s): if len(s) == 0: return 0 else: if s[0] not in 'aeiou': return sajak(s[1:]) else: return 1+sajak(s[1:])

def sScore(s): if len(s) == 0: return 0 else: return letScore(s[0]) + \

sScore(s[1:])

scrabble score

List Comprehensions

LC = [1 for x in L] return sum( LC )

len(L)

List Comprehensions

LC = [1 for x in L] return sum( LC )

len(L)

sajak(s)LC = [c in 'aeiou' for c in s]return sum( LC )

# of vowels

List Comprehensions

LC = [1 for x in L] return sum( LC )

len(L)

sScore(s)

sajak(s)LC = [c in 'aeiou' for c in s]return sum( LC )

scrabble score

# of vowels

LC = [ letScore(c) for c in s] return sum( LC )

Write each of these functions concisely using list comprehensions…

Write

def count(e,L):

Write

def lotto(Y,W):

input: e, any element L, any list or stringoutput: the # of times L contains e example: count('f', 'fluff') == 3

input: Y and W, two lists of lottery numbers (ints)

output: the # of matches between Y & W

example: lotto([5,7,42,44],[3,5,7,44]) == 3

Y are your numbers

W are the winning numbers

Remember True == 1 and False == 0

Extra! Write

def divs(N):

input: N, an int >= 2output: the number of positive divisors of Nexample: divs(12) == 6 (1,2,3,4,6,12)

LC = [x==e for x in L] return sum( LC )

count(e,L)

lotto(Y,W)LC = [c in Y for c in W]return sum( LC )

divs(N)LC = [ N%c==0 for c in range(1,N+1)] return sum( LC )

LC = [x==e for x in L] return sum( LC )

count(e,L)

divs(N)

lotto(Y,W)LC = [c in Y for c in W]return sum( LC )

LC = [ N%c==0 for c in range(1,N+1)] return sum( LC )