300 lines
11 KiB
Python
300 lines
11 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
Vimsopaka Bala Calculator - 分盘综合力量计算器
|
||
印度占星 Vimsopaka Bala(20分力量)系统
|
||
|
||
核心功能:
|
||
- 计算16种分盘(Shodasavarga)的行星尊严
|
||
- 根据BPHS权重系统计算Vimsopaka Bala
|
||
- 提供行星在各分盘的综合力量评分
|
||
- 支持Dasa Varga(10分盘)和Shodasavarga(16分盘)两种模式
|
||
|
||
参考文献:
|
||
- Brihat Parashara Hora Shastra (BPHS) Chapter 7
|
||
- B.V. Raman - "A Manual of Hindu Astrology"
|
||
"""
|
||
|
||
from typing import Dict, List, Tuple
|
||
from enum import Enum
|
||
|
||
class VargaType(Enum):
|
||
"""分盘类型"""
|
||
D1 = "Rashi" # 本命盘
|
||
D2 = "Hora" # 财富
|
||
D3 = "Drekkana" # 兄弟姐妹
|
||
D4 = "Chaturthamsa" # 财产/运气
|
||
D7 = "Saptamsa" # 子女
|
||
D9 = "Navamsa" # 配偶/灵性
|
||
D10 = "Dasamsa" # 事业
|
||
D12 = "Dwadasamsa" # 父母
|
||
D16 = "Shodasamsa" # 交通工具
|
||
D20 = "Vimsamsa" # 灵性修行
|
||
D24 = "Chaturvimsamsa" # 教育/学习
|
||
D27 = "Bhamsa" # 力量/弱点
|
||
D30 = "Trimsamsa" # 不幸/困难
|
||
D40 = "Khavedamsa" # 吉凶效果
|
||
D45 = "Akshavedamsa" # 全面判断
|
||
D60 = "Shashtiamsa" # 前世业力
|
||
|
||
class DignityLevel(Enum):
|
||
"""行星尊严等级"""
|
||
EXALTED = "Exalted" # 入庙(最高)
|
||
MOOLATRIKONA = "Moolatrikona" # 根本三角
|
||
OWN_SIGN = "Own Sign" # 自己的星座
|
||
GREAT_FRIEND = "Great Friend" # 极友
|
||
FRIEND = "Friend" # 友好星座
|
||
NEUTRAL = "Neutral" # 中性星座
|
||
ENEMY = "Enemy" # 敌对星座
|
||
GREAT_ENEMY = "Great Enemy" # 极敌
|
||
DEBILITATED = "Debilitated" # 落陷(最低)
|
||
NEECHA_BHANGA = "Neecha Bhanga" # 落陷取消
|
||
|
||
class VimsopakaBalaCalculator:
|
||
"""Vimsopaka Bala计算器"""
|
||
|
||
# BPHS标准权重系统(Shodasavarga - 16分盘)
|
||
SHODASAVARGA_WEIGHTS = {
|
||
VargaType.D1: 3.5, # Rashi
|
||
VargaType.D2: 1.0, # Hora
|
||
VargaType.D3: 1.0, # Drekkana
|
||
VargaType.D4: 0.5, # Chaturthamsa
|
||
VargaType.D7: 0.5, # Saptamsa
|
||
VargaType.D9: 3.0, # Navamsa;十六分盘权重合计 20
|
||
VargaType.D10: 0.5, # Dasamsa
|
||
VargaType.D12: 0.5, # Dwadasamsa
|
||
VargaType.D16: 2.0, # Shodasamsa
|
||
VargaType.D20: 0.5, # Vimsamsa
|
||
VargaType.D24: 0.5, # Chaturvimsamsa
|
||
VargaType.D27: 0.5, # Bhamsa
|
||
VargaType.D30: 1.0, # Trimsamsa
|
||
VargaType.D40: 0.5, # Khavedamsa
|
||
VargaType.D45: 0.5, # Akshavedamsa
|
||
VargaType.D60: 4.0 # Shashtiamsa
|
||
}
|
||
|
||
# Dasa Varga权重系统(10分盘 - 简化版)
|
||
DASAVARGA_WEIGHTS = {
|
||
VargaType.D1: 3.0,
|
||
VargaType.D2: 1.5,
|
||
VargaType.D3: 1.5,
|
||
VargaType.D7: 1.5,
|
||
VargaType.D9: 1.5,
|
||
VargaType.D10: 1.5,
|
||
VargaType.D12: 1.5,
|
||
VargaType.D16: 1.5,
|
||
VargaType.D30: 1.5,
|
||
VargaType.D60: 5.0
|
||
}
|
||
|
||
# 星主关系对应的 Virupas。落陷和落陷取消不是这项的输入。
|
||
DIGNITY_VIRUPAS = {
|
||
DignityLevel.EXALTED: 20.0,
|
||
DignityLevel.MOOLATRIKONA: 20.0,
|
||
DignityLevel.OWN_SIGN: 20.0,
|
||
DignityLevel.GREAT_FRIEND: 18.0,
|
||
DignityLevel.FRIEND: 15.0,
|
||
DignityLevel.NEUTRAL: 10.0,
|
||
DignityLevel.ENEMY: 7.0,
|
||
DignityLevel.GREAT_ENEMY: 5.0,
|
||
}
|
||
|
||
# 数值分档。不再借用 Vaiseshikamsa 的分盘计数名称。
|
||
STRENGTH_CATEGORIES = {
|
||
"High": (15.0, 20.000001),
|
||
"Moderate": (10.0, 15.0),
|
||
"Limited": (5.0, 10.0),
|
||
"Low": (0.0, 5.0),
|
||
}
|
||
|
||
def __init__(self, mode: str = "shodasavarga"):
|
||
"""
|
||
初始化计算器
|
||
|
||
Args:
|
||
mode: "shodasavarga" (16分盘) 或 "dasavarga" (10分盘)
|
||
"""
|
||
self.mode = mode
|
||
self.weights = self.SHODASAVARGA_WEIGHTS if mode == "shodasavarga" else self.DASAVARGA_WEIGHTS
|
||
|
||
def calculate_vimsopaka_bala(self, planet_vargas: Dict[str, Dict[VargaType, DignityLevel]]) -> Dict[str, Dict]:
|
||
"""
|
||
计算所有行星的Vimsopaka Bala
|
||
|
||
Args:
|
||
planet_vargas: {行星名: {分盘类型: 尊严等级}}
|
||
|
||
Returns:
|
||
{行星名: {
|
||
"total_score": 总分,
|
||
"category": 力量等级,
|
||
"varga_scores": {分盘: 得分},
|
||
"interpretation": 解读
|
||
}}
|
||
"""
|
||
results = {}
|
||
|
||
for planet, vargas in planet_vargas.items():
|
||
planet_result = self._calculate_planet_vimsopaka(planet, vargas)
|
||
results[planet] = planet_result
|
||
|
||
return results
|
||
|
||
def _calculate_planet_vimsopaka(self, planet: str, vargas: Dict[VargaType, DignityLevel]) -> Dict:
|
||
"""计算单个行星的Vimsopaka Bala"""
|
||
varga_scores = {}
|
||
total_weighted_score = 0.0
|
||
total_weight = 0.0
|
||
|
||
# 计算每个分盘的得分
|
||
for varga_type, dignity in vargas.items():
|
||
if varga_type in self.weights:
|
||
# 只接受星主关系。落陷或落陷取消不能当作尊贵分。
|
||
if dignity not in self.DIGNITY_VIRUPAS:
|
||
raise ValueError('Varga Viswa requires a sign-owner relationship, not debility/cancellation')
|
||
virupas = self.DIGNITY_VIRUPAS[dignity]
|
||
|
||
# 获取分盘权重
|
||
weight = self.weights[varga_type]
|
||
|
||
# 计算加权得分
|
||
weighted_score = virupas * weight
|
||
|
||
varga_scores[varga_type.value] = {
|
||
"dignity": dignity.value,
|
||
"virupas": virupas,
|
||
"weight": weight,
|
||
"weighted_score": round(weighted_score, 2)
|
||
}
|
||
|
||
total_weighted_score += weighted_score
|
||
total_weight += weight
|
||
|
||
# 分母固定为 20,不按已提供分盘的权重再归一。
|
||
if total_weight > 0:
|
||
final_score = total_weighted_score / 20.0
|
||
else:
|
||
final_score = 0.0
|
||
|
||
# 确定力量等级
|
||
category = self._get_strength_category(final_score)
|
||
|
||
# 生成解读
|
||
interpretation = self._generate_interpretation(planet, final_score, category, varga_scores)
|
||
|
||
return {
|
||
"planet": planet,
|
||
"total_score": round(final_score, 2),
|
||
"category": category,
|
||
"varga_scores": varga_scores,
|
||
"interpretation": interpretation,
|
||
"mode": self.mode,
|
||
"calculation_profile": "bphs_7_21_27_varga_viswa_compound_relationships",
|
||
"included_weight": total_weight,
|
||
"complete": set(vargas).issuperset(self.weights),
|
||
"missing_vargas": [v.value for v in self.weights if v not in vargas],
|
||
"category_basis": "Numeric score band; not Vaiseshikamsa varga-count titles",
|
||
}
|
||
|
||
def _get_strength_category(self, score: float) -> str:
|
||
"""根据得分确定力量等级"""
|
||
for category, (min_score, max_score) in self.STRENGTH_CATEGORIES.items():
|
||
if min_score <= score < max_score:
|
||
return category
|
||
return "Unclassified"
|
||
|
||
def _generate_interpretation(self, planet: str, score: float, category: str, varga_scores: Dict) -> str:
|
||
"""陈述加权后的星主关系,不把分数说成吉凶或应验。"""
|
||
text = (
|
||
f"{planet}的 Vimsopaka Bala 为 {score:.2f}/20,数值分档 {category}。"
|
||
"这项只计分盘里的星主关系,不是功能吉凶,也不表示必然结果。"
|
||
)
|
||
if varga_scores:
|
||
ranked = sorted(varga_scores.items(), key=lambda item: item[1]['virupas'], reverse=True)
|
||
text += f" 关系分最高:{ranked[0][0]}({ranked[0][1]['virupas']:g}/20)。"
|
||
text += f" 关系分最低:{ranked[-1][0]}({ranked[-1][1]['virupas']:g}/20)。"
|
||
if len(varga_scores) < len(self.weights):
|
||
text += " 输入不完整,这里只是已计入分盘的合计,不是完整分数。"
|
||
return text
|
||
|
||
def compare_planets(self, results: Dict[str, Dict]) -> List[Tuple[str, float]]:
|
||
"""
|
||
比较所有行星的力量,返回排序列表
|
||
|
||
Args:
|
||
results: calculate_vimsopaka_bala的返回结果
|
||
|
||
Returns:
|
||
[(行星名, 得分), ...] 按得分降序排列
|
||
"""
|
||
planet_scores = [(planet, data["total_score"]) for planet, data in results.items()]
|
||
return sorted(planet_scores, key=lambda x: x[1], reverse=True)
|
||
|
||
def get_remedial_recommendations(self, planet: str, score: float) -> List[str]:
|
||
"""
|
||
根据Vimsopaka Bala得分提供补救建议
|
||
|
||
Args:
|
||
planet: 行星名
|
||
score: Vimsopaka Bala得分
|
||
|
||
Returns:
|
||
补救建议列表
|
||
"""
|
||
recommendations = []
|
||
|
||
if score < 8: # 力量较弱,需要补救
|
||
recommendations.append(f"建议佩戴{planet}对应的宝石来增强力量")
|
||
recommendations.append(f"在{planet}主管的日子进行布施(Daan)")
|
||
recommendations.append(f"念诵{planet}的咒语(Mantra)")
|
||
recommendations.append(f"在{planet}主管的时辰进行重要活动")
|
||
|
||
if score < 4: # 极弱,需要额外补救
|
||
recommendations.append(f"考虑进行{planet}的火祭仪式(Homa)")
|
||
recommendations.append(f"在{planet}主管的日子断食")
|
||
|
||
return recommendations
|
||
|
||
|
||
# 示例用法
|
||
if __name__ == "__main__":
|
||
# 创建计算器(使用16分盘模式)
|
||
calculator = VimsopakaBalaCalculator(mode="shodasavarga")
|
||
|
||
# 示例数据:太阳在各分盘的尊严
|
||
sun_vargas = {
|
||
VargaType.D1: DignityLevel.EXALTED,
|
||
VargaType.D2: DignityLevel.OWN_SIGN,
|
||
VargaType.D3: DignityLevel.FRIEND,
|
||
VargaType.D9: DignityLevel.MOOLATRIKONA,
|
||
VargaType.D10: DignityLevel.FRIEND,
|
||
VargaType.D12: DignityLevel.NEUTRAL,
|
||
VargaType.D16: DignityLevel.OWN_SIGN,
|
||
VargaType.D20: DignityLevel.FRIEND,
|
||
VargaType.D30: DignityLevel.ENEMY,
|
||
VargaType.D60: DignityLevel.EXALTED
|
||
}
|
||
|
||
# 计算所有行星的Vimsopaka Bala
|
||
planet_vargas = {
|
||
"Sun": sun_vargas
|
||
}
|
||
|
||
results = calculator.calculate_vimsopaka_bala(planet_vargas)
|
||
|
||
# 打印结果
|
||
for planet, data in results.items():
|
||
print(f"\n{'='*60}")
|
||
print(f"{planet} - Vimsopaka Bala分析")
|
||
print(f"{'='*60}")
|
||
print(f"总分:{data['total_score']}/20")
|
||
print(f"等级:{data['category']}")
|
||
print(f"\n{data['interpretation']}")
|
||
|
||
# 如果需要补救
|
||
remedies = calculator.get_remedial_recommendations(planet, data['total_score'])
|
||
if remedies:
|
||
print(f"\n补救建议:")
|
||
for i, remedy in enumerate(remedies, 1):
|
||
print(f"{i}. {remedy}")
|