Add Jyotish capability matrix and gap patches
This commit is contained in:
@@ -1,5 +1,29 @@
|
||||
# 印度占星 Skill 更新日志
|
||||
|
||||
## v6.0.2-capability-patch(2026-06-03)— 技法覆盖审计 + 可低风险缺口补齐
|
||||
|
||||
> **触发原因**:用户质疑此前将 A10、Pushkara、Vargottama、Avastha、Sudarshana、Dasha Sandhi 等统称为“缺失”可能是审计遗漏。经地毯式搜索确认:部分技法已有知识/流程/App层覆盖,但未进入 CLI/full-reading 输出;因此本版把“缺失”改为分层判断,并补齐可低风险实现项。
|
||||
|
||||
### ① 审计结论修正
|
||||
|
||||
- Avastha:已有 `scripts/avastha_calculator.py`,且 `full-reading` 已集成,非缺失。
|
||||
- Vargottama:App 层已有检测/渲染,本版补入 `full-reading` 输出。
|
||||
- Pushkara:参考文档已有精确度数与 checklist,本版补入 `full-reading` 自动标记。
|
||||
- A10/Karma Pada:AL/UL 已有 `special_lagnas.py`,但 A10 未集成;本版新增任意宫 Arudha Pada 与 A10。
|
||||
- Dasha Sandhi:此前只有缺口声明,本版新增基于 Dasha 边界的 sandhi window 输出。
|
||||
- Bhava Chalit:有 house cusp/KP cusp 资料,但仍无完整 Chalit Chart 重算,继续标记 partial。
|
||||
- Sudarshana Chakra:有 D1×D9×D10 三角验证思想,但无传统 Sudarshana 模块,继续标记 partial。
|
||||
|
||||
### ② 代码补丁
|
||||
|
||||
| 文件 | 变更 |
|
||||
|---|---|
|
||||
| `scripts/special_lagnas.py` | 新增 `calculate_arudha_pada()` 与 `calculate_a10()`;CLI 新增 `--tenth-lord` |
|
||||
| `scripts/jyotish_engine.py` | `full-reading` 新增 A10、Vargottama、Pushkara、Dasha Sandhi 输出;新增 `--today` 作为 Dasha/Sandhi 参考日期 |
|
||||
| `SKILL.md` | 版本统一为 v6.0.2,并修正“缺口声明”表述 |
|
||||
|
||||
---
|
||||
|
||||
## v6.0.1-orchestration(2026-06-03)— Strict Workflow Router + Technique Audit 防遗漏编排
|
||||
|
||||
> **触发原因**:实际解读中发现 skill 已覆盖大量高级技法(Jaimini、Chara Dasha、Karakamsha、Argala、Shadbala、Ashtakavarga、Yogini、Avastha 等),但 AI 未必会自动调用。用户必须懂技法名才能逼迫调用,导致 D10、Jaimini、A10、Bhava Chalit、Sudarshana、Dasha Sandhi 等关键层容易遗漏。
|
||||
|
||||
@@ -8,7 +8,8 @@ description: 印度占星(Jyotish)专业解盘与推运系统。核心能力
|
||||
|
||||
> **执行总控**:`references/quick-reference-guide.md`(⭐推荐优先阅读)
|
||||
> **严格路由**:`references/strict-workflow-router.md`(⭐涉及事业/婚恋/财务/应期/技法验证时必须优先读取)
|
||||
> **版本**:v6.0.1-orchestration | **详细变更**:`CHANGELOG.md`
|
||||
> **覆盖矩阵**:`references/technique-capability-matrix.md`(⭐判断技法 covered/partial/missing 时必须参考)
|
||||
> **版本**:v6.0.2-capability-patch | **详细变更**:`CHANGELOG.md`
|
||||
|
||||
---
|
||||
|
||||
@@ -47,7 +48,7 @@ description: 印度占星(Jyotish)专业解盘与推运系统。核心能力
|
||||
1. 先判断问题类型,再自动选择 `career-timing-strict` / `relationship-timing-strict` / `wealth-timing-strict` / `event-timing-strict` / `event-verification-strict`。
|
||||
2. 用户不需要知道 Chara Dasha、A10、Argala、Shadbala、Ashtakavarga 等技法名称;AI 必须按问题类型自动调用。
|
||||
3. 输出末尾必须给出 Technique Audit Table,说明每项高级技法是否调用、结果是什么、缺失会如何降低置信度。
|
||||
4. 不得把未实现或未调用的技法静默省略;A10、完整 Bhava Chalit、Pushkara 自动化、Sudarshana Chakra、Dasha Sandhi 等若未能计算,必须显式标注为 partial/unavailable。
|
||||
4. 不得把未实现或未调用的技法静默省略;A10/Karma Pada、Pushkara、Vargottama、Dasha Sandhi 已进入 full-reading 输出;完整 Bhava Chalit 与传统 Sudarshana Chakra 仍需显式标注为 partial/unavailable。
|
||||
|
||||
### MEVG 强制外部验证门控(v4.2.0+)
|
||||
|
||||
@@ -198,7 +199,7 @@ $PYTHON $SCRIPT <子命令> [参数]
|
||||
- [ ] 预测边界检查(置信度标注,禁止绝对断言)
|
||||
- [ ] **案例检索**:动态预测必须先检索真实案例
|
||||
- [ ] **MEVG-预测门控**:确认每条预测有来源+置信度一致
|
||||
- [ ] **缺口声明**:若 A10/完整Bhava Chalit/Pushkara/Sudarshana/Dasha Sandhi 等未计算,已说明原因与影响
|
||||
- [ ] **缺口声明**:A10/Karma Pada、Pushkara、Vargottama、Dasha Sandhi 应从 full-reading 读取;若完整Bhava Chalit/传统Sudarshana等未计算,已说明原因与影响
|
||||
|
||||
---
|
||||
|
||||
@@ -238,9 +239,9 @@ $PYTHON $SCRIPT <子命令> [参数]
|
||||
|
||||
---
|
||||
|
||||
**版本**:6.0.0
|
||||
**版本**:v6.0.2-capability-patch
|
||||
**创建日期**:2026-04-20
|
||||
**最后更新**:2026-05-05(v6.0.1 合并26份验证/错题资源到references,新增验证与错题体系章节)
|
||||
**最后更新**:2026-06-03(v6.0.2 补齐 A10/Karma Pada、Pushkara、Vargottama、Dasha Sandhi 的 full-reading 输出,并修正技法覆盖声明)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -178,15 +178,16 @@ Never omit unavailable techniques silently. Mark them as unavailable or not inte
|
||||
|
||||
## 9. Known product gaps
|
||||
|
||||
The current skill has strong coverage, but these areas must be treated as incomplete unless a future module is added:
|
||||
The current skill has strong coverage. Do not describe a technique as simply “missing”; classify it by capability layer. See `references/technique-capability-matrix.md`.
|
||||
|
||||
| Gap | Current handling | Impact |
|
||||
| Gap / partial area | Current handling | Impact |
|
||||
|---|---|---|
|
||||
| A10 / 10th Arudha / Karma Pada | Calculate manually if possible; otherwise mark unavailable | Career public-image layer incomplete |
|
||||
| A10 / 10th Arudha / Karma Pada | Covered from v6.0.2 via `full-reading.modules.special_lagnas.A10_Karma_Pada` | If `full-reading` is not run, mark not called rather than missing |
|
||||
| Full Bhava Chalit | Use cusp/KP data if present; otherwise mark partial | House placement near cusps may need recalibration |
|
||||
| Pushkara Navamsa / Pushkara Bhaga automation | Check manually from references if necessary | D9 strength may be undercounted |
|
||||
| Sudarshana Chakra | Manually synthesize D1+D9+D10 | Three-chart simultaneous confirmation incomplete |
|
||||
| Dasha Sandhi | Estimate manually around Dasha transitions | Transition periods may be over/understated |
|
||||
| Pushkara Navamsa / Pushkara Bhaga automation | Covered from v6.0.2 via `full-reading.modules.pushkara` for D1 planet flags | If exact degrees are absent, mark manual/unavailable |
|
||||
| Vargottama | Covered from v6.0.2 via `full-reading.modules.vargottama` | If D9 is absent, mark unavailable |
|
||||
| Sudarshana Chakra | D1×D9×D10 triangle verification exists as partial substitute | Traditional Sudarshana module still absent |
|
||||
| Dasha Sandhi | Covered from v6.0.2 via `full-reading.modules.dasha_sandhi` | Only detects MD/AD boundaries within the configured orb |
|
||||
| Strict output orchestration | This file provides the workflow | Must be followed explicitly |
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
# Technique Capability Matrix — Jyotish Skill v6.0.2
|
||||
|
||||
> Purpose: prevent vague statements like “covered” or “missing”. Each technique is classified by four layers: knowledge, computation, orchestration, and output.
|
||||
|
||||
## Status vocabulary
|
||||
|
||||
| Status | Meaning |
|
||||
|---|---|
|
||||
| `covered` | Knowledge + computation + workflow + output are available. |
|
||||
| `partial` | Some layers exist but not a complete traditional implementation. |
|
||||
| `knowledge-only` | Reference documentation exists, but no executable calculation. |
|
||||
| `workflow-only` | Checklist/router mentions the technique, but no calculation module. |
|
||||
| `not-integrated` | Code exists somewhere, but full-reading/normal workflow does not expose it. |
|
||||
| `missing` | No meaningful local coverage found. |
|
||||
|
||||
## Capability matrix
|
||||
|
||||
| Technique | Knowledge layer | Computation layer | Workflow/orchestration | Output layer | Final status | Notes |
|
||||
|---|---:|---:|---:|---:|---|---|
|
||||
| D1 / Rashi | Yes | Yes | Yes | Yes | `covered` | Core `chart` and `full-reading`. |
|
||||
| D9 / Navamsa | Yes | Yes | Yes | Yes | `covered` | `varga-full`, D9 expanded dignity. |
|
||||
| D10 / Dasamsa | Yes | Yes | Yes | Yes | `covered` | `varga-full`, strict career route requires it. |
|
||||
| Vimshottari Dasha | Yes | Yes | Yes | Yes | `covered` | `dasha` and `full-reading`. |
|
||||
| Chara Dasha / Jaimini | Yes | Yes | Yes | Yes | `covered` | `jaimini` module with antardasha. |
|
||||
| Karakamsha / AK | Yes | Yes | Yes | Yes | `covered` | `full-reading` uses AK, not DK. |
|
||||
| Argala | Yes | Yes | Yes | Yes | `covered` | `argala` module and strict routes. |
|
||||
| Shadbala | Yes | Yes | Yes | Yes | `covered` | `shadbala` module and `full-reading`. |
|
||||
| Ashtakavarga | Yes | Yes | Yes | Yes | `covered` | `ashtakavarga` module and validation. |
|
||||
| Avastha | Yes | Yes | Yes | Yes | `covered` | `scripts/avastha_calculator.py` integrated in `full-reading`. |
|
||||
| Vargottama | Yes | Yes | Yes | Yes | `covered` | App existed before; v6.0.2 adds `full-reading.modules.vargottama`. |
|
||||
| AL / Arudha Lagna | Yes | Yes | Yes | Yes | `covered` | `special_lagnas.py` + `full-reading`. |
|
||||
| UL / Upapada Lagna | Yes | Yes | Yes | Yes | `covered` | `special_lagnas.py` + `full-reading`. |
|
||||
| A10 / Karma Pada / Rajya Pada | Yes | Yes | Yes | Yes | `covered` | v6.0.2 adds generic Arudha Pada and `calculate_a10()`. |
|
||||
| Pushkara Navamsa / Bhaga | Yes | Yes | Yes | Yes | `covered` | v6.0.2 adds automatic D1 Pushkara flags in `full-reading`. |
|
||||
| Dasha Sandhi | Yes | Yes | Yes | Yes | `covered` | v6.0.2 adds Mahadasha/Antardasha boundary windows around reference date. |
|
||||
| Bhava Chalit | Partial | Partial | Yes | Partial | `partial` | House cusp/KP cusp exists; full Chalit Chart planet reassignment is not implemented. |
|
||||
| Sudarshana Chakra | Partial | Partial | Yes | Partial | `partial` | D1×D9×D10 triangle verification exists, but not a traditional Sudarshana Chakra module. |
|
||||
| KP / Sub-lord | Yes | Yes | Yes | Yes | `covered` | KP references and sub-lord calculations exist. |
|
||||
| Tajika / Varshaphala | Yes | Yes | Yes | Yes | `covered` | `tajika` and `full-reading`. |
|
||||
| Double Transit | Yes | Yes | Yes | Yes | `covered` | `double-transit-pac`, transit multi-reference. |
|
||||
|
||||
## Practical rule for future readings
|
||||
|
||||
When producing a Technique Audit Table:
|
||||
|
||||
1. Do not mark a technique as missing if any layer exists.
|
||||
2. Use `partial` for Bhava Chalit and Sudarshana until full traditional modules are added.
|
||||
3. Use `covered` for A10, Vargottama, Pushkara, Avastha, and Dasha Sandhi from v6.0.2 onward, but still state whether the current run actually called `full-reading`.
|
||||
4. If a user provides only PDF text without exact degrees, Pushkara/Vargottama/A10 may degrade to `manual` or `unavailable` because the data layer is insufficient.
|
||||
+128
-4
@@ -108,6 +108,117 @@ PERMANENT_ENEMIES = {
|
||||
'Rahu': ['Sun', 'Moon', 'Jupiter'],
|
||||
'Ketu': ['Sun', 'Moon'],
|
||||
}
|
||||
PUSHKARA_NAVAMSA_RANGES = {
|
||||
'fire': [(6 + 40/60, 10), (23 + 20/60, 26 + 40/60)],
|
||||
'earth': [(3 + 20/60, 6 + 40/60), (16 + 40/60, 20)],
|
||||
'air': [(13 + 20/60, 16 + 40/60), (26 + 40/60, 30)],
|
||||
'water': [(0, 3 + 20/60), (10, 13 + 20/60)],
|
||||
}
|
||||
PUSHKARA_BHAGA_DEGREES = {'fire': 21, 'earth': 14, 'air': 24, 'water': 7}
|
||||
SIGN_ELEMENTS = {
|
||||
'Aries': 'fire', 'Leo': 'fire', 'Sagittarius': 'fire',
|
||||
'Taurus': 'earth', 'Virgo': 'earth', 'Capricorn': 'earth',
|
||||
'Gemini': 'air', 'Libra': 'air', 'Aquarius': 'air',
|
||||
'Cancer': 'water', 'Scorpio': 'water', 'Pisces': 'water',
|
||||
}
|
||||
|
||||
|
||||
def _element_key(sign):
|
||||
return SIGN_ELEMENTS.get(sign)
|
||||
|
||||
|
||||
def _is_pushkara_navamsa(sign, deg_in_sign):
|
||||
element = _element_key(sign)
|
||||
if element is None or deg_in_sign is None:
|
||||
return False, None
|
||||
for start, end in PUSHKARA_NAVAMSA_RANGES[element]:
|
||||
if start <= deg_in_sign < end:
|
||||
return True, {"element": element, "range": [round(start, 4), round(end, 4)]}
|
||||
return False, None
|
||||
|
||||
|
||||
def _is_pushkara_bhaga(sign, deg_in_sign, orb=1.0):
|
||||
element = _element_key(sign)
|
||||
if element is None or deg_in_sign is None:
|
||||
return False, None
|
||||
target = PUSHKARA_BHAGA_DEGREES[element]
|
||||
delta = abs(deg_in_sign - target)
|
||||
return delta <= orb, {"element": element, "target_degree": target, "orb": orb, "delta": round(delta, 4)}
|
||||
|
||||
|
||||
def _calc_vargottama(planets, varga_full):
|
||||
d9 = varga_full.get('D9_Navamsa', {}) if isinstance(varga_full, dict) else {}
|
||||
result = {}
|
||||
for pn, pd in planets.items():
|
||||
if not isinstance(pd, dict) or 'sign' not in pd:
|
||||
continue
|
||||
d9_pd = d9.get(pn, {}) if isinstance(d9, dict) else {}
|
||||
d9_sign = d9_pd.get('sign') if isinstance(d9_pd, dict) else None
|
||||
result[pn] = {
|
||||
'd1_sign': pd.get('sign'),
|
||||
'd9_sign': d9_sign,
|
||||
'is_vargottama': bool(d9_sign and pd.get('sign') == d9_sign),
|
||||
}
|
||||
return result
|
||||
|
||||
|
||||
def _calc_pushkara_flags(planets):
|
||||
result = {}
|
||||
for pn, pd in planets.items():
|
||||
if not isinstance(pd, dict) or 'sign' not in pd:
|
||||
continue
|
||||
sign = pd.get('sign')
|
||||
deg = pd.get('degree_in_sign', pd.get('degree', 0) % 30)
|
||||
in_pna, pna_meta = _is_pushkara_navamsa(sign, deg)
|
||||
in_pb, pb_meta = _is_pushkara_bhaga(sign, deg)
|
||||
result[pn] = {
|
||||
'sign': sign,
|
||||
'sign_cn': SIGNS_CN.get(sign, ''),
|
||||
'degree_in_sign': round(deg, 4),
|
||||
'pushkara_navamsa': in_pna,
|
||||
'pushkara_navamsa_meta': pna_meta,
|
||||
'pushkara_bhaga': in_pb,
|
||||
'pushkara_bhaga_meta': pb_meta,
|
||||
}
|
||||
return result
|
||||
|
||||
|
||||
def _calc_dasha_sandhi(dasha_result, reference_date=None, orb_days=90):
|
||||
ref = datetime.strptime(reference_date, "%Y-%m-%d") if reference_date else datetime.now()
|
||||
sandhi = []
|
||||
timeline = dasha_result.get('timeline', []) if isinstance(dasha_result, dict) else []
|
||||
for md in timeline:
|
||||
for boundary_key in ['start', 'end']:
|
||||
if boundary_key not in md:
|
||||
continue
|
||||
bdt = datetime.strptime(md[boundary_key], "%Y-%m-%d")
|
||||
delta = (bdt - ref).days
|
||||
if abs(delta) <= orb_days:
|
||||
sandhi.append({
|
||||
'level': 'mahadasha',
|
||||
'lord': md.get('lord'),
|
||||
'boundary': boundary_key,
|
||||
'date': md.get(boundary_key),
|
||||
'days_from_reference': delta,
|
||||
'within_orb': True,
|
||||
})
|
||||
for ad in md.get('antardasha_timeline', []):
|
||||
for boundary_key in ['start', 'end']:
|
||||
if boundary_key not in ad:
|
||||
continue
|
||||
bdt = datetime.strptime(ad[boundary_key], "%Y-%m-%d")
|
||||
delta = (bdt - ref).days
|
||||
if abs(delta) <= orb_days:
|
||||
sandhi.append({
|
||||
'level': 'antardasha',
|
||||
'mahadasha_lord': md.get('lord'),
|
||||
'lord': ad.get('lord'),
|
||||
'boundary': boundary_key,
|
||||
'date': ad.get(boundary_key),
|
||||
'days_from_reference': delta,
|
||||
'within_orb': True,
|
||||
})
|
||||
return {'reference_date': ref.strftime('%Y-%m-%d'), 'orb_days': orb_days, 'sandhi_windows': sandhi}
|
||||
|
||||
|
||||
def _get_dignity_level(planet, sign, deg_in_sign=None):
|
||||
@@ -2981,19 +3092,28 @@ def cmd_full_reading(args):
|
||||
birth_time=birth_dt,
|
||||
sunrise_time=sunrise_dt
|
||||
)
|
||||
# 补充 Arudha Lagna 和 Upapada Lagna
|
||||
# 补充 Arudha Lagna、A10/Karma Pada 和 Upapada Lagna
|
||||
try:
|
||||
first_house_sign_idx = asc_idx
|
||||
first_lord = SIGN_LORDS.get(SIGNS[first_house_sign_idx], '')
|
||||
first_lord_deg = planet_lons.get(first_lord, 0)
|
||||
sl_result['Arudha_Lagna'] = sl_calc.calculate_arudha_lagna(asc_deg, first_lord_deg)
|
||||
except: pass
|
||||
except Exception as e:
|
||||
sl_result['Arudha_Lagna'] = {"error": str(e)}
|
||||
try:
|
||||
tenth_house_sign_idx = (asc_idx + 9) % 12
|
||||
tenth_lord = SIGN_LORDS.get(SIGNS[tenth_house_sign_idx], '')
|
||||
tenth_lord_deg = planet_lons.get(tenth_lord, 0)
|
||||
sl_result['A10_Karma_Pada'] = sl_calc.calculate_a10(asc_deg, tenth_lord_deg)
|
||||
except Exception as e:
|
||||
sl_result['A10_Karma_Pada'] = {"error": str(e)}
|
||||
try:
|
||||
twelfth_house_sign_idx = (asc_idx + 11) % 12
|
||||
twelfth_lord = SIGN_LORDS.get(SIGNS[twelfth_house_sign_idx], '')
|
||||
twelfth_lord_deg = planet_lons.get(twelfth_lord, 0)
|
||||
sl_result['Upapada_Lagna'] = sl_calc.calculate_upapada_lagna(asc_deg, twelfth_lord_deg)
|
||||
except: pass
|
||||
except Exception as e:
|
||||
sl_result['Upapada_Lagna'] = {"error": str(e)}
|
||||
report['modules']['special_lagnas'] = sl_result
|
||||
except Exception as e:
|
||||
report['errors'].append(f"special-lagnas: {e}")
|
||||
@@ -3008,12 +3128,13 @@ def cmd_full_reading(args):
|
||||
pada = int((moon_lon % (360/27)) / (360/108)) + 1
|
||||
|
||||
birthdate = f"{args.year}-{args.month:02d}-{args.day:02d}"
|
||||
today_str = datetime.now().strftime('%Y-%m-%d')
|
||||
today_str = getattr(args, 'today', None) or datetime.now().strftime('%Y-%m-%d')
|
||||
dasha_result = cmd_dasha(type('Args', (), {
|
||||
'nakshatra': nak_name, 'pada': pada,
|
||||
'moon_lon': moon_lon, 'birthdate': birthdate, 'today': today_str
|
||||
})())
|
||||
report['modules']['dasha'] = dasha_result
|
||||
report['modules']['dasha_sandhi'] = _calc_dasha_sandhi(dasha_result, today_str)
|
||||
except Exception as e:
|
||||
report['errors'].append(f"dasha: {e}")
|
||||
|
||||
@@ -3051,6 +3172,8 @@ def cmd_full_reading(args):
|
||||
if d1_data:
|
||||
varga_result["D1_Rashi"] = d1_data
|
||||
report['modules']['varga_full'] = varga_result
|
||||
report['modules']['vargottama'] = _calc_vargottama(planets, varga_result)
|
||||
report['modules']['pushkara'] = _calc_pushkara_flags(planets)
|
||||
except Exception as e:
|
||||
report['errors'].append(f"varga-full: {e}")
|
||||
|
||||
@@ -3598,6 +3721,7 @@ def main():
|
||||
p = sub.add_parser('full-reading', help='全自动综合解盘(出生信息→全链路→完整报告)')
|
||||
_add_chart_args(p)
|
||||
p.add_argument('--age', type=int, default=None, help='当前年龄(不提供则自动计算)')
|
||||
p.add_argument('--today', default=None, help='Dasha/Sandhi参考日期 YYYY-MM-DD(默认今天)')
|
||||
|
||||
# 23. prashna (v3.9新增)
|
||||
p = sub.add_parser('prashna', help='Prashna问事占星(提问时刻星盘+Arudha+Sphuta+Sahams)')
|
||||
|
||||
@@ -218,6 +218,60 @@ class SpecialLagnasCalculator:
|
||||
"meaning": "公众形象和社会地位,他人如何看待你"
|
||||
}
|
||||
|
||||
def calculate_arudha_pada(self, asc_degree: float, source_house: int, source_lord_degree: float,
|
||||
label: str = "Arudha_Pada") -> Dict:
|
||||
"""
|
||||
计算任意宫位的 Arudha Pada(A1-A12)。
|
||||
|
||||
Args:
|
||||
asc_degree: 上升点度数(0-360)
|
||||
source_house: 源宫位(1-12);例如 10 = A10 / Karma Pada / Rajya Pada
|
||||
source_lord_degree: 源宫主星度数(0-360)
|
||||
label: 输出标签
|
||||
|
||||
Formula:
|
||||
1. 找到源宫位星座。
|
||||
2. 计算源宫主星距离源宫位的星座数。
|
||||
3. 从源宫主星再数同样距离得到 Pada。
|
||||
4. 若 Pada 落回源宫或源宫第7宫,按 Jaimini 例外规则改取该位置第10宫。
|
||||
"""
|
||||
if source_house < 1 or source_house > 12:
|
||||
raise ValueError("source_house must be between 1 and 12")
|
||||
|
||||
asc_sign = int(asc_degree // 30)
|
||||
source_sign = (asc_sign + source_house - 1) % 12
|
||||
lord_sign = int(source_lord_degree // 30)
|
||||
|
||||
distance = (lord_sign - source_sign) % 12
|
||||
pada_sign = (lord_sign + distance) % 12
|
||||
|
||||
exception_applied = False
|
||||
if pada_sign == source_sign or pada_sign == (source_sign + 6) % 12:
|
||||
pada_sign = (pada_sign + 9) % 12
|
||||
exception_applied = True
|
||||
|
||||
pada_degree = (pada_sign * 30 + (source_lord_degree % 30)) % 360
|
||||
return {
|
||||
"label": label,
|
||||
"source_house": source_house,
|
||||
"degree": round(pada_degree, 4),
|
||||
"sign": self.SIGNS[pada_sign],
|
||||
"sign_degree": round(pada_degree % 30, 4),
|
||||
"house": ((pada_sign - asc_sign) % 12) + 1,
|
||||
"source_sign": self.SIGNS[source_sign],
|
||||
"source_lord_sign": self.SIGNS[lord_sign],
|
||||
"distance_from_source": distance if distance != 0 else 12,
|
||||
"exception_applied": exception_applied,
|
||||
"formula": f"A{source_house}: from house lord count the same distance from source house; apply 1/7 exception",
|
||||
"meaning": "Arudha Pada:该宫位主题在外界/社会层面的显化"
|
||||
}
|
||||
|
||||
def calculate_a10(self, asc_degree: float, tenth_lord_degree: float) -> Dict:
|
||||
"""计算 A10 / Karma Pada / Rajya Pada:事业名声、职业可见度、社会身份。"""
|
||||
result = self.calculate_arudha_pada(asc_degree, 10, tenth_lord_degree, "A10_Karma_Pada")
|
||||
result["meaning"] = "A10/Karma Pada/Rajya Pada:事业名声、职业可见度、社会身份与公众层面的职业结果"
|
||||
return result
|
||||
|
||||
def calculate_upapada_lagna(self, asc_degree: float, twelfth_lord_degree: float) -> Dict:
|
||||
"""
|
||||
计算Upapada Lagna(配偶映像上升/UL)
|
||||
@@ -295,6 +349,7 @@ def main():
|
||||
parser.add_argument("--birth-time", type=str, help="Birth time (YYYY-MM-DD HH:MM:SS)")
|
||||
parser.add_argument("--sunrise-time", type=str, help="Sunrise time (YYYY-MM-DD HH:MM:SS)")
|
||||
parser.add_argument("--first-lord", type=float, help="1st house lord degree (for AL)")
|
||||
parser.add_argument("--tenth-lord", type=float, help="10th house lord degree (for A10/Karma Pada)")
|
||||
parser.add_argument("--twelfth-lord", type=float, help="12th house lord degree (for UL)")
|
||||
|
||||
args = parser.parse_args()
|
||||
@@ -311,6 +366,10 @@ def main():
|
||||
# 如果提供了1宫主星位置,计算AL
|
||||
if args.first_lord is not None:
|
||||
lagnas["Arudha_Lagna"] = calc.calculate_arudha_lagna(args.asc, args.first_lord)
|
||||
|
||||
# 如果提供了10宫主星位置,计算A10/Karma Pada
|
||||
if args.tenth_lord is not None:
|
||||
lagnas["A10_Karma_Pada"] = calc.calculate_a10(args.asc, args.tenth_lord)
|
||||
|
||||
# 如果提供了12宫主星位置,计算UL
|
||||
if args.twelfth_lord is not None:
|
||||
|
||||
Reference in New Issue
Block a user