0f0c5dbdfa
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%
344 lines
14 KiB
Python
344 lines
14 KiB
Python
#!/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']}")
|