From 81bf99616481e26b89bff8fb66defeab500edea9 Mon Sep 17 00:00:00 2001 From: 732642856 <732642856@qq.com> Date: Sun, 3 May 2026 18:09:33 +0800 Subject: [PATCH] =?UTF-8?q?fix:=208=E4=B8=AA=E4=B8=A5=E9=87=8Dbug=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20-=20=E9=A2=84=E6=B5=8B=E5=BC=95=E6=93=8E=E4=BB=8E?= =?UTF-8?q?=E7=A9=BA=E5=A3=B3=E6=81=A2=E5=A4=8D=E4=B8=BA=E5=85=A8=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复清单: 1. jyotish_engine.py: 缺少 List 类型导入 (NameError崩溃) 2. cmd_predict: 传给EventPredictionModel的ascendant是str不是dict 3. cmd_predict: 未传入dasha/congregation/vivah_saham/chara_dasha数据 4. Dasha timeline: MD的is_current字段未设置 5. event_prediction_model: status检查不兼容中英混合格式 6. event_prediction_model: Dasha数据格式不匹配(current_dasha vs current_mahadasha) 7. event_prediction_model: Chara Dasha key名不匹配(dasha_sequence vs dasha_list) 8. cmd_predict: 序列化缺少confidence/dasha_signals/transit_signals字段 修复前: predict命令直接fallback到空壳,所有事件概率30%,0信号 修复后: marriage=43%(1静态+1Dasha), career=54%(3Dasha) --- scripts/event_prediction_model.py | 44 ++++++++++++++++++++++--------- scripts/jyotish_engine.py | 32 ++++++++++++++-------- 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/scripts/event_prediction_model.py b/scripts/event_prediction_model.py index d4495230..7ea33848 100644 --- a/scripts/event_prediction_model.py +++ b/scripts/event_prediction_model.py @@ -252,11 +252,13 @@ class EventPredictionModel: if ph == h and pn in target_karakas: pd = self.chart.get('planets', {}).get(pn, {}) status = pd.get('status', '') - if status == 'exalted': + # 支持"擢升(Exalted)"、"落陷(Debilitated)"、"入庙(Own Sign)"等中英混合格式 + status_lower = status.lower() if status else '' + if 'exalted' in status_lower or '擢升' in status: result['signals'].append(f'Karaka {pn}在{h}宫擢升') - elif status == 'own_sign': + elif 'own' in status_lower or '入庙' in status: result['signals'].append(f'Karaka {pn}在{h}宫入庙') - elif status == 'debilitated': + elif 'debilitated' in status_lower or '落陷' in status: result['signals'].append(f'Karaka {pn}在{h}宫落陷(负面)') # 2. 行星聚集分析(使用 congregation_data) @@ -309,8 +311,24 @@ class EventPredictionModel: # ── 2a. Vimshottari Dasha ── if self.dasha: - # 当前 Mahadasha - md_lord = self.dasha.get('current_mahadasha', {}).get('lord', '') + # 适配 full-reading 输出格式:current_dasha.lord + current_dasha.antardasha[] + md_lord = '' + ad_lord = '' + + # 方式1:current_dasha 格式(full-reading输出) + current_md = self.dasha.get('current_dasha') + if current_md and isinstance(current_md, dict): + md_lord = current_md.get('lord', '') + # 从 antardasha 列表中找 is_current=True 的 + for ad in current_md.get('antardasha', []): + if ad.get('is_current'): + ad_lord = ad.get('lord', '') + break + else: + # 方式2:current_mahadasha / current_antardasha 格式 + md_lord = self.dasha.get('current_mahadasha', {}).get('lord', '') + ad_lord = self.dasha.get('current_antardasha', {}).get('lord', '') + if md_lord: md_house = self.planet_houses.get(md_lord, 0) # MD 主星是否关联目标宫位 @@ -326,8 +344,6 @@ class EventPredictionModel: if self.house_lords.get(h) == md_lord: signals.append(f'当前MD {md_lord}是{h}宫主(目标宫)') - # 当前 Antardasha - ad_lord = self.dasha.get('current_antardasha', {}).get('lord', '') if ad_lord: ad_house = self.planet_houses.get(ad_lord, 0) if ad_house in target_houses: @@ -339,28 +355,30 @@ class EventPredictionModel: # MD+AD 组合信号(高权重) if md_lord and ad_lord: - if ad_house in target_houses and md_house in target_houses: + md_house2 = self.planet_houses.get(md_lord, 0) + if ad_house in target_houses and md_house2 in target_houses: signals.append(f'★ MD+AD双激活目标宫位({md_lord}+{ad_lord})') # ── 2b. Chara Dasha (Jaimini) ── if self.chara_dasha: - cd_list = self.chara_dasha.get('dasha_list', []) + # 适配实际格式:dasha_sequence[] 或 dasha_list[] + cd_list = self.chara_dasha.get('dasha_sequence') or self.chara_dasha.get('dasha_list', []) if cd_list: - # 当前 Chara Mahadasha + # 当前 Chara Mahadasha(第一个条目) current_cd = cd_list[0] if cd_list else {} cd_sign = current_cd.get('sign', '') - cd_lord = SIGN_LORDS.get(cd_sign, '') + cd_lord = current_cd.get('lord', '') or SIGN_LORDS.get(cd_sign, '') cd_house = self.planet_houses.get(cd_lord, 0) if cd_house in target_houses: signals.append(f'当前Chara Dasha {cd_sign}({cd_lord})在{cd_house}宫(目标宫)') # Chara Antardasha - antardashas = current_cd.get('antardashas', []) + antardashas = current_cd.get('antardashas') or current_cd.get('antardasha', []) if antardashas: current_ad = antardashas[0] if antardashas else {} ad_sign = current_ad.get('sign', '') - ad_lord_name = SIGN_LORDS.get(ad_sign, '') + ad_lord_name = current_ad.get('lord', '') or SIGN_LORDS.get(ad_sign, '') ad_h = self.planet_houses.get(ad_lord_name, 0) if ad_h in target_houses: signals.append(f'Chara AD {ad_sign}({ad_lord_name})在{ad_h}宫(目标宫)') diff --git a/scripts/jyotish_engine.py b/scripts/jyotish_engine.py index 967fd85d..e7b51999 100644 --- a/scripts/jyotish_engine.py +++ b/scripts/jyotish_engine.py @@ -43,7 +43,7 @@ import csv import math import sqlite3 from datetime import datetime, timedelta -from typing import Dict +from typing import Dict, List # ============================================================================ # 路径常量 @@ -219,7 +219,7 @@ def cmd_dasha(args): for i in range(9): lord = DASHA_ORDER[(si + i) % 9]; years = DASHA_YEARS[lord] end_dt = dt + timedelta(days=years * 365.25) - timeline.append({"lord": lord, "lord_cn": PLANET_CN[lord], "start": dt.strftime("%Y-%m-%d"), "end": end_dt.strftime("%Y-%m-%d"), "years": years}) + timeline.append({"lord": lord, "lord_cn": PLANET_CN[lord], "start": dt.strftime("%Y-%m-%d"), "end": end_dt.strftime("%Y-%m-%d"), "years": years, "is_current": False}) dt = end_dt today = datetime.strptime(args.today, "%Y-%m-%d") if args.today else datetime.now() @@ -227,6 +227,7 @@ def cmd_dasha(args): for d in timeline: ds = datetime.strptime(d["start"], "%Y-%m-%d"); de = datetime.strptime(d["end"], "%Y-%m-%d") if ds <= today < de: + d["is_current"] = True total_days = (de - ds).days; li = DASHA_ORDER.index(d["lord"]) sub = []; sdt = ds for j in range(9): @@ -313,16 +314,21 @@ def cmd_predict(args): try: sys.path.insert(0, SCRIPT_DIR) from event_prediction_model import EventPredictionModel - asc_sign = chart.get("ascendant", {}).get("sign", "Unknown") - planets = chart.get("planets", {}) - # 构建模型需要的行星简化数据 - planet_positions = {} - for pn, pd in planets.items(): - if isinstance(pd, dict) and 'house' in pd: - planet_positions[pn] = {'sign': pd.get('sign', ''), 'house': pd.get('house', 0)} - model = EventPredictionModel(chart_data={"ascendant": asc_sign, "planets": planet_positions}) + # 直接传完整chart数据给EventPredictionModel(v5.0需要ascendant dict和planets dict) + # 同时从 full-reading 输出中提取所有模块数据传入(v5.1修复:之前丢失dasha/congregation等) + modules = chart.get("modules", {}) + model = EventPredictionModel( + chart_data={ + "ascendant": chart.get("ascendant", {}), + "planets": chart.get("planets", {}), + }, + dasha_data=modules.get("dasha"), + congregation_data=modules.get("congregation"), + vivah_saham_data=modules.get("vivah_saham"), + chara_dasha_data=modules.get("jaimini", {}).get("chara_dasha"), + ) raw_preds = model.predict_all_events() - # 将 Prediction dataclass 转为可序列化 dict + # 将 Prediction dataclass 转为可序列化 dict(v5.1补充缺失字段) predictions = [] for p in raw_preds: predictions.append({ @@ -330,9 +336,13 @@ def cmd_predict(args): "description": p.description, "probability": p.probability, "risk_level": str(p.risk_level.value) if hasattr(p.risk_level, 'value') else str(p.risk_level), + "confidence": str(p.confidence.value) if hasattr(p.confidence, 'value') else str(p.confidence), "timing": p.timing, "key_factors": p.key_factors, "recommendations": p.recommendations, + "dasha_signals": p.dasha_signals, + "transit_signals": p.transit_signals, + "timing_windows": p.timing_windows, }) return { "method": "三层验证法(EventPredictionModel规则引擎)",