rebuild(stage-11): deliver deterministic heaven workflows
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
TRIGRAM_NAMES = {
|
||||
(1, 1, 1): "乾",
|
||||
(1, 1, 0): "兑",
|
||||
(1, 0, 1): "离",
|
||||
(1, 0, 0): "震",
|
||||
(0, 1, 1): "巽",
|
||||
(0, 1, 0): "坎",
|
||||
(0, 0, 1): "艮",
|
||||
(0, 0, 0): "坤",
|
||||
}
|
||||
LINE_POSITIONS = ("初爻", "二爻", "三爻", "四爻", "五爻", "上爻")
|
||||
|
||||
|
||||
def from_lines(values: list[int], data_path: Path) -> dict[str, Any]:
|
||||
if len(values) != 6 or any(value not in {6, 7, 8, 9} for value in values):
|
||||
raise ValueError("六爻必须由六、七、八、九组成,且从初爻到上爻排列。")
|
||||
bits = tuple(1 if value % 2 else 0 for value in values)
|
||||
transformed_values = [7 if value == 6 else 8 if value == 9 else value for value in values]
|
||||
transformed_bits = tuple(1 if value % 2 else 0 for value in transformed_values)
|
||||
data = _load(data_path)
|
||||
primary = data.get(str(bits))
|
||||
transformed = data.get(str(transformed_bits))
|
||||
if not primary or not transformed:
|
||||
raise ValueError("卦象数据不完整。")
|
||||
line_texts = list(primary["lines"].values())
|
||||
lines = [
|
||||
{
|
||||
"position": index + 1,
|
||||
"position_name": LINE_POSITIONS[index],
|
||||
"value": value,
|
||||
"yin_yang": "阳" if value % 2 else "阴",
|
||||
"moving": value in {6, 9},
|
||||
"line_name": line_texts[index]["name"],
|
||||
"text": line_texts[index]["text"],
|
||||
"image": line_texts[index].get("image") or "",
|
||||
}
|
||||
for index, value in enumerate(values)
|
||||
]
|
||||
return {
|
||||
"name": primary["name"],
|
||||
"text": primary["text"],
|
||||
"image": primary.get("image") or "",
|
||||
"inner_trigram": TRIGRAM_NAMES[bits[:3]],
|
||||
"outer_trigram": TRIGRAM_NAMES[bits[3:]],
|
||||
"lines": lines,
|
||||
"moving_lines": [index + 1 for index, value in enumerate(values) if value in {6, 9}],
|
||||
"transformed": {
|
||||
"name": transformed["name"],
|
||||
"text": transformed["text"],
|
||||
"image": transformed.get("image") or "",
|
||||
"inner_trigram": TRIGRAM_NAMES[transformed_bits[:3]],
|
||||
"outer_trigram": TRIGRAM_NAMES[transformed_bits[3:]],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def line_for_score(score: float) -> int:
|
||||
if score >= 0.72:
|
||||
return 9
|
||||
if score >= 0:
|
||||
return 7
|
||||
if score <= -0.72:
|
||||
return 6
|
||||
return 8
|
||||
|
||||
|
||||
@lru_cache(maxsize=2)
|
||||
def _load(path: Path) -> dict[str, Any]:
|
||||
payload = json.loads(path.read_text(encoding="utf-8"))
|
||||
return payload.get("hexagrams", payload)
|
||||
Reference in New Issue
Block a user