#!/usr/bin/env python3 """How a Shadbala strength is shown (astrologer rulings 2026-10-03 甲13, BUG-1208). First whether the planet meets the BPHS minimum (BPHS ch. 27 vv. 32-33, the `shadbala.MIN_REQUIRED` table), then the site's own band (150/125/100/75/50 % of that minimum -> 极强…极弱), labelled as the site's band. `shadbala.py` is in the frozen rectification identity, so the fields are added here, at display time, from values the engine already returns; nothing is recomputed. """ from __future__ import annotations from typing import Any, Dict, Optional LEVEL_SOURCE = 'site_band' SITE_BAND_SUFFIX = '(网站分档)' SITE_BAND_SUFFIX_EN = ' (site band)' MEETS_ZH = '达到 BPHS 最低要求' MISSES_ZH = '未达到 BPHS 最低要求' MEETS_EN = 'meets the BPHS minimum' MISSES_EN = 'below the BPHS minimum' def _number(value: Any) -> Optional[float]: return float(value) if isinstance(value, (int, float)) and not isinstance(value, bool) else None def minimum_fields(rupas: Any, min_required: Any, band: Any) -> Dict[str, Any]: """`min_required`, `meets_minimum`, `minimum_check`, band label and source.""" total = _number(rupas) minimum = _number(min_required) meets = None if total is None or minimum is None else total >= minimum fields: Dict[str, Any] = { 'min_required': minimum, 'meets_minimum': meets, 'minimum_check': None if meets is None else (MEETS_ZH if meets else MISSES_ZH), 'level_source': LEVEL_SOURCE, } if band not in (None, ''): fields['level'] = f'{band}{SITE_BAND_SUFFIX}' return fields def row_fields(row: Dict[str, Any]) -> Dict[str, Any]: """Display fields for one `shadbala.calc_shadbala` planet row.""" return minimum_fields(row.get('total_rupas', row.get('rupas')), row.get('min_required'), row.get('strength_level')) BAND_EN = {'极强': 'very strong', '强': 'strong', '充足': 'adequate', '略弱': 'slightly weak', '弱': 'weak', '极弱': 'very weak'} def band_text(band: Any, language: str = 'zh') -> Optional[str]: if band in (None, ''): return None if language == 'en': return f"{BAND_EN.get(str(band), str(band))}{SITE_BAND_SUFFIX_EN}" return f'{band}{SITE_BAND_SUFFIX}' def check_text(meets: Optional[bool], language: str = 'zh') -> str: if meets is None: return '-' if language == 'en': return MEETS_EN if meets else MISSES_EN return MEETS_ZH if meets else MISSES_ZH