Venus/Jupiter/Moon periods no longer collapse into one marriage-opportunity line. Full reading reports the ten BPHS conditional dasha families; Skill 6.9.16. Co-authored-by: Cursor <cursoragent@cursor.com>
89 lines
3.6 KiB
Python
89 lines
3.6 KiB
Python
"""Optional child-period expanders for source-bounded Dasha producers."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from copy import deepcopy
|
|
from datetime import datetime, timedelta
|
|
from typing import Any
|
|
|
|
|
|
PYJHORA_PARENT_SEEDED_EQUAL_SPLIT_PROFILE = "pyjhora_parent_seeded_equal_split_observed_v1"
|
|
|
|
|
|
def _parse_dt(value: Any) -> datetime:
|
|
if isinstance(value, datetime):
|
|
return value
|
|
return datetime.fromisoformat(str(value))
|
|
|
|
|
|
def _iso(value: datetime) -> str:
|
|
return value.isoformat(timespec="seconds")
|
|
|
|
|
|
def _sequence_from(lord: str, sequence: tuple[tuple[str, int], ...]) -> list[tuple[str, int]]:
|
|
start = next(index for index, (item, _years) in enumerate(sequence) if item == lord)
|
|
return list(sequence[start:] + sequence[:start])
|
|
|
|
|
|
def expand_parent_seeded_equal_split_children(
|
|
major_rows: list[dict[str, Any]],
|
|
sequence: tuple[tuple[str, int], ...],
|
|
*,
|
|
profile: str | None,
|
|
) -> tuple[list[dict[str, Any]], list[dict[str, Any]], list[dict[str, Any]], str]:
|
|
"""Attach PyJHora-observed equal-split AD/PD rows when explicitly selected."""
|
|
rows = deepcopy(major_rows)
|
|
if profile in (None, "", "blocked"):
|
|
return rows, [], [], "mahadasha_executed_ad_pd_blocked_pending_row_level_replay"
|
|
if profile != PYJHORA_PARENT_SEEDED_EQUAL_SPLIT_PROFILE:
|
|
return rows, [], [], "mahadasha_executed_child_period_profile_unknown_blocked"
|
|
|
|
child_count = len(sequence)
|
|
all_ad: list[dict[str, Any]] = []
|
|
all_pd: list[dict[str, Any]] = []
|
|
for md in rows:
|
|
md_lord = str(md.get("lord") or md.get("planet"))
|
|
md_start = _parse_dt(md["start_date"])
|
|
md_end = _parse_dt(md["end_date"])
|
|
md_seconds = (md_end - md_start).total_seconds()
|
|
ad_seconds = md_seconds / child_count
|
|
ad_rows: list[dict[str, Any]] = []
|
|
ad_cursor = md_start
|
|
for ad_index, (ad_lord, _ad_years) in enumerate(_sequence_from(md_lord, sequence)):
|
|
ad_end = md_end if ad_index == child_count - 1 else ad_cursor + timedelta(seconds=ad_seconds)
|
|
pd_seconds = (ad_end - ad_cursor).total_seconds() / child_count
|
|
pd_rows: list[dict[str, Any]] = []
|
|
pd_cursor = ad_cursor
|
|
for pd_index, (pd_lord, _pd_years) in enumerate(_sequence_from(ad_lord, sequence)):
|
|
pd_end = ad_end if pd_index == child_count - 1 else pd_cursor + timedelta(seconds=pd_seconds)
|
|
pd_row = {
|
|
"level": "pratyantardasha",
|
|
"lord": pd_lord,
|
|
"planet": pd_lord,
|
|
"parent_mahadasha": md_lord,
|
|
"parent_antardasha": ad_lord,
|
|
"start_date": _iso(pd_cursor),
|
|
"end_date": _iso(pd_end),
|
|
"child_period_profile": profile,
|
|
"derivation": "pyjhora_observed_parent_seeded_equal_split",
|
|
}
|
|
pd_rows.append(pd_row)
|
|
all_pd.append(pd_row)
|
|
pd_cursor = pd_end
|
|
ad_row = {
|
|
"level": "antardasha",
|
|
"lord": ad_lord,
|
|
"planet": ad_lord,
|
|
"parent_mahadasha": md_lord,
|
|
"start_date": _iso(ad_cursor),
|
|
"end_date": _iso(ad_end),
|
|
"child_period_profile": profile,
|
|
"derivation": "pyjhora_observed_parent_seeded_equal_split",
|
|
"pratyantardasha": pd_rows,
|
|
}
|
|
ad_rows.append(ad_row)
|
|
all_ad.append(ad_row)
|
|
ad_cursor = ad_end
|
|
md["antardasha"] = ad_rows
|
|
return rows, all_ad, all_pd, "mahadasha_antardasha_pratyantardasha_executed_pyjhora_observed_profile"
|