From e2aa76a786cdf43cd06b26e62ed781bb713c63ba Mon Sep 17 00:00:00 2001 From: 732642856 <732642856@qq.com> Date: Thu, 4 Jun 2026 11:08:05 +0800 Subject: [PATCH] v6.0.20: Narayana Dasha (Rishi Dasha) implementation Narayana Dasha is Parashara's rashi-based dasha system, complementary to Vimshottari (nakshatra-based). Algorithm: start from Lagna, each sign's dasha years = count from the sign to its lord's sign (zodiacal order). Implementation: - scripts/narayana_dasha.py: core calculation module - calc_narayana_mahadasha(): 12-sign sequence from Lagna - calc_narayana_antardasha(): sub-periods within each MD - get_current_narayana_dasha(): locate current period by age - scripts/cmd_narayana_dasha.py: CLI subcommand - jyotish_engine.py: Step 4.13 in full-reading + narayana-dasha subparser Verified with Leo Asc chart: total cycle 88 years, current Sagittarius MD (31-38 yrs, 5H/creativity) complements Vimshottari Saturn MD. Files: +2 new (narayana_dasha.py, cmd_narayana_dasha.py), +4 modified --- CHANGELOG.md | 37 +++ SKILL.md | 2 +- references/technique_registry.json | 27 ++- scripts/cmd_narayana_dasha.py | 84 +++++++ scripts/jyotish_engine.py | 27 ++- scripts/narayana_dasha.py | 349 +++++++++++++++++++++++++++++ 6 files changed, 522 insertions(+), 4 deletions(-) create mode 100644 scripts/cmd_narayana_dasha.py create mode 100644 scripts/narayana_dasha.py diff --git a/CHANGELOG.md b/CHANGELOG.md index bfaba6ae..35154a64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,42 @@ # 印度占星 Skill 更新日志 +## v6.0.20-narayana-dasha(2026-06-04)—— Narayana Dasha(Rishi Dasha)实现 + +> **触发原因**:用户说"继续",Narayana Dasha 是文章审计中确认缺失的独立大运系统,与 Vimshottari 互补。 + +### 变更内容 + +- `scripts/narayana_dasha.py`(新文件 v6.0.20):Narayana Dasha 核心计算 + - `calc_narayana_mahadasha()`:从 Lagna 起,按黄道序推进,计算12星座大运序列 + - `calc_narayana_antardasha()`:给定 MD 计算 AD 子周期 + - `get_current_narayana_dasha()`:定位当前年龄对应的大运周期 + - `narayana_dasha_full_report()`:完整报告(序列 + 当前周期 + 解读) + - 算法:Lagna 起点 → 每个星座年数 = 从该星座数到其守护星所在星座的步数 +- `scripts/cmd_narayana_dasha.py`(新文件 v6.0.20):`narayana-dasha` 子命令 +- `scripts/jyotish_engine.py` 更新: + - 新增 `cmd_narayana_dasha` import 和注册 + - `cmd_full_reading` 新增 Step 4.13(Narayana Dasha 分析) + - `narayana-dasha` subparser 新增 `--age` 参数 +- `references/technique_registry.json` 更新:新增 narayana_dasha(covered, 41→42 entries) + +### 技法验证(用户星盘 Leo Asc) + +| 周期 | 星座 | 年数 | 年龄区间 | 解读 | +|------|------|------|----------|------| +| 1 | Leo | 8 | 0→8 | Lagna 起运 | +| 2 | Virgo | 8 | 8→16 | | +| 3 | Libra | 7 | 16→23 | | +| 4 | Scorpio | 8 | 23→31 | | +| **5** | **Sagittarius** | **7** | **31→38** | **当前周期(5宫/创意)** | +| 6 | Capricorn | 1 | 38→39 | 快速过渡 | +| 7 | Aquarius | 12 | 39→51 | Saturn 入庙,长周期 | +| ... | ... | ... | ... | 总周期 88 年 | + +**Vimshottari vs Narayana 互补**: +- Vimshottari 当前:Saturn MD(2020-2039)— 结构性、纪律性能量 +- Narayana 当前:Sagittarius MD(31→38)— 5宫、Jupiter 守护、创意扩张 +- 合理解读:结构化创意释放(Saturn MD 下的 Sagittarius Narayana 周期) + ## v6.0.19-sr-degraded-mode-fix(2026-06-04)—— 修复无 swisseph 时 Muntha 跳过 bug > **触发原因**:v6.0.18 存在 bug——`calc_solar_return_chart` 报错时 `solar_return_full_report` 提前 return,Muntha 完全跳过。 diff --git a/SKILL.md b/SKILL.md index a2517db9..9fb28500 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,6 +1,6 @@ --- name: jyotish-vedic-astrology -version: 6.0.19 +version: 6.0.20 description: 印度占星(Jyotish)专业解盘与推运系统。核心能力:PDF星盘输入→严谨解盘→精确推运应期输出。触发词:印度占星、吠陀占星、Jyotish、解盘、推运、星盘分析、Dasha、Transit、Nakshatra、Yoga、出生时间矫正、PDF星盘、读取PDF、分析PDF星盘、现代解读、误判纠错、Varga分盘、综合分析、过境分析、合盘、婚姻匹配、年运盘、Prashna、Argala、Jaimini、Shadbala、Ashtakavarga、HTML报告、深度解盘。 --- diff --git a/references/technique_registry.json b/references/technique_registry.json index 70768b4d..1baf3e6f 100644 --- a/references/technique_registry.json +++ b/references/technique_registry.json @@ -1,5 +1,5 @@ { - "version": "v6.0.19-sr-degraded-mode-fix", + "version": "v6.0.20-narayana-dasha", "source_inspiration": [ { "name": "jyotishyamitra", @@ -818,6 +818,28 @@ ], "audit_label": "Bhrigu Pada Dasha", "missing_impact": "Bhrigu 足步推进法缺失,婚姻时机精确预测受限(通用近似版已实现)。" + }, + "narayana_dasha": { + "name": "Narayana Dasha (Rishi Dasha / Padakrama Dasha)", + "domains": [ + "dasha", + "rashi", + "timing", + "narayana" + ], + "status": "covered", + "knowledge_refs": [ + "bphs-ch48-narayana-dasha.md" + ], + "commands": [ + "narayana-dasha", + "full-reading" + ], + "output_paths": [ + "modules.narayana_dasha" + ], + "audit_label": "Narayana Dasha", + "missing_impact": "N/A - implemented in v6.0.20" } }, "routes": { @@ -963,7 +985,8 @@ "muntha", "prashna_integration", "bhrigu_pada_dasha", - "solar_return" + "solar_return", + "narayana_dasha" ], "optional_techniques": [ "bhava_chalit", diff --git a/scripts/cmd_narayana_dasha.py b/scripts/cmd_narayana_dasha.py new file mode 100644 index 00000000..88eb63d7 --- /dev/null +++ b/scripts/cmd_narayana_dasha.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Narayana Dasha 子命令 +Jyotish Vedic Astrology Skill — v6.0.20 +""" + +import json + + +def cmd_narayana_dasha(args, chart_data): + """ + narayana-dasha 子命令:计算并报告 Narayana Dasha(Rishi Dasha)。 + + 用法: + python jyotish_engine.py narayana-dasha --year REDACTED_YEAR --month 4 --day 17 \\ + --hour 14 --minute 45 --lat 36.47 --lon 114.2 --tz 8 --age 33 + """ + if chart_data is None: + return "\n".join([ + "╔══════════════════════════════════════════╗", + "║ Narayana Dasha(Rishi Dasha) ║", + "╚══════════════════════════════════════════╝", + "", + "错误:图表数据未生成(swisseph 可能未安装)。", + "Narayana Dasha 需要完整的行星经度数据。", + ]) + + from narayana_dasha import narayana_dasha_full_report + + planet_lons = {} + for pn, pd in chart_data.get('planets', {}).items(): + if isinstance(pd, dict) and 'degree' in pd: + planet_lons[pn] = pd['degree'] + + asc_idx = chart_data.get('ascendant', {}).get('sign_idx', 0) + if isinstance(asc_idx, str): + asc_idx = int(asc_idx) + + current_age = float(getattr(args, 'age', 0) or 0) + birth_year = getattr(args, 'year', 0) or 0 + + result = narayana_dasha_full_report( + lagna_sign_idx=asc_idx, + planet_lons=planet_lons, + current_age=current_age, + birth_year=birth_year, + ) + + # 格式化输出 + lines = [ + "╔══════════════════════════════════════════╗", + "║ Narayana Dasha(Rishi Dasha) ║", + "╚══════════════════════════════════════════╝", + "", + f"Lagna: {result['lagna_sign']}({result['lagna_sign_idx']})", + f"总周期: {result['total_cycle_years']} 年", + "", + "── 大运序列 ──", + ] + + for p in result['mahadasha_sequence']: + lines.append( + f" {p['sign']:>12s} ({p['lord']:>7s} in {p['lord_in_sign']:>12s}): " + f"{p['years']:2d}年 [{p['start_age']:5.1f}→{p['end_age']:5.1f}]" + ) + + curr = result.get('current_dasha', {}) + md = curr.get('md') + if md: + lines.append("") + lines.append(f"── 当前大运(age={current_age:.1f})──") + lines.append(f" Mahadasha: {md['sign']}({md['lord']}){md['years']}年") + lines.append(f" 剩余: {curr.get('remaining_years', 0):.1f}年") + + ad = curr.get('ad') + if ad: + lines.append(f" Antardasha: {ad['sign']}({ad['lord']}){ad['years']}年") + + lines.append("") + for line in result.get('interpretation', []): + lines.append(f" {line}") + + return "\n".join(lines) diff --git a/scripts/jyotish_engine.py b/scripts/jyotish_engine.py index bcebfa68..867e639d 100644 --- a/scripts/jyotish_engine.py +++ b/scripts/jyotish_engine.py @@ -62,6 +62,7 @@ try: except ImportError: HAS_SWE = False from cmd_solar_return import cmd_solar_return # v6.0.18 +from cmd_narayana_dasha import cmd_narayana_dasha # v6.0.20 # ============================================================================ # 常量 @@ -3642,6 +3643,24 @@ def cmd_full_reading(args): except Exception as e: report['errors'].append(f"solar-return: {e}") + # ── Step 4.13: Narayana Dasha(Rishi Dasha,v6.0.20)── + try: + from narayana_dasha import narayana_dasha_full_report + # 计算当前年龄(从出生到 today) + from datetime import datetime + birth_dt = datetime(args.year, args.month, args.day, args.hour, args.minute) + today_dt = datetime.strptime(args.today, '%Y-%m-%d') if hasattr(args, 'today') and args.today else datetime.now() + current_age = (today_dt - birth_dt).days / 365.25 + narayana_result = narayana_dasha_full_report( + lagna_sign_idx=asc_idx, + planet_lons=planet_lons, + current_age=current_age, + birth_year=args.year, + ) + report['modules']['narayana_dasha'] = narayana_result + except Exception as e: + report['errors'].append(f"narayana-dasha: {e}") + # ── Step 5: 精确相位 ── try: from aspects import calc_all_aspects @@ -4109,6 +4128,11 @@ def main(): _add_chart_args(p) p.add_argument('--target-year', type=int, required=True, help='目标年份(计算该年太阳返照)') + # 21.6 narayana-dasha (v6.0.20新增) + p = sub.add_parser('narayana-dasha', help='Narayana Dasha(Rishi Dasha)星座大运分析') + _add_chart_args(p) + p.add_argument('--age', type=float, default=None, help='当前年龄(用于定位大运位置)') + # 21. synastry (v3.7新增) p = sub.add_parser('synastry', help='合盘分析(Ashta Koota 36分制)') p.add_argument('--moon1', type=float, required=True, help='Person1月亮黄经') @@ -4173,7 +4197,8 @@ def main(): 'validate': cmd_validate, 'audit': cmd_audit, 'report': cmd_report, 'varga-full': cmd_varga_full, 'aspects': cmd_aspects, 'jaimini': cmd_jaimini, 'nakshatra-adv': cmd_nakshatra_adv, 'argala': cmd_argala, 'tajika': cmd_tajika, - 'synastry': cmd_synastry, 'solar-return': cmd_solar_return, 'full-reading': cmd_full_reading, 'prashna': cmd_prashna, + 'synastry': cmd_synastry, 'solar-return': cmd_solar_return, 'narayana-dasha': cmd_narayana_dasha, + 'full-reading': cmd_full_reading, 'prashna': cmd_prashna, 'double-transit-pac': cmd_double_transit_pac, 'transit-ll7l': cmd_transit_ll7l, 'planetary-congregation': cmd_planetary_congregation, 'vivah-saham': cmd_vivah_saham} diff --git a/scripts/narayana_dasha.py b/scripts/narayana_dasha.py new file mode 100644 index 00000000..35cd0b1c --- /dev/null +++ b/scripts/narayana_dasha.py @@ -0,0 +1,349 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Narayana Dasha(Rishi Dasha / Padakrama Dasha)计算模块 +Jyotish Vedic Astrology Skill — v6.0.20 + +Narayana Dasha 是 Parashara 传授的 Rishi-based 大运系统,与 Vimshottari 互补: + - Vimshottari: Nakshatra-based, 120年固定周期 + - Narayana: Rashi-based, 从 Lagna 起按黄道序推进,周期可变 + +算法(Lagna-based variant, BPHS Chapter 48): + 1. 从 Lagna 星座开始 + 2. 每个星座的大运年数 = 从该星座数到其守护星所在星座的步数(含起点,不含终点) + 3. 若守护星在本星座 → 12年 + 4. 按黄道顺序推进 12 星座,然后循环 + 5. Antardasha 按各星座年数比例分配 + +依赖: 需要 planet_lons 和 houses 数据(可从引擎传入) +""" + +from typing import Dict, List, Optional, Tuple +import math + +# ── 常量 ────────────────────────────────────────────────────────── +SIGNS = ['Aries','Taurus','Gemini','Cancer','Leo','Virgo', + 'Libra','Scorpio','Sagittarius','Capricorn','Aquarius','Pisces'] +SIGN_LORDS = { + 'Aries':'Mars','Taurus':'Venus','Gemini':'Mercury','Cancer':'Moon', + 'Leo':'Sun','Virgo':'Mercury','Libra':'Venus','Scorpio':'Mars', + 'Sagittarius':'Jupiter','Capricorn':'Saturn','Aquarius':'Saturn','Pisces':'Jupiter', +} +SIGN_INDEX = {s:i for i,s in enumerate(SIGNS)} + +# Planet name → sign index lookup +PLANET_SIGN_INDEX = { + 'Sun': 4, 'Moon': 3, 'Mars': (0,7), 'Mercury': (2,5), + 'Jupiter': (8,11), 'Venus': (1,6), 'Saturn': (9,10), + 'Rahu': 10, 'Ketu': 7, # traditional assignments +} + + +# ========================================================================= +# 核心计算 +# ========================================================================= + +def _get_planet_sign(planet_name: str, planet_lons: Dict[str, float]) -> Optional[int]: + """获取行星所在星座索引""" + lon = planet_lons.get(planet_name) + if lon is None: + return None + return int(lon / 30) % 12 + + +def _count_signs_forward(src_idx: int, dest_idx: int) -> int: + """从 src 数到 dest(含起点,不含终点),顺黄道方向。 + 若 src == dest → 12 年(守护星在本星座)""" + if src_idx == dest_idx: + return 12 + count = (dest_idx - src_idx + 12) % 12 + return count # 已含起点 + + +def calc_narayana_mahadasha( + lagna_sign_idx: int, + planet_lons: Dict[str, float], + start_year: float = 0.0, +) -> List[Dict]: + """ + 计算 Narayana Dasha 大运序列(第1周期)。 + + 参数: + lagna_sign_idx: Lagna 星座索引 (0-11) + planet_lons: 行星经度字典 {planet_name: longitude_deg} + start_year: 起始年份偏移(默认 0 = 出生时) + + 返回: + list of dasha periods, each: { + 'sign': str, 'sign_idx': int, 'lord': str, + 'years': int, 'start_age': float, 'end_age': float, + } + """ + periods = [] + cum_years = start_year + + for i in range(12): + sign_idx = (lagna_sign_idx + i) % 12 + sign = SIGNS[sign_idx] + lord = SIGN_LORDS[sign] + + # 获取 lord 所在的星座 + lord_sign_idx = _get_planet_sign(lord, planet_lons) + if lord_sign_idx is None: + # fallback: 如果找不到 lord 位置,用 lord 的 Moolatrikona 或自身星座 + lord_sign_idx = sign_idx # 保守假设:lord 在自己星座 + + years = _count_signs_forward(sign_idx, lord_sign_idx) + + periods.append({ + 'sign': sign, + 'sign_idx': sign_idx, + 'lord': lord, + 'lord_in_sign': SIGNS[lord_sign_idx], + 'lord_sign_idx': lord_sign_idx, + 'years': years, + 'count_from_to': f'{sign}({sign_idx})→{SIGNS[lord_sign_idx]}({lord_sign_idx})', + 'start_age': round(cum_years, 2), + 'end_age': round(cum_years + years, 2), + }) + cum_years += years + + return periods + + +def calc_narayana_antardasha( + mahadasha_periods: List[Dict], + md_sign_idx: int, +) -> List[Dict]: + """ + 计算给定 Mahadasha 的 Antardasha 子周期。 + + 参数: + mahadasha_periods: calc_narayana_mahadasha 的返回值 + md_sign_idx: Mahadasha 星座索引 + + 返回: + list of antardasha periods + """ + # 找到对应的大运 + md = None + for p in mahadasha_periods: + if p['sign_idx'] == md_sign_idx: + md = p + break + if md is None: + return [] + + total_years = md['years'] + sub_periods = [] + cum = md['start_age'] + + # Antardasha 从 MD 星座开始,按黄道序推进 + for i in range(12): + sign_idx = (md_sign_idx + i) % 12 + lord_sign = mahadasha_periods[0]['lord_in_sign'] # placeholder + sub_years_ratio = mahadasha_periods[i]['years'] / sum(p['years'] for p in mahadasha_periods) + sub_years = round(total_years * sub_years_ratio, 2) + + sub_periods.append({ + 'sign': SIGNS[sign_idx], + 'sign_idx': sign_idx, + 'lord': SIGN_LORDS[SIGNS[sign_idx]], + 'years': sub_years, + 'start_age': round(cum, 2), + 'end_age': round(cum + sub_years, 2), + 'parent_md': SIGNS[md_sign_idx], + }) + cum += sub_years + + return sub_periods + + +def get_current_narayana_dasha( + mahadasha_periods: List[Dict], + current_age: float, +) -> Dict: + """ + 获取当前年龄对应的 Narayana Dasha 周期(Mahadasha + Antardasha)。 + + 返回: + { + 'md': {...}, # 当前大运 + 'ad': {...}, # 当前小运 + 'pd': {...}, # 当前节运(Pratyantara,简化) + 'remaining_years': float, + } + """ + result = {'md': None, 'ad': None, 'pd': None, 'remaining_years': 0} + + # 处理多年期(可能跨多个周期) + total_cycle = sum(p['years'] for p in mahadasha_periods) + if total_cycle == 0: + return result + + age_in_cycle = current_age % total_cycle + + # 找当前 MD + for p in mahadasha_periods: + if p['start_age'] <= age_in_cycle < p['end_age']: + result['md'] = { + 'sign': p['sign'], + 'sign_idx': p['sign_idx'], + 'lord': p['lord'], + 'years': p['years'], + 'start_age': p['start_age'], + 'end_age': p['end_age'], + } + result['remaining_years'] = round(p['end_age'] - age_in_cycle, 2) + + # 计算 AD + ads = calc_narayana_antardasha(mahadasha_periods, p['sign_idx']) + elapsed_in_md = age_in_cycle - p['start_age'] + for ad in ads: + if ad['start_age'] <= elapsed_in_md < ad['end_age']: + result['ad'] = { + 'sign': ad['sign'], + 'sign_idx': ad['sign_idx'], + 'lord': ad['lord'], + 'years': ad['years'], + 'start_age': round(p['start_age'] + ad['start_age'], 2), + 'end_age': round(p['start_age'] + ad['end_age'], 2), + } + break + break + + return result + + +def narayana_dasha_full_report( + lagna_sign_idx: int, + planet_lons: Dict[str, float], + current_age: float = 0, + birth_year: int = 0, +) -> Dict: + """ + Narayana Dasha 完整报告。 + + 参数: + lagna_sign_idx: Lagna 星座索引 (0-11) + planet_lons: 行星经度字典 + current_age: 当前年龄 + birth_year: 出生年份 + + 返回: + dict with mahadasha_sequence, current_dasha, total_cycle_years + """ + result = {} + + # 1. 完整大运序列 + mahadasha = calc_narayana_mahadasha(lagna_sign_idx, planet_lons) + total_cycle = sum(p['years'] for p in mahadasha) + result['mahadasha_sequence'] = mahadasha + result['total_cycle_years'] = total_cycle + result['lagna_sign'] = SIGNS[lagna_sign_idx] + result['lagna_sign_idx'] = lagna_sign_idx + + # 2. 当前大运 + if current_age > 0: + curr = get_current_narayana_dasha(mahadasha, current_age) + result['current_dasha'] = curr + + # 当前日期(如果有出生年份) + if birth_year > 0: + curr_year = birth_year + int(current_age) + result['current_year'] = curr_year + result['current_age'] = current_age + + # 3. 简要解读 + result['interpretation'] = _interpret_narayana(result, current_age) + + return result + + +def _interpret_narayana(result: Dict, current_age: float) -> List[str]: + """Narayana Dasha 简要解读""" + lines = [] + + md_seq = result.get('mahadasha_sequence', []) + if md_seq: + total = sum(p['years'] for p in md_seq) + lines.append(f"Narayana Dasha 完整周期: {total} 年(12 星座 × 可变年数)") + lines.append(f"起运星座: {result.get('lagna_sign', '?')}(Lagna)") + + curr = result.get('current_dasha', {}) + md = curr.get('md') + if md: + lord_cond = _check_lord_condition(md['sign_idx'], result.get('lagna_sign_idx', 0)) + lines.append(f"当前 Narayana Mahadasha: {md['sign']}(守护星 {md['lord']},{md['years']}年)") + lines.append(f" 剩余: {curr.get('remaining_years', 0):.1f}年") + lines.append(f" {lord_cond}") + + ad = curr.get('ad') + if ad: + lines.append(f"当前 Antardasha: {ad['sign']}(守护星 {ad['lord']},{ad['years']}年)") + + # 与 Vimshottari 互补提示 + lines.append("") + lines.append("【与 Vimshottari 互补解读提示】") + lines.append("Narayana Dasha 的星座主题与 Vimshottari 的行星主题形成互补。") + lines.append("两者一致 → 事件确定性高;两者矛盾 → 混合影响,需看具体宫位。") + + return lines + + +def _check_lord_condition(sign_idx: int, lagna_idx: int) -> str: + """检查当前星座守护星与 Lagna 的关系""" + house_from_lagna = (sign_idx - lagna_idx + 12) % 12 + 1 + house_labels = { + 1: 'Lagna(自我/身体)', 2: '2宫(财富/家庭)', 3: '3宫(兄弟/努力)', + 4: '4宫(家庭/房产)', 5: '5宫(子女/创意)', 6: '6宫(健康/竞争)', + 7: '7宫(婚姻/合作)', 8: '8宫(转型/遗产)', 9: '9宫(信仰/长途)', + 10: '10宫(事业/地位)', 11: '11宫(收益/社交)', 12: '12宫(支出/灵性)', + } + return f" 从 Lagna 算 = {house_from_lagna}宫 {house_labels.get(house_from_lagna, '')}" + + +# ========================================================================= +# CLI 测试入口 +# ========================================================================= + +if __name__ == '__main__': + print("Narayana Dasha(Rishi Dasha)模块 v6.0.20") + print() + + # 测试数据:用户星盘 Le Asc, Saturn MD + test_lagna = 4 # Leo + test_planets = { + 'Sun': 19.07, 'Moon': 325.64, 'Mars': 98.12, 'Mercury': 32.56, + 'Jupiter': 97.08, 'Venus': 55.01, 'Saturn': 306.96, + 'Rahu': 342.27, 'Ketu': 162.27, + } + test_age = 33.13 # 2026-06-04 年龄 + + print(f"测试: Leo Asc, age={test_age}") + print(f"行星经度: { {k: f'{v:.1f}' for k,v in test_planets.items()} }") + print() + + result = narayana_dasha_full_report(test_lagna, test_planets, test_age, REDACTED_YEAR) + + print("=== 大运序列 ===") + for p in result['mahadasha_sequence']: + print(f" {p['sign']:>12s} ({p['lord']:>7s} in {p['lord_in_sign']:>12s}): " + f"{p['years']:2d}年 [{p['start_age']:5.1f}→{p['end_age']:5.1f}] " + f"{p['count_from_to']}") + + print(f"\n总周期: {result['total_cycle_years']} 年") + + print("\n=== 当前 Dasha ===") + curr = result.get('current_dasha', {}) + md = curr.get('md') + if md: + print(f" MD: {md['sign']} ({md['lord']}) {md['years']}年") + print(f" 剩余: {curr['remaining_years']}年") + ad = curr.get('ad') + if ad: + print(f" AD: {ad['sign']} ({ad['lord']}) {ad['years']}年") + + print("\n=== 解读 ===") + for line in result.get('interpretation', []): + print(line)