Skip to content

Commit 9f5bda3

Browse files
authored
Merge pull request #3 from kokesak/ch3
Chapter 3: data structures
2 parents 2ebacb9 + 60aa1de commit 9f5bda3

File tree

4 files changed

+209
-0
lines changed

4 files changed

+209
-0
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from typing import Dict, List
2+
3+
cars = {
4+
'Ford': ['Falcon', 'Focus', 'Festiva', 'Fairlane'],
5+
'Holden': ['Commodore', 'Captiva', 'Barina', 'Trailblazer'],
6+
'Nissan': ['Maxima', 'Pulsar', '350Z', 'Navara'],
7+
'Honda': ['Civic', 'Accord', 'Odyssey', 'Jazz'],
8+
'Jeep': ['Grand Cherokee', 'Cherokee', 'Trailhawk', 'Trackhawk']
9+
}
10+
DEFAULT_SEARCH = "trail"
11+
CarsType = Dict[str, List[str]]
12+
13+
14+
def get_all_jeeps(cars: CarsType = cars) -> str:
15+
"""
16+
Retrieve the 'Jeep' models from the cars dict and join them by a
17+
comma and space (', '). Leave the original ordering intact.
18+
"""
19+
ret_str = cars['Jeep'][0]
20+
for car in cars['Jeep'][1:]:
21+
ret_str += ", " + car
22+
return ret_str
23+
24+
def get_first_model_each_manufacturer(cars: CarsType = cars) -> List[str]:
25+
"""
26+
Loop through the cars dict filtering out the first model for each
27+
manufacturer. Return the matching models in a list leaving the original
28+
ordering intact.
29+
"""
30+
ret_list = []
31+
for manf in cars.values():
32+
ret_list.append(manf[0])
33+
return ret_list
34+
35+
36+
def get_all_matching_models(
37+
cars: CarsType = cars, grep: str = DEFAULT_SEARCH
38+
) -> List[str]:
39+
"""
40+
Return a list of all models containing the case insensitive
41+
'grep' string which defaults to DEFAULT_SEARCH ('trail').
42+
Sort the resulting sequence alphabetically
43+
"""
44+
ret_list = []
45+
for models in cars.values():
46+
for car in models:
47+
if grep.lower() in car.lower():
48+
ret_list.append(car)
49+
50+
return sorted(ret_list)
51+
52+
53+
def sort_car_models(cars: CarsType = cars) -> CarsType:
54+
"""
55+
Loop through the cars dict returning a new dict with the
56+
same keys and the values sorted alphabetically.
57+
"""
58+
sorted_dict = {}
59+
for manuf, models in cars.items():
60+
sorted_dict[manuf] = sorted(models)
61+
62+
return sorted_dict
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from cars import (get_all_jeeps, get_first_model_each_manufacturer,
2+
get_all_matching_models, sort_car_models)
3+
4+
5+
def test_get_all_jeeps():
6+
expected = 'Grand Cherokee, Cherokee, Trailhawk, Trackhawk'
7+
actual = get_all_jeeps()
8+
assert type(actual) == str
9+
assert actual == expected
10+
11+
12+
def test_get_first_model_each_manufacturer():
13+
actual = get_first_model_each_manufacturer()
14+
expected = ['Falcon', 'Commodore', 'Maxima', 'Civic', 'Grand Cherokee']
15+
assert actual == expected
16+
17+
18+
def test_get_all_matching_models_default_grep():
19+
expected = ['Trailblazer', 'Trailhawk']
20+
assert get_all_matching_models() == expected
21+
22+
23+
def test_get_all_matching_models_different_grep():
24+
expected = ['Accord', 'Commodore', 'Falcon']
25+
assert get_all_matching_models(grep='CO') == expected
26+
27+
28+
def test_sort_dict_alphabetically():
29+
actual = sort_car_models()
30+
# Order of keys should not matter, two dicts are equal if they have the
31+
# same keys and the same values.
32+
# The car models (values) need to be sorted here though
33+
expected = {
34+
'Ford': ['Fairlane', 'Falcon', 'Festiva', 'Focus'],
35+
'Holden': ['Barina', 'Captiva', 'Commodore', 'Trailblazer'],
36+
'Honda': ['Accord', 'Civic', 'Jazz', 'Odyssey'],
37+
'Jeep': ['Cherokee', 'Grand Cherokee', 'Trackhawk', 'Trailhawk'],
38+
'Nissan': ['350Z', 'Maxima', 'Navara', 'Pulsar'],
39+
}
40+
assert actual == expected
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
us_state_abbrev = {'Alabama': 'AL', 'Alaska': 'AK', 'Arizona': 'AZ',
2+
'Arkansas': 'AR', 'California': 'CA', 'Colorado': 'CO',
3+
'Connecticut': 'CT', 'Delaware': 'DE', 'Florida': 'FL',
4+
'Georgia': 'GA', 'Hawaii': 'HI', 'Idaho': 'ID',
5+
'Illinois': 'IL', 'Indiana': 'IN', 'Iowa': 'IA',
6+
'Kansas': 'KS', 'Kentucky': 'KY', 'Louisiana': 'LA',
7+
'Maine': 'ME', 'Maryland': 'MD', 'Massachusetts': 'MA',
8+
'Michigan': 'MI', 'Minnesota': 'MN', 'Mississippi': 'MS',
9+
'Missouri': 'MO', 'Montana': 'MT', 'Nebraska': 'NE',
10+
'Nevada': 'NV', 'New Hampshire': 'NH', 'New Jersey': 'NJ',
11+
'New Mexico': 'NM', 'New York': 'NY',
12+
'North Carolina': 'NC', 'North Dakota': 'ND',
13+
'Ohio': 'OH', 'Oklahoma': 'OK', 'Oregon': 'OR',
14+
'Pennsylvania': 'PA', 'Rhode Island': 'RI',
15+
'South Carolina': 'SC', 'South Dakota': 'SD',
16+
'Tennessee': 'TN', 'Texas': 'TX', 'Utah': 'UT',
17+
'Vermont': 'VT', 'Virginia': 'VA', 'Washington': 'WA',
18+
'West Virginia': 'WV', 'Wisconsin': 'WI', 'Wyoming': 'WY'}
19+
20+
states = ['Oklahoma', 'Kansas', 'North Carolina', 'Georgia', 'Oregon',
21+
'Mississippi', 'Minnesota', 'Colorado', 'Alabama',
22+
'Massachusetts', 'Arizona', 'Connecticut', 'Montana',
23+
'West Virginia', 'Nebraska', 'New York', 'Nevada', 'Idaho',
24+
'New Jersey', 'Missouri', 'South Carolina', 'Pennsylvania',
25+
'Rhode Island', 'New Mexico', 'Alaska', 'New Hampshire',
26+
'Tennessee', 'Washington', 'Indiana', 'Hawaii', 'Kentucky',
27+
'Virginia', 'Ohio', 'Wisconsin', 'Maryland', 'Florida',
28+
'Utah', 'Maine', 'California', 'Vermont', 'Arkansas', 'Wyoming',
29+
'Louisiana', 'North Dakota', 'South Dakota', 'Texas',
30+
'Illinois', 'Iowa', 'Michigan', 'Delaware']
31+
32+
NOT_FOUND = 'N/A'
33+
34+
35+
def get_every_nth_state(states=states, n=10):
36+
"""Return a list with every nth item (default argument n=10, so every
37+
10th item) of the states list above (remember: lists keep order)"""
38+
return states[n-1::n]
39+
40+
41+
def get_state_abbrev(state_name, us_state_abbrev=us_state_abbrev):
42+
"""Look up a state abbreviation by querying the us_state_abbrev
43+
dict by full state name, for instance 'Alabama' returns 'AL',
44+
'Illinois' returns 'IL'.
45+
If the state is not in the dict, return 'N/A' which we stored
46+
in the NOT_FOUND constant (takeaway: dicts are great for lookups)"""
47+
try:
48+
result = us_state_abbrev[state_name]
49+
except KeyError:
50+
result = NOT_FOUND
51+
return result
52+
53+
54+
def get_longest_state(data):
55+
"""Receives data, which can be the us_state_abbrev dict or the states
56+
list (see above). It returns the longest state measured by the length
57+
of the string"""
58+
return max(data, key=len)
59+
60+
61+
62+
def combine_state_names_and_abbreviations(us_state_abbrev=us_state_abbrev,
63+
states=states):
64+
"""Get the first 10 state abbreviations ('AL', 'AK', 'AZ', ...) from
65+
the us_state_abbrev dict, and the last 10 states from the states
66+
list (see above) and combine them into a new list. The resulting list
67+
has both sorted, so:
68+
['AK', 'AL', 'AZ', ..., 'South Dakota', 'Tennessee', 'Texas', ...]
69+
(see also test_combine_state_names_and_abbreviations)"""
70+
result = []
71+
result = list(us_state_abbrev.values())[:10] + list(us_state_abbrev.keys())[-10:]
72+
return sorted(result)
73+
74+
print(get_every_nth_state())
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from states import (get_every_nth_state, get_state_abbrev,
2+
get_longest_state, combine_state_names_and_abbreviations,
3+
states, us_state_abbrev, NOT_FOUND)
4+
5+
6+
def test_get_every_nth_state():
7+
expected = ['Massachusetts', 'Missouri', 'Hawaii',
8+
'Vermont', 'Delaware']
9+
assert list(get_every_nth_state()) == expected
10+
expected = ['Missouri', 'Vermont']
11+
assert list(get_every_nth_state(n=20)) == expected
12+
13+
14+
def test_get_state_abbrev():
15+
assert get_state_abbrev('Illinois') == 'IL'
16+
assert get_state_abbrev('North Dakota') == 'ND'
17+
assert get_state_abbrev('bogus') == NOT_FOUND
18+
19+
20+
def test_get_longest_state():
21+
# depending the direction of the sort (reversed or not)
22+
# both North and South Carolina are correct
23+
possible_answers = ('North Carolina', 'South Carolina')
24+
assert get_longest_state(us_state_abbrev) in possible_answers
25+
assert get_longest_state(states) in possible_answers
26+
27+
28+
def test_combine_state_names_and_abbreviations():
29+
expected = ['AK', 'AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DE', 'FL', 'GA',
30+
'South Dakota', 'Tennessee', 'Texas', 'Utah',
31+
'Vermont', 'Virginia', 'Washington', 'West Virginia',
32+
'Wisconsin', 'Wyoming']
33+
assert combine_state_names_and_abbreviations() == expected

0 commit comments

Comments
 (0)