← Teacher guide

A bag that grows

Students keep an inventory in a list that grows with append() and shrinks with remove(), check with in before removing, list it with join(), and build a shopping list app.

Deeper Python in the console · Lists and dictionaries · about 45 minutes · Open the student lesson

Classroom resources

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.

Students will be able to

Timing

Predict and Run 10 min · Investigate 15 min · Modify 10 min · Make 10 min

Before class

Read the unit primer first. bag.append(x) adds to the end; bag.remove(x) takes the first x out and stops with a ValueError if it is not there, so check with x in bag first. ", ".join(bag) joins a list of texts into one, with a comma and space between. items.sort() puts the list itself in order. Students met break and while True in the console bridge.

Running the lesson

  1. Predict: draw the bag as boxes; add one on the end, cross one out.
  2. Run: give students the list of commands to type, then let them invent their own.
  3. Investigate: drop map is the interesting row: nothing changes, thanks to the in check.
  4. Bug task: ask what should happen when someone drops something they do not have.
  5. Make: students write the loop themselves. Point them to the bag program as a pattern.

The hard part (on purpose)

Checking with in before remove(). Let the ValueError happen first, then ask what the program should say when the thing isn't in the bag.

When students get stuck

What you will seeA question to askThe fix
ValueError: list.remove(x): x not in list.Was the item in the list? Did you check first?if item in bag: bag.remove(item), with an else that replies.
TypeError when joining the list.Is everything in the list text?Only lists of text can be joined; store words, or use str() first.
The list prints as ['lamp', 'key'] with brackets and quotes.How do you want it to look?Use ", ".join(bag) to print lamp, key.

Answers to the checks

  1. Predict: What is the first line it prints?
    ['lamp', 'key']. append() put "key" on the end; remove() took "map" out. The second line is False: "map" is no longer in the bag.
  2. Follow the bag: Start with an empty bag. Fill in how many things are in it after each command.
    2, 2, 1, 2
    drop map changes nothing, because the map is not in the bag: the in check catches it. After drop lamp the bag holds only the key; take rope adds a second thing.
  3. Why check first?: Why does the drop part check if words[1] in bag first?
    remove() stops with an error if the item is not in the list
    remove() only works for items that are there. Checking with in first lets the program reply politely instead of stopping.
  4. Spot the bug: You type map and it stops with ValueError: list.remove(x): x not in list. Click the line where it stops.
    line 3
    remove() stops with an error when the item is not in the list. Check first: if item in bag: bag.remove(item).
  5. Where this leads: A music app's queue lets you add songs, skip one, and see what is next. What is the queue?
    A list that grows and shrinks
    Queues, baskets, playlists and to-do lists are all lists that change while the program runs.

Solutions

One possible solution for each task. Other correct programs are fine.

Modify › How many?

bag = []
while True:
    command = input("> ").strip().lower()
    words = command.split()
    if command == "quit":
        break
    elif command == "bag":
        print("You carry: " + ", ".join(bag))
        print("That is " + str(len(bag)) + " things.")
    elif len(words) == 2 and words[0] == "take":
        bag.append(words[1])
        print("You take the " + words[1] + ".")
    elif len(words) == 2 and words[0] == "drop":
        if words[1] in bag:
            bag.remove(words[1])
            print("You drop the " + words[1] + ".")
        else:
            print("You don't have a " + words[1] + ".")
    else:
        print("Try: take lamp, drop lamp, bag or quit")

Modify › A full bag

bag = []
while True:
    command = input("> ").strip().lower()
    words = command.split()
    if command == "quit":
        break
    elif command == "bag":
        print("You carry: " + ", ".join(bag))
    elif len(words) == 2 and words[0] == "take":
        if len(bag) < 3:
            bag.append(words[1])
            print("You take the " + words[1] + ".")
        else:
            print("Your bag is full.")
    elif len(words) == 2 and words[0] == "drop":
        if words[1] in bag:
            bag.remove(words[1])
            print("You drop the " + words[1] + ".")
        else:
            print("You don't have a " + words[1] + ".")
    else:
        print("Try: take lamp, drop lamp, bag or quit")

Make a shopping list

items = []
while True:
    command = input("add, remove, show or done: ").strip().lower()
    if command == "done":
        break
    elif command == "add":
        items.append(input("What? ").strip().lower())
    elif command == "remove":
        item = input("What? ").strip().lower()
        if item in items:
            items.remove(item)
        else:
            print(item + " is not on the list.")
    elif command == "show":
        items.sort()
        print(", ".join(items))
print("Final list: " + ", ".join(items))

Stretch and support

Stretch: Let the shopping list remember how many of each item (milk x2), ready for next lesson's dictionaries.

Support: Give students the loop and the done command, and ask them to add add, remove and show one at a time.

Exit ticket

bag = ["lamp"]. What happens with bag.remove("key"), and how do you avoid it?

It stops with a ValueError because key is not in the bag. Check first: if "key" in bag: bag.remove("key").

What each step is for

Where it leads

Next lesson stores rooms and exits in dictionaries. The bag comes back in the text adventure.