公众授权版:normal · 1000 次 · 有效期至 2026-12-31
副本编号 LY-20261007-AC63(水印指纹已嵌入) 含 README、.gitignore;排除 .DS_Store / __pycache__ / .pytest_cache
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
"""L1→L2 数据契约(文档 4.7 节)。
|
||||
|
||||
改动本文件等于改契约版本(schema_version)。
|
||||
本模块只做数据定义与组装,不含任何命理判断(P1)。
|
||||
"""
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class Pillar:
|
||||
gan: str
|
||||
zhi: str
|
||||
gan_ten_god: str | None = None # 该柱天干相对日干的十神
|
||||
hidden_stems: list[str] = field(default_factory=list) # 藏干
|
||||
hidden_ten_gods: list[str] = field(default_factory=list)
|
||||
na_yin: str | None = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class LuckPillar:
|
||||
index: int
|
||||
gan: str
|
||||
zhi: str
|
||||
start_age: float
|
||||
start_year: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class ChartData:
|
||||
# —— 输入 ——
|
||||
name: str
|
||||
gender: str
|
||||
birthplace: str
|
||||
birth_clock: str # 用户原始输入
|
||||
|
||||
# —— 时间归算审计(P3)——
|
||||
tz_used: str
|
||||
is_dst: bool
|
||||
lon_correction_min: float
|
||||
eot_minutes: float
|
||||
true_solar_time: str
|
||||
is_late_zi: bool
|
||||
|
||||
# —— 四柱 ——
|
||||
year: Pillar
|
||||
month: Pillar
|
||||
day: Pillar
|
||||
hour: Pillar
|
||||
|
||||
# —— 派生 ——
|
||||
day_master: str # 日干
|
||||
month_ling: str # 月令地支(取格之锚)
|
||||
solar_term_before: str # 出生前一个节气
|
||||
solar_term_after: str # 出生后一个节气
|
||||
luck_pillars: list[LuckPillar] = field(default_factory=list)
|
||||
|
||||
# —— 派生(渲染层补充字段)——
|
||||
luck_is_forward: bool = False # 大运顺排/逆排
|
||||
start_age_text: str = "" # 起运年龄,如「7 岁 7 个月 19 天」
|
||||
terrain: dict[str, str] = field(default_factory=dict) # 四柱键 → 十二长生
|
||||
void: dict[str, str] = field(default_factory=dict) # {"day": .., "hour": ..}
|
||||
shen_sha: list[str] = field(default_factory=list) # 神煞
|
||||
flow_years: list[tuple[int, str]] = field(default_factory=list) # 流年 (年份, 干支)
|
||||
flow_months: list[tuple[str, str]] = field(default_factory=list) # 流月 (标签, 干支)
|
||||
tai_yuan: str = "" # 胎元
|
||||
ming_gong: str = "" # 命宫
|
||||
|
||||
# —— 溯源 ——
|
||||
library_version: str = "" # tyme4py 版本,写入输出
|
||||
schema_version: str = "1.0"
|
||||
|
||||
|
||||
def _fmt_dt(dt: datetime) -> str:
|
||||
return dt.strftime("%Y-%m-%d %H:%M")
|
||||
|
||||
|
||||
def _fmt_term(term: dict) -> str:
|
||||
"""{"name", "time"} → 「节气名 YYYY-MM-DD HH:MM」"""
|
||||
return f"{term['name']} {_fmt_dt(term['time'])}"
|
||||
|
||||
|
||||
def _build_pillar(key: str, raw: dict) -> Pillar:
|
||||
gz = raw[key]
|
||||
hidden_pairs = raw.get("hidden", {}).get(key, [])
|
||||
return Pillar(
|
||||
gan=gz["gan"],
|
||||
zhi=gz["zhi"],
|
||||
gan_ten_god=raw.get("ten_god", {}).get(key),
|
||||
hidden_stems=[pair[0] for pair in hidden_pairs],
|
||||
hidden_ten_gods=[pair[1] for pair in hidden_pairs],
|
||||
na_yin=raw.get("na_yin", {}).get(key),
|
||||
)
|
||||
|
||||
|
||||
def build_chart_data(
|
||||
name: str,
|
||||
gender: str,
|
||||
place: str,
|
||||
clock: str,
|
||||
loc,
|
||||
tz_audit: dict,
|
||||
st_audit: dict,
|
||||
bd_audit: dict,
|
||||
raw: dict,
|
||||
luck: dict,
|
||||
luck_pillars: list[LuckPillar],
|
||||
flow_years: list[tuple[int, str]],
|
||||
flow_months: list[tuple[str, str]],
|
||||
) -> ChartData:
|
||||
"""把 tyme_adapter 的原始 dict、各层 audit 与 luck 结果组装成 ChartData。
|
||||
|
||||
纯组装,零命理判断。
|
||||
"""
|
||||
return ChartData(
|
||||
# 输入
|
||||
name=name,
|
||||
gender=gender,
|
||||
birthplace=place,
|
||||
birth_clock=clock,
|
||||
# 时间归算审计
|
||||
tz_used=tz_audit["tz_used"],
|
||||
is_dst=tz_audit["is_dst"],
|
||||
lon_correction_min=st_audit["lon_correction_min"],
|
||||
eot_minutes=st_audit["eot_minutes"],
|
||||
true_solar_time=_fmt_dt(st_audit["tst"]),
|
||||
is_late_zi=bd_audit["is_late_zi"],
|
||||
# 四柱
|
||||
year=_build_pillar("year", raw),
|
||||
month=_build_pillar("month", raw),
|
||||
day=_build_pillar("day", raw),
|
||||
hour=_build_pillar("hour", raw),
|
||||
# 派生
|
||||
day_master=raw["day_master"],
|
||||
month_ling=raw["month"]["zhi"],
|
||||
solar_term_before=_fmt_term(raw["prev_jie"]),
|
||||
solar_term_after=_fmt_term(raw["next_jie"]),
|
||||
luck_pillars=luck_pillars,
|
||||
# 派生(补充字段)
|
||||
luck_is_forward=luck["is_forward"],
|
||||
start_age_text=luck["start_age_text"],
|
||||
terrain=raw.get("terrain", {}),
|
||||
void=raw.get("void", {}),
|
||||
shen_sha=raw.get("shen_sha", []),
|
||||
flow_years=flow_years,
|
||||
flow_months=flow_months,
|
||||
tai_yuan=raw.get("tai_yuan", ""),
|
||||
ming_gong=raw.get("ming_gong", ""),
|
||||
# 溯源
|
||||
library_version=raw.get("library_version", ""),
|
||||
)
|
||||
Reference in New Issue
Block a user