Files
Jyotisha/scripts/avastha_calculator.py
T
Jesse_ChenandClaude Opus 5.5 982c53dd17 fix(avastha): mark Shayanadi blocked when there is no sunrise instead of dropping the table
Polar day or night left determine_daytime without a sunrise, so the whole
avasthas module failed after the PVR activity formula was wired in. Only
the Shayanadi cell is blocked now; the other four states still compute
(BUG-1390).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HwMNZEzdzmrbPhuRNmZe3C
2026-10-18 18:46:02 +08:00

605 lines
26 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Avastha Calculator - 行星状态计算器
印度占星 Avastha(行星状态)系统
核心功能:
- Bala Avastha(年龄状态):5种生命阶段
- Jagrat Avastha(警觉状态):3种意识状态
- Deeptadi Avastha(情绪状态):15种情绪/能量状态
- Lajjitadi Avastha(羞耻状态):6种社会状态
- Shayanadi Avastha(姿态状态):12种行为模式
参考文献:
- Brihat Parashara Hora Shastra (BPHS) Chapter 47-48
- Phaladeepika by Mantreswara
- Jataka Parijata by Vaidyanatha Dikshita
"""
from typing import Dict, List, Tuple
from enum import Enum
import json
import math
from bisect import bisect_right
from pathlib import Path
with (Path(__file__).resolve().parents[1] / 'references' / 'shat_bala_constants.json').open(encoding='utf-8') as _handle:
NATURAL_RELATIONSHIPS = json.load(_handle)['natural_relationships']
SIGNS = ['Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo',
'Libra', 'Scorpio', 'Sagittarius', 'Capricorn', 'Aquarius', 'Pisces']
def calculate_pvr_shayanadi(planet, longitude, moon_longitude, asc_longitude, hours_since_sunrise):
"""PVR §15.4.4/Table 36; running ghati, not elapsed fractional ghatis.
Activity intensity requires the name's Sanskrit first-sound index and is
deliberately not guessed from an English display name.
"""
order = ('Sun', 'Moon', 'Mars', 'Mercury', 'Jupiter', 'Venus', 'Saturn', 'Rahu', 'Ketu')
if planet not in order:
raise ValueError('Unsupported Shayanadi planet')
values = (longitude, moon_longitude, asc_longitude, hours_since_sunrise)
if any(isinstance(value, bool) or not math.isfinite(float(value)) for value in values):
raise ValueError('Finite numeric Shayanadi inputs required')
if hours_since_sunrise < 0:
raise ValueError('Use the preceding sunrise, not a future sunrise')
longitude, moon_longitude, asc_longitude = (float(value) % 360 for value in values[:3])
boundaries = [i * 40 / 3 for i in range(1, 27)]
c = bisect_right(boundaries, longitude) + 1
p = order.index(planet) + 1
a = bisect_right([i * 10 / 3 for i in range(1, 9)], longitude % 30) + 1
m = bisect_right(boundaries, moon_longitude) + 1
g = math.floor(hours_since_sunrise * 2.5) + 1
l = int(asc_longitude // 30) + 1
total = c * p * a + m + g + l
index = (total - 1) % 12 + 1
states = ('Shayana', 'Upaveshana', 'Netrapani', 'Prakashana', 'Gamana', 'Agamana',
'Sabha', 'Agama', 'Bhojana', 'Nrityalipsa', 'Kautuka', 'Nidra')
return {
'state': states[index - 1],
'state_index': index,
'sign': SIGNS[int(longitude // 30)],
'meaning': 'Activity state from the PVR constellation, navamsa and running-ghati formula.',
'method_status': 'pvr_15_4_4_running_ghati',
'components': {
'planet_nakshatra': c,
'planet_index': p,
'navamsa_part': a,
'moon_nakshatra': m,
'running_ghati': g,
'lagna_sign_number': l,
'formula_sum': total,
},
'activity_intensity_status': 'requires_name_first_sound_index',
}
class BalaAvastha(Enum):
"""年龄状态(5种生命阶段)"""
INFANT = "Infant" # 婴儿期(0-6度)
YOUNG = "Young" # 少年期(6-12度)
YOUTH = "Youth" # 青年期(12-18度)
OLD = "Old" # 老年期(18-24度)
DEAD = "Dead" # 死亡期(24-30度)
class JagratAvastha(Enum):
"""警觉状态(3种意识状态)"""
AWAKE = "Awake" # 清醒(Jagrat)
DREAMING = "Dreaming" # 梦境(Swapna)
DEEP_SLEEP = "Deep Sleep" # 深睡(Sushupti)
class DeeptadiAvastha(Enum):
"""情绪状态(15种)- Deeptadi Avastha"""
DEEPTA = "Deepta" # 光辉(Exalted)
SWASTHA = "Swastha" # 舒适(Own Sign)
MUDITA = "Mudita" # 快乐(Friend's Sign)
SHANTA = "Shanta" # 平静(Friend's Sign)
DINA = "Dina" # 低落(Neutral Sign)
DUHKHITA = "Duhkhita" # 困苦(Enemy Sign)
VIKALA = "Vikala" # 残缺(Joined by malefics)
KHALA = "Khala" # 负担(Debilitated; Science of Light)
KOPA = "Kopa" # 愤怒(Combust)
GARVITA = "Garvita" # 骄傲(Victorious in War)
KSHUDITA = "Kshudita" # 饥饿(In Sandhi)
TRUSHITA = "Trushita" # 口渴(In Gandanta)
MUDITA_SPECIAL = "Mudita" # 特殊快乐(Aspected by Jupiter)
KSHOBHITA = "Kshobhita" # 激动(Aspected by Mars)
LAJJITA = "Lajjita" # 羞耻(Aspected by Saturn)
GARVITA_SPECIAL = "Garvita" # 特殊骄傲(Aspected by Mercury)
class LajjitadiAvastha(Enum):
"""羞耻状态(6种社会状态)"""
LAJJITA = "Lajjita" # 羞耻(与敌对行星同宫)
GARVITA = "Garvita" # 骄傲(入庙)
KSHUDITA = "Kshudita" # 饥饿(在6/8/12宫)
TRUSHITA = "Trushita" # 口渴(在火象星座)
MUDITA = "Mudita" # 快乐(与友好行星同宫)
KSHOBHITA = "Kshobhita" # 激动(与火星同宫)
class ShayanadiAvastha(Enum):
"""姿态状态(12种行为模式)"""
SHAYANA = "Shayana" # 躺卧(在水象星座)
UPAVESHANA = "Upaveshana" # 坐着(在土象星座)
NETRAPANI = "Netrapani" # 手持武器(在火象星座)
PRAKASHANA = "Prakashana" # 显现(在风象星座)
GAMANA = "Gamana" # 行走(在双体星座)
AGAMANA = "Agamana" # 到来(在固定星座)
SABHA = "Sabha" # 集会(在变动星座)
AGAMA = "Agama" # 学习(在水星星座)
BHOJANA = "Bhojana" # 进食(在金星星座)
NRITYALIPSA = "Nrityalipsa" # 舞蹈(在月亮星座)
KAUTUKA = "Kautuka" # 好奇(在木星星座)
NIDRA = "Nidra" # 睡眠(在土星星座)
class AvasthaCalculator:
"""行星状态计算器"""
# 星座分类
FIRE_SIGNS = ["Aries", "Leo", "Sagittarius"]
EARTH_SIGNS = ["Taurus", "Virgo", "Capricorn"]
AIR_SIGNS = ["Gemini", "Libra", "Aquarius"]
WATER_SIGNS = ["Cancer", "Scorpio", "Pisces"]
DUAL_SIGNS = ["Gemini", "Virgo", "Sagittarius", "Pisces"]
FIXED_SIGNS = ["Taurus", "Leo", "Scorpio", "Aquarius"]
MOVABLE_SIGNS = ["Aries", "Cancer", "Libra", "Capricorn"]
# 行星主宰星座
PLANET_SIGNS = {
"Mercury": ["Gemini", "Virgo"],
"Venus": ["Taurus", "Libra"],
"Moon": ["Cancer"],
"Jupiter": ["Sagittarius", "Pisces"],
"Saturn": ["Capricorn", "Aquarius"],
"Mars": ["Aries", "Scorpio"],
"Sun": ["Leo"]
}
# 行星入庙/落陷度数
EXALTATION = {
"Sun": ("Aries", 10),
"Moon": ("Taurus", 3),
"Mars": ("Capricorn", 28),
"Mercury": ("Virgo", 15),
"Jupiter": ("Cancer", 5),
"Venus": ("Pisces", 27),
"Saturn": ("Libra", 20)
}
DEBILITATION = {
"Sun": ("Libra", 10),
"Moon": ("Scorpio", 3),
"Mars": ("Cancer", 28),
"Mercury": ("Pisces", 15),
"Jupiter": ("Capricorn", 5),
"Venus": ("Virgo", 27),
"Saturn": ("Aries", 20)
}
def __init__(self):
pass
def calculate_all_avasthas(self, planet: str, sign: str, degree: float,
house: int, conjunctions: List[str] = None,
aspects: List[str] = None, is_combust: bool = False,
is_retrograde: bool = False, activity_context: Dict = None) -> Dict[str, any]:
"""
计算行星的所有Avastha状态
Args:
planet: 行星名
sign: 所在星座
degree: 星座内度数(0-30)
house: 所在宫位(1-12)
conjunctions: 合相的行星列表
aspects: 相位的行星列表
is_combust: 是否燃烧
is_retrograde: 是否逆行
Returns:
所有Avastha状态的字典
"""
result = {
"planet": planet,
"sign": sign,
"degree": round(degree, 4),
"house": house,
"avasthas": {}
}
# 1. Bala Avastha(年龄状态)
result["avasthas"]["Bala"] = self._calculate_bala_avastha(degree, sign)
# 2. Jagrat Avastha(警觉状态)
result["avasthas"]["Jagrat"] = self._calculate_jagrat_avastha(planet, sign, house)
# 3. Deeptadi Avastha(情绪状态)
result["avasthas"]["Deeptadi"] = self._calculate_deeptadi_avastha(
planet, sign, degree, is_combust, aspects
)
# 4. Lajjitadi Avastha(羞耻状态)
result["avasthas"]["Lajjitadi"] = self._calculate_lajjitadi_avastha(
planet, sign, house, conjunctions
)
# 5. Shayanadi Avastha(姿态状态)
result["avasthas"]["Shayanadi"] = self._calculate_shayanadi_avastha(planet, sign)
for name in ('Deeptadi', 'Lajjitadi', 'Shayanadi'):
result['avasthas'][name]['method_status'] = 'simplified_heuristic'
if activity_context is not None and activity_context.get('unavailable_reason'):
# 极昼极夜等算不出日出时,PVR 公式缺一项。不退回元素启发式冒充,标成无法计算(BUG-1390)。
result['avasthas']['Shayanadi'] = {
'state': None,
'sign': sign,
'meaning': '当天没有可用的日出(极昼或极夜),姿态无法按 PVR 公式计算。',
'method_status': 'blocked',
'blocked_reason': activity_context['unavailable_reason'],
}
elif activity_context is not None:
result['avasthas']['Shayanadi'] = calculate_pvr_shayanadi(
planet,
SIGNS.index(sign) * 30 + degree,
activity_context['moon_longitude'],
activity_context['asc_longitude'],
activity_context['hours_since_sunrise'],
)
result['inputs'] = {
'conjunctions': conjunctions or [],
'aspects': aspects or [],
'is_combust': is_combust,
'is_retrograde': is_retrograde,
}
if activity_context is not None:
result['inputs']['activity_context'] = dict(activity_context)
# 6. 综合解读
result["interpretation"] = self._generate_interpretation(result["avasthas"])
# 7. 补救建议
result["remedies"] = self._generate_remedies(planet, result["avasthas"])
return result
def _calculate_bala_avastha(self, degree: float, sign: str = 'Aries') -> Dict:
"""计算Bala Avastha(年龄状态)"""
if not 0 <= degree < 30:
raise ValueError('Avastha degree must be within [0, 30)')
original_degree = degree
even_sign = SIGNS.index(sign) % 2 == 1
band = int(degree // 6)
degree = (4 - band if even_sign else band) * 6
if degree < 6:
state = BalaAvastha.INFANT
strength = 0.25
meaning = "婴儿期:行星力量微弱,潜力未开发,需要时间成长"
elif degree < 12:
state = BalaAvastha.YOUNG
strength = 0.5
meaning = "少年期:行星力量增长中,开始显现特质,但尚未成熟"
elif degree < 18:
state = BalaAvastha.YOUTH
strength = 1.0
meaning = "青年期:行星力量最强,充满活力,能够充分发挥作用"
elif degree < 24:
state = BalaAvastha.OLD
strength = None
meaning = "老年期:行星力量开始衰退,经验丰富但活力下降"
else:
state = BalaAvastha.DEAD
strength = 0.0
meaning = "死亡期:行星力量极弱,难以发挥作用,需要补救"
return {
"state": state.value,
"degree_range": f"{int(original_degree//6)*6}-{int(original_degree//6)*6+6}°",
"strength": strength,
"result_grade": 'negligible' if state == BalaAvastha.OLD else 'fraction',
"sign_parity": 'even' if even_sign else 'odd',
"method_status": 'bphs_age_sign_parity',
"meaning": meaning
}
def _calculate_jagrat_avastha(self, planet: str, sign: str, house: int) -> Dict:
"""计算Jagrat Avastha(警觉状态)"""
if planet not in self.PLANET_SIGNS:
return {
'state': 'Not classified',
'house': house,
'method_status': 'node_dignity_not_assigned',
'meaning': '交点未指定尊贵度流派,不套用七曜警觉状态规则',
}
if self._is_own_sign(planet, sign) or self._is_exalted(planet, sign, 0):
state = JagratAvastha.AWAKE
meaning = "清醒状态:行星完全活跃,能够主动发挥作用,影响显著"
elif not self._is_enemy_sign(planet, sign) and not self._is_debilitated(planet, sign, 0):
state = JagratAvastha.DREAMING
meaning = "梦境状态:行星半活跃,作用不稳定,时强时弱"
else:
state = JagratAvastha.DEEP_SLEEP
meaning = "深睡状态:行星不活跃,难以发挥作用,影响微弱"
return {
"state": state.value,
"house": house,
"method_status": 'bphs_dignity_natural_relationships',
"meaning": meaning
}
def _calculate_deeptadi_avastha(self, planet: str, sign: str, degree: float,
is_combust: bool, aspects: List[str] = None) -> Dict:
"""计算Deeptadi Avastha(情绪状态)"""
aspects = aspects or []
if planet not in self.PLANET_SIGNS:
return {
'state': 'Not classified',
'meaning': '该口径未定义此天体的状态',
'aspect_effects': [],
'label_profile': 'science_of_light_deeptadi_natural_relationship_subset',
'claim_boundary': 'Classical seven-planet profile; no nodal dignity is assumed.',
}
conditions = {
'exalted': self._is_exalted(planet, sign, degree),
'debilitated': self._is_debilitated(planet, sign, degree),
'combust': bool(is_combust),
'own_sign': self._is_own_sign(planet, sign),
'natural_friend_sign': self._is_friend_sign(planet, sign),
'natural_enemy_sign': self._is_enemy_sign(planet, sign),
}
applicable_states = [label for key, label in (
('exalted', 'Deepta'), ('debilitated', 'Khala'), ('combust', 'Kopa'),
('own_sign', 'Swastha'), ('natural_friend_sign', 'Shanta'),
('natural_enemy_sign', 'Duhkhita')) if conditions[key]]
if not any(conditions[key] for key in ('own_sign', 'natural_friend_sign', 'natural_enemy_sign')):
applicable_states.append('Dina')
# 单标签顺序是兼容字段,无经典出处。并存条件全部留在 applicable_states。
if self._is_exalted(planet, sign, degree):
state = DeeptadiAvastha.DEEPTA
meaning = "光辉状态:行星处于最佳位置,能量充沛,带来积极结果"
elif self._is_debilitated(planet, sign, degree):
state = DeeptadiAvastha.KHALA
meaning = "负担状态:行星落陷;采用 Science of Light 的 Khala 定义"
elif is_combust:
state = DeeptadiAvastha.KOPA
meaning = "愤怒状态:行星受太阳燃烧;对应 Kopa"
elif self._is_own_sign(planet, sign):
state = DeeptadiAvastha.SWASTHA
meaning = "舒适状态:行星在自己的星座,感觉自在,能够稳定发挥"
elif self._is_friend_sign(planet, sign):
state = DeeptadiAvastha.SHANTA
meaning = "平静状态:行星在自然友星的星座;对应 Shanta"
elif self._is_enemy_sign(planet, sign):
state = DeeptadiAvastha.DUHKHITA
meaning = "困苦状态:行星在自然敌星的星座;对应 Duhkhita"
else:
state = DeeptadiAvastha.DINA
meaning = "低落状态:行星在自然中性星的星座;对应 Dina"
# 检查相位影响
aspect_effects = []
if "Jupiter" in aspects:
aspect_effects.append("木星相位:增加乐观和扩展性")
if "Mars" in aspects:
aspect_effects.append("火星相位:增加激情和冲动性")
if "Saturn" in aspects:
aspect_effects.append("土星相位:增加限制和责任感")
if "Mercury" in aspects:
aspect_effects.append("水星相位:增加智慧和沟通能力")
return {
"state": state.value,
"meaning": meaning,
"aspect_effects": aspect_effects,
"label_profile": "science_of_light_deeptadi_natural_relationship_subset",
"conditions": conditions,
"applicable_states": applicable_states,
"legacy_single_label_note": "无经典出处",
"uncomputed_conditions": ["great_friend", "malefic_conjunction"],
"uncomputed_label": "未计算",
"source": "Science of Light, source p475; Khala is debility in this profile",
"claim_boundary": "Single-label priority is a legacy heuristic. Natural friendship only; great-friend and simultaneous conjunction states are not fully calculated. Khala follows Science of Light debility, not the alternative PVR malefic-sign definition.",
}
def _calculate_lajjitadi_avastha(self, planet: str, sign: str, house: int,
conjunctions: List[str] = None) -> Dict:
"""计算Lajjitadi Avastha(羞耻状态)"""
conjunctions = conjunctions or []
# 简化规则
if self._is_exalted(planet, sign, 15): # 简化判断
state = LajjitadiAvastha.GARVITA
meaning = "骄傲状态:行星入庙,充满自信,能够展现最佳特质"
elif house in [6, 8, 12]:
state = LajjitadiAvastha.KSHUDITA
meaning = "饥饿状态:行星在困难宫位,渴望满足,但难以获得"
elif sign in self.FIRE_SIGNS:
state = LajjitadiAvastha.TRUSHITA
meaning = "口渴状态:行星在火象星座,能量过热,需要冷却"
elif "Mars" in conjunctions:
state = LajjitadiAvastha.KSHOBHITA
meaning = "激动状态:与火星合相,能量激烈,容易冲动"
elif any(self._is_enemy_planet(planet, conj) for conj in conjunctions):
state = LajjitadiAvastha.LAJJITA
meaning = "羞耻状态:与敌对行星同宫,感到不适,发挥受限"
else:
state = LajjitadiAvastha.MUDITA
meaning = "快乐状态:与友好行星同宫,感到愉悦,能够良好发挥"
return {
"state": state.value,
"meaning": meaning,
"conjunctions": conjunctions
}
def _calculate_shayanadi_avastha(self, planet: str, sign: str) -> Dict:
"""计算Shayanadi Avastha(姿态状态)"""
# 根据星座元素和类型判断
if sign in self.WATER_SIGNS:
state = ShayanadiAvastha.SHAYANA
meaning = "躺卧姿态:行星在水象星座,处于休息状态,被动接受"
elif sign in self.EARTH_SIGNS:
state = ShayanadiAvastha.UPAVESHANA
meaning = "坐着姿态:行星在土象星座,稳定扎根,缓慢行动"
elif sign in self.FIRE_SIGNS:
state = ShayanadiAvastha.NETRAPANI
meaning = "持武器姿态:行星在火象星座,充满战斗力,主动出击"
elif sign in self.AIR_SIGNS:
state = ShayanadiAvastha.PRAKASHANA
meaning = "显现姿态:行星在风象星座,灵活多变,善于表达"
else:
state = ShayanadiAvastha.GAMANA
meaning = "行走姿态:行星处于移动状态,不断变化"
# 根据行星主宰星座判断特殊状态
for planet_name, signs in self.PLANET_SIGNS.items():
if sign in signs:
if planet_name == "Mercury":
state = ShayanadiAvastha.AGAMA
meaning = "学习姿态:在水星星座,专注于学习和沟通"
elif planet_name == "Venus":
state = ShayanadiAvastha.BHOJANA
meaning = "进食姿态:在金星星座,享受物质和感官愉悦"
elif planet_name == "Moon":
state = ShayanadiAvastha.NRITYALIPSA
meaning = "舞蹈姿态:在月亮星座,情感丰富,富有表现力"
elif planet_name == "Jupiter":
state = ShayanadiAvastha.KAUTUKA
meaning = "好奇姿态:在木星星座,渴望探索和扩展"
elif planet_name == "Saturn":
state = ShayanadiAvastha.NIDRA
meaning = "睡眠姿态:在土星星座,能量收缩,需要休息"
break
return {
"state": state.value,
"sign": sign,
"meaning": meaning
}
def _is_exalted(self, planet: str, sign: str, degree: float) -> bool:
"""检查是否入庙"""
if planet in self.EXALTATION:
exalt_sign, exalt_degree = self.EXALTATION[planet]
return sign == exalt_sign
return False
def _is_debilitated(self, planet: str, sign: str, degree: float) -> bool:
"""检查是否落陷"""
if planet in self.DEBILITATION:
debil_sign, debil_degree = self.DEBILITATION[planet]
return sign == debil_sign
return False
def _is_own_sign(self, planet: str, sign: str) -> bool:
"""检查是否在自己的星座"""
return sign in self.PLANET_SIGNS.get(planet, [])
def _is_friend_sign(self, planet: str, sign: str) -> bool:
"""检查是否在自然友星星座。"""
lord = next((name for name, signs in self.PLANET_SIGNS.items() if sign in signs), None)
return lord in NATURAL_RELATIONSHIPS.get(planet, {}).get('friends', [])
def _is_enemy_sign(self, planet: str, sign: str) -> bool:
"""检查是否在自然敌星星座。"""
lord = next((name for name, signs in self.PLANET_SIGNS.items() if sign in signs), None)
return lord in NATURAL_RELATIONSHIPS.get(planet, {}).get('enemies', [])
def _is_enemy_planet(self, planet1: str, planet2: str) -> bool:
"""检查两个行星是否敌对(简化版)"""
# 这里需要完整的行星关系表,暂时简化
enemies = {
"Sun": ["Saturn", "Venus"],
"Moon": ["Rahu", "Ketu"],
"Mars": ["Mercury"],
"Mercury": ["Moon"],
"Jupiter": ["Mercury", "Venus"],
"Venus": ["Sun", "Moon"],
"Saturn": ["Sun", "Moon", "Mars"]
}
return planet2 in enemies.get(planet1, [])
def _generate_interpretation(self, avasthas: Dict) -> str:
"""生成综合解读"""
interpretation = "行星状态综合分析:\n\n"
# Bala Avastha
bala = avasthas["Bala"]
interpretation += f"1. 年龄状态:{bala['state']}({bala['degree_range']})\n"
interpretation += f" {bala['meaning']}\n\n"
# Jagrat Avastha
jagrat = avasthas["Jagrat"]
interpretation += f"2. 警觉状态:{jagrat['state']}(第{jagrat['house']}宫)\n"
interpretation += f" {jagrat['meaning']}\n\n"
# Deeptadi Avastha
deeptadi = avasthas["Deeptadi"]
interpretation += f"3. 情绪状态:{deeptadi['state']}\n"
interpretation += f" {deeptadi['meaning']}\n"
if deeptadi['aspect_effects']:
interpretation += " 相位影响:\n"
for effect in deeptadi['aspect_effects']:
interpretation += f" - {effect}\n"
interpretation += "\n"
# Lajjitadi Avastha
lajjitadi = avasthas["Lajjitadi"]
interpretation += f"4. 社会状态:{lajjitadi['state']}\n"
interpretation += f" {lajjitadi['meaning']}\n\n"
# Shayanadi Avastha
shayanadi = avasthas["Shayanadi"]
interpretation += f"5. 行为模式:{shayanadi['state'] or '无法计算'}({shayanadi['sign']})\n"
interpretation += f" {shayanadi['meaning']}\n"
return interpretation
def _generate_remedies(self, planet: str, avasthas: Dict) -> List[str]:
"""生成补救建议"""
remedies = []
# 根据Bala Avastha
bala_strength = avasthas["Bala"]["strength"]
if bala_strength is not None and bala_strength < 0.5:
remedies.append(f"行星处于弱势年龄阶段,建议佩戴{planet}对应的宝石")
remedies.append(f"在{planet}主管的日子进行布施和祈祷")
# 根据Jagrat Avastha
if avasthas["Jagrat"]["state"] == "Deep Sleep":
remedies.append("行星处于深睡状态,建议通过冥想和咒语激活其能量")
# 根据Deeptadi Avastha
deeptadi_state = avasthas["Deeptadi"]["state"]
if deeptadi_state in ["Vikala", "Khala", "Duhkhita", "Kopa"]:
remedies.append(f"行星处于{deeptadi_state}状态,需要特别补救")
remedies.append(f"念诵{planet}的Beeja Mantra(种子咒)")
return remedies
# 示例用法
if __name__ == "__main__":
calculator = AvasthaCalculator()
# 示例:太阳在白羊座15度,第10宫
result = calculator.calculate_all_avasthas(
planet="Sun",
sign="Aries",
degree=15.0,
house=10,
conjunctions=["Mercury"],
aspects=["Jupiter", "Saturn"],
is_combust=False,
is_retrograde=False
)
print("="*60)
print(f"{result['planet']} 在 {result['sign']} {result['degree']}° (第{result['house']}宫)")
print("="*60)
print(result['interpretation'])
if result['remedies']:
print("\n补救建议:")
for i, remedy in enumerate(result['remedies'], 1):
print(f"{i}. {remedy}")