fix(yogas): restore English combination text for the five-planet BVR rules; Kemadruma text says nodes are not counted (BUG-1187)
Follow-up to f3ed9509 (TASK-upstream-sync4-20261002 T5). The port dropped
combo_template_en from bvr_002/003/004/016/017/018, so the English edition had
no combination text for them; restored. kemadruma_yoga's text still said "only
the Sun and Moon" although the nodes no longer count. New tests: Ketu alone
next to the Moon leaves Kemadruma in place in both the rule and
detect_kemadruma; Saturn there cancels it and forms Sunaphaa.
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
09c0efc2a1
commit
0a4e6d0aa4
+18
-10
@@ -1306,8 +1306,8 @@
|
||||
"logic": {
|
||||
"type": "custom",
|
||||
"expr": "\n# PyJHora/BVR-5: none of the five true planets (Mars..Saturn) in 1st/2nd/12th from Moon;\n# the Sun and the nodes do not count (sync4 T5, BPHS / Raman 300 Combinations no. 5),\n# and no planets other than Moon in quadrants from Lagna.\nif 'Moon' not in ctx.planets:\n False\nelse:\n moon_h = house_of('Moon')\n moon_zone = {moon_h, ((moon_h - 1 + 1) % 12) + 1, ((moon_h - 1 + 11) % 12) + 1}\n ky1 = all(p in ['Moon', 'Sun', 'Rahu', 'Ketu'] for p, info in ctx.planets.items() if info.get('house') in moon_zone)\n ky2 = all(p == 'Moon' for p, info in ctx.planets.items() if info.get('house') in [1, 4, 7, 10])\n ky1 and ky2\n",
|
||||
"combo_template": "月亮1/2/12宫仅日月,且Lagna角宫仅月亮",
|
||||
"combo_template_en": "Only the Sun and Moon in the 1st/2nd/12th from the Moon, and only the Moon in the Kendras from the Lagna"
|
||||
"combo_template": "月亮1/2/12宫无火水木金土(太阳与罗计不计),且Lagna角宫仅月亮",
|
||||
"combo_template_en": "None of Mars to Saturn in the 1st/2nd/12th from the Moon (the Sun and the nodes are not counted), and only the Moon in the Kendras from the Lagna"
|
||||
},
|
||||
"effects": [
|
||||
"人生艰辛",
|
||||
@@ -9894,7 +9894,8 @@
|
||||
"houses": [
|
||||
2
|
||||
],
|
||||
"combo_template": "{planets}在太阳的第2宫"
|
||||
"combo_template": "{planets}在太阳的第2宫",
|
||||
"combo_template_en": "{planets} in the 2nd from the Sun"
|
||||
},
|
||||
"effects": [
|
||||
"太阳后方有行星支持",
|
||||
@@ -9936,7 +9937,8 @@
|
||||
"houses": [
|
||||
12
|
||||
],
|
||||
"combo_template": "{planets}在太阳的第12宫"
|
||||
"combo_template": "{planets}在太阳的第12宫",
|
||||
"combo_template_en": "{planets} in the 12th from the Sun"
|
||||
},
|
||||
"effects": [
|
||||
"太阳前方有行星铺垫",
|
||||
@@ -9983,7 +9985,8 @@
|
||||
"houses": [
|
||||
2
|
||||
],
|
||||
"combo_template": "{planets}在太阳的第2宫"
|
||||
"combo_template": "{planets}在太阳的第2宫",
|
||||
"combo_template_en": "{planets} in the 2nd from the Sun"
|
||||
},
|
||||
{
|
||||
"type": "has_planet_in_house_from",
|
||||
@@ -10001,7 +10004,8 @@
|
||||
"houses": [
|
||||
12
|
||||
],
|
||||
"combo_template": "{planets}在太阳的第12宫"
|
||||
"combo_template": "{planets}在太阳的第12宫",
|
||||
"combo_template_en": "{planets} in the 12th from the Sun"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -10045,7 +10049,8 @@
|
||||
"houses": [
|
||||
2
|
||||
],
|
||||
"combo_template": "{planets}在月亮的第2宫"
|
||||
"combo_template": "{planets}在月亮的第2宫",
|
||||
"combo_template_en": "{planets} in the 2nd from the Moon"
|
||||
},
|
||||
"effects": [
|
||||
"自力更生",
|
||||
@@ -10089,7 +10094,8 @@
|
||||
"houses": [
|
||||
12
|
||||
],
|
||||
"combo_template": "{planets}在月亮的第12宫"
|
||||
"combo_template": "{planets}在月亮的第12宫",
|
||||
"combo_template_en": "{planets} in the 12th from the Moon"
|
||||
},
|
||||
"effects": [
|
||||
"心智有背景支持",
|
||||
@@ -10136,7 +10142,8 @@
|
||||
"houses": [
|
||||
2
|
||||
],
|
||||
"combo_template": "{planets}在月亮的第2宫"
|
||||
"combo_template": "{planets}在月亮的第2宫",
|
||||
"combo_template_en": "{planets} in the 2nd from the Moon"
|
||||
},
|
||||
{
|
||||
"type": "has_planet_in_house_from",
|
||||
@@ -10154,7 +10161,8 @@
|
||||
"houses": [
|
||||
12
|
||||
],
|
||||
"combo_template": "{planets}在月亮的第12宫"
|
||||
"combo_template": "{planets}在月亮的第12宫",
|
||||
"combo_template_en": "{planets} in the 12th from the Moon"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
"""sync4 T5 follow-up (BUG-1187).
|
||||
|
||||
* Kemadruma: a node alone next to the Moon does not cancel it, in both the rule
|
||||
version (kemadruma_yoga) and yoga_expansion.detect_kemadruma.
|
||||
* The six five-planet BVR rules keep their English combination text (the port
|
||||
dropped combo_template_en, so the English edition fell back to no text).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from scripts.yoga_engine import YogaEngine
|
||||
from scripts.yoga_expansion import detect_kemadruma
|
||||
from tests.test_lunar_solar_yogas_count_five_planets import _chart
|
||||
|
||||
RULES = Path(__file__).resolve().parents[1] / "references" / "yoga_rules.json"
|
||||
|
||||
# Aries lagna; Moon in Taurus, Ketu alone in Gemini (2nd from Moon), Aries (12th) empty,
|
||||
# no planet in Aries / Cancer / Libra / Capricorn (kendras from lagna).
|
||||
ISOLATED = dict(Moon="Taurus", Ketu="Gemini", Rahu="Sagittarius", Sun="Leo", Mars="Leo",
|
||||
Mercury="Virgo", Jupiter="Virgo", Venus="Leo", Saturn="Scorpio")
|
||||
|
||||
|
||||
def test_ketu_next_to_the_moon_does_not_cancel_kemadruma() -> None:
|
||||
planets = _chart(**ISOLATED)
|
||||
names = {row["name"] for row in YogaEngine(str(RULES)).detect(planets, "Aries")}
|
||||
assert "Kemadruma Yoga" in names
|
||||
assert not {"Sunaphaa Yoga", "Anaphaa Yoga", "Duradhara Yoga"} & names
|
||||
assert detect_kemadruma(planets)["present"] is True
|
||||
|
||||
|
||||
def test_saturn_next_to_the_moon_cancels_kemadruma() -> None:
|
||||
planets = _chart(**{**ISOLATED, "Saturn": "Gemini"})
|
||||
names = {row["name"] for row in YogaEngine(str(RULES)).detect(planets, "Aries")}
|
||||
assert "Kemadruma Yoga" not in names
|
||||
assert "Sunaphaa Yoga" in names
|
||||
assert detect_kemadruma(planets)["present"] is False
|
||||
|
||||
|
||||
def _templates(node, acc):
|
||||
if isinstance(node, dict):
|
||||
if "combo_template" in node:
|
||||
acc.append(node)
|
||||
for value in node.values():
|
||||
_templates(value, acc)
|
||||
elif isinstance(node, list):
|
||||
for value in node:
|
||||
_templates(value, acc)
|
||||
return acc
|
||||
|
||||
|
||||
def test_five_planet_bvr_rules_keep_english_combination_text() -> None:
|
||||
rules = {rule["id"]: rule for rule in json.loads(RULES.read_text(encoding="utf-8"))["rules"]}
|
||||
for rule_id in ("bvr_002_sunapha_precise", "bvr_003_anapha_precise", "bvr_004_duradhara_precise",
|
||||
"bvr_016_vesi_precise", "bvr_017_vosi_precise", "bvr_018_ubhayachara_precise",
|
||||
"kemadruma_yoga"):
|
||||
conditions = _templates(rules[rule_id]["logic"], [])
|
||||
assert conditions, rule_id
|
||||
for cond in conditions:
|
||||
assert cond.get("combo_template_en"), rule_id
|
||||
Reference in New Issue
Block a user