divicast 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
divicast-0.1.1/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ MIT License
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
@@ -0,0 +1,76 @@
1
+ Metadata-Version: 2.3
2
+ Name: divicast
3
+ Version: 0.1.1
4
+ Summary: This is a metaphysical chart library, including six line
5
+ Author: Wáng Sōng
6
+ Author-email: Wáng Sōng <wangsquirrel@gmail.com>
7
+ License: MIT License
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+ Requires-Dist: pydantic>=2.11.9
27
+ Requires-Dist: rich==14.0.0
28
+ Requires-Dist: tyme4py>=1.3.4
29
+ Requires-Python: >=3.12
30
+ Project-URL: Homepage, https://github.com/wangsquirrel/divicast
31
+ Description-Content-Type: text/markdown
32
+
33
+ # 玄学排盘库
34
+
35
+ 本库用于六爻排盘(六爻预测),提供了基础的六爻相关实体、符号、五行、天干地支等数据结构和推演逻辑,适合用于命理、易学、占卜等相关应用的开发。致力于面向未来,面向AI
36
+
37
+ ## 功能简介
38
+
39
+ - 支持六爻排盘的基本流程
40
+ - 内置天干、地支、五行、六神、卦象等基础数据
41
+ - 提供六爻相关实体和符号的操作
42
+ - 易于扩展和集成到其他 Python 项目
43
+
44
+ ## 安装
45
+
46
+ ```bash
47
+ pip install divicast
48
+ ```
49
+
50
+ 或直接克隆仓库:
51
+ ```
52
+ git clone https://github.com/wangsquirrel/divicast.git
53
+ cd divicast
54
+ pip install .
55
+ ```
56
+
57
+ ## 快速上手
58
+
59
+ 以下是一个简单的六爻排盘示例:
60
+
61
+ 更多用法请参考 examples/sixline_example.py。
62
+
63
+ ```python
64
+ from divicast.sixline import DivinatorySymbol, rich_draw_divination, to_standard_format
65
+
66
+ # 创建一个六爻卦象
67
+ d = DivinatorySymbol.create()
68
+
69
+ # 输出文本排版格式的卦象
70
+ rich_draw_divination(d)
71
+
72
+ # 输出卦象标准化json格式
73
+ print(to_standard_format(d).model_dump_json(exclude_none=True))
74
+ ```
75
+
76
+ 如有问题或建议,欢迎提交 issue 或 PR
@@ -0,0 +1,44 @@
1
+ # 玄学排盘库
2
+
3
+ 本库用于六爻排盘(六爻预测),提供了基础的六爻相关实体、符号、五行、天干地支等数据结构和推演逻辑,适合用于命理、易学、占卜等相关应用的开发。致力于面向未来,面向AI
4
+
5
+ ## 功能简介
6
+
7
+ - 支持六爻排盘的基本流程
8
+ - 内置天干、地支、五行、六神、卦象等基础数据
9
+ - 提供六爻相关实体和符号的操作
10
+ - 易于扩展和集成到其他 Python 项目
11
+
12
+ ## 安装
13
+
14
+ ```bash
15
+ pip install divicast
16
+ ```
17
+
18
+ 或直接克隆仓库:
19
+ ```
20
+ git clone https://github.com/wangsquirrel/divicast.git
21
+ cd divicast
22
+ pip install .
23
+ ```
24
+
25
+ ## 快速上手
26
+
27
+ 以下是一个简单的六爻排盘示例:
28
+
29
+ 更多用法请参考 examples/sixline_example.py。
30
+
31
+ ```python
32
+ from divicast.sixline import DivinatorySymbol, rich_draw_divination, to_standard_format
33
+
34
+ # 创建一个六爻卦象
35
+ d = DivinatorySymbol.create()
36
+
37
+ # 输出文本排版格式的卦象
38
+ rich_draw_divination(d)
39
+
40
+ # 输出卦象标准化json格式
41
+ print(to_standard_format(d).model_dump_json(exclude_none=True))
42
+ ```
43
+
44
+ 如有问题或建议,欢迎提交 issue 或 PR
@@ -0,0 +1,27 @@
1
+ [project]
2
+ name = "divicast"
3
+ version = "0.1.1"
4
+ description = "This is a metaphysical chart library, including six line"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "Wáng Sōng", email = "wangsquirrel@gmail.com" }
8
+ ]
9
+ requires-python = ">=3.12"
10
+ dependencies = [
11
+ "pydantic>=2.11.9",
12
+ "rich==14.0.0",
13
+ "tyme4py>=1.3.4",
14
+ ]
15
+ license = { file = "LICENSE" }
16
+
17
+ [project.urls]
18
+ "Homepage" = "https://github.com/wangsquirrel/divicast"
19
+
20
+ [build-system]
21
+ requires = ["uv_build>=0.8.4,<0.9.0"]
22
+ build-backend = "uv_build"
23
+
24
+ [dependency-groups]
25
+ test = [
26
+ "jsonschema>=4.25.0",
27
+ ]
@@ -0,0 +1,8 @@
1
+ __version__ = "0.1.1"
2
+
3
+ from .sixline.divinatory_symbol import DivinatorySymbol
4
+
5
+ __all__ = [
6
+ "DivinatorySymbol",
7
+ "__version__"
8
+ ]
File without changes
@@ -0,0 +1,113 @@
1
+ from enum import Enum
2
+ from typing import Any, Iterator, List, Self, Type, TypeVar
3
+
4
+ T = TypeVar("T", bound="ValuedMultiton")
5
+
6
+
7
+ class ValuedMultiton(Enum):
8
+ """
9
+ 一个功能丰富的枚举基类,旨在通过继承来使用。
10
+
11
+ 它提供了多种方式来定义和访问枚举成员,每个成员都包含一个整数值和一个中文描述。
12
+
13
+ 特性:
14
+ - 通过 `(整数, "中文名")` 的元组形式来定义成员。
15
+ - 实例可以通过名称、整数值或中文名进行检索。
16
+ - 提供了清晰的 `__str__` 和 `__repr__` 表示。
17
+ - 支持迭代、比较,并提供了 `next()` 方法用于循环遍历。
18
+ - 提供了 `all()` 和 `iterator_from()` 等便利的类方法。
19
+
20
+ """
21
+
22
+ def __init__(self, num: int, chinese_name: str | None = None):
23
+ if not isinstance(num, int) or not isinstance(chinese_name, str):
24
+ raise TypeError(
25
+ "Enum members must be defined as a tuple of (int, str).")
26
+ self.num = num
27
+ self.chinese_name = chinese_name
28
+
29
+ @classmethod
30
+ def _missing_(cls: Type[T], value: Any) -> T | None:
31
+ """
32
+ 实现通过整数值查找实例,例如 `Color(1)`。
33
+ """
34
+ if isinstance(value, int):
35
+ for member in cls:
36
+ if member.num == value:
37
+ return member
38
+ return None
39
+
40
+ @classmethod
41
+ def from_chinese_name(cls: Type[T], chinese_name: str) -> T:
42
+ """通过中文名查找枚举成员。"""
43
+ for member in cls:
44
+ if member.chinese_name == chinese_name:
45
+ return member
46
+ raise ValueError(
47
+ f"'{chinese_name}' is not a valid chinese_name for {cls.__name__}"
48
+ )
49
+
50
+ @classmethod
51
+ def all(cls: Type[T]) -> List[T]:
52
+ """以列表形式返回所有枚举成员,按定义顺序排列。"""
53
+ return list(cls)
54
+
55
+ def next(self, step: int = 1) -> Self:
56
+ """返回后`step`个枚举成员。如果是最后一个,则循环回到第一个。"""
57
+ members = self.all()
58
+ index = members.index(self)
59
+ return members[(index + step) % len(members)]
60
+
61
+ @classmethod
62
+ def iterator_from(cls: Type[T], start_member: T) -> Iterator[T]:
63
+ """创建一个从指定成员开始并循环一次的迭代器。"""
64
+ if not isinstance(start_member, cls):
65
+ raise TypeError(
66
+ f"start_member must be an instance of {cls.__name__}")
67
+
68
+ current = start_member
69
+ while True:
70
+ yield current
71
+ current = current.next()
72
+ if current == start_member:
73
+ break
74
+
75
+ def __str__(self) -> str:
76
+ """返回用户的友好字符串表示(中文名)。"""
77
+ return self.chinese_name
78
+
79
+ def __repr__(self) -> str:
80
+ """返回开发者的清晰、无歧义的表示。"""
81
+ return f"<{self.__class__.__name__}.{self.name}: {self.num} ('{self.chinese_name}')>"
82
+
83
+ def __eq__(self, other: Any) -> bool:
84
+ """
85
+ 允许枚举成员与整数值进行比较。
86
+ 例如 `Color.RED == 1`。
87
+ """
88
+ if isinstance(other, int):
89
+ return self.num == other
90
+ # 对于其他类型,使用 `enum.Enum` 的默认比较逻辑
91
+ return super().__eq__(other)
92
+
93
+ def __hash__(self) -> int:
94
+ """确保枚举成员是可哈希的,以便在字典键或集合中使用。"""
95
+ return hash(self.num)
96
+
97
+ # --- 序列化 ---
98
+
99
+ def to_dict(self) -> str:
100
+ """
101
+ 返回一个简单的、可序列化的表示(成员名称)。
102
+ """
103
+ return self.name
104
+
105
+
106
+ class BelongsTo:
107
+ """
108
+ 继承此类以创建一个属于另一个类的类。
109
+ """
110
+
111
+ def belongs_to(self, _: type[T], map_name: str) -> T:
112
+ a = getattr(self, map_name)[self]
113
+ return a
@@ -0,0 +1,21 @@
1
+ from divicast.base.symbol import ValuedMultiton
2
+
3
+
4
+ class Daemon(ValuedMultiton):
5
+ """
6
+ 神煞
7
+ """
8
+
9
+ Tianyiguiren = (0, "天乙贵人")
10
+ Yima = (1, "驿马")
11
+ Taohua = (2, "桃花")
12
+ Wenchang = (3, "文昌")
13
+ Lushen = (4, "禄神")
14
+ Jiesha = (5, "劫煞")
15
+ Huagai = (6, "华盖")
16
+ Jiangxing = (7, "将星")
17
+ Tianxi = (8, "天喜")
18
+ Tianyi = (9, "天医")
19
+ Yangren = (10, "阳刃")
20
+ Zaisha = (11, "灾煞")
21
+ Mouxing = (12, "谋星")
@@ -0,0 +1,78 @@
1
+ from __future__ import annotations # 用于前向引用
2
+
3
+ from typing import ClassVar, Dict, List
4
+
5
+ from divicast.base.symbol import ValuedMultiton
6
+ from divicast.entities.wuxing import *
7
+
8
+
9
+ class Dizhi(BelongsToYinYang, BelongsToWuxing, ValuedMultiton):
10
+ """
11
+ 地支
12
+ """
13
+
14
+ _WUXING_MAP: Dict['Dizhi', 'Wuxing']
15
+
16
+ Zi = (0, "子")
17
+ Chou = (1, "丑")
18
+ Yin = (2, "寅")
19
+ Mou = (3, "卯")
20
+ Chen = (4, "辰")
21
+ Si = (5, "巳")
22
+ Wu = (6, "午")
23
+ Wei = (7, "未")
24
+ Shen = (8, "申")
25
+ You = (9, "酉")
26
+ Xu = (10, "戌")
27
+ Hai = (11, "亥")
28
+
29
+ def is_chong(self, d: Dizhi) -> bool:
30
+ """判断地支相冲"""
31
+ return abs(self.num - d.num) == 6
32
+
33
+ def chong(self) -> Dizhi:
34
+ """返回相冲的地支"""
35
+ return Dizhi((self.num + 6) % 12)
36
+
37
+ def is_he(self, d: Dizhi) -> bool:
38
+ """判断地支相合"""
39
+ return (self.num + d.num) % 12 == 1
40
+
41
+ def he(self) -> Dizhi:
42
+ """返回相合的地支"""
43
+ return Dizhi((13 - self.num) % 12)
44
+
45
+ def belongs_to_yinyang(self) -> YinYang:
46
+ return YinYang((self.num+1) % 2)
47
+
48
+ def generate(self) -> List[Dizhi]:
49
+ r = []
50
+ w = self.belongs_to_wuxing().generate()
51
+ for d in self.all():
52
+ if d.belongs_to_wuxing() == w:
53
+ r.append(d)
54
+ return r
55
+
56
+ def restrain(self) -> List[Dizhi]:
57
+ r = []
58
+ w = self.belongs_to_wuxing().restrain()
59
+ for d in self.all():
60
+ if d.belongs_to_wuxing() == w:
61
+ r.append(d)
62
+ return r
63
+
64
+
65
+ Dizhi._WUXING_MAP = {
66
+ Dizhi.Zi: Wuxing.Water,
67
+ Dizhi.Chou: Wuxing.Earth,
68
+ Dizhi.Yin: Wuxing.Wood,
69
+ Dizhi.Mou: Wuxing.Wood,
70
+ Dizhi.Chen: Wuxing.Earth,
71
+ Dizhi.Si: Wuxing.Fire,
72
+ Dizhi.Wu: Wuxing.Fire,
73
+ Dizhi.Wei: Wuxing.Earth,
74
+ Dizhi.Shen: Wuxing.Metal,
75
+ Dizhi.You: Wuxing.Metal,
76
+ Dizhi.Xu: Wuxing.Earth,
77
+ Dizhi.Hai: Wuxing.Water,
78
+ }
@@ -0,0 +1,14 @@
1
+ from divicast.base.symbol import ValuedMultiton
2
+
3
+
4
+ class Liushen(ValuedMultiton):
5
+ """
6
+ 六神
7
+ """
8
+
9
+ QingLong = (0, "青龙")
10
+ ZhuQue = (1, "朱雀")
11
+ GouChen = (2, "勾陈")
12
+ TengShe = (3, "腾蛇")
13
+ BaiHu = (4, "白虎")
14
+ XuanWu = (5, "玄武")
@@ -0,0 +1,14 @@
1
+ from divicast.base.symbol import ValuedMultiton
2
+ from divicast.entities.wuxing import Wuxing
3
+
4
+
5
+ class Relative(ValuedMultiton):
6
+ """
7
+ 六亲
8
+ """
9
+
10
+ Brother = (0, "兄弟")
11
+ Descendant = (1, "子孙")
12
+ Parent = (2, "父母")
13
+ Governer = (3, "官鬼")
14
+ Wife = (4, "妻财")
@@ -0,0 +1,104 @@
1
+ from __future__ import annotations # 用于前向引用
2
+
3
+ from typing import ClassVar, Dict, Self
4
+
5
+ from divicast.base.symbol import ValuedMultiton
6
+ from divicast.entities.wuxing import (BelongsToWuxing, BelongsToYinYang,
7
+ Wuxing, YinYang)
8
+
9
+
10
+ class Shishen(ValuedMultiton):
11
+ """
12
+ 十神
13
+ """
14
+
15
+ BiJian = (0, "比肩")
16
+ JieCai = (1, "劫财")
17
+ ShiShen = (2, "食神")
18
+ ShangGuan = (3, "伤官")
19
+ PianCai = (4, "偏财")
20
+ ZhengCai = (5, "正财")
21
+ QiSha = (6, "七杀") # 也叫偏官
22
+ ZhengGuan = (7, "正官")
23
+ PianYin = (8, "偏印") # 也叫枭神
24
+ ZhengYin = (9, "正印")
25
+
26
+
27
+ class Tiangan(BelongsToWuxing, BelongsToYinYang, ValuedMultiton):
28
+ """
29
+ 天干
30
+ """
31
+ _WUXING_MAP: ClassVar[Dict[Tiangan, Wuxing]]
32
+
33
+ Jia = (0, "甲")
34
+ Yi = (1, "乙")
35
+ Bing = (2, "丙")
36
+ Ding = (3, "丁")
37
+ Wu = (4, "戊")
38
+ Ji = (5, "己")
39
+ Geng = (6, "庚")
40
+ Xin = (7, "辛")
41
+ Ren = (8, "壬")
42
+ Gui = (9, "癸")
43
+
44
+ def belongs_to_yinyang(self) -> YinYang:
45
+ """
46
+ 获取天干所属的阴阳
47
+ """
48
+ return YinYang((self.num+1) % 2)
49
+
50
+ def get_shishen(self, other: Self) -> Shishen:
51
+ """
52
+ 获取对应的十神
53
+ """
54
+ if self.belongs_to_wuxing() == other.belongs_to_wuxing():
55
+ # 同五行
56
+ return (
57
+ Shishen.BiJian
58
+ if self.belongs_to_yinyang() == other.belongs_to_yinyang()
59
+ else Shishen.JieCai # type: ignore
60
+ )
61
+ elif self.belongs_to_wuxing().generate() == other.belongs_to_wuxing():
62
+ # 我生对方
63
+ return (
64
+ Shishen.ShiShen
65
+ if self.belongs_to_yinyang() == other.belongs_to_yinyang()
66
+ else Shishen.ShangGuan # type: ignore
67
+ )
68
+ elif self.belongs_to_wuxing().restrain() == other.belongs_to_wuxing():
69
+ # 我克对方
70
+ return (
71
+ Shishen.PianCai
72
+ if self.belongs_to_yinyang() == other.belongs_to_yinyang()
73
+ else Shishen.ZhengCai # type: ignore
74
+ )
75
+ elif self.belongs_to_wuxing() == other.belongs_to_wuxing().restrain():
76
+ # 对方克我
77
+ return (
78
+ Shishen.QiSha
79
+ if self.belongs_to_yinyang() == other.belongs_to_yinyang()
80
+ else Shishen.ZhengGuan # type: ignore
81
+ )
82
+ elif self.belongs_to_wuxing() == other.belongs_to_wuxing().generate():
83
+ # 对方生我
84
+ return (
85
+ Shishen.PianYin
86
+ if self.belongs_to_yinyang() == other.belongs_to_yinyang()
87
+ else Shishen.ZhengYin # type: ignore
88
+ )
89
+ else:
90
+ raise ValueError("无法计算对应的十神关系")
91
+
92
+
93
+ Tiangan._WUXING_MAP = {
94
+ Tiangan.Jia: Wuxing.Wood,
95
+ Tiangan.Yi: Wuxing.Wood,
96
+ Tiangan.Bing: Wuxing.Fire,
97
+ Tiangan.Ding: Wuxing.Fire,
98
+ Tiangan.Wu: Wuxing.Earth,
99
+ Tiangan.Ji: Wuxing.Earth,
100
+ Tiangan.Geng: Wuxing.Metal,
101
+ Tiangan.Xin: Wuxing.Metal,
102
+ Tiangan.Ren: Wuxing.Water,
103
+ Tiangan.Gui: Wuxing.Water,
104
+ }