fix(jaimini): 8-karaka order follows BPHS ch. 32 (PiK 5th, DK 8th) (T6, BUG-1204)
KARAKA_8 put Putrakaraka 5th, Darakaraka 7th and Pitrukaraka 8th. BPHS ch. 32 order with Rahu counted is AK, AmK, BK, MK, PiK, PK, GK, DK. Test pins the table and a public AA chart (Steve Jobs, Raman, mean nodes) plus the reader report's live 8-karaka rows. jaimini.py is in the frozen rectification identity; re-freeze follows in a separate commit (rectification does not read karakas). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
60d065a8cf
commit
0cf2249e6b
+5
-2
@@ -49,10 +49,13 @@ KARAKA_7 = {
|
||||
7: 'Darakaraka', # DK - 配偶(度数最低)
|
||||
}
|
||||
|
||||
# 8星制(含Rahu,用绝对度数)
|
||||
# 8星制(含Rahu;Rahu 按 30° 减星座内度数排位)。BPHS 第 32 章次序:
|
||||
# AK、AmK、BK、MK、PiK、PK、GK、DK,即 PiK 第 5、PK 第 6、GK 第 7、DK 第 8
|
||||
# (度数最低者为 DK)。旧表把第 5/7/8 位写成 PK/DK/PiK(BUG-1204,上游
|
||||
# yinduzhanxing 同样写错)。
|
||||
KARAKA_8 = {
|
||||
1: 'Atmakaraka', 2: 'Amatyakaraka', 3: 'Bhratrikaraka', 4: 'Matrikaraka',
|
||||
5: 'Putrakaraka', 6: 'Gnatikaraka', 7: 'Darakaraka', 8: 'Pitrukaraka',
|
||||
5: 'Pitrukaraka', 6: 'Putrakaraka', 7: 'Gnatikaraka', 8: 'Darakaraka',
|
||||
}
|
||||
|
||||
KARAKA_CN = {
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
"""8-karaka Chara Karaka order follows BPHS ch. 32 (BUG-1204).
|
||||
|
||||
BPHS ch. 32 (Karakas): with Rahu counted, the eight roles in descending
|
||||
order of degrees are Atma, Amatya, Bhratru, Matru, Pitru, Putra, Gnati, Dara;
|
||||
Rahu ranks by 30 minus its degree in sign. The old table put Putra 5th, Dara
|
||||
7th and Pitru 8th (TASK-astrologer-rulings-batch1-20261003 T6).
|
||||
|
||||
Public chart: Steve Jobs, Astro-Databank AA (repository development case
|
||||
library), Raman ayanamsa, mean nodes.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from scripts.jaimini import KARAKA_7, KARAKA_8, calc_chara_karaka_8
|
||||
from scripts.jyotish_engine import compute_chart_data
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
BPHS_8 = ["Atmakaraka", "Amatyakaraka", "Bhratrikaraka", "Matrikaraka",
|
||||
"Pitrukaraka", "Putrakaraka", "Gnatikaraka", "Darakaraka"]
|
||||
|
||||
|
||||
def _jobs_degrees() -> dict[str, float]:
|
||||
cases = json.loads((ROOT / "references/real_case_calibration/minute_rectification_development_v1.json").read_text(encoding="utf-8"))["cases"]
|
||||
birth = next(case for case in cases if case["case_id"] == "steve_jobs_1955_development")["birth"]
|
||||
assert birth["source"]["rodden_rating"] == "AA"
|
||||
year, month, day = (int(part) for part in birth["date"].split("-"))
|
||||
hour, minute = (int(part) for part in birth["time"].split(":"))
|
||||
chart, *_ = compute_chart_data(year, month, day, hour, minute, birth["latitude"], birth["longitude"],
|
||||
birth["timezone_offset"], ayanamsa_name="raman")
|
||||
return {name: row["degree_raw"] % 30 for name, row in chart["planets"].items()}
|
||||
|
||||
|
||||
def test_table_is_the_bphs_order() -> None:
|
||||
assert [KARAKA_8[rank] for rank in range(1, 9)] == BPHS_8
|
||||
# The 7-karaka scheme (no Pitrukaraka) is unchanged.
|
||||
assert [KARAKA_7[rank] for rank in range(1, 8)] == [
|
||||
"Atmakaraka", "Amatyakaraka", "Bhratrikaraka", "Matrikaraka", "Putrakaraka", "Gnatikaraka", "Darakaraka"]
|
||||
|
||||
|
||||
def test_public_chart_roles_follow_bphs_ranking() -> None:
|
||||
degrees = _jobs_degrees()
|
||||
effective = {name: (30.0 - value) % 30.0 if name == "Rahu" else value
|
||||
for name, value in degrees.items() if name != "Ketu"}
|
||||
expected_order = sorted(effective, key=effective.get, reverse=True)
|
||||
table = calc_chara_karaka_8(degrees)["karaka_table_8"]
|
||||
assert {role: row["planet"] for role, row in table.items()} == dict(zip(BPHS_8, expected_order))
|
||||
assert {role: row["rank"] for role, row in table.items()} == {role: rank for rank, role in enumerate(BPHS_8, 1)}
|
||||
# Lowest effective degree is Dara; Pitru sits between Matru and Putra.
|
||||
assert table["Darakaraka"]["planet"] == min(effective, key=effective.get)
|
||||
assert table["Matrikaraka"]["effective_degree_in_sign"] >= table["Pitrukaraka"]["effective_degree_in_sign"] >= table["Putrakaraka"]["effective_degree_in_sign"]
|
||||
# This chart's own values (Raman, mean nodes): Rahu at 10.72° ranks by 19.28°.
|
||||
assert table["Pitrukaraka"]["planet"] == "Rahu"
|
||||
assert table["Darakaraka"]["planet"] == "Mars"
|
||||
assert table["Putrakaraka"]["planet"] == "Moon"
|
||||
|
||||
|
||||
def test_reader_report_karaka_table_is_in_bphs_order() -> None:
|
||||
"""Live render of a fictional chart: the reader's 8-karaka rows run AK..DK."""
|
||||
import copy
|
||||
|
||||
from scripts.jaimini import KARAKA_CN
|
||||
from scripts.pl9_reader_export import _pl9_export_markdown_for_edition
|
||||
from tests.test_report_english_edition import CASES, _packet
|
||||
|
||||
packet = _packet(CASES["day"])
|
||||
markdown = _pl9_export_markdown_for_edition(copy.deepcopy(packet), "reader_main")
|
||||
lines = markdown.splitlines()
|
||||
start = next(i for i, line in enumerate(lines) if line.startswith("### Jaimini Karaka"))
|
||||
rows = [line for line in lines[start + 1:start + 14] if line.startswith("| ") and "星" in line.split("|")[1]]
|
||||
assert [row.split("|")[1].strip() for row in rows] == [KARAKA_CN[role] for role in BPHS_8]
|
||||
Reference in New Issue
Block a user