#!/usr/bin/env python3 """Theme-level KP monthly support aggregation.""" from __future__ import annotations _DOMAIN_HOUSES = { "career": (2, 6, 10, 11), "wealth": (2, 5, 9, 11), "relationship": (2, 7, 11), } _DOMAIN_LABELS = { "career": "事业", "wealth": "财务", "relationship": "关系", } _HOUSE_LABELS = { 2: "收入与资源", 5: "机会与投入", 6: "职责与压力", 7: "合作与伴侣", 9: "运气与扩张", 10: "事业与位置", 11: "回报与支持", } _DOMAIN_TEMPLATES = { "career": "这段时间更适合把重心放在职责变化、位置调整和回报兑现的节奏里观察。", "wealth": "这段时间更适合把注意力放在现金流、机会选择和回报兑现的节奏里观察。", "relationship": "这段时间更适合把重心放在合作默契、关系回应和现实支持的变化里观察。", } _PLANET_CN = { "Sun": "太阳", "Moon": "月亮", "Mars": "火星", "Mercury": "水星", "Jupiter": "木星", "Venus": "金星", "Saturn": "土星", "Rahu": "北交点", "Ketu": "南交点", } _SIGN_CN = { "Aries": "白羊座", "Taurus": "金牛座", "Gemini": "双子座", "Cancer": "巨蟹座", "Leo": "狮子座", "Virgo": "处女座", "Libra": "天秤座", "Scorpio": "天蝎座", "Sagittarius": "射手座", "Capricorn": "摩羯座", "Aquarius": "水瓶座", "Pisces": "双鱼座", } def _collect_active_houses(houses: dict, house_numbers: tuple[int, ...]) -> list[int]: active: list[int] = [] for house in house_numbers: row = houses.get(str(house)) if isinstance(houses.get(str(house)), dict) else {} significators = row.get("significators") if isinstance(row.get("significators"), dict) else {} if significators.get("A") not in (None, "", [], (), set()): active.append(house) return active def _house_signal_text(active_houses: list[int], fallback_houses: tuple[int, ...]) -> str: if not active_houses: return "相关宫位线索暂时偏弱" labels = [f"{house}宫{_HOUSE_LABELS.get(house, '')}" for house in active_houses] return "、".join(labels) def _summary_text(domain: str, active_houses: list[int], fallback_houses: tuple[int, ...], md_lord: str, saturn_sign: str) -> str: label = _DOMAIN_LABELS.get(domain, domain) focus = _house_signal_text(active_houses, fallback_houses) template = _DOMAIN_TEMPLATES.get(domain, "这段时间更适合先看结构支持,再看外部触发。") md_label = _PLANET_CN.get(md_lord, md_lord) saturn_label = _SIGN_CN.get(saturn_sign, saturn_sign) if active_houses: return ( f"{label}线本月先看 {focus} 的本命承诺;" f"当前主运星为{md_label},土星行运落在{saturn_label},{template}" ) fallback_text = "、".join( f"{house}宫{_HOUSE_LABELS.get(house, '')}" for house in fallback_houses ) return ( f"{label}线本月更适合先按 {fallback_text} 这组标准宫位阅读,再等待更强触发出现;" f"当前主运星为{md_label},土星行运落在{saturn_label},{template}" ) def _brief_summary_text(domain: str, active_houses: list[int], fallback_houses: tuple[int, ...], md_lord: str) -> str: label = _DOMAIN_LABELS.get(domain, domain) md_label = _PLANET_CN.get(md_lord, md_lord) focus_houses = active_houses or list(fallback_houses[:2]) focus_text = "、".join(f"{house}宫" for house in focus_houses) return f"本命焦点:{focus_text};月运主轴:{label}线跟随{md_label}主运推进。" def build_kp_monthly_theme_support( *, natal_kp: dict, monthly_levels: dict, monthly_transits: dict ) -> dict: houses = natal_kp.get("houses") if isinstance(natal_kp.get("houses"), dict) else {} ruling = natal_kp.get("ruling_planets") if isinstance(natal_kp.get("ruling_planets"), dict) else {} md_lord = ((monthly_levels.get("mahadasha") or {}) if isinstance(monthly_levels, dict) else {}).get("lord") or "-" saturn_sign = ((((monthly_transits.get("planets") or {}) if isinstance(monthly_transits, dict) else {}).get("Saturn") or {}) if isinstance((monthly_transits.get("planets") or {}).get("Saturn"), dict) else {}).get("sign") or "-" out = {} for domain, house_numbers in _DOMAIN_HOUSES.items(): active_houses = _collect_active_houses(houses, house_numbers) out[domain] = { "houses": list(house_numbers), "active_houses": active_houses, "promise_code": " / ".join(str(h) for h in active_houses) if active_houses else "-", "summary": _summary_text(domain, active_houses, house_numbers, md_lord, saturn_sign), "brief_summary": _brief_summary_text(domain, active_houses, house_numbers, md_lord), "ruling_planet_snapshot": ruling.get("day_lord") or "-", "status": "parameter_sensitive", "must_not_claim": ["exact_event_timing", "specific_event_prediction"], } return out