Files
Jyotisha/scripts/pancha_pakshi.py
T
732642856 0f0c5dbdfa v6.1.0: Add 6 core missing modules + infrastructure
New modules (from Chinese reference articles):
- darakaraka_reader.py: DK spouse deep analysis (planet/sign/house/aspects)
- rashi_tulya_navamsa.py: RTN mapping engine (D9->D1, Gunas, curse detection)
- curse_yoga_detector.py: Curse yoga naming (Yama/Preta/Rakshasa/Pisacha)
- spouse_status_yoga.py: High-status spouse detection (7 principles)
- pancha_pakshi.py: Five-bird electional timing (daily schedule)
- tithi_analyzer.py: Tithi lord emotional pattern analysis

Infrastructure:
- technique_registry.py: Unified technique registry (31 techniques tracked)
- reading_orchestrator.py: Theme-based reading orchestrator (5 themes)

All 6 modules tested and runnable.
Current baseline: Precision 94.66%, Recall 92.95%, F1 93.80%
2026-06-07 12:11:15 +08:00

344 lines
14 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 -*-
"""
pancha_pakshi.py — Pancha Pakshi 五鸟择时引擎
===============================================
基于出生Nakshatra和Paksha计算每日吉凶活动时段
版本: v1.0 | 2026-06-07
"""
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass, field
from enum import Enum
class ActivityType(Enum):
"""五鸟活动类型"""
RULE = "rule" # 统治 — 吉
EAT = "eat" # 进食 — 吉
WALK = "walk" # 行走 — 中
SLEEP = "sleep" # 睡眠 — 凶
DEATH = "death" # 死亡 — 凶
class BirdType(Enum):
"""五鸟类型"""
VULTURE = "vulture" # 兀鹫
OWL = "owl" # 猫头鹰
CROW = "crow" # 乌鸦
COCK = "cock" # 公鸡
PEACOCK = "peacock" # 孔雀
# Nakshatra到鸟的映射(Shukla Paksha / Krishna Paksha
NAKSHATRA_BIRDS = {
# Shukla Paksha (亮月期)
"shukla": {
"Ashwini": BirdType.VULTURE, "Bharani": BirdType.OWL,
"Krittika": BirdType.CROW, "Rohini": BirdType.COCK,
"Mrigashira": BirdType.PEACOCK, "Ardra": BirdType.VULTURE,
"Punarvasu": BirdType.OWL, "Pushya": BirdType.CROW,
"Ashlesha": BirdType.COCK, "Magha": BirdType.PEACOCK,
"Purva Phalguni": BirdType.VULTURE, "Uttara Phalguni": BirdType.OWL,
"Hasta": BirdType.CROW, "Chitra": BirdType.COCK,
"Swati": BirdType.PEACOCK, "Vishakha": BirdType.VULTURE,
"Anuradha": BirdType.OWL, "Jyeshtha": BirdType.CROW,
"Mula": BirdType.COCK, "Purva Ashadha": BirdType.PEACOCK,
"Uttara Ashadha": BirdType.VULTURE, "Shravana": BirdType.OWL,
"Dhanishta": BirdType.CROW, "Shatabhisha": BirdType.COCK,
"Purva Bhadrapada": BirdType.PEACOCK, "Uttara Bhadrapada": BirdType.VULTURE,
"Revati": BirdType.OWL,
},
# Krishna Paksha (暗月期)
"krishna": {
"Ashwini": BirdType.OWL, "Bharani": BirdType.VULTURE,
"Krittika": BirdType.PEACOCK, "Rohini": BirdType.COCK,
"Mrigashira": BirdType.CROW, "Ardra": BirdType.OWL,
"Punarvasu": BirdType.VULTURE, "Pushya": BirdType.PEACOCK,
"Ashlesha": BirdType.COCK, "Magha": BirdType.CROW,
"Purva Phalguni": BirdType.OWL, "Uttara Phalguni": BirdType.VULTURE,
"Hasta": BirdType.PEACOCK, "Chitra": BirdType.COCK,
"Swati": BirdType.CROW, "Vishakha": BirdType.OWL,
"Anuradha": BirdType.VULTURE, "Jyeshtha": BirdType.PEACOCK,
"Mula": BirdType.COCK, "Purva Ashadha": BirdType.CROW,
"Uttara Ashadha": BirdType.OWL, "Shravana": BirdType.VULTURE,
"Dhanishta": BirdType.PEACOCK, "Shatabhisha": BirdType.COCK,
"Purva Bhadrapada": BirdType.CROW, "Uttara Bhadrapada": BirdType.OWL,
"Revati": BirdType.VULTURE,
},
}
# 鸟的活动周期表(5个Yama × 5种活动)
# 每个Yama约3小时(一天15小时,从日出到日落)
BIRD_ACTIVITY_TABLE = {
BirdType.VULTURE: [
[ActivityType.RULE, ActivityType.EAT, ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH],
[ActivityType.EAT, ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH, ActivityType.RULE],
[ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH, ActivityType.RULE, ActivityType.EAT],
[ActivityType.SLEEP, ActivityType.DEATH, ActivityType.RULE, ActivityType.EAT, ActivityType.WALK],
[ActivityType.DEATH, ActivityType.RULE, ActivityType.EAT, ActivityType.WALK, ActivityType.SLEEP],
],
BirdType.OWL: [
[ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH, ActivityType.RULE, ActivityType.EAT],
[ActivityType.SLEEP, ActivityType.DEATH, ActivityType.RULE, ActivityType.EAT, ActivityType.WALK],
[ActivityType.DEATH, ActivityType.RULE, ActivityType.EAT, ActivityType.WALK, ActivityType.SLEEP],
[ActivityType.RULE, ActivityType.EAT, ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH],
[ActivityType.EAT, ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH, ActivityType.RULE],
],
BirdType.CROW: [
[ActivityType.DEATH, ActivityType.RULE, ActivityType.EAT, ActivityType.WALK, ActivityType.SLEEP],
[ActivityType.RULE, ActivityType.EAT, ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH],
[ActivityType.EAT, ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH, ActivityType.RULE],
[ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH, ActivityType.RULE, ActivityType.EAT],
[ActivityType.SLEEP, ActivityType.DEATH, ActivityType.RULE, ActivityType.EAT, ActivityType.WALK],
],
BirdType.COCK: [
[ActivityType.SLEEP, ActivityType.DEATH, ActivityType.RULE, ActivityType.EAT, ActivityType.WALK],
[ActivityType.DEATH, ActivityType.RULE, ActivityType.EAT, ActivityType.WALK, ActivityType.SLEEP],
[ActivityType.RULE, ActivityType.EAT, ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH],
[ActivityType.EAT, ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH, ActivityType.RULE],
[ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH, ActivityType.RULE, ActivityType.EAT],
],
BirdType.PEACOCK: [
[ActivityType.EAT, ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH, ActivityType.RULE],
[ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH, ActivityType.RULE, ActivityType.EAT],
[ActivityType.SLEEP, ActivityType.DEATH, ActivityType.RULE, ActivityType.EAT, ActivityType.WALK],
[ActivityType.DEATH, ActivityType.RULE, ActivityType.EAT, ActivityType.WALK, ActivityType.SLEEP],
[ActivityType.RULE, ActivityType.EAT, ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH],
],
}
# 活动吉凶
ACTIVITY_FORTUNE = {
ActivityType.RULE: "", # 统治 — 适合开始重要事务
ActivityType.EAT: "", # 进食 — 适合获取资源
ActivityType.WALK: "", # 行走 — 适合日常活动
ActivityType.SLEEP: "", # 睡眠 — 避免重要决策
ActivityType.DEATH: "", # 死亡 — 极度不利
}
# 活动建议
ACTIVITY_ADVICE = {
ActivityType.RULE: ["开始新项目", "做重要决策", "领导会议", "签署合同"],
ActivityType.EAT: ["财务活动", "求职面试", "购买资产", "接受礼物"],
ActivityType.WALK: ["日常事务", "短途旅行", "社交活动", "信息收集"],
ActivityType.SLEEP: ["避免重要决策", "休息", "内省", "推迟行动"],
ActivityType.DEATH: ["避免一切重要活动", "取消计划", "防护", "等待"],
}
# 活动相克
ACTIVITY_DOMINANCE = {
ActivityType.RULE: [ActivityType.EAT, ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH],
ActivityType.EAT: [ActivityType.WALK, ActivityType.SLEEP, ActivityType.DEATH],
ActivityType.WALK: [ActivityType.SLEEP, ActivityType.DEATH],
ActivityType.SLEEP: [ActivityType.DEATH],
ActivityType.DEATH: [],
}
@dataclass
class YamaActivity:
"""单个Yama的活动"""
yama_number: int # 1-5
yama_name: str # Pratah/Madhyahna/Aparahna/Sayam/Ratri
start_time: str # 开始时间(近似)
end_time: str # 结束时间
activity: ActivityType
activity_cn: str
fortune: str # 吉/中/凶
advice: List[str]
@dataclass
class DailySchedule:
"""每日活动表"""
date: str
bird: BirdType
bird_cn: str
paksha: str # shukla/krishna
yama_activities: List[YamaActivity] = field(default_factory=list)
# 推荐时段
best_periods: List[str] = field(default_factory=list)
avoid_periods: List[str] = field(default_factory=list)
narrative: str = ""
class PanchaPakshi:
"""五鸟择时引擎"""
def __init__(self):
self.nakshatra_birds = NAKSHATRA_BIRDS
self.activity_table = BIRD_ACTIVITY_TABLE
self.activity_fortune = ACTIVITY_FORTUNE
self.activity_advice = ACTIVITY_ADVICE
def calculate(self, birth_nakshatra: str, paksha: str,
date: Optional[str] = None) -> DailySchedule:
"""
计算某日的五鸟活动表
Args:
birth_nakshatra: 出生Nakshatra
paksha: 'shukla' (亮月) 或 'krishna' (暗月)
date: 日期字符串(可选)
Returns:
DailySchedule对象
"""
# 确定鸟类型
bird = self._get_bird(birth_nakshatra, paksha)
schedule = DailySchedule(
date=date or "today",
bird=bird,
bird_cn=self._bird_to_chinese(bird),
paksha=paksha,
)
# 生成5个Yama的活动
yama_names = ["Pratah (晨)", "Madhyahna (午)", "Aparahna (下午)",
"Sayam (傍晚)", "Ratri (夜)"]
time_ranges = ["6:00-9:00", "9:00-12:00", "12:00-15:00",
"15:00-18:00", "18:00-21:00"]
for i in range(5):
activity = self.activity_table[bird][i][i] # 对角线
yama = YamaActivity(
yama_number=i+1,
yama_name=yama_names[i],
start_time=time_ranges[i].split("-")[0],
end_time=time_ranges[i].split("-")[1],
activity=activity,
activity_cn=self._activity_to_chinese(activity),
fortune=self.activity_fortune.get(activity, ""),
advice=self.activity_advice.get(activity, [])
)
schedule.yama_activities.append(yama)
# 推荐/避免时段
self._generate_recommendations(schedule)
# 生成叙事
schedule.narrative = self._generate_narrative(schedule)
return schedule
def _get_bird(self, nakshatra: str, paksha: str) -> BirdType:
"""根据Nakshatra和Paksha确定鸟"""
paksha_data = self.nakshatra_birds.get(paksha, self.nakshatra_birds["shukla"])
return paksha_data.get(nakshatra, BirdType.PEACOCK)
def _bird_to_chinese(self, bird: BirdType) -> str:
"""鸟类型转中文"""
names = {
BirdType.VULTURE: "兀鹫",
BirdType.OWL: "猫头鹰",
BirdType.CROW: "乌鸦",
BirdType.COCK: "公鸡",
BirdType.PEACOCK: "孔雀",
}
return names.get(bird, "未知")
def _activity_to_chinese(self, activity: ActivityType) -> str:
"""活动类型转中文"""
names = {
ActivityType.RULE: "统治",
ActivityType.EAT: "进食",
ActivityType.WALK: "行走",
ActivityType.SLEEP: "睡眠",
ActivityType.DEATH: "死亡",
}
return names.get(activity, "未知")
def _generate_recommendations(self, schedule: DailySchedule):
"""生成推荐和避免时段"""
for yama in schedule.yama_activities:
time_str = f"{yama.start_time}-{yama.end_time}"
if yama.fortune == "":
schedule.best_periods.append(f"{time_str} ({yama.activity_cn})")
elif yama.fortune == "":
schedule.avoid_periods.append(f"{time_str} ({yama.activity_cn})")
def _generate_narrative(self, schedule: DailySchedule) -> str:
"""生成叙事"""
parts = []
parts.append("### Pancha Pakshi 五鸟择时\n")
parts.append(f"您的出生鸟: **{schedule.bird_cn}** ({schedule.bird.value})\n")
parts.append(f"月相: {'亮月期 (Shukla Paksha)' if schedule.paksha == 'shukla' else '暗月期 (Krishna Paksha)'}\n")
parts.append("\n#### 今日活动表\n")
for yama in schedule.yama_activities:
emoji = "🟢" if yama.fortune == "" else "🟡" if yama.fortune == "" else "🔴"
parts.append(f"{emoji} **{yama.yama_name}** ({yama.start_time}-{yama.end_time})")
parts.append(f" 活动: {yama.activity_cn} ({yama.fortune})")
if yama.advice:
parts.append(f" 建议: {'; '.join(yama.advice[:2])}")
parts.append("")
if schedule.best_periods:
parts.append(f"\n✅ **最佳活动时段**: {'; '.join(schedule.best_periods[:3])}\n")
if schedule.avoid_periods:
parts.append(f"\n❌ **避免活动时段**: {'; '.join(schedule.avoid_periods)}\n")
parts.append(f"\n#### 五鸟相克规则\n")
parts.append("统治 > 进食 > 行走 > 睡眠 > 死亡\n")
parts.append("当对方的活动克制你的活动时,不利。\n")
return "\n".join(parts)
def to_dict(self, schedule: DailySchedule) -> Dict:
"""转换为字典"""
return {
"date": schedule.date,
"bird": schedule.bird.value,
"bird_cn": schedule.bird_cn,
"paksha": schedule.paksha,
"activities": [
{
"yama": y.yama_number,
"time": f"{y.start_time}-{y.end_time}",
"activity": y.activity.value,
"activity_cn": y.activity_cn,
"fortune": y.fortune,
"advice": y.advice,
}
for y in schedule.yama_activities
],
"best_periods": schedule.best_periods,
"avoid_periods": schedule.avoid_periods,
"narrative": schedule.narrative,
}
# ============================================================================
# 便捷函数
# ============================================================================
def get_pancha_pakshi_schedule(birth_nakshatra: str, paksha: str,
date: Optional[str] = None) -> Dict:
"""便捷函数"""
engine = PanchaPakshi()
schedule = engine.calculate(birth_nakshatra, paksha, date)
return engine.to_dict(schedule)
# ============================================================================
# CLI 调试
# ============================================================================
if __name__ == "__main__":
print("=" * 60)
print("Pancha Pakshi 五鸟择时引擎")
print("=" * 60)
result = get_pancha_pakshi_schedule("Rohini", "shukla", "2026-06-07")
print(result["narrative"])
print(f"\n出生鸟: {result['bird_cn']}")