Test the parser
parse_line() now reads every telemetry line the ground station receives, so a mistake in it would quietly corrupt every chart and report. It deserves tests that run every time someone changes it.
Check what a good line becomes, then what the parser does with lines that aren't readings.
Finish stage 1 to unlock this stage.
Write assert checks for good lines: compare the whole record parse_line() returns with the dict you expect, so every field and its type are checked. When they all hold, print:
All checks passed
For example, a line from the feed, "2026-03-14T09:30:05Z,ENG-2,412.5,C", should give {"time": "09:30:05", "sensor": "ENG-2", "value": 412.5, "unit": "C"}. Leave the function as it is.
Finish stage 1 to unlock this stage.
Add checks for the lines the parser must turn into None: an empty line, a line of spaces, a comment, and a line with a missing field such as "2026-03-14T09:30:10Z,TANK-1". Use is None. Then check that a good line with spaces around it still gives the right record. Keep the passed line at the end.
Hints
Returning Dictionary or List
# Returning complex data structures from functions
def planet_data(name):
"""Returns dictionary with planet info."""
database = {
"Mars": {"diameter_km": 6779, "moons": 2, "type": "rocky"},
"Jupiter": {"diameter_km": 139820, "moons": 95, "type": "gas giant"},
"Saturn": {"diameter_km": 116460, "moons": 146, "type": "gas giant"}
}
return database.get(name, {"error": f"Planet {name} not found"})
def mission_checklist(crew_size, days):
"""Returns list of supply items scaled to crew and duration."""
water_liters = crew_size * days * 2.5
food_kg = crew_size * days * 1.8
oxygen_kg = crew_size * days * 0.84
return [
f"Water: {water_liters:.0f} liters",
f"Food: {food_kg:.0f} kg",
f"Oxygen: {oxygen_kg:.1f} kg"
]
mars = planet_data("Mars")
print(f"Mars has {mars['moons']} moons and is {mars['type']}")
pluto = planet_data("Pluto")
print(pluto)
supplies = mission_checklist(4, 180)
print("Mission supplies needed:")
for item in supplies:
print(f" - {item}")
Separate arguments with commas. They're passed on every Run as sys.argv[1:].