Students store a map in dictionaries (rooms by name, and each room's exits), look values up by key, check keys with in, use a dictionary inside a dictionary, and count words with a dictionary.
Load these into Waypoints Prepare: choose Load URL and paste the copied address, or download the file and import it. In Prepare, the worksheet's Teacher edition shows the answers; the student copy hides them.
Predict and Run 10 min · Investigate 15 min · Modify 10 min · Make 15 min
Read the unit primer first. A dictionary pairs keys with values: {"north": "kitchen"}; exits["north"] looks up the value. Keys must match exactly (the bug task: "Hall" is not "hall", so KeyError). "west" in exits checks for a key. exits[here] is itself a dictionary, so exits[here]["north"] looks up twice. ", ".join(exits[here]) joins the keys. Counting with a dictionary (the Make task) is a classic pattern: a new key starts at 1, an existing one goes up by 1.
A dictionary of dictionaries: two lookups in one line. Have them say each step aloud (which room, then which way) before writing rooms[here][way].
| What you will see | A question to ask | The fix |
|---|---|---|
| KeyError: ... | Is the key spelled exactly as it was stored, capitals included? | Tidy text before using it as a key (lower()), or check with in first. |
| The new room cannot be reached. | Which room's exits lead to it? | Add it to another room's exits as well as to rooms and exits. |
| The word counter crashes on the first word (KeyError). | What is counts[word] before that word has been seen? | If the word is not in counts yet, set it to 1; otherwise add 1. |
One possible solution for each task. Other correct programs are fine.
rooms = {
"hall": "A long hall with a creaky floor.",
"kitchen": "A kitchen that smells of toast.",
"garden": "A garden full of tall grass.",
"attic": "A dusty attic full of old boxes.",
}
exits = {
"hall": {"north": "kitchen", "east": "garden", "up": "attic"},
"kitchen": {"south": "hall"},
"garden": {"west": "hall"},
"attic": {"down": "hall"},
}
here = "hall"
while True:
print(rooms[here])
print("Exits: " + ", ".join(exits[here]))
command = input("> ").strip().lower()
words = command.split()
if command == "quit":
break
elif len(words) == 2 and words[0] == "go":
if words[1] in exits[here]:
here = exits[here][words[1]]
else:
print("You can't go that way.")
else:
print("Try: go north, or quit")
rooms = {
"hall": "A long hall with a creaky floor.",
"kitchen": "A kitchen that smells of toast.",
"garden": "A garden full of tall grass.",
}
exits = {
"hall": {"north": "kitchen", "east": "garden"},
"kitchen": {"south": "hall"},
"garden": {"west": "hall"},
}
here = "hall"
moves = 0
while True:
print(rooms[here])
print("Exits: " + ", ".join(exits[here]))
command = input("> ").strip().lower()
words = command.split()
if command == "quit":
print("You made " + str(moves) + " moves.")
break
elif len(words) == 2 and words[0] == "go":
if words[1] in exits[here]:
here = exits[here][words[1]]
moves += 1
else:
print("You can't go that way.")
else:
print("Try: go north, or quit")
sentence = input("Type a sentence: ").strip().lower()
counts = {}
for word in sentence.split():
if word in counts:
counts[word] += 1
else:
counts[word] = 1
for word in counts:
print(word + ": " + str(counts[word]))
Stretch: Put things in rooms (a dictionary from room to a list of things) and let the player take them into last lesson's bag.
Support: Give students the loop over the words and the if, and ask them to fill in the two lines that count.
ages = {"Ada": 12}. What do ages["Ada"] and "Bo" in ages give?
12, and False: Bo is not a key.
This completes the lessons that run in the turtle playground. Still to come: errors with try, saving the game to a file, and the text adventure, which joins the parser, the bag and the map. Data detective uses lists of dictionaries for real data.