Today is release day. Comet has her bomber jacket on and Pip parked at the edge of the Larkspur test field.
"Let us finish fieldsim.py and send Pip out!" she says.
Wren holds up a hand. "What does the evidence say? First the simulation runs the whole route. Then the tests pass. Then we save a release copy."
Nova projects a checklist with three empty boxes. "How can I help?" she asks. "Programmers test with many conditions to make a program reliable. Each box is one check."
Comet laughs and sits down at the keyboard. "Fine. Simulation first, lead programmer."
fieldsim.py brings every file together: field_data.py, grid.py, rover.py, sample.py and sorts.py. The field and samples are made-up data from the FieldSim story.
Pip follows the command string one letter at a time. After each letter, collect_here picks up a sample if Pip is on a sample spot.
# fieldsim.py
# FieldSim: drive a rover across the test field and report what it found.
from field_data import FIELD, FIELD_SAMPLES
from grid import FieldGrid
from rover import Rover
from sample import Sample
from sorts import sort_by_grams
def collect_here(rover, grid, samples_by_spot):
"""Pick up the sample under the rover, if there is one."""
spot = (rover.get_row(), rover.get_col())
if grid.cell(spot[0], spot[1]) == "*" and spot in samples_by_spot:
if rover.pick_up(samples_by_spot[spot]):
grid.set_cell(spot[0], spot[1], ".")
def main():
grid = FieldGrid(FIELD)
samples_by_spot = {}
for label, kind, grams, row, col in FIELD_SAMPLES:
samples_by_spot[(row, col)] = Sample(label, kind, grams, row, col)
pip = Rover("Pip")
for c in "FFRFFFLFFLFRRFFLF":
pip.run(c, grid)
collect_here(pip, grid, samples_by_spot)
grid.show(pip)
print(pip.status())
found = pip.get_samples()
sort_by_grams(found)
for s in found:
print(s.describe())
print(f"Total: {pip.total_grams()} g")
main() .....# .#.... ...#.. *..... ..#..R Pip at (4, 5) facing E, battery 45 S04 mica 7 g at (4, 5) S02 quartz 18 g at (2, 4) S01 basalt 42 g at (0, 2) Total: 67 g
Then the tests from week 6. One line means every assert held:
All FieldSim tests passed
Never experiment in a release. Save Copy As again, this time as fieldsim_try.py, and open that copy. Change its first comment line to match the program below.
Change one thing: add a line after print(pip.status()) that prints the last log entry. Predict it, then run it.
# fieldsim_try.py (a copy to experiment in)
# FieldSim: drive a rover across the test field and report what it found.
from field_data import FIELD, FIELD_SAMPLES
from grid import FieldGrid
from rover import Rover
from sample import Sample
from sorts import sort_by_grams
def collect_here(rover, grid, samples_by_spot):
"""Pick up the sample under the rover, if there is one."""
spot = (rover.get_row(), rover.get_col())
if grid.cell(spot[0], spot[1]) == "*" and spot in samples_by_spot:
if rover.pick_up(samples_by_spot[spot]):
grid.set_cell(spot[0], spot[1], ".")
def main():
grid = FieldGrid(FIELD)
samples_by_spot = {}
for label, kind, grams, row, col in FIELD_SAMPLES:
samples_by_spot[(row, col)] = Sample(label, kind, grams, row, col)
pip = Rover("Pip")
for c in "FFRFFFLFFLFRRFFLF":
pip.run(c, grid)
collect_here(pip, grid, samples_by_spot)
grid.show(pip)
print(pip.status())
print("Last log:", pip.get_log()[-1])
found = pip.get_samples()
sort_by_grams(found)
for s in found:
print(s.describe())
print(f"Total: {pip.total_grams()} g")
main() Now break it on purpose: in fieldsim_try.py, change total_grams to total_gram on the last line of main. Run it and read the traceback calmly.
# fieldsim_try.py (a copy to experiment in)
# FieldSim: drive a rover across the test field and report what it found.
from field_data import FIELD, FIELD_SAMPLES
from grid import FieldGrid
from rover import Rover
from sample import Sample
from sorts import sort_by_grams
def collect_here(rover, grid, samples_by_spot):
"""Pick up the sample under the rover, if there is one."""
spot = (rover.get_row(), rover.get_col())
if grid.cell(spot[0], spot[1]) == "*" and spot in samples_by_spot:
if rover.pick_up(samples_by_spot[spot]):
grid.set_cell(spot[0], spot[1], ".")
def main():
grid = FieldGrid(FIELD)
samples_by_spot = {}
for label, kind, grams, row, col in FIELD_SAMPLES:
samples_by_spot[(row, col)] = Sample(label, kind, grams, row, col)
pip = Rover("Pip")
for c in "FFRFFFLFFLFRRFFLF":
pip.run(c, grid)
collect_here(pip, grid, samples_by_spot)
grid.show(pip)
print(pip.status())
print("Last log:", pip.get_log()[-1])
found = pip.get_samples()
sort_by_grams(found)
for s in found:
print(s.describe())
print(f"Total: {pip.total_gram()} g")
main() .....#
.#....
...#..
*.....
..#..R
Pip at (4, 5) facing E, battery 45
Last log: moved to (4, 5)
S04 mica 7 g at (4, 5)
S02 quartz 18 g at (2, 4)
S01 basalt 42 g at (0, 2)
Traceback (most recent call last):
File "fieldsim_try.py", line 37, in <module>
main()
~~~~^^
File "fieldsim_try.py", line 34, in main
print(f"Total: {pip.total_gram()} g")
^^^^^^^^^^^^^^
AttributeError: 'Rover' object has no attribute 'total_gram'. Did you mean: 'total_grams'? Now fix it: change total_gram back to total_grams in fieldsim_try.py, save it and run it again. Keep this working copy; you will use it on Saturday.
| Statement | True or false? |
|---|---|
| The release copy fieldsim_v1.py is where you try new changes. | ? |
| Running the tests after the program runs is part of checking reliability. | ? |
| Everything before the error still printed in the broken copy. | ? |
| Testing compares what a program does with what it should do. | ? |
FieldSim version 1 is shipped, lead programmer. The whole crew is proud of you. Tomorrow comes the code review.