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
This commit is contained in:
@@ -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 完全跳过。
|
||||
|
||||
@@ -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报告、深度解盘。
|
||||
---
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
@@ -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}
|
||||
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user