Fill in the blanks in the function definition below to make it consistent with its header and docstring. Each blank should contain just one identifier, constant, or operator. [Recall that an identifier is just a name: a variable name, a parameter name, a field/attribute name, a function name, a method name.]
Dish = namedtuple('Dish', 'name price calories')
Restaurant = namedtuple('Restaurant', 'name cuisine phone menu')
def Restaurant_average_calories (R: Restaurant) -> float:
''' Return the average number of calories on the restaurant's menu.
The menu is a list of Dish structures.
'''
return Menu_average_calories(_______________._______________)
def Menu_average_calories(M: list) -> float:
''' Return the average number of calories on the menu (a list of Dishes)
'''
if len(M) == 0:
return 0
else:
sum = _______________
for d in _______________ :
_______________ += _______________.calories
return _______________ / _______________(M)
from collections import namedtuple
# You weren't required to supply this line by the question.
# In general on exams, you may assume that the appropriate libraries
# have been imported. If you have a question about this on an exam,
# you should ask.
Dish = namedtuple('Dish', 'name price calories')
Restaurant = namedtuple('Restaurant', 'name cuisine phone menu')
def Restaurant_average_calories (R: Restaurant) -> float:
''' Return the average number of calories on the restaurant's menu.
The menu is a list of Dish structures.
'''
return Menu_average_calories(R.menu)
def Menu_average_calories(M: list) -> float:
''' Return the average number of calories on the menu (a list of Dishes)
'''
if len(M) == 0:
return 0
else:
sum = 0
for d in M:
sum += d.calories
return sum/len(M)
If this was hard for you, it may be that you're not yet familiar
enough with Python statements and how they're constructed.
Take the first two blanks: We know that the
Restaurant_average_calories function takes a Restaurant (which has four
fields). We also know that Menu_average_calories takes a list, so that
those first two blanks, the arguments in the call to
Menu_average_calories, must specify a list. Where can we get a list
with what we have inside Restaurant_average_calories? The only data
there is R, the parameter, which is a Restaurant. The only list
available is the menu field/attribute of R. So how do we get one field
out of a namedtuple? With dot notation. R.menu (that's the answer)
gives us the menu field of R, a list of dishes, which is the
appropriate type of data to call Menu_average_calories with.
If any terms or concepts in the preceding paragraph are unclear to
you, now's the time, before the next midterm, to learn or review what
they mean.
It may also mean that you're not comfortable enough with the parts of Lab 5 that deal with dishes and collections. Processing lists, and processing lists of objects that themselves include lists, is an important aspect of the course.
Write the import statement that allows the creation of namedtuples.
from collections import namedtuple
There are other variations of the import statement,
but we've been using this one and the others require
different ways of referring to namedtuples in the rest
of the program.
Write the namedtuple definition for a Book as described above.
Write an assignment statement that assigns to B a new Book namedtuple
for the computer science book "Algorithms + Data Structures = Programs"
by Niklaus Wirth, which sells for $23.50.
B = Book('Algorithms + Data Structures = Programs', 'Niklaus Wirth',
'computer science', 23.50)
Note the distinction between defining the namedtuple itself as
in part (b), which
describes Books in general, and defining a specific instance of a Book
as in part (c).
Note also that the order of the fields you specified when you
defined the namedtuple (title first, author second, and so on)
must match the order in the Book() constructor function (as
shown above). The problem description may not give the data
in the same order; problem descriptions are in English, which
allows a lot of variety in expressing things.
Complete the definition of the function below, consistent with its
header, docstring comment, and assertions.
def Books_in_category(L: 'list of Book', cat: str) -> 'list of Book':
''' Return a list of all the books in L whose category matches cat
'''
assert(Books_in_category([ ], 'fiction') == [ ])
assert(Books_in_category([Book('a', 'b', 'c', 10),
Book('d', 'e', 'f', 20),
Book('g', 'h', 'c', 30)], 'fiction') == [ ])
assert(Books_in_category([Book('a', 'b', 'c', 10),
Book('d', 'e', 'f', 20),
Book('g', 'h', 'c', 30)], 'c')
==
[Book('a', 'b', 'c', 10),
Book('g', 'h', 'c', 30)])
assert(Books_in_category([Book('a', 'b', 'c', 10),
Book('d', 'e', 'f', 20),
Book('g', 'h', 'c', 30)], 'f')
==
[Book('d', 'e', 'f', 20)])
def Books_in_category(L: 'list of Book', cat: str) -> 'list of Book':
''' Return a list of all the books in L whose category matches cat
'''
result = [ ]
for b in L:
if b.category == cat:
result = result + [b]
# result += [b] # alternative
# result.append(b) # alternative
return result
Suppose we want to change the Books_in_category function above so that
it returns a list of all the books in a specified category by a
specified author. We'd need a third parameter to specify the
author; let's call it auth. You should need to change just one line in
the body of the function (i.e., not counting the function header, the
docstring comment, and the assertions). Rewrite that line below.
Parts of this excerpt from help(str) may be useful in this problem:
find(...)
S.find(sub) -> int
Return the lowest index in S where the string sub is found.
Return -1 on failure.
split(...)
S.split(sep) -> list of strings
Return a list of the words in S, using sep as the
delimiter string.
strip(...)
S.strip() -> str
Return a copy of the string S with leading and trailing
whitespace removed.
Complete the function definition below, consistent with its header, docstring, and assertions.
MONTHS = ['January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December']
def mmddyy_to_MonthDayYear(mmddyy: str) -> str:
''' From an argument in the form '10/31/12' (month, day, year),
return a string in the form 'October 31, 2012'. Assume all
values are valid numbers and all years are in this century.
'''
assert(mmddyy_to_MonthDayYear('10/31/12') == 'October 31, 2012')
assert(mmddyy_to_MonthDayYear('12/1/07') == 'December 1, 2007')
assert(mmddyy_to_MonthDayYear('1/3/99') == 'January 3, 2099')
def mmddyy_to_MonthDayYear(mmddyy: str) -> str:
''' From an argument in the form '10/31/12' (month, day, year),
return a string in the form 'October 31, 2012'. Assume all
values are valid numbers and all years are in this century.
'''
fields = mmddyy.split('/')
month_number = int(fields[0]) - 1
# Subtract 1 for indexing into the MONTHS list starting at 0 for January
month_name = MONTHS[month_number]
day = fields[1] # for clarity; could just use fields[1] in the return statement
year = '20' + fields[2] # no need in this problem to convert to a number,
# Also, leaving it a string helps with leading zeroes in, e.g., '12/1/07'
return month_name + " " + day + ", " + year
Suppose we have this definition:
from collections import namedtuple
Date = namedtuple('Date', 'year month day')
where all three fields are numbers, so that November 12, 2012 would be represented as Date(2012, 11, 12). [You might think about how to define a function to convert a mmddyy string to a Date, or to convert a Date to a MonthDayYear string, but neither one is part of this quiz.]
Suppose we also have this definition:
DrivingRecord = namedtuple('DrivingRecord', 'name license age tickets')
where name is a string representing a driver's name, license is a string representing his or her driver's licence number, age is the driver's age, and tickets is a (possibly empty) list of Date objects containing the dates on which the driver has received a traffic ticket (i.e., was cited by a police officer for violating a driving law).
Complete the two function definitions below, consistent with their headers, docstrings, and assertions.
def is_dangerous(d: DrivingRecord, limit: int) -> bool:
''' Return True if d has more tickets than the limit (and false otherwise)
'''
def dangerous_drivers(DRL: 'list of DrivingRecord', limit: int) -> 'list of str':
''' Return a list of the names of drivers in DRL who have
more tickets than the specified limit. '''
assert(dangerous_drivers(
[DrivingRecord('a', '1', '16', [Date(1,2,3),Date(2,3,4),Date(3,4,5)]),
DrivingRecord('b', '1', '66', [Date(1,2,3),Date(2,3,4)]),
DrivingRecord('c', '1', '66', [Date(1,2,3)]),
DrivingRecord('d', '1', '116', []),
DrivingRecord('e', '1', '116', [Date(1,2,3),Date(2,3,4),Date(3,4,5)])], 1)
== ['a', 'b', 'e'])
def is_dangerous(d: DrivingRecord, limit: int) -> bool:
''' Return True if d has more tickets than the limit (and false otherwise)
'''
return len(d.tickets) > limit
# Be careful to say > and not >= --- it specifies "MORE ... than the limit"
def dangerous_drivers(DRL: 'list of DrivingRecord', limit: int) -> 'list of str':
''' Return a list of the names of drivers in DRL who have
more tickets than the specified limit. '''
result = [ ]
for d in DRL:
if is_dangerous(d, limit):
result += [d.name] # or result.append(d.name)
return result
A quiz has scores in the range 0 to 10. We can represent the distribution of scores on this quiz a list of numbers, each number being the count of students who received a particular score. So in the list below, 1 person scored 0, 3 people scored 5, and 45 people scored 10:
scores = [1, 0, 0, 2, 2, 3, 8, 22, 33, 40, 45]
Suppose we want to print these statistics in a table in the following format:
0. 1 ( 0.64%)
1. 0 ( 0.00%)
2. 0 ( 0.00%)
3. 2 ( 1.28%)
4. 2 ( 1.28%)
5. 3 ( 1.92%)
6. 8 ( 5.13%)
7. 22 (14.10%)
8. 33 (21.15%)
9. 40 (25.64%)
10. 45 (28.85%)
In the following code, fill in each blank with one character per blank so that the output is formatted as shown above.
TOPSCORE = 10
for s in range(TOPSCORE + 1):
print("{:_____d}. {:3d} ({:_____ . _____ _____}%)".format(s,
scores[s], scores[s]/sum(scores)*100))
print("{:2d}. {:3d} ({:5.2f}%)".format(s, scores[s], scores[s]/sum(scores)*100))