#!/usr/bin/env python3 """Navigation computer of the SS Probably Fine. Usage: python3 nav.py DESTINATION python3 nav.py --list """ import sys # Distances between neighboring waypoints, in million km. DISTANCES = { ("earth", "moon"): 0.4, ("earth", "gateway"): 0.4, ("gateway", "mars"): 225.0, ("gateway", "venus"): 41.0, ("mars", "phobos"): 0.01, } # Every route starts at Earth. ROUTES = { "moon": ["earth", "moon"], "mars": ["earth", "gateway", "mars"], "venus": ["earth", "gateway", "venus"], "phobos": ["earth", "gateway", "mars", "phobos"], } NAMES = { "earth": "Earth", "moon": "Moon", "gateway": "Lunar Gateway", "mars": "Mars", "venus": "Venus", "phobos": "Phobos", } CRUISE_SPEED = 0.87 # million km per day FUEL_PER_MKM = 0.142 # tonnes of fuel per million km LAUNCH_FUEL = 380.0 # tonnes of fuel to escape Earth's gravity def distance(a, b): """Return the distance between two neighboring waypoints.""" if (a, b) in DISTANCES: return DISTANCES[(a, b)] return DISTANCES[(b, a)] def legs(route): """Return the legs (pairs of consecutive waypoints) of a route.""" return [(route[i], route[i + 1]) for i in range(len(route) - 1)] def plan(destination): """Return route, distance, travel time (days) and fuel (t).""" route = ROUTES[destination] total = 0.0 fuel = 0.0 for start, end in legs(route): d = distance(start, end) total += d fuel += d * FUEL_PER_MKM if start == "earth": fuel += LAUNCH_FUEL return route, total, total / CRUISE_SPEED, fuel def print_plan(destination): """Print the flight plan for a destination.""" route, total, days, fuel = plan(destination) print("Route: " + " -> ".join(NAMES[w] for w in route)) print(f"Distance: {total:.1f} million km") print(f"Travel time: {round(days)} days") print(f"Fuel required: {round(fuel)} t") def main(): if len(sys.argv) != 2: sys.exit(__doc__) if sys.argv[1] == "--list": for key in sorted(ROUTES): print(f"{key:12} {NAMES[key]}") return destination = sys.argv[1].lower() if destination not in ROUTES: known = ", ".join(sorted(ROUTES)) sys.exit(f"Unknown destination: {destination} (known: {known})") print_plan(destination) if __name__ == "__main__": main()