A BARD DAY'S NIGHTa.k.a. BARD ROCK CAFEa.k.a. THE SCHOOL OF BARD KNOCKSa.k.a. A BARD RAIN'S A-GONNA FALL
Question:
"""A BARD DAY'S NIGHTa.k.a. BARD ROCK CAFEa.k.a. THE SCHOOL OF BARD KNOCKSa.k.a. A BARD RAIN'S A-GONNA FALL"""
# Imports
from typing import Optional, TextIO, Dict, Set, List,Tuple # Specific annotations
from math import ceil # For stats
# Constants
# Minimum number of songs for a villager to be promoted to abardBARD_THRESHOLD = 10
# Number of songs for the billboard_top statisticBILLBOARD_N = 10
# Maps from {name: songs that this person knows}villagers_type = Dict[str, Set[str]]
bards_type = Set[str]
# Maps from {song name: names of people that know thissong}songs_type = Dict[str, Set[str]]
# A list of parties; each party is a set of the attendeenamesparties_type = List[Set[str]]
def read_input( f: TextIO,) -> Tuple[villagers_type, bards_type, songs_type,parties_type]: """ Read the given file and return the villagers,bards, songs, and parties.
f is an open file containing VILLAGERS andbards, SONGS, and PARTIES, in that order. One villager or bard perline; one song per line; one party per line,consisting of attendees separated by commas. The parties are given inthe order they're held.
""" # TODO villagers = dict() bards = set() songs = dict() parties = list() while True: line =f.readline().strip() if line =='VILLAGERS': while True: name = f.readline().strip() if name == '': break if name[-1] == '*': bards.add(name[:-1]) else: villagers[name] = set() elif line =='SONGS': while True: song = f.readline().strip() if song == '': break songs[song] = bards.copy() else: while True: line = f.readline().strip() if line == '': break names = set() for name in line.split(','): names.add(name) parties.append(names) break return villagers, bards, songs, parties
def sing_at_party( villagers:villagers_type, bards: bards_type, songs: songs_type, party:Set[str]) -> None: """ A bard sings if present, otherwise the villagerssing. """ # TODO pass
def update_bards_after_party( villagers:villagers_type, bards: bards_type, songs: songs_type, party:Set[str]) -> None: """ Promote attendees who have learned enough songsto bards, iff there is another bard present at theparty. """ # TODO pass
def unheard_songs( villagers:villagers_type, bards: bards_type, songs: songs_type, parties:parties_type,) -> Set[str]: """ Return a set of songs that have never been heardby non-bards. (This means that only the bards know it.) """ # TODO pass
def billboard_top( villagers:villagers_type, bards: bards_type, songs: songs_type, parties:parties_type,) -> List[str]: """ Return a list of the BILLBOARD_N most popularsongs by number of people who know them, in descending order. Break tiesalphabetically. """ # TODO pass
def all_bards( villagers:villagers_type, bards: bards_type, songs: songs_type, parties:parties_type,) -> Set[str]: """Return the set of the village'sbards.""" # TODO pass
def average_attendees( villagers:villagers_type, bards: bards_type, songs: songs_type, parties:parties_type,) -> int: """ Return the average number of attendees atparties in the village. Round up to the nearest integer. """ # TODO pass
# Main process
def run(filename: str) -> Dict[str, object]: """ Run the program: Create a village, read theinput, host the parties, and return a dictionary of resulting statisticskeyed by name: unheard_songs, billboard_top, all_bards,average_attendees
filename is the name of an input file. """ # TODO f = open(filename) villagers, bards, songs, parties =read_input(f) for party in parties: sing_at_party(villagers,bards, songs, party) update_bards_after_party(villagers, bards, songs, party) return dict()
# Run program
if __name__ == "__main__":
# Sample input from the handout -- you cantweak this if you like stats_handout = run("handout_example.txt") print("Results of handout sample input") for key, value in stats_handout.items(): print(f"{key}:{value}")
print()
# Sample bigger input -- you can tweak thisif you like stats_bigger = run("bigger_example.txt") print("Results of bigger sample input") for key, value in stats_bigger.items(): print(f"{key}:{value}")