Comet has a plan for the hauler. "It carries six samples, so I need a new __init__," she says. "I will copy all of Rover's __init__ lines and change the 3 to a 6."
Wren reads over her shoulder. "What does the evidence say? Rover.__init__ already has nine lines. If we add a tenth next month, your copy will miss it."
Nova projects a short line in gold: super().__init__(name, row, col). "How can I help?" she asks. "A subclass can ask the base class to do its part first, then add its own."
Comet grins and flips to a clean page. "Lead programmer, you type. I will check names against our design."
super() reaches the base class methods. It is useful for calling a method you have overridden.
In ScoutRover.__init__, the line super().__init__(name, row, col) runs Rover's __init__ first. That sets the name, position, heading, battery, samples and log. Then the next line changes the capacity to 1.
An override can also extend the base method instead of replacing it. ScoutRover.status() calls super().status() and puts "Scout " in front.
# fleet.py
# Two kinds of rover built on Rover (week 7).
from rover import Rover
class ScoutRover(Rover):
"""Light and quick: little battery per step, carries one sample."""
def __init__(self, name, row=0, col=0):
super().__init__(name, row, col)
self._capacity = 1
def step_use(self):
return 2 # check_scout.py
from field_data import FIELD
from fleet import ScoutRover
from grid import FieldGrid
from sample import Sample
grid = FieldGrid(FIELD)
dot = ScoutRover("Dot")
dot.run("FF", grid)
print(dot.status())
print(dot.pick_up(Sample("T1", "clay", 10)))
print(dot.pick_up(Sample("T2", "clay", 10))) Dot at (0, 2) facing E, battery 96 True False
Stage 2: add these lines to ScoutRover, under step_use(). Run check_scout.py again.
def status(self):
return "Scout " + super().status() Scout Dot at (0, 2) facing E, battery 96 True False
Stage 3: add HaulerRover to the end of fleet.py, after two blank lines. Your fleet.py now matches the whole file below. Then type fleet_demo.py.
# fleet.py
# Two kinds of rover built on Rover (week 7).
from rover import Rover
class ScoutRover(Rover):
"""Light and quick: little battery per step, carries one sample."""
def __init__(self, name, row=0, col=0):
super().__init__(name, row, col)
self._capacity = 1
def step_use(self):
return 2
def status(self):
return "Scout " + super().status()
class HaulerRover(Rover):
"""Heavy: more battery per step, carries up to six samples."""
def __init__(self, name, row=0, col=0):
super().__init__(name, row, col)
self._capacity = 6
def step_use(self):
return 8
def status(self):
return "Hauler " + super().status() # fleet_demo.py
from field_data import FIELD
from fleet import HaulerRover, ScoutRover
from grid import FieldGrid
from rover import Rover
grid = FieldGrid(FIELD)
pip = Rover("Pip")
dot = ScoutRover("Dot")
moss = HaulerRover("Moss")
pip.run("FF", grid)
dot.run("FF", grid)
moss.run("FF", grid)
print(pip.status())
print(dot.status())
print(moss.status())
print(Rover.rovers_built) Pip at (0, 2) facing E, battery 90 Scout Dot at (0, 2) facing E, battery 96 Hauler Moss at (0, 2) facing E, battery 84 3
Here is the run after the change to "FFF". Check your prediction.
Pip at (0, 3) facing E, battery 85 Scout Dot at (0, 3) facing E, battery 94 Hauler Moss at (0, 3) facing E, battery 76 3
Now break one thing on purpose. Save a copy of fleet.py as fleet_w7.py first. Then, in fleet.py, delete the super().__init__(name, row, col) line inside ScoutRover only. Run fleet_demo.py and read the traceback from the bottom.
Traceback (most recent call last):
File "fleet_demo.py", line 12, in <module>
dot.run("FF", grid)
~~~~~~~^^^^^^^^^^^^
File "rover.py", line 92, in run
self.move(grid)
~~~~~~~~~^^^^^^
File "rover.py", line 73, in move
d_row, d_col = STEPS[self._heading]
^^^^^^^^^^^^^
AttributeError: 'ScoutRover' object has no attribute '_heading'. Did you mean: 'get_heading'? Python adds a guess at the end: Did you mean get_heading? Here the guess is not the fix. The real clue is that _heading was never set.
Put the super().__init__ line back, or copy it from fleet_w7.py, and run fleet_demo.py again. Then run test_fieldsim.py from week 6. fleet.py is a new file, so every old test should still pass.
All FieldSim tests passed
fleet.py is done: two new kinds of rover in about thirty lines, built on code you already trusted. Tomorrow the whole fleet answers one call.