Dict and File Practical Exam
60 minutes · 60 points · dict lookup, nested dict, counting, file modes, debugging, and a save/load pair
Instructions
Time
60 min
Total
60 pts
Language
Python
No shortcuts
no .get()/.items()
Section A — Code Tracing
3 questions, 4 points each. Write the exact output and one short reason.
Add, change, delete
4 ptsTwo of these lines look identical but do different jobs. Say which is which.
bag = {"rope": 2, "lamp": 1}bag["lamp"] = 5bag["torch"] = 1del bag["rope"]print(len(bag))print(bag)print("rope" in bag)A dict inside a dict
4 ptsrooms = { "hall": {"name": "Great Hall", "exits": {"north": "library"}}, "library": {"name": "Library", "exits": {"south": "hall"}},}print(rooms["library"]["name"])print(rooms["hall"]["exits"]["north"])rooms["hall"]["exits"]["east"] = "kitchen"print(rooms["hall"]["exits"])Counting, then looping
4 ptsSix printed lines in total. The last loop is the one students most often get wrong.
items = ["bolt", "rope", "bolt", "bolt", "rope"]counts = {}for item in items: if item not in counts: counts[item] = 0 counts[item] = counts[item] + 1print(counts)print(counts["bolt"])for key in counts: print(key)Section B — Fill And Complete
4 questions, 14 points total. Fill every blank so the comment on the right comes true.
Look up a room safely
3 ptsA room id that is not a key must not crash the program.
ROOMS = { "hall": {"name": "Great Hall"}, "library": {"name": "Library"},}def room_name(room_id): if room_id ____ ROOMS: return "Unknown Room" return ROOMS[room_id]____print(room_name("library")) # Libraryprint(room_name("attic")) # Unknown RoomTwo lookups deep
3 ptsReturn the room you arrive at, or None when that direction has no exit.
ROOMS = { "hall": {"name": "Great Hall", "exits": {"north": "library"}}, "library": {"name": "Library", "exits": {"south": "hall"}},}def next_room(room_id, direction): exits = ROOMS[room_id]["exits"] if direction not in ____: return ____ return exits[____]print(next_room("hall", "north")) # libraryprint(next_room("hall", "east")) # NoneA bag that counts
4 ptsA brand new item must end up at 1, and a repeat must count up.
def add_item(bag, item): if item not in bag: bag[item] = ____ bag[item] = ____ + 1bag = {}add_item(bag, "rope")add_item(bag, "rope")add_item(bag, "lamp")print(bag) # {'rope': 2, 'lamp': 1}Use one up and tidy the bag
4 ptsOnce a count reaches 0, the key must disappear completely.
def remove_item(bag, item): if item not in bag: return ____ bag[item] = bag[item] - 1 if bag[item] == 0: ____ bag[item] return Truebag = {"rope": 2, "lamp": 1}print(remove_item(bag, "lamp")) # Trueprint(bag) # {'rope': 2}print(remove_item(bag, "torch")) # FalseSection C — Choices
5 questions, 12 points total. Q8-Q10 are single choice. Q11-Q12 are multiple choice.
Single choice: which line adds a pair?
2 ptsStarting from bag = {"rope": 2}, which line ADDS a new pair rather than touching an existing one?
- A. bag["rope"] = 5
- B. bag["lamp"] = 1
- C. del bag["rope"]
- D. print(bag["rope"])
Single choice: what does the loop give you?
2 ptsbag = {"rope": 2, "lamp": 1}for x in bag: print(x)- A. The values 2 and 1
- B. The keys "rope" and "lamp"
- C. Pairs such as ("rope", 2)
- D. Nothing, a dict cannot be looped
Single choice: exact output
2 ptsstock = {"a": 1, "b": 2}stock["a"] = stock["a"] + stock["b"]print(stock)- A. {'a': 1, 'b': 2}
- B. {'a': 3, 'b': 2}
- C. {'a': 2, 'b': 2}
- D. 3
Multiple choice: which lines crash?
3 ptsEach line runs on its own, starting from bag = {"rope": 2}. Which ones raise KeyError?
- A. print(bag["rope"])
- B. print(bag["lamp"])
- C. bag["lamp"] = 1
- D. del bag["lamp"]
Multiple choice: files
3 ptsWhich statements are TRUE?
- A. open(path, "w") empties the file even before you write anything.
- B. open(path, "a") keeps the old lines and writes at the end.
- C. open(path, "r") creates the file when it is missing.
- D. write() puts a line break at the end of every call.
Section D — Debugging
3 questions, 4 points each. For each bug: say what it prints now, name the bad line, and write the fix.
The log keeps losing its history
4 ptsdef append_log(path, message): with open(path, "w") as log_file: log_file.write(message + "\n")append_log("log.txt", "opened the door")append_log("log.txt", "took the keycard")with open("log.txt", "r") as log_file: print(log_file.read())Adding up numbers from a file
4 ptswith open("scores.txt", "w") as score_file: score_file.write("ana 30\n") score_file.write("bo 12\n")total = 0with open("scores.txt", "r") as score_file: for line in score_file: parts = line.split() total = total + parts[1]print(total)Searching for a value
4 ptsThis should print True, because one room really is red.
def has_color(rooms, color): if color in rooms: return True return Falserooms = {"hall": "red", "library": "blue"}print(has_color(rooms, "red"))Section E — Short Answer And Coding
2 questions, 10 points total. Use clear steps and simple Python.
Describe the round trip
4 ptsIn 4-6 sentences, describe both directions. Name the Python pieces you would use, and say where str() and int() are needed.
bag = {"potion": 2, "keycard": 1}# The save file has to end up looking exactly like this:## item potion 2# item keycard 1## (a) How do you turn the bag into those lines?# (b) How do you turn those lines back into a bag?Write save_scores and load_scores
6 ptsComplete both functions. Saving then loading must give back exactly the same dict, and a missing file must not crash.
def save_scores(path, scores): # Input: # path - a file name, for example "scores.txt" # scores - a dict, for example {"ana": 30, "bo": 12} # Output: # Return nothing. Write one line per pair, like: ana 30 # Running it a second time must REPLACE the old file, not grow it. passdef load_scores(path): # Input: # path - a file name # Output: # Return a dict rebuilt from the file. # Return an empty dict {} when the file does not exist. passsave_scores("scores.txt", {"ana": 30, "bo": 12})print(load_scores("scores.txt"))# expected: {'ana': 30, 'bo': 12}print(load_scores("missing.txt"))# expected: {}