Files
moxiaonian d9da4301cd 公众授权版:normal · 1000 次 · 有效期至 2026-12-31
副本编号 LY-20261007-AC63(水印指纹已嵌入)
含 README、.gitignore;排除 .DS_Store / __pycache__ / .pytest_cache
2026-10-07 17:29:52 +08:00

180 lines
4.4 KiB
Python
Raw Permalink 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.
# -*- coding:utf-8 -*-
from __future__ import annotations
from abc import ABC, abstractmethod
from typing import Union, List
__version__ = '1.5.0'
class Culture(ABC):
"""传统文化(民俗)"""
@abstractmethod
def get_name(self) -> str:
"""
名称
:return: 名称
"""
pass
class Tyme(Culture):
@abstractmethod
def next(self, n: int) -> Union[Tyme, None]:
"""
推移
:param n: 推移步数
:return: 推移后的Tyme或None
"""
pass
class AbstractCulture(Culture):
"""传统文化抽象"""
@abstractmethod
def get_name(self) -> str:
pass
def __str__(self) -> str:
return self.get_name()
def __eq__(self, other: Culture) -> bool:
return other and other.__str__() == self.__str__()
@staticmethod
def index_of(index: int, size: int) -> int:
"""
转换为不超范围的索引
:param index: 索引
:param size: 长度大小
:return: 索引,从0开始
"""
i: int = index % size
return i + size if i < 0 else i
class AbstractTyme(AbstractCulture, Tyme):
"""抽象Tyme"""
@abstractmethod
def get_name(self) -> str:
pass
@abstractmethod
def next(self, n: int) -> Union[Tyme, None]:
pass
class AbstractCultureDay(AbstractCulture):
"""带天索引的传统文化抽象"""
def __init__(self, culture: AbstractCulture, day_index: int):
"""
初始化
:param culture: 传统文化抽象
:param day_index: 天索引
"""
self._culture = culture
self._day_index = day_index
def get_day_index(self) -> int:
"""
天索引
:return: 索引
"""
return self._day_index
def get_culture(self) -> AbstractCulture:
return self._culture
def get_name(self) -> str:
return self._culture.get_name()
def __str__(self) -> str:
return f'{self.get_name()}第{self.get_day_index() + 1}天'
class LoopTyme(AbstractTyme):
"""可轮回的Tyme"""
def __init__(self, names: List[str], index_or_name: Union[int, str]):
"""
初始化
:param names: 名称列表
:param index_or_name: 索引,支持负数,自动轮转; 名称
"""
self._names = names
self._index = self._index_of_by(index_or_name)
def _index_of_by(self, index_or_name: Union[int, str]) -> int:
"""
:param index_or_name: 索引或名称
:return: 索引
"""
if isinstance(index_or_name, int):
return self.index_of(index_or_name, self.get_size())
else:
for i in range(0, self.get_size()):
if index_or_name == self._names[i]:
return i
raise ValueError(f"illegal name: {index_or_name}")
def get_name(self) -> str:
return self._names[self._index]
def get_index(self) -> int:
"""
索引
:return: 索引,从0开始
"""
return self._index
def get_size(self) -> int:
"""
数量
:return: 数量
"""
return self._names.__len__()
def next_index(self, n: int) -> int:
"""
推移后的索引
:param n: 推移步数
:return: 索引,从0开始
"""
return self._index_of_by(self._index + n)
def steps_to(self, target_index: int) -> int:
"""
到目标索引的步数(从左往右顺序)
:param target_index: 目标索引
:return: 步数(>=0)
"""
return self.index_of(target_index - self._index, self.get_size())
def steps_back_to(self, target_index: int) -> int:
"""
到目标索引的步数(从右往左逆序)
:param target_index: 目标索引
:return: 步数(<=0)
"""
n = self.get_size()
return -((self._index - target_index + n) % n)
def steps_close_to(self, target_index: int) -> int:
"""
到目标索引的最少步数
:param target_index: 目标索引
:return: 步数(从左往右顺序>=0,从右往左逆序<=0)
"""
d1 = self.steps_to(target_index)
d2 = self.steps_back_to(target_index)
if d1 <= abs(d2):
return d1
return d2
@abstractmethod
def next(self, n: int) -> Union[LoopTyme, None]:
pass