7.9. Exercises¶
-
In Robert McCloskey’s book Make Way for Ducklings, the names of the ducklings are Jack, Kack, Lack, Mack, Nack, Ouack, Pack, and Quack. This loop tries to output these names in order. Save your answer in a variable named
words
and make sure that this value doesn’t get overwritten later in your program.Use map plus a helper function to solve this problem.
prefixes = "JKLMNOPQ" suffix = "ack" words = [first + suffix for first in prefixes]
Of course, that’s not quite right because Ouack and Quack are misspelled. Can you fix it?
(ex_8_2)
-
Use map and filter to filter the hours table to include only managers. In SQL this would be performed using SELECT and WHERE. Hint: Start by creating a list of the names of all managers.
hours = [["Alice", 43], ["Bob", 37], ["Fred", 15]] titles = [["Alice", "Manager"], ["Betty", "Consultant"], ["Bob", "Assistant"]]
-
Use map, len, and filter to decide if the following tables contain a manager that worked at least 40 hours.
hours = [["Alice", 43], ["Bob", 37], ["Fred", 15]] titles = [["Alice", "Manager"], ["Betty", "Consultant"], ["Bob", "Assistant"]]
-
Use some combination of map and filter to create a sequence of functions that combine to average two matrices. A complete solution will provide functions for each level of abstraction.
(average-matrices)
-
Create a function that takes a value n as input and constructs a multiplication table for whole numbers up to n. Use some combination of map, filter and reduce to solve this problem.
(ex_8_3)
In [1]: row = lambda j, n: list(map(lambda i: j*i, range(1, n+1))) In [2]: table = lambda n: list(map(lambda j: row(j, n), range(1, n+1))) In [3]: table(12) Out[3]: [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24], [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36], [4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48], [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60], [6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72], [7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84], [8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96], [9, 18, 27, 36, 45, 54, 63, 72, 81, 90, 99, 108], [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120], [11, 22, 33, 44, 55, 66, 77, 88, 99, 110, 121, 132], [12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144]]
-
Print out a neatly formatted multiplication table, up to 12 x 12. You should
do this by constructing a string. For full credit, each column should be
right-justified and your solution should include only
map
and helper functions. (You are allowed to use the stringsjoin
andrjust
methods in your helper functions) Hint: Write a lambda function pads a number with the right number of spaces. Use some combination of map, filter and reduce to solve this problem.
-
Write a function that will return the number of digits in an integer.
Use reduce to solve thie problem.
(ex_7_10)
In [4]: from functools import reduce In [5]: numDigits = lambda n: reduce(lambda acc, ch: acc + 1, str(n), 0) In [6]: numDigits(50) Out[6]: 2 In [7]: numDigits(20000) Out[7]: 5 In [8]: numDigits(1) Out[8]: 1
-
Write a function named
remove_char
that removes all occurrences of a given letter from a string. Do not use thereplace
string method.Use reduce to solve this problem.
(ex_8_7)
-
Write a function called
str_join
that takes two argumentss
(a string) andL
(a list of strings) and returns the equivalent ofs.join(L)
. Use reduce to solve this problem without using the stringjoin
method.
-
Write a function that recognizes palindromes. Use reduce to solve thie problem. Hint: Use reversed and zip.
(ex_8_8)
In [9]: from functools import reduce In [10]: is_palindrome = lambda mystr: reduce(lambda acc, tup: acc and tup[0] == tup[1], zip(mystr,reversed(mystr)), True) In [11]: is_palindrome('abba') Out[11]: True
-
Write a function called
has_vowel
that takes a string as input and returnsTrue
if the string contains a vowel ('aeiou'
ignore'y'
) andFalse
otherwise. Usereduce
to perform this task.
-
Write a Python function that takes
n
andm
as input and returns the maximum value of a the list ofn
random integers between 0 andm
. (Note:. there is a builtin function namedmax
.)Use map to generating the random sequence and reduce to find the max.
(ex_9_5)
In [12]: from random import randint In [13]: from functools import reduce In [14]: from itertools import repeat In [15]: rand_seq = lambda n, m: map(randint, repeat(0, n), repeat(m, n)) In [16]: update_max = lambda cur_max, item: item if item > cur_max else cur_max In [17]: rand_max = lambda n, m: reduce(update_max, rand_seq(n, m)) In [18]: rand_max(10,5) Out[18]: 4
-
Write a function called
mean_normal(n, m, sd)
that computes the mean ofn
randomly selected values taken from a normal distribution with meanm
and standard deviationsd
. Use map and normalvariate (from the random module) to generate the sequence and use reduce to compute the mean.(ex_9_4)
-
Write a function
sum_of_squares(xs)
that computes the sum of the squares of the numbers in the listxs
. For example,sum_of_squares([2, 3, 4])
should return 4+9+16 which is 29.Use reduce to solve this problem.
(ex_7_11)
-
Write a function to count how many odd numbers are in a list.
Use some combination of map, filter and reduce to solve this problem.
(ex_9_6)
In [19]: import random In [20]: countOdd = lambda lst: reduce(lambda a, i: a + 1, filter(lambda n: n % 2 == 1, lst)) # make a random list to test the function In [21]: lst = [random.randint(0, 1000) for i in range(100)] In [22]: countOdd(lst) Out[22]: 194
-
Write a function called
sum_even
that sums up all the even numbers in a list. Use some combination of map, filter and reduce to solve this problem.(ex_9_7)
-
Sum up all the negative numbers in a list. Use some combination of map, filter and reduce to solve this problem.
(ex_9_8)
In [23]: import random In [24]: from operator import add In [25]: sumNegatives = lambda lst: reduce(add, filter(lambda n: n < 0, lst)) In [26]: lst = [random.randint(-1000, 1000) for i in range(100)] In [27]: sumNegatives(lst) Out[27]: -24819
-
Write a function called
num_greater_5
that counts how many words in a list have a more than than 5 characters. Use some combination of map, filter and reduce to solve this problem.(ex_9_9)
(ex_8_4)
-
The following sample file called
studentdata.txt
contains one line for each student in an imaginary class. The student’s name is the first thing on each line, followed by some exam scores. The number of scores might be different for each student.joe 10 15 20 30 40 bill 23 16 19 22 sue 8 22 17 14 32 17 24 21 2 9 11 17 grace 12 28 21 45 26 10 john 14 32 25 16 89
Using the text file
studentdata.txt
(shown in above) write a program that creates a new data table that contains the students’ names along with the minimum and maximum score for each student.Complete this exercise using
map
,filter
and/or reduce. Note: For full credit you will need to also implementmax
andmin
usingreduce
.(ex_6_3)
81# Convert the following solution to one that uses map, filter and/or reduce
2# For this exercise,
3with open("studentdata.txt", "r") as f:
4table = [line.split() for line in f]
5process_row = lambda row: (row[0], max(row), min(row))
6new_table = [process_row(row) for row in table]
7new_table
8
(ch_files_q3answer)
-
SeanLahman.com provides a database of baseball statistics. Download, unzip and extract the file titled Batting.csv.
Write each of the following functions and apply them to the related task. Write all of your functions and expressions only using funcitonal tools like
with_iter
,map
,filter
,reduce
,compose
and/orpipe
.- Write a function that takes a year and table of batting data as input and returns the average number of runs scored in that year. Call this function average_runs_year.
- Write a function takes a list of years and a table of batting data and returns of list of tuples of the form (year, averages_runs). Call this function average_runs_years Use a list comprehension and the function from the last step.
- Write a program that includes the above functions and reads Batting.csv and compute the average number of runs for the following years: 1900, 1910, ..., 2000, 2010. Assume that the Batting.csv file is the same directory as your program.
-
The
toolz
library includes a function calledcomplement
, which takes a Boolean function as input and returns a Boolean function that is the logical opposite.For example,
complement(is_odd)
would be equivalent tois_even
andcomplement(less_than_5)
would be equivalent toat_least_5
.In [28]: from toolz import complement In [29]: is_odd = lambda n: n % 2 == 1 In [30]: is_odd(5) Out[30]: True In [31]: is_odd(4) Out[31]: False In [32]: is_even = complement(is_odd) In [33]: is_even(5) Out[33]: False In [34]: is_even(4) Out[34]: True
In [35]: less_than_5 = lambda n: n < 5 In [36]: less_than_5(2) Out[36]: True In [37]: less_than_5(22) Out[37]: False In [38]: at_least_5 = complement(less_than_5) In [39]: at_least_5(2) Out[39]: False In [40]: at_least_5(22) Out[40]: True
Implement your own version of this function named
my_complement
.
-
The
toolz
library includes a function calleddo
that is useful when performing side effects. We sawdo
in action in Chapter 5 when printing a sequence out to a file. The functiondo(func, x)
takes a (likely side-effecting) functionfunc
and a valuex
as inputs. First,func
is called withx
as an argument then the originalx
is returned. Note that the any value returned byfunc(x)
is discarded.For example, we can use
do
to say hello to a given value (with print) and then return that value.In [41]: from toolz import do In [42]: say_hello = lambda x: print("Hello", x) In [43]: do(say_hello, 4) Hello 4 Out[43]: 4 In [44]: list(map(lambda x: do(say_hello, x), [1,2,3])) Hello 1 Hello 2 Hello 3 Out[44]: [1, 2, 3]
Implement a version of this function named
my_do
.
-
The
toolz
library includes a function calledjuxt
that takes a sequence of functions that returns a function. The new function will apply each of the original functions to any input and return a tuple containing the results.For example, suppose that we want to make a function that (a) adds 1, (b) doubles and (c) squares any input. This is accomplished using
juxt
as follows.In [45]: from toolz import juxt In [46]: f = juxt(lambda i: i + 1, ....: lambda i: 2*i, ....: lambda i: i**2) ....: In [47]: f(3) Out[47]: (4, 6, 9) In [48]: assert f(5) == (5 + 1, 2*5, 5**2)
Implement a version of this function named
my_juxt
.
-
Write and implementation of
pipe
calledmy_pipe
that takes an expressionx
as the first argument and a sequence of functionsf1
,f2
, ... as the remaining arguments and applies each function to the result ofx
, from left to right. Your function should pass the following assertions.
-
Implement a version of
thread_first
calledmy_thread_first
that threads a value through the first argument of each of a list of functions. If any of the functions take more than one argument, these arguments can be given along with the function in a tuple. For example,my_thread_first(5, f, g)
should be equivalent tog(f(5))
andmy_thread_first(5, (add, 1), (pow, 2))
expands topow(add(5,1), 2)
. Note that each expression goes in the first argument of the next function call.
-
Download, unzip and extract the file titled Salaries.csv and AllstarFull.csv from seanlahman.com .
Write a program that computes the average salary of all players in the all star game in for each year between 2000 and 2010. Write all of your functions and expressions only using funcitonal tools like
with_iter
,map
,filter
,reduce
,compose
and/orpipe
. Hint: You will want to usegroupby
in your solution.
-
Download, unzip and extract the file titled Master.csv and BattingPost.csv. from seanlahman.com
Write a program that computes the total runs scored in the post season by all players from from each state (all time). Write all of your functions and expressions only using funcitonal tools like
with_iter
,map
,filter
,reduce
,compose
and/orpipe
. Hint: You will want to usegroupby
in your solution.