Extract planetary data into _data.py and add Wikidata refresh script

This commit is contained in:
Jan Doubravský
2026-04-21 14:25:52 +02:00
parent 0e49259a01
commit a87a0ebbd0
8 changed files with 479 additions and 166 deletions

View File

@@ -0,0 +1,31 @@
# AUTO-GENERATED by scripts/refresh_data.py — do not edit by hand.
from datetime import date
# (name, rotation_hours, orbital_hours, discovery_date, contact_date | None)
PLANET_ROWS: list[tuple[str, float, float, date, date | None]] = [
('Mercury' , 1407.600, 2111.2800, date(1631, 11, 7), date(2011, 3, 18)),
('Venus' , 5832.500, 5392.8000, date(1610, 1, 1), date(1970, 12, 15)),
('Mars' , 24.600, 16487.2800, date(1610, 1, 1), date(1976, 7, 20)),
('Jupiter' , 9.900, 103982.1600, date(1610, 1, 7), None),
('Saturn' , 10.700, 258221.2800, date(1610, 7, 25), None),
('Uranus' , 17.200, 736524.0000, date(1781, 3, 13), None),
('Neptune' , 16.100, 1444368.0000, date(1846, 9, 23), None),
]
# (name, rotation_hours, orbital_hours, is_tidally_locked, discovery_date, contact_date | None)
MOON_ROWS: list[tuple[str, float, float, bool, date, date | None]] = [
('Phobos' , 7.653, 7.653, True , date(1877, 8, 18), None),
('Deimos' , 30.312, 30.312, True , date(1877, 8, 12), None),
('Io' , 42.456, 42.456, True , date(1610, 1, 8), None),
('Europa' , 85.228, 85.228, True , date(1610, 1, 8), None),
('Ganymede' , 171.709, 171.709, True , date(1610, 1, 7), None),
('Callisto' , 400.535, 400.535, True , date(1610, 1, 7), None),
('Titan' , 382.690, 382.690, True , date(1655, 3, 25), date(2005, 1, 14)),
('Enceladus' , 32.923, 32.923, True , date(1789, 8, 28), None),
('Miranda' , 33.923, 33.923, True , date(1948, 2, 16), None),
('Ariel' , 60.489, 60.489, True , date(1851, 10, 24), None),
('Umbriel' , 99.460, 99.460, True , date(1851, 10, 24), None),
('Titania' , 208.940, 208.940, True , date(1787, 1, 11), None),
('Oberon' , 323.117, 323.117, True , date(1787, 1, 11), None),
('Triton' , 141.045, 141.045, True , date(1846, 10, 10), None),
]

View File

@@ -2,6 +2,7 @@ from __future__ import annotations
from enum import Enum
from planetarytime._data import PLANET_ROWS
from planetarytime.moon import (
ARIEL,
CALLISTO,
@@ -62,24 +63,11 @@ class Body(Enum):
_ROTATION_HOURS: dict[Body, float] = {
Body.MERCURY: 1407.6,
Body.VENUS: 5832.5,
Body.MARS: 24.6,
Body.JUPITER: 9.9,
Body.SATURN: 10.7,
Body.URANUS: 17.2,
Body.NEPTUNE: 16.1,
Body(row[0]): row[1] for row in PLANET_ROWS
}
# Orbital periods in Earth hours
_ORBITAL_HOURS: dict[Body, float] = {
Body.MERCURY: 87.97 * 24,
Body.VENUS: 224.70 * 24,
Body.MARS: 686.97 * 24,
Body.JUPITER: 4332.59 * 24,
Body.SATURN: 10759.22 * 24,
Body.URANUS: 30688.50 * 24,
Body.NEPTUNE: 60182.00 * 24,
Body(row[0]): row[2] for row in PLANET_ROWS
}
# Moons per body, ordered by orbital distance from the planet

View File

@@ -3,6 +3,7 @@ from __future__ import annotations
from datetime import datetime, timezone
from enum import Enum
from planetarytime._data import PLANET_ROWS
from planetarytime.body import Body
from planetarytime.exceptions import EpochUnavailableError
from planetarytime.moon import Moon
@@ -15,27 +16,22 @@ class EpochType(Enum):
CONTACT = "contact"
# Discovery dates for Solar System bodies (UTC midnight).
def _dt(d: object) -> datetime:
from datetime import date as _date
assert isinstance(d, _date)
return datetime(d.year, d.month, d.day, tzinfo=timezone.utc)
def _dt_opt(d: object) -> datetime | None:
return None if d is None else _dt(d)
_DISCOVERY_DATES: dict[Body, datetime] = {
Body.MERCURY: datetime(1631, 11, 7, tzinfo=timezone.utc), # first recorded transit (Gassendi)
Body.VENUS: datetime(1610, 1, 1, tzinfo=timezone.utc), # telescopic observation (Galileo)
Body.MARS: datetime(1610, 1, 1, tzinfo=timezone.utc), # telescopic observation (Galileo)
Body.JUPITER: datetime(1610, 1, 7, tzinfo=timezone.utc), # moons discovered (Galileo)
Body.SATURN: datetime(1610, 7, 25, tzinfo=timezone.utc), # rings observed (Galileo)
Body.URANUS: datetime(1781, 3, 13, tzinfo=timezone.utc), # Herschel
Body.NEPTUNE: datetime(1846, 9, 23, tzinfo=timezone.utc), # Le Verrier / Galle
Body(row[0]): _dt(row[3]) for row in PLANET_ROWS
}
# First contact dates — automated probe landing or crewed landing.
# None means no contact has occurred yet.
_CONTACT_DATES: dict[Body, datetime | None] = {
Body.MERCURY: datetime(2011, 3, 18, tzinfo=timezone.utc), # MESSENGER orbit insertion (closest approach)
Body.VENUS: datetime(1970, 12, 15, tzinfo=timezone.utc), # Venera 7 — first soft landing
Body.MARS: datetime(1976, 7, 20, tzinfo=timezone.utc), # Viking 1 — first soft landing
Body.JUPITER: None,
Body.SATURN: None,
Body.URANUS: None,
Body.NEPTUNE: None,
Body(row[0]): _dt_opt(row[4]) for row in PLANET_ROWS
}

View File

@@ -3,6 +3,8 @@ from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime, timezone
from planetarytime._data import MOON_ROWS
@dataclass(frozen=True)
class Moon:
@@ -35,125 +37,36 @@ class Moon:
return self.name
# ── Mars ──────────────────────────────────────────────────────────────────────
def _make_moon(name: str, rot: float, orb: float, locked: bool,
disc: object, contact: object) -> Moon:
from datetime import date as _date
def _dt(d: object) -> datetime | None:
if d is None:
return None
assert isinstance(d, _date)
return datetime(d.year, d.month, d.day, tzinfo=timezone.utc)
disc_dt = _dt(disc)
assert disc_dt is not None
return Moon(name=name, rotation_hours=rot, orbital_hours=orb,
is_tidally_locked=locked, discovery_date=disc_dt,
contact_date=_dt(contact))
PHOBOS = Moon(
name="Phobos",
rotation_hours=7.653,
orbital_hours=7.653,
is_tidally_locked=True,
discovery_date=datetime(1877, 8, 18, tzinfo=timezone.utc),
)
DEIMOS = Moon(
name="Deimos",
rotation_hours=30.312,
orbital_hours=30.312,
is_tidally_locked=True,
discovery_date=datetime(1877, 8, 12, tzinfo=timezone.utc),
)
_MOONS_BY_NAME: dict[str, Moon] = {
row[0]: _make_moon(*row) for row in MOON_ROWS
}
# ── Jupiter (Galilean moons) ──────────────────────────────────────────────────
IO = Moon(
name="Io",
rotation_hours=42.456,
orbital_hours=42.456,
is_tidally_locked=True,
discovery_date=datetime(1610, 1, 8, tzinfo=timezone.utc),
)
EUROPA = Moon(
name="Europa",
rotation_hours=85.228,
orbital_hours=85.228,
is_tidally_locked=True,
discovery_date=datetime(1610, 1, 8, tzinfo=timezone.utc),
)
GANYMEDE = Moon(
name="Ganymede",
rotation_hours=171.709,
orbital_hours=171.709,
is_tidally_locked=True,
discovery_date=datetime(1610, 1, 7, tzinfo=timezone.utc),
)
CALLISTO = Moon(
name="Callisto",
rotation_hours=400.535,
orbital_hours=400.535,
is_tidally_locked=True,
discovery_date=datetime(1610, 1, 7, tzinfo=timezone.utc),
)
# ── Saturn ────────────────────────────────────────────────────────────────────
TITAN = Moon(
name="Titan",
rotation_hours=382.690,
orbital_hours=382.690,
is_tidally_locked=True,
discovery_date=datetime(1655, 3, 25, tzinfo=timezone.utc),
contact_date=datetime(2005, 1, 14, tzinfo=timezone.utc), # Huygens probe
)
ENCELADUS = Moon(
name="Enceladus",
rotation_hours=32.923,
orbital_hours=32.923,
is_tidally_locked=True,
discovery_date=datetime(1789, 8, 28, tzinfo=timezone.utc),
)
# ── Uranus ────────────────────────────────────────────────────────────────────
MIRANDA = Moon(
name="Miranda",
rotation_hours=33.923,
orbital_hours=33.923,
is_tidally_locked=True,
discovery_date=datetime(1948, 2, 16, tzinfo=timezone.utc),
)
ARIEL = Moon(
name="Ariel",
rotation_hours=60.489,
orbital_hours=60.489,
is_tidally_locked=True,
discovery_date=datetime(1851, 10, 24, tzinfo=timezone.utc),
)
UMBRIEL = Moon(
name="Umbriel",
rotation_hours=99.460,
orbital_hours=99.460,
is_tidally_locked=True,
discovery_date=datetime(1851, 10, 24, tzinfo=timezone.utc),
)
TITANIA = Moon(
name="Titania",
rotation_hours=208.940,
orbital_hours=208.940,
is_tidally_locked=True,
discovery_date=datetime(1787, 1, 11, tzinfo=timezone.utc),
)
OBERON = Moon(
name="Oberon",
rotation_hours=323.117,
orbital_hours=323.117,
is_tidally_locked=True,
discovery_date=datetime(1787, 1, 11, tzinfo=timezone.utc),
)
# ── Neptune ───────────────────────────────────────────────────────────────────
TRITON = Moon(
name="Triton",
rotation_hours=141.045,
orbital_hours=141.045,
is_tidally_locked=True,
discovery_date=datetime(1846, 10, 10, tzinfo=timezone.utc),
)
PHOBOS = _MOONS_BY_NAME["Phobos"]
DEIMOS = _MOONS_BY_NAME["Deimos"]
IO = _MOONS_BY_NAME["Io"]
EUROPA = _MOONS_BY_NAME["Europa"]
GANYMEDE = _MOONS_BY_NAME["Ganymede"]
CALLISTO = _MOONS_BY_NAME["Callisto"]
TITAN = _MOONS_BY_NAME["Titan"]
ENCELADUS = _MOONS_BY_NAME["Enceladus"]
MIRANDA = _MOONS_BY_NAME["Miranda"]
ARIEL = _MOONS_BY_NAME["Ariel"]
UMBRIEL = _MOONS_BY_NAME["Umbriel"]
TITANIA = _MOONS_BY_NAME["Titania"]
OBERON = _MOONS_BY_NAME["Oberon"]
TRITON = _MOONS_BY_NAME["Triton"]