Comet arrives early with a printout. Last night she wrote the sample log as a list of dicts, one dict per sample.
"Four samples, five keys each," she says. "Let's run it and move on to the rover!"
Wren reads the printout line by line. "What does the evidence say?" he asks. "How do we know every dict has every key? A dict will hold whatever we type into it."
Nova draws four boxes on the wall, one for each stage of the build. "How can I help?" she asks. "Build it in stages, and predict before every run."
Comet grins and hands you the keyboard. "Lead programmer, stage one is yours."
A prototype is a quick first version, built to try an idea. Comet's idea is to store each sample as a dict with the keys label, kind, grams, row and col.
The four samples in this table are made-up data from the FieldSim story. Row and col give each sample's spot on the test field.
| label | kind | grams | row | col |
|---|---|---|---|---|
| S01 | basalt | 42 | 0 | 2 |
| S02 | quartz | 18 | 2 | 4 |
| S03 | clay | 65 | 3 | 0 |
| S04 | mica | 7 | 4 | 5 |
# samples_v1.py
# Comet's first prototype: each sample is a dict.
def describe(sample):
return (f"{sample['label']} {sample['kind']} {sample['grams']} g "
f"at ({sample['row']}, {sample['col']})")
s01 = {"label": "S01", "kind": "basalt", "grams": 42, "row": 0, "col": 2}
print(describe(s01)) Replace the last two lines of stage 1 with the list below and a loop. Keep describe() as it is.
# samples_v1.py
# Comet's first prototype: each sample is a dict.
def describe(sample):
return (f"{sample['label']} {sample['kind']} {sample['grams']} g "
f"at ({sample['row']}, {sample['col']})")
samples = [
{"label": "S01", "kind": "basalt", "grams": 42, "row": 0, "col": 2},
{"label": "S02", "kind": "quartz", "grams": 18, "row": 2, "col": 4},
{"label": "S03", "kind": "clay", "grams": 65, "row": 3, "col": 0},
{"label": "S04", "kind": "mica", "grams": 7, "row": 4, "col": 5},
]
for s in samples:
print(describe(s)) Add these lines at the end of samples_v1.py to find the total grams of all four samples.
# samples_v1.py
# Comet's first prototype: each sample is a dict.
def describe(sample):
return (f"{sample['label']} {sample['kind']} {sample['grams']} g "
f"at ({sample['row']}, {sample['col']})")
samples = [
{"label": "S01", "kind": "basalt", "grams": 42, "row": 0, "col": 2},
{"label": "S02", "kind": "quartz", "grams": 18, "row": 2, "col": 4},
{"label": "S03", "kind": "clay", "grams": 65, "row": 3, "col": 0},
{"label": "S04", "kind": "mica", "grams": 7, "row": 4, "col": 5},
]
for s in samples:
print(describe(s))
total = 0
for s in samples:
total += s["grams"]
print(f"Total: {total} g") Here is what happened in Comet's first draft. She typed one key in the S04 dict as "gram" instead of "grams".
Make the same typo in your file, run it, and read the message from the bottom up.
# samples_v1.py
# Comet's first prototype: each sample is a dict.
def describe(sample):
return (f"{sample['label']} {sample['kind']} {sample['grams']} g "
f"at ({sample['row']}, {sample['col']})")
samples = [
{"label": "S01", "kind": "basalt", "grams": 42, "row": 0, "col": 2},
{"label": "S02", "kind": "quartz", "grams": 18, "row": 2, "col": 4},
{"label": "S03", "kind": "clay", "grams": 65, "row": 3, "col": 0},
{"label": "S04", "kind": "mica", "gram": 7, "row": 4, "col": 5},
]
for s in samples:
print(describe(s)) S01 basalt 42 g at (0, 2)
S02 quartz 18 g at (2, 4)
S03 clay 65 g at (3, 0)
Traceback (most recent call last):
File "samples_v1.py", line 18, in <module>
print(describe(s))
~~~~~~~~^^^
File "samples_v1.py", line 6, in describe
return (f"{sample['label']} {sample['kind']} {sample['grams']} g "
~~~~~~^^^^^^^^^
KeyError: 'grams' KeyError means a dictionary has no such key. The S04 dict has a key called gram, but describe() asks for grams.
This is a run-time error: it happens while the program runs, after three lines have already printed. An exception, like this KeyError, is one kind of run-time error.
Wren writes one note on his clipboard. Nothing stopped Comet from making a dict without a grams key. Python only noticed when describe() asked for it.
Next week the crew tries a class: one blueprint that every sample is built from. Tomorrow you will sort errors into three kinds.