Functional programming is the basis of most modern Big Data processing systems. Before going forward to the course, it is important to master data processing techniques using a functional programming style. In this assignment, your task is to train yourselves in thinking in a functional way when processing data.
Many of the the tasks below are easy, but some are not and require many iterations (and extensive testing!) to get right. For some of them, you can find ready-made solutions on the internet. Even though it may be tempting, we advise you against copying and pasting them here, as you will regret it later on in the course. Wax on, wax off!
This assignment has a total of 115 points. Your grade is calculated with min(points/11, 10)
, i.e. you need 110 points for a 10.
A few notes:
In this part you will implement core functions that are vital to functional programming.
T (5pts): Implement map
using iteration for lists/arrays
def map(func, xs):
pass
map(lambda x: x*2, range(7))
T (5pts): Implement filter
using iteration for lists/arrays
def filter(func, xs):
pass
filter(lambda x: x % 2 == 0, range(7))
T (5pts): Implement reduceR
using iteration for lists/arrays
def reduceR(func, xs, init):
pass
reduceR(lambda x, y: x-y, range(7), 0)
T (5pts): Implement a function flatten(xs: [[A]]): [A]
that converts a list of
lists into a list formed by the elements of these lists. For example:
>>> a = [[1,2],[2,3],[3,[4]]]
>>> flatten(a)
[1,2,2,3,3,[4]]
def flatten(xss):
pass
flatten([[1,2,3],[4,5], [7,[8,9]]])
In every implementation from now (also in next steps)on you should reuse at least one of your answers to an earlier question.
T (5pts): Implement reduceL
by reusing reduceR
def reduceL(func, xs, init):
pass
reduceL(lambda x, y: x-y, range(7), 0)
T (10pts): Implement group_by
by reusing reduceL
.
def group_by(classifier, xs):
pass
group_by(lambda x: "even" if x % 2 == 0 else "odd", range(10))
T (5pts): Implement distinct
using reduceL
.
def distinct(xs):
pass
a = [1,2,3,1,2,3,4,5,6,5,4,3,2,1]
distinct(a)
T (5pts): Implement flatmap
.
def flatmap(func, xs):
pass
flatmap(lambda x: list(range(x)), range(5))
T (5pts): Implement max(xs: [Integer]): Integer
that finds the largest value in xs
. You can assume the list is non-empty.
def max(xs):
pass
max([1,59,42,27,38])
T (10pts): Implement a function called drop_while(f: A -> Boolean, xs: [A]) : [A]
that drops the longest prefix of elements from xs
that satisfy f
.
>>> a = [1,2,3,4,3,2,1]
>>> dropWhile(lambda x: x <= 3, a)
[4,3,2,1]
def drop_while(func, xs):
pass
drop_while(lambda x: x <= 3, [1,2,1,3,5,3,1,4,1,5,6])
T (10pts): Implement a function zip(xs: [A], ys: [B]): List[(A,B)]
that returns a list formed from this list and another list by combining the corresponding elements in pairs. If one of the two lists is longer
than the other, its remaining elements are ignored.
>>> a = [1,2,3,4]
>>> b = [a,b,c,d,e]
>>> zip(a,b)
[(1, 'a'), (2, 'b'), (3, 'c'), (4,'d')]
def zip(xs, ys):
pass
a = [2,3,4]
b = ['a','b','c','d']
zip(a,b)
T (10pts): Implement a function
scanL(f: (acc: B, x: A) -> B, xs: [A], init: B) -> [B]
that works like reduceL
but instead of producing one final result, it also
returns all the intermediate results.
>>> a = [2,3,4]
>>> scanL(a, 0, lambda x, y: x + y)
[0, 2, 5, 9]
def scanL(func, xs, init):
pass
scanL(lambda x, y: x + y, [2,3,4], 0)
In the following questions you will solve realistic problems with the techniques you learned in this assignment. You will be working with data of San Francisco Library patrons. You can find the data file here. Below you can find what each field means.
Solve the following questions using functions you implemented earlier. The code for reading the file is already given. Hint: for testing purposes it could be beneficial to only use a small part of the dataset.
# This snippet imports the csv file to a list of dicts
import csv
file = 'library.csv' # Change this filepath to the location of your file if necessary
patrons = []
try:
with open(file) as fh:
rd = csv.DictReader(fh, delimiter=',')
for row in rd:
patrons.append(row)
except FileNotFoundError as e:
print(e)
T (10pts) Some patrons have indicated that they want to receive notices via email, but have not provided their email address. Implement a function that outputs a list of the IDs of these patrons.
def missing_email(xs):
pass
missing_email(patrons)
T (10pts) Implement a function that outputs the total amount of checkouts from members originally registered at a given location.
>>> checkouts(patrons, "Noe Valley/Sally Brunn")
1355624
def checkouts(xs, location):
pass
checkouts(patrons, "Mission")
T (15pts) Implement a function that lists the number of renewals per location in a tuple. Example output for part of the dataset:
>>> number_renewals(patrons)
[('Presidio', 431988),
('Mission', 1218976)]
def number_renewals(xs):
pass
number_renewals(patrons)