Launch schedule digest
Every morning, mission control wants one short list: which launches are coming up, in what order, and how long until each. The launch archive's API has all of it, as JSON, in no particular order and mixed with launches that have already flown.
Build the digest, then make it run on the live clock.
Finish stage 1 to unlock this stage.
Parse schedule_text, keep the launches whose window starts after report_time, sort them by their window and print:
Upcoming launches: 4 2026-11-05 09:10 UTC Aurora Relay (KASA) 2026-11-05 14:30 UTC Lumen-3 (JAXA) 2026-11-12 03:15 UTC Kestrel-7 (ISRO) 2026-11-20 18:45 UTC Polaris Cargo 4 (NASA)
A small function such as window(launch), returning the parsed datetime, works for the comparison and as the key for sorted(). strftime("%Y-%m-%d %H:%M") formats a datetime.
Finish stage 1 to unlock this stage.
Add the time left to each launch, as days, hours and minutes, and mark a launch on hold:
Upcoming launches: 4 2026-11-05 09:10 UTC Aurora Relay (KASA) in 0d 01h 10m 2026-11-05 14:30 UTC Lumen-3 (JAXA) in 0d 06h 30m 2026-11-12 03:15 UTC Kestrel-7 (ISRO) in 6d 19h 15m 2026-11-20 18:45 UTC Polaris Cargo 4 (NASA) in 15d 10h 45m [HOLD]
left = window(launch) - report_time is a timedelta: left.days is the whole days, and left.seconds the rest of the time, in seconds.
Finish stage 2 to unlock this stage.
Mission control runs the digest on the live clock. Replace the fixed report_time with datetime.now(timezone.utc), importing timezone too. Nothing else changes.
When you run it, you'll see the digest for right now; after November 2026, the list is empty. The check stops the clock twice, at 08:00 UTC on 5 November and at midnight on 12 November, which gives:
Upcoming launches: 2 2026-11-12 03:15 UTC Kestrel-7 (ISRO) in 0d 03h 15m 2026-11-20 18:45 UTC Polaris Cargo 4 (NASA) in 8d 18h 45m [HOLD]
Hints
Import System Modules
# A module is a toolbox someone else already built and tested for you
# Plain import brings in the whole module
import sys
import platform
import math
# from ... import brings in just one tool
from math import sqrt
# as gives a module a shorter nickname
import random as rng
# With a plain import: module name, a dot, then the tool
print("Python version:", platform.python_version())
print("Running on:", platform.system())
print("Python lives at:", sys.executable)
# math carries constants you would not want to type from memory
radius_km = 6371
print("Earth circumference:", round(2 * math.pi * radius_km), "km")
# sqrt arrived on its own, so it needs no dot in front
print("Square root of 9:", sqrt(9))
# rng is simply a nickname for random
print("Random sol of the Martian year:", rng.randint(1, 687))
Separate arguments with commas. They're passed on every Run as sys.argv[1:].