March 9th, 2021
Written by Juliette Woodrow, Brahm Capoor, and Nick Parlante
>>> strs = ['Rhyme', 'Donut', '3xx', 'Orange']
>>> list(map(lambda s: s.upper(), strs))
>>> points = [(10, 0), (1, 3), (3, 2), (5, 4)]
>>> sorted(points, key=lambda pt: pt[0] + pt[1], reverse=True)
def parse_hosts(addrs):
"""
>>> parse_hosts(['a@x', 'b@x', 'a@x'])
{'x': ['a', 'b']}
>>> parse_hosts(['a@x', 'b@x', 'a@y'])
{'x': ['a', 'b'], 'y': ['a']}
>>> parse_hosts(['a@x', 'bob@x', 'c@z'])
{'x': ['a', 'bob'], 'z': ['c']}
"""
hosts = {}
for addr in addrs:
at = addr.find('@')
user = addr[:at]
host = addr[at + 1:]
if host not in hosts:
hosts[host] = []
users = hosts[host] # style: decomp by var
if user not in users: # no duplicates
users.append(user)
return hosts
def parse_sends(filename):
with open(filename, 'r') as f:
sends = {}
for line in f:
line = line.strip() # \n handling, not marking off for this
parts = line.split(',')
src = parts[0]
if src not in sends:
sends[src] = {}
nested = sends[src] # decomp by var
for dst in parts[1:]:
if dst not in nested:
nested[dst] = 0
nested[dst] += 1
return sends
def commons(sends, srca, srcb):
countsa = sends[srca] # Given that srca/b are in sends
countsb = sends[srcb] # so don't need "in" check first.
result = []
for dest in countsa.keys():
# is it in b too? "in" handy here
if dest in countsb:
result.append(dest)
return result
def make_county(words):
"""
Given a list of non-empty words, produce 'county' dict
where each first-char-of-word seen is a key, and its value
is a count dict of words starting with that char.
So ['aaa', 'abb', 'aaa'] yields {'a': {'aaa': 2, 'abb': 1}}
"""
county = {}
for word in words:
ch = word[0]
if ch not in county:
county[ch] = {}
inner = county[ch]
if not word in inner:
inner[word] = 0
inner[word] += 1
return county
def is_sub_list(curr_ingredients, recipe_ingredients):
for ingredient in recipe_ingredients:
if ingredient not in curr_ingredients:
return False
return True
def find_recipes(curr_ingredients, recipe_book):
possible_recipes = []
for recipe in recipe_book:
recipe_ingredients = recipe_book[recipe]
if is_sub_list(curr_ingredients, recipe_ingredients):
possible_recipes.append(recipe)
return possible_recipes
def make_glossary(filename):
glossary = {}
with open(filename, 'r') as f:
line_num = 0
for line in f:
line = line.strip()
for word in line.split():
if word not in glossary:
glossary[word] = []
glossary[word].append((line_num, line))
line_num += 1
return glossary
SAMPLE_INPUT = {
'Khaled': ['Chibundu', 'Jesmyn'],
'Daniel': ['Khaled', 'Eve'],
'Jesmyn': ['Frank'],
'Eve': ['Grace']
}
def add_grandchildren(grandparents_dictionary, grandparent, new_grandchildren):
if grandparent not in grandparents_dictionary:
# if we haven't seen this grandparent before, add them to the dictionary
grandparents_dictionary[grandparent] = []
# add the new grandchildren to the grandparent's list of
# grandchildren
current_grandchildren = grandparents_dictionary[grandparent]
current_grandchildren += new_grandchildren
def find_grandchildren(parents_dictionary):
"""
>>> find_grandchildren(SAMPLE_INPUT)
{'Khaled': ['Frank'], 'Daniel': ['Chibundu', 'Jesmyn', 'Grace']}
"""
grandparents_dictionary = {}
for parent in parents_dictionary:
children = parents_dictionary[parent]
for child in children:
if child in parents_dictionary: # check if the child is a parent themselves
grandchildren = parents_dictionary[child]
add_grandchildren(grandparents_dictionary,
parent, grandchildren)
return grandparents_dictionary
def prime_file(filename):
"""
The given file contains text data on each line as follows.
Each line is made of a mixture of non-empty alphabetic words
and non-negative ints, all separated by colons. The numbers can be distinguished
since their first char is a digit. Lines like this:
aaa:123:420:xyz:xxx:44:zz:a
The first element is the "prime" for that line, and is always alphabetic.
Read through all the lines and build a dict with a key for each prime,
and its value is a list of all the int number values from all the lines
with that prime.
Add every number to the list, even if it is a duplicate.
When all the data is loaded, print the primes in alphabetical order
1 per line, each followed by its sorted list of numbers, like this
aaa [44, 123, 123, 125, 420, 693]
bbb [16, 23, 101, 101]
"""
primes = {}
with open(filename) as f:
for line in f:
parts = line.split(':')
prime = parts[0]
# pick out which parts are ints - comprehension is cute here
# or could do this as a regular old for-loop with an append
# inside is fine and full credit.
nums = [int(part) for part in parts if part[0].isdigit()]
if not prime in primes:
primes[prime] = []
primes[prime].extend(nums)
# now output
for prime in sorted(primes.keys()):
print(prime, sorted(primes[prime]))
def count_zips(filename):
states = {}
with open(filename) as f:
for line in f:
pass
words = line.split(',')
state = words[0]
if state not in states:
states[state] = {}
counts = states[state]
for word in words[1:]:
zip = word[:5]
if zip not in counts:
counts[zip] = 0
counts[zip] += 1
for state in sorted(states.keys()):
print(state)
counts = states[state]
for zip in sorted(counts.keys()):
print(zip, counts[zip])
def parse_lightning(filename):
states = {}
with open(filename) as f:
for line in f:
pass
words = line.split(',')
i_state = len(words) - 1
state = words[i_state].strip() # not grading off: remove \n
if state not in states:
states[state] = []
nums = states[state] # decomp by var
for numstr in words[:i_state]: # omit last elem
nums.append(int(numstr))
for state in sorted(states.keys()):
print(state, states[state], sum(states[state]))