Files
ZiPingEightChar/tests/test_luck.py
T
moxiaonian 618bf8dcab v3.4:童限小运、全量流年与节气边界提示;解释输出契约 v3.0 直答先行
排盘输出 schema 1.1→1.2:
- ## 流年 改为出生年至今+10 年全量,逐年标注所属区间(童限/某运/交运年)
- 新增 ## 小运(童限各虚岁干支,自时柱起、一位一岁、顺逆同大运)
- 生于交节前后 12 小时内出 ⚠️ 节气边界提示(月令敏感性)
- 神煞改由脚本按查法直接计算并列锚点;新增 scripts/query_shensha.py 查岁运神煞

规则库 380→541(16→20 文件,版本 3.4):
- 新增 89_旺衰扶抑 / 91_何知事类 / 92_调候 / 93_性情(滴天髓、穷通宝鉴参看层)
- 90_行运.md 新增 §10 童限(R-运-36~39,蒸馏《命理探源》《三命通会》小运诸法)
- R-运-33 改写为核对前置:intake 一问定场景,可核对走锚点、不可核对直推,输出只出现一次
- R-运-32 增前提挑战、直答收敛(一个主答案+置信度)、同机制证伪降权
- R-运-34 增救应回查(合绊解冲折减引动并回写排序);R-运-10 补「缓急非早晚」之辨
- 94 神煞扩展 19 条(三命通会书证);规则编号记录移调试层
- sources 按书归档五书全文;黄金集扩至 291 例(真诠 92 + 滴天髓 199)

SKILL.md 输出契约 v2.1→v3.0:
- 骨架改为 排盘口径→直答→现实对应→分析推理→存疑与边界→免责
- 说人话段改现实对应段(问题域优先);编号默认不进用户面输出
- Intake 增场景判定一问(命主本人/替人看/能否核对)

测试:新增 test_luck.py 9 项,全套 65 项通过
2026-10-08 13:07:23 +08:00

69 lines
2.4 KiB
Python

"""流年/小运/大运标签单元测试(schema 1.2)。"""
import sys
import unittest
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "scripts"))
from chart.luck import ( # noqa: E402
childhood_luck, decade_pillars, flow_years, ganzhi_of_year,
luck_label_for_year,
)
from chart.model import LuckPillar # noqa: E402
class FlowYearsTest(unittest.TestCase):
def test_ganzhi_of_year(self):
self.assertEqual(ganzhi_of_year(2007), "丁亥")
self.assertEqual(ganzhi_of_year(2026), "丙午")
def test_full_range_from_birth_year(self):
years = flow_years(2007, 2026, 10)
self.assertEqual(years[0], (2007, "丁亥"))
self.assertEqual(years[-1], (2035, "乙卯"))
self.assertEqual(len(years), 29)
self.assertIn((2013, "癸巳"), years)
class ChildhoodLuckTest(unittest.TestCase):
def test_forward(self):
# 阴年女命顺行:时柱辛巳 → 1 岁壬午、2 岁癸未……10 岁辛卯
rows = childhood_luck("辛", "巳", True, 10.34, 2007)
self.assertEqual(rows[0], (1, 2007, "壬午"))
self.assertEqual(rows[1], (2, 2008, "癸未"))
self.assertEqual(rows[-1], (10, 2016, "辛卯"))
self.assertEqual(len(rows), 10)
def test_backward(self):
rows = childhood_luck("辛", "巳", False, 3.0, 2000)
self.assertEqual(rows[0], (1, 2000, "庚辰"))
self.assertEqual(rows[-1], (3, 2002, "戊寅"))
def test_empty_when_luck_starts_under_one(self):
self.assertEqual(childhood_luck("辛", "巳", True, 0.34, 2007), [])
class LuckLabelTest(unittest.TestCase):
def setUp(self):
self.pillars = [
LuckPillar(index=1, gan="丙", zhi="午", start_age=10.34, start_year=2017),
LuckPillar(index=2, gan="丁", zhi="未", start_age=20.34, start_year=2027),
]
def test_childhood(self):
self.assertEqual(luck_label_for_year(2013, self.pillars), "童限")
def test_boundary_year(self):
self.assertEqual(luck_label_for_year(2017, self.pillars), "交运年·入丙午运")
def test_inside_pillar(self):
self.assertEqual(luck_label_for_year(2020, self.pillars), "丙午运")
self.assertEqual(luck_label_for_year(2030, self.pillars), "丁未运")
def test_no_pillars(self):
self.assertEqual(luck_label_for_year(2020, []), "童限")
if __name__ == "__main__":
unittest.main()