mirror of
https://github.com/migatu/astrololo.git
synced 2026-07-18 13:02:10 +00:00
9d5b65ddbd
- engine/firdaria.py: sekta (dzień = Słońce nad horyzontem, ta sama półkula osi Asc-Dsc co MC); kolejność diurnalna/nokturnalna; klasyczne długości okresów (Su10 Ve8 Me13 Mo9 Sa11 Ju12 Ma7 + NN3 + SN2 = 75 lat); okresy główne planet dzielone na 7 podokresów (sub-lord od władcy okresu), węzły bez sub. - endpoint /chart/firdaria. - oś czasu: firdaria_events — starty (pod)okresów w oknie; wpięte w build_timeline (domyślnie) + tokeny [major][sub] do dopięcia interpretacji (1B->2B). Walidacja: - sekta = day dla horoskopu referencyjnego (zgodnie z notes3 "Day birth"); night gdy Słońce po stronie IC; sumy i przyleganie okresów; podokresy 7x sumujące się do okresu; wiek 42 w okresie Saturna. - E2E: okresy Sun 1984-1994 ... Saturn 2024-2035; w osi czasu "Firdaria: Saturn / Mars" 2027 -> 223 interpretacje ([Sa+[Ma -> "injury"). - 78 testów przechodzi (nowy test_firdaria). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
58 lines
2.4 KiB
Python
58 lines
2.4 KiB
Python
"""Firdaria (LOG-11) — perska technika time-lord.
|
||
|
||
Sekwencja okresów głównych zależy od sekty (dzień/noc). Sekta: urodzenie dzienne,
|
||
gdy Słońce jest nad horyzontem, czyli po tej samej stronie osi Asc–Dsc co MC.
|
||
|
||
Klasyczne długości okresów (lata): Su 10, Ve 8, Me 13, Mo 9, Sa 11, Ju 12, Ma 7
|
||
(razem 70) + Węzeł Północny 3 + Węzeł Południowy 2 = 75 lat. Każdy okres główny
|
||
planety dzieli się na 7 podokresów (sub-lord w tej samej kolejności, cyklicznie).
|
||
Węzły — bez podokresów (najczęstsza konwencja).
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from datetime import datetime, timedelta
|
||
|
||
DAY_ORDER = ["Sun", "Venus", "Mercury", "Moon", "Saturn", "Jupiter", "Mars"]
|
||
NIGHT_ORDER = ["Moon", "Saturn", "Jupiter", "Mars", "Sun", "Venus", "Mercury"]
|
||
YEARS = {"Sun": 10, "Venus": 8, "Mercury": 13, "Moon": 9,
|
||
"Saturn": 11, "Jupiter": 12, "Mars": 7}
|
||
NODES = [("North Node", 3), ("South Node", 2)]
|
||
DAYS_PER_YEAR = 365.2422
|
||
|
||
|
||
def is_day_birth(sun_lon: float, asc: float, mc: float) -> bool:
|
||
"""Słońce nad horyzontem = ta sama półkula osi Asc–Dsc co MC."""
|
||
return (((sun_lon - asc) % 360.0) < 180.0) == (((mc - asc) % 360.0) < 180.0)
|
||
|
||
|
||
def _date(birth: datetime, years: float) -> str:
|
||
return (birth + timedelta(days=years * DAYS_PER_YEAR)).date().isoformat()
|
||
|
||
|
||
def firdaria(birth: datetime, sun_lon: float, asc: float, mc: float) -> dict:
|
||
"""Pełny rozkład Firdarii: sekta, kolejność, okresy główne i podokresy."""
|
||
day = is_day_birth(sun_lon, asc, mc)
|
||
order = DAY_ORDER if day else NIGHT_ORDER
|
||
majors = [(lord, YEARS[lord]) for lord in order] + NODES
|
||
|
||
periods: list[dict] = []
|
||
age = 0.0
|
||
for lord, yrs in majors:
|
||
period = {"lord": lord, "years": yrs,
|
||
"start": _date(birth, age), "end": _date(birth, age + yrs)}
|
||
if lord in YEARS: # planeta -> 7 podokresów
|
||
sub_len = yrs / 7.0
|
||
i = order.index(lord)
|
||
sub_age = age
|
||
subs: list[dict] = []
|
||
for k in range(7):
|
||
sub_lord = order[(i + k) % 7]
|
||
subs.append({"lord": sub_lord,
|
||
"start": _date(birth, sub_age),
|
||
"end": _date(birth, sub_age + sub_len)})
|
||
sub_age += sub_len
|
||
period["sub"] = subs
|
||
periods.append(period)
|
||
age += yrs
|
||
return {"sect": "day" if day else "night", "order": order, "periods": periods}
|