feat: add yoga logic validation and varga fixes

This commit is contained in:
732642856
2026-06-05 14:30:20 +08:00
parent ad69744617
commit 8da45c56b3
19 changed files with 34872 additions and 700 deletions
+76
View File
@@ -0,0 +1,76 @@
#!/usr/bin/env python3
"""用PyJhora计算单张星盘的Yoga列表 - 被build_standard_test_charts.py调用"""
import sys, json, os, datetime, io
# 抑制PyJhora的所有输出(stdout + stderr + logging
class SuppressAll:
def __enter__(self):
self._stdout = sys.stdout
self._stderr = sys.stderr
sys.stdout = io.StringIO()
sys.stderr = io.StringIO()
return self
def __exit__(self, *a):
sys.stdout = self._stdout
sys.stderr = self._stderr
try:
with SuppressAll():
from jhora.horoscope.chart import yoga as yoga_mod
from jhora.panchanga.drik import Place
import jhora.utils as utils
PYJHORA_OK = True
except Exception as e:
PYJHORA_OK = False
IMPORT_ERR = str(e)
def tz_to_float(tz_str):
"""将 +05:30 格式转为 5.5 小时浮点数"""
tz_str = tz_str.strip()
sign = -1 if tz_str.startswith('-') else 1
tz_str = tz_str.lstrip('+-')
parts = tz_str.split(':')
hours = int(parts[0])
minutes = int(parts[1]) if len(parts) > 1 else 0
return sign * (hours + minutes / 60.0)
def compute_yogas(chart):
"""计算给定星盘的所有Yoga"""
if not PYJHORA_OK:
return {"error": f"PyJhora import failed: {IMPORT_ERR}"}
try:
with SuppressAll():
# 构造Place对象(timezone是浮点数小时)
tz = tz_to_float(chart["tz"])
place = Place(chart["city"], chart["lat"], chart["lon"], tz)
# 构造datetime并转JD
date_str = chart["date"] + " " + chart["time"]
if date_str.count(':') == 1:
date_str += ":00"
dt = datetime.datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
jd = utils.gregorian_to_jd(dt)
# 计算 D1/Rasi Yoga。v2 逻辑正确性验证必须与 Skill 的 D1 Yoga 引擎逐层对齐;
# 不能使用 get_yoga_details_for_all_charts(),否则会把 D2/D9/D10 等分盘 Yoga 混入,
# 造成大量“Skill 漏检”的假阴性。
result = yoga_mod.get_yoga_details(jd, place, divisional_chart_factor=1)
yogas = list(result[0].keys()) if result and len(result) > 0 else []
return {"yogas": yogas, "count": len(yogas), "status": "ok"}
except Exception as e:
return {"error": str(e)}
if __name__ == "__main__":
if len(sys.argv) >= 2:
chart = json.loads(sys.argv[1])
else:
# Read from stdin
raw = sys.stdin.read()
if not raw.strip():
print(json.dumps({"error": "No chart data"}))
sys.exit(1)
chart = json.loads(raw)
result = compute_yogas(chart)
# 最后一行必须是纯净JSON
print(json.dumps(result, ensure_ascii=False))