feat(bhava-bala): reports use the formal three components; local +2/-1.5 score hidden (T4, BUG-1210)
Astrologer ruling 甲13. shadbala.calc_bhava_bala renamed calc_local_bhava_score and removed from calc_shadbala's result (it fed the report's Bhava Bala table). New bhava_bala.bhava_bala_from_chart (Bhavadhipati = lord's Shadbala virupas, Bhava Dig, Bhava Drishti; equal houses as /api/bhava_bala; total and total_rupas; the module's invented level bands not shown) drives modules.bhava_bala in the full reading. Reader table: Bhavadhipati | Dig | Drishti | Total (Virupa) | Total (Rupa); reference edition table and wealth/summary lines read the formal totals. Other users of the local score: none outside shadbala.py (remedies and health narrative read Shadbala rupas only). Changed assertions (three columns in PROGRESS): test_shadbala_complete local-score tests renamed; test_report_longform_gaps2 fixture rows and heading. 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
ea78804b78
commit
6feb1a4aaa
@@ -244,3 +244,44 @@ def calc_bhava_bala(house_signs: List[str], house_degrees: List[float],
|
||||
'strongest_house': max(houses, key=lambda h: h['total'])['house'],
|
||||
'weakest_house': min(houses, key=lambda h: h['total'])['house'],
|
||||
}
|
||||
|
||||
|
||||
def bhava_bala_from_chart(planets: Dict, asc_sign: str, asc_degree: float, shadbala_planets: Dict) -> Dict:
|
||||
"""Formal three-component Bhava Bala for one D1 chart (BUG-1210, ruling 甲13).
|
||||
|
||||
`planets` rows carry `sign` and a degree (`degree_in_sign`, `degree` or a
|
||||
longitude); `shadbala_planets` is `shadbala.calc_shadbala(...)['planets']`,
|
||||
whose `total_virupas` is each lord's Shadbala (Bhavadhipati Bala). Houses are
|
||||
equal houses from the Lagna degree, as `/api/bhava_bala` uses. Totals are in
|
||||
Virupas; `total_rupas` = total / 60. The `level` bands of `calc_bhava_bala`
|
||||
are not a classical scale and are not displayed.
|
||||
"""
|
||||
if asc_sign not in SIGNS:
|
||||
return {}
|
||||
asc_idx = SIGNS.index(asc_sign)
|
||||
house_signs = [SIGNS[(asc_idx + i) % 12] for i in range(12)]
|
||||
house_degrees = [float(asc_degree) % 30 for _ in range(12)]
|
||||
positions = {}
|
||||
for name, row in (planets or {}).items():
|
||||
if not isinstance(row, dict) or row.get('sign') not in SIGNS:
|
||||
continue
|
||||
degree = row.get('degree_in_sign')
|
||||
if degree is None:
|
||||
degree = row.get('degree', 0)
|
||||
positions[name] = {'sign': row['sign'], 'degree': float(degree or 0) % 30}
|
||||
virupas = {}
|
||||
for name, row in (shadbala_planets or {}).items():
|
||||
value = row.get('total_virupas') if isinstance(row, dict) else None
|
||||
if isinstance(value, (int, float)):
|
||||
virupas[name] = float(value)
|
||||
if len(virupas) < 7:
|
||||
return {}
|
||||
result = calc_bhava_bala(house_signs, house_degrees, asc_sign, float(asc_degree) % 30, positions, virupas)
|
||||
for house in result['houses']:
|
||||
house['lord'] = SIGN_LORDS.get(house['sign'])
|
||||
house['total_rupas'] = round(house['total'] / 60.0, 2)
|
||||
house.pop('level', None)
|
||||
result['method'] = 'Bhava Bala 三分量:Bhavadhipati(宫主 Shadbala)+ Bhava Dig + Bhava Drishti(jyotishganit MIT 算法,等宫)'
|
||||
result['unit'] = 'virupa'
|
||||
result['source'] = 'scripts/bhava_bala.py'
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user