For reference, here are copies of the test cases provided:

Phase 0: Utilities

Tests - Problem 0

Problem 0 > Suite 1 > Case 1

>>> from utils import *
>>> square = lambda x: x * x
>>> is_odd = lambda x: x % 2 == 1
>>> map_and_filter([1, 2, 3, 4, 5], square, is_odd)
______

>>> map_and_filter(['hi', 'hello', 'hey', 'world'],
...                lambda x: x[4], lambda x: len(x) > 4)
______

---------------------------------------------------------------------
Problem 0 > Suite 1 > Case 2

>>> from utils import *
>>> key_of_min_value({1: 6, 2: 5, 3: 4})
______

>>> key_of_min_value({'a': 6, 'b': 5, 'c': 4})
______

>>> key_of_min_value({'hello': 'world', 'hi': 'there'})
______

---------------------------------------------------------------------
Problem 0 > Suite 1 > Case 3
(cases remaining: 2)

>>> from utils import *
>>> enumerate([6, 'one', 'a'], 3)[1]
______

---------------------------------------------------------------------
Problem 0 > Suite 2 > Case 1

Q: Consider the lists xs = [6, 1, 4] and ys = [2, 6, 2]. Which
of the choices below for EXPR would produce the following
output?

>>> for x, y in EXPR:
...     print(x + y)
8
7
6
Choose the number of the correct choice:
0) (xs, ys)
1) zip(xs, ys)
2) zip([xs, ys])
3) xs + ys
______

Phase 1: Data Abstraction

Tests - Problem 1

Problem 1 > Suite 1 > Case 1

>>> from abstractions import *
>>> import abstractions
>>> soda_reviews = [make_review('Soda', 4.5),
...                 make_review('Soda', 4)]
>>> soda = make_restaurant('Soda', [127.0, 0.1],
...                        ['Restaurants', 'Breakfast & Brunch'],
...                        1, soda_reviews)
>>> restaurant_ratings(soda)
______

Tests - Problem 2

Problem 2 > Suite 1 > Case 1

>>> import abstractions
>>> from abstractions import *
>>> woz_reviews = [make_review('Wozniak Lounge', 4),
...                make_review('Wozniak Lounge', 3),
...                make_review('Wozniak Lounge', 5)]
>>> woz = make_restaurant('Wozniak Lounge', [127.0, 0.1],
...                       ['Restaurants', 'Pizza'],
...                       1, woz_reviews)
>>> restaurant_num_ratings(woz)
______

>>> restaurant_mean_rating(woz) # should be a decimal
______

Phase 2: Unsupervised Learning

Tests - Problem 3

Problem 3 > Suite 1 > Case 1

Q: Which of the following types of values can be passed as
an argument to distance?
Choose the number of the correct choice:
0) restaurant; e.g. make_restaurant('A', [1, 1], ['Food'], 1, [])
1) pair; e.g. [1, 1]
2) string of a pair; e.g. '[1, 1]'
3) number; e.g. 1
______

---------------------------------------------------------------------
Problem 3 > Suite 1 > Case 2

Q: Consider the list l = [[4, 1], [-3, 2], [5, 0]]. Which of
the choices below for fn would make min(l, key=fn) evaluate
to [4, 1]?
Choose the number of the correct choice:
0) lambda x: abs(x[0] - x[1])
1) lambda x, y: pow(-x, y)
2) lambda x, y: abs(x - y)
3) sum
______

---------------------------------------------------------------------
Problem 3 > Suite 2 > Case 1

>>> import tests.test_functions as test
>>> from recommend import *
>>> distance([0, 0], [3, 4]) # should be a decimal
______

>>> distance([6, 1], [6, 1]) # should be a decimal
______

>>> distance([-2, 7], [-3.5, 9]) # should be a decimal
______

---------------------------------------------------------------------
Problem 3 > Suite 2 > Case 2

>>> import tests.test_functions as test
>>> from recommend import *
>>> find_closest([6, 1],
...              [[1, 5], [3, 3]])
______

>>> find_closest([1, 6],
...              [[1, 5], [3, 3]])
______

---------------------------------------------------------------------
Problem 3 > Suite 2 > Case 3

>>> import tests.test_functions as test
>>> from recommend import *
>>> find_closest([0, 0],
...              [[-2, 0], [2, 0]])
______

>>> find_closest([0, 0],
...              [[1000, 1000]])
______

---------------------------------------------------------------------
Problem 3 > Suite 2 > Case 4

>>> import tests.test_functions as test
>>> from recommend import *
>>> # Be sure to use the distance function!
>>> find_closest([0, 0],
...              [[2, 2], [0, 3]])
______

>>> find_closest([0, 0],
...              [[5, 5], [2, 7]])
______

Tests - Problem 4

Problem 4 > Suite 1 > Case 1

Q: If centroids is [[-1, 1], [5, -1], [1, 10], [-1, -10]],
to which centroid will [6, 0] be associated?
Choose the number of the correct choice:
0) [-1, -10]
1) [5, -1]
2) [1, 10]
3) [-1, 1]
______

---------------------------------------------------------------------
Problem 4 > Suite 1 > Case 2

Q: If centroids is [[1, 1], [1, -1], [-1, 1], [-1, -1]],
to which centroid will [0, 0] be associated?
Choose the number of the correct choice:
0) [1, 1]
1) [-1, 1]
2) [1, -1]
3) [-1, -1]
______

---------------------------------------------------------------------
Problem 4 > Suite 2 > Case 1

>>> import tests.test_functions as test
>>> from recommend import *
>>> r1 = make_restaurant('A', [-10, 2], [], 2, [
...         make_review('A', 4),
...      ])
>>> r2 = make_restaurant('B', [-9, 1], [], 3, [
...         make_review('B', 5),
...         make_review('B', 3.5),
...      ])
>>> c1 = [0, 0]
>>> groups = group_by_centroid([r1, r2], [c1])
>>> test.deep_check_same_elements(groups, [[r1, r2]])
True

---------------------------------------------------------------------
Problem 4 > Suite 2 > Case 2

>>> import tests.test_functions as test
>>> from recommend import *
>>> r1 = make_restaurant('A', [-10, 2], [], 2, [
...         make_review('A', 4),
...      ])
>>> r2 = make_restaurant('B', [-9, 1], [], 3, [
...         make_review('B', 5),
...         make_review('B', 3.5),
...      ])
>>> r3 = make_restaurant('C', [4, 2], [], 1, [
...         make_review('C', 5)
...      ])
>>> c1 = [0, 0]
>>> c2 = [3, 4]
>>> groups = group_by_centroid([r1, r2, r3], [c1, c2])
>>> test.deep_check_same_elements(groups, [[r1, r2], [r3]])
True

---------------------------------------------------------------------
Problem 4 > Suite 2 > Case 3

>>> import tests.test_functions as test
>>> from recommend import *
>>> r1 = make_restaurant('A', [-10, 2], [], 2, [
...         make_review('A', 4),
...      ])
>>> r2 = make_restaurant('B', [-9, 1], [], 3, [
...         make_review('B', 5),
...         make_review('B', 3.5),
...      ])
>>> r3 = make_restaurant('C', [4, 2], [], 1, [
...         make_review('C', 5)
...      ])
>>> r4 = make_restaurant('D', [-2, 6], [], 4, [
...         make_review('D', 2)
...      ])
>>> r5 = make_restaurant('E', [4, 2], [], 3.5, [
...         make_review('E', 2.5),
...         make_review('E', 3),
...      ])
>>> c1 = [0, 0]
>>> c2 = [3, 4]
>>> groups = group_by_centroid([r1, r2, r3, r4, r5], [c1, c2])
>>> test.deep_check_same_elements(groups, [[r1, r2], [r3, r4, r5]])
True

---------------------------------------------------------------------
Problem 4 > Suite 2 > Case 4

>>> import tests.test_functions as test
>>> from recommend import *
>>> r = make_restaurant('Zero', [0, 0], [], 1, [
...         make_review('Zero', 5)
...     ])
>>> groups = group_by_centroid(
...     [r], [[x, y] for x in [1, -1] for y in [1, -1]]
... )
>>> test.deep_check_same_elements(groups, [[r]])
True

Tests - Problem 5

Problem 5 > Suite 1 > Case 1

>>> from recommend import *
>>> cluster1 = [
...     make_restaurant('A', [-3, -4], [], 3, [make_review('A', 2)]),
...     make_restaurant('B', [1, -1],  [], 1, [make_review('B', 1)]),
...     make_restaurant('C', [2, -4],  [], 1, [make_review('C', 5)]),
... ]
>>> find_centroid(cluster1) # should be a pair of decimals
______

Tests - Problem 6

Problem 6 > Suite 1 > Case 1

Q: What is the first step of the iterative portion of the
k-means algorithm?
Choose the number of the correct choice:
0) create a cluster for each centroid consisting of all elements closest to
   that centroid.
1) find the centroid (average position) of each cluster.
2) randomly initialize k centroids
______

---------------------------------------------------------------------
Problem 6 > Suite 2 > Case 1

>>> import tests.test_functions as test
>>> import recommend
>>> old_sample = recommend.sample
>>> test.swap_implementations(recommend)
>>> recommend.sample = test.sample # deterministic sampling
>>> make_review, make_restaurant = recommend.make_review, recommend.make_restaurant
>>> k_means = recommend.k_means
>>> restaurants1 = [
...     make_restaurant('A', [-3, -4], [], 3, [make_review('A', 2)]),
...     make_restaurant('B', [1, -1],  [], 1, [make_review('B', 1)]),
...     make_restaurant('C', [2, -4],  [], 1, [make_review('C', 5)]),
... ]
>>> centroids = k_means(restaurants1, 1)
>>> centroids # should be 2-element lists of decimals
[[0.0, -3.0]]

>>> recommend.sample = old_sample
>>> test.restore_implementations(recommend)

---------------------------------------------------------------------
Problem 6 > Suite 2 > Case 2

>>> import tests.test_functions as test
>>> import recommend
>>> old_sample = recommend.sample
>>> test.swap_implementations(recommend)
>>> recommend.sample = test.sample # deterministic sampling
>>> make_review, make_restaurant = recommend.make_review, recommend.make_restaurant
>>> k_means = recommend.k_means
>>> restaurants2 = [
...     make_restaurant('D', [2, 3], [], 2, [make_review('D', 2)]),
...     make_restaurant('E', [0, 3], [], 3, [make_review('E', 1)]),
... ]
>>> centroids = k_means(restaurants2, 1)
>>> centroids # should be 2-element lists of decimals
[[1.0, 3.0]]

>>> recommend.sample = old_sample
>>> test.restore_implementations(recommend)

Phase 3: Supervised Learning

Tests - Problem 7

Problem 7 > Suite 1 > Case 1

Q: What does the list xs represent?
Choose the number of the correct choice:
0) the restaurants reviewed by user
1) the extracted values for each restaurant in restaurants
2) the names of restaurants in restaurants
3) the restaurants in restaurants
______

---------------------------------------------------------------------
Problem 7 > Suite 1 > Case 2

Q: What does the list ys represent?
Choose the number of the correct choice:
0) the names for the restaurants reviewed by user
1) the average rating for the restaurants in restaurants
2) user's ratings for the restaurants in restaurants
3) the names for the restaurants in restaurants
______

---------------------------------------------------------------------
Problem 7 > Suite 2 > Case 1

>>> import tests.test_functions as test
>>> import recommend
>>> test.swap_implementations(recommend)
>>> from recommend import *
>>> user = make_user('John D.', [
...     make_review('A', 1),
...     make_review('B', 5),
...     make_review('C', 2),
...     make_review('D', 2.5),
... ])
>>> restaurant = make_restaurant('New', [-10, 2], [], 2, [
...         make_review('New', 4),
... ])
>>> cluster = [
...     make_restaurant('B', [4, 2], [], 1, [
...         make_review('B', 5)
...     ]),
...     make_restaurant('C', [-2, 6], [], 4, [
...         make_review('C', 2)
...     ]),
...     make_restaurant('D', [4, 2], [], 3.5, [
...         make_review('D', 2.5),
...         make_review('D', 3),
...     ]),
... ]
>>> pred, r_squared = find_predictor(user, cluster, restaurant_price)
>>> round(pred(restaurant), 5)
4.0
>>> round(r_squared, 5)
1.0

>>> test.restore_implementations(recommend)

---------------------------------------------------------------------
Problem 7 > Suite 2 > Case 2

>>> import tests.test_functions as test
>>> import recommend
>>> test.swap_implementations(recommend)
>>> from recommend import *
>>> user = make_user('John D.', [
...     make_review('A', 1),
...     make_review('B', 5),
...     make_review('C', 2),
...     make_review('D', 2.5),
... ])
>>> restaurant = make_restaurant('New', [-10, 2], [], 2, [
...         make_review('New', 4),
... ])
>>> cluster = [
...     make_restaurant('B', [4, 2], [], 1, [
...         make_review('B', 5)
...     ]),
...     make_restaurant('C', [-2, 6], [], 4, [
...         make_review('C', 2)
...     ]),
...     make_restaurant('D', [4, 2], [], 3.5, [
...         make_review('D', 2.5),
...         make_review('D', 3),
...     ]),
... ]
>>> pred, r_squared = find_predictor(user, cluster, restaurant_mean_rating)
>>> round(pred(restaurant), 5)
3.9359
>>> round(r_squared, 5)
0.99256

>>> test.restore_implementations(recommend)

Tests - Problem 8

Problem 8 > Suite 1 > Case 1

Q: In best_predictor, what does the variable reviewed represent?
Choose the number of the correct choice:
0) a list of restaurants reviewed by the user
1) a list of all possible restaurants
2) a list of ratings for restaurants reviewed by the user
______

---------------------------------------------------------------------
Problem 8 > Suite 1 > Case 2

Q: Given a user, a list of restaurants, and a feature function, what
does find_predictor from Problem 7 return?
Choose the number of the correct choice:
0) a restaurant
1) a predictor function
2) a predictor function, and its r_squared value
3) an r_squared value
______

---------------------------------------------------------------------
Problem 8 > Suite 1 > Case 3

Q: After getting a list of [predictor, r_squared] pairs,
which predictor should we select?
Choose the number of the correct choice:
0) the predictor with the highest r_squared
1) the predictor with the lowest r_squared
2) an arbitrary predictor
3) the first predictor in the list
______

---------------------------------------------------------------------
Problem 8 > Suite 2 > Case 1

>>> import tests.test_functions as test
>>> from recommend import *
>>> user = make_user('Cheapskate', [
...     make_review('A', 2),
...     make_review('B', 5),
...     make_review('C', 2),
...     make_review('D', 5),
... ])
>>> cluster = [
...     make_restaurant('A', [5, 2], [], 4, [
...         make_review('A', 5)
...     ]),
...     make_restaurant('B', [3, 2], [], 2, [
...         make_review('B', 5)
...     ]),
...     make_restaurant('C', [-2, 6], [], 4, [
...         make_review('C', 4)
...     ]),
...     make_restaurant('D', [4, 2], [], 2, [
...         make_review('D', 3),
...         make_review('D', 4)
...     ]),
... ]
>>> fns = [restaurant_price, restaurant_mean_rating]
>>> pred = best_predictor(user, cluster, fns)
>>> [round(pred(r), 5) for r in cluster] # should be a list of decimals
[2.0, 5.0, 2.0, 5.0]

---------------------------------------------------------------------
Problem 8 > Suite 2 > Case 2

>>> import tests.test_functions as test
>>> from recommend import *
>>> user = make_user('Cheapskate', [
...     make_review('A', 2),
...     make_review('B', 5),
...     make_review('C', 2),
...     make_review('D', 5),
... ])
>>> cluster = [
...     make_restaurant('A', [5, 2], [], 4, [
...         make_review('A', 5)
...     ]),
...     make_restaurant('B', [3, 2], [], 2, [
...         make_review('B', 5)
...     ]),
...     make_restaurant('C', [-2, 6], [], 4, [
...         make_review('C', 4)
...     ]),
... ]
>>> fns = [restaurant_price, restaurant_mean_rating]
>>> pred = best_predictor(user, cluster, fns)
>>> [round(pred(r), 5) for r in cluster]
[2.0, 5.0, 2.0]

Tests - Problem 9

Problem 9 > Suite 1 > Case 1

Q: rate_all returns a dictionary. What are the keys of this dictionary?
Choose the number of the correct choice:
0) restaurant names
1) restaurant ratings
2) restaurants
______

---------------------------------------------------------------------
Problem 9 > Suite 1 > Case 2

Q: What are the values of the returned dictionary?
Choose the number of the correct choice:
0) numbers - predicted ratings only
1) lists - list of all restaurant ratings
2) numbers - user ratings only
3) numbers - mean restaurant ratings
4) numbers - a mix of user ratings and predicted ratings
______

---------------------------------------------------------------------
Problem 9 > Suite 1 > Case 3

Q: In rate_all, what does the variable reviewed represent?
Choose the number of the correct choice:
0) a list of all possible restaurants
1) a list of ratings for restaurants reviewed by the user
2) a list of restaurants reviewed by the user
______

---------------------------------------------------------------------
Problem 9 > Suite 2 > Case 1

>>> import tests.test_functions as test
>>> import recommend
>>> from recommend import *
>>> user = make_user('Mr. Mean Rating Minus One', [
...     make_review('A', 3),
...     make_review('B', 4),
...     make_review('C', 1),
... ])
>>> cluster = [
...     make_restaurant('A', [1, 2], [], 4, [
...         make_review('A', 4),
...         make_review('A', 4)
...     ]),
...     make_restaurant('B', [4, 2], [], 3, [
...         make_review('B', 5)
...     ]),
...     make_restaurant('C', [-2, 6], [], 4, [
...         make_review('C', 2)
...     ]),
...     make_restaurant('D', [4, 4], [], 3.5, [
...         make_review('D', 2.5),
...         make_review('D', 3.5),
...     ]),
... ]
>>> restaurants = {restaurant_name(r): r for r in cluster}
>>> recommend.ALL_RESTAURANTS = cluster
>>> to_rate = cluster[2:]
>>> fns = [restaurant_price, restaurant_mean_rating]
>>> ratings = rate_all(user, to_rate, fns)
>>> type(ratings)
<class 'dict'>
>>> len(ratings) # Only the restaurants passed to rate_all
2
>>> ratings['C'] # A restaurant rated by the user (should be an integer)
1
>>> round(ratings['D'], 5) # A predicted rating (should be a decimal)
2.0

Tests - Problem 10

Problem 10 > Suite 1 > Case 1

Q: Given a restaurant, what does restaurant_categories in
abstractions.py return?
Choose the number of the correct choice:
0) a single string (category)
1) a list of strings (categories)
2) a single number (rating)
3) a list of numbers (ratings)
______

---------------------------------------------------------------------
Problem 10 > Suite 1 > Case 2

Q: When does a restaurant match a search query?
Choose the number of the correct choice:
0) if the query string is mentioned in the restaurant's reviews
1) if the query string is a substring of the restaurant's name
2) if the query string is one of the restaurant's categories
3) if the query string is equal to the restaurant's categories
______

---------------------------------------------------------------------
Problem 10 > Suite 1 > Case 3

Q: What type of object does search return?
Choose the number of the correct choice:
0) a list of restaurants
1) a dictionary that maps restaurant names (strings) to restaurants
2) a dictionary that maps restaurant categories (strings) to restaurants
3) a list of restaurant names (strings)
______

---------------------------------------------------------------------
Problem 10 > Suite 2 > Case 1

>>> import tests.test_functions as test
>>> import recommend
>>> make_user = recommend.make_user
>>> make_review = recommend.make_review
>>> make_restaurant = recommend.make_restaurant
>>> search = recommend.search
>>> def make_testaurant(name, categories):
...     return make_restaurant(name, [0, 0], categories, 1, [
...         make_review(name, 5)
...     ])
>>> a = make_testaurant('A', ['Creperies', 'Italian'])
>>> b = make_testaurant('B', ['Italian', 'Coffee & Tea'])
>>> c = make_testaurant('C', ['Coffee & Tea', 'Greek', 'Creperies'])
>>> d = make_testaurant('D', ['Greek'])
>>> test.check_same_elements(search('Creperies', [a, b, c, d]), [a, c])
True
>>> test.check_same_elements(search('Thai', [a, b, c, d]), [])
True
>>> test.check_same_elements(search('Coffee & Tea', [a, b, d]), [b])
True
>>> test.check_same_elements(search('Greek', [a, b, c, d]), [c, d])
True
>>> test.check_same_elements(search('Italian', [a, b, c, d]), [a, b])
True