From 38f720aa7bd041a1436fc773f6e388f733b46f1b Mon Sep 17 00:00:00 2001 From: david-ajax Date: Wed, 17 Dec 2025 20:52:11 +0800 Subject: [PATCH] format --- CONTRIBUTING.md | 20 +-- README.md | 40 +++--- data/template/template_1.toml | 130 +++++++++--------- src/heurams/context.py | 4 +- src/heurams/interface/screens/nucreator.py | 2 +- src/heurams/interface/widgets/basic_puzzle.py | 2 +- src/heurams/kernel/algorithms/__init__.py | 2 +- src/heurams/kernel/algorithms/base.py | 8 +- src/heurams/kernel/algorithms/sm2.py | 14 +- src/heurams/kernel/particles/atom.py | 16 +-- src/heurams/kernel/particles/electron.py | 20 +-- src/heurams/kernel/particles/loader.py | 10 +- src/heurams/kernel/particles/nucleon.py | 2 +- src/heurams/kernel/particles/probe.py | 4 +- src/heurams/kernel/puzzles/__init__.py | 4 +- src/heurams/kernel/puzzles/cloze.py | 2 +- src/heurams/kernel/reactor/phaser.py | 4 +- src/heurams/kernel/reactor/procession.py | 4 +- src/heurams/providers/tts/base.py | 2 +- src/heurams/providers/tts/edge_tts.py | 2 +- src/heurams/services/audio_service.py | 2 +- src/heurams/services/config.py | 2 +- src/heurams/services/logger.py | 6 +- src/heurams/services/tts_service.py | 2 +- tests/interface/test_dashboard.py | 32 ++--- tests/kernel/algorithms/test_sm2.py | 10 +- tests/kernel/particles/test_electron.py | 6 +- tests/kernel/puzzles/test_cloze.py | 2 +- tests/kernel/puzzles/test_mcq.py | 4 +- tests/kernel/reactor/test_phaser.py | 4 +- 30 files changed, 181 insertions(+), 181 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b77726e..8f964fe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,25 +5,25 @@ ## 开发流程 -1. **分支划分**: - - `main` 分支:稳定版本 - - `develop` 分支:开发版本 - - 功能分支:从 `develop` 分支创建,命名格式为 `feature/描述` 或 `fix/描述` -2. **代码风格**: +1. **分支划分**: + - `main` 分支: 稳定版本 + - `develop` 分支: 开发版本 + - 功能分支: 从 `develop` 分支创建, 命名格式为 `feature/描述` 或 `fix/描述` +2. **代码风格**: - 请使用 Black 格式化代码 - 遵循 PEP 8 规范 - 添加适当的文档字符串 -3. **提交消息**: +3. **提交消息**: - 使用中文或英文撰写清晰的提交消息 - - 格式:`类型: 描述`,例如 `fix: 修复登录错误` 或 `feat: 添加新算法` -4. **测试**: + - 格式: `类型: 描述`, 例如 `fix: 修复登录错误` 或 `feat: 添加新算法` +4. **测试**: - 为新功能添加单元测试 - 确保所有测试通过 - 运行 `pytest` 检查 ## 项目结构 -请参阅 README.md 中的项目结构部分,了解代码组织方式。 +请参阅 README.md 中的项目结构部分, 了解代码组织方式. ## 设置开发环境 @@ -41,4 +41,4 @@ pip install -e . ## 许可证 -贡献者同意其贡献将在 AGPL-3.0 许可证下发布。 +贡献者同意其贡献将在 AGPL-3.0 许可证下发布. diff --git a/README.md b/README.md index 48674bf..3143d29 100644 --- a/README.md +++ b/README.md @@ -19,17 +19,17 @@ ## 特性 ### 间隔迭代算法 -> 许多出版物都广泛讨论了不同重复间隔对学习效果的影响。特别是,间隔效应被认为是一种普遍现象。间隔效应是指,如果重复的间隔是分散/稀疏的,而不是集中重复,那么学习任务的表现会更好。因此,有观点提出,学习中使用的最佳重复间隔是**最长的、但不会导致遗忘的间隔**。 +> 许多出版物都广泛讨论了不同重复间隔对学习效果的影响. 特别是, 间隔效应被认为是一种普遍现象. 间隔效应是指, 如果重复的间隔是分散/稀疏的, 而不是集中重复, 那么学习任务的表现会更好. 因此, 有观点提出, 学习中使用的最佳重复间隔是**最长的、但不会导致遗忘的间隔**. - 采用经实证的 SM-2 间隔迭代算法, 此算法亦用作 Anki 闪卡记忆软件的默认闪卡调度器 - 动态规划每个记忆单元的记忆间隔时间表 -- 动态跟踪记忆反馈数据,优化长期记忆保留率与稳定性 +- 动态跟踪记忆反馈数据, 优化长期记忆保留率与稳定性 ### 学习进程优化 -- 逐字解析:支持逐字详细释义解析 -- 语法分析:接入生成式人工智能, 支持古文结构交互式解析 -- 自然语音:集成微软神经网络文本转语音 (TTS) 技术 -- 多种谜题类型:选择题 (MCQ)、填空题 (Cloze)、识别题 (Recognition) -- 动态内容生成:支持宏驱动的模板系统,根据上下文动态生成题目 +- 逐字解析: 支持逐字详细释义解析 +- 语法分析: 接入生成式人工智能, 支持古文结构交互式解析 +- 自然语音: 集成微软神经网络文本转语音 (TTS) 技术 +- 多种谜题类型: 选择题 (MCQ)、填空题 (Cloze)、识别题 (Recognition) +- 动态内容生成: 支持宏驱动的模板系统, 根据上下文动态生成题目 ### 实用用户界面 - 响应式 Textual 框架构建的跨平台 TUI 界面 @@ -37,27 +37,27 @@ - 简洁直观的复习流程设计 ### 架构特性 -- 模块化设计:算法、谜题、服务提供者可插拔替换 -- 上下文管理:使用 ContextVar 实现隐式依赖注入 -- 数据持久化:TOML 配置与内容,JSON 算法状态 -- 服务抽象:音频播放、TTS、LLM 通过 provider 架构支持多种后端 -- 完整日志系统:带轮转的日志记录,便于调试 +- 模块化设计: 算法、谜题、服务提供者可插拔替换 +- 上下文管理: 使用 ContextVar 实现隐式依赖注入 +- 数据持久化: TOML 配置与内容, JSON 算法状态 +- 服务抽象: 音频播放、TTS、LLM 通过 provider 架构支持多种后端 +- 完整日志系统: 带轮转的日志记录, 便于调试 ## 安装 ### 从源码安装 -1. 克隆仓库: +1. 克隆仓库: ```bash git clone https://gitea.imwangzhiyu.xyz/ajax/heurams.git HeurAMS cd HeurAMS ``` -2. 安装依赖: +2. 安装依赖: ```bash pip install -r requirements.txt ``` -3. 以开发模式安装包: +3. 以开发模式安装包: ```bash pip install -e . ``` @@ -71,7 +71,7 @@ python -m heurams.interface ``` ### 数据目录结构 -应用会在工作目录下创建以下数据目录: +应用会在工作目录下创建以下数据目录: - `data/nucleon/`: 记忆内容 (TOML 格式) - `data/electron/`: 算法状态 (JSON 格式) - `data/orbital/`: 策略配置 (TOML 格式) @@ -82,13 +82,13 @@ python -m heurams.interface ## 配置 -配置文件位于 `config/config.toml`(相对于工作目录)。如果不存在,会使用内置的默认配置。 +配置文件位于 `config/config.toml`(相对于工作目录). 如果不存在, 会使用内置的默认配置. ## 项目结构 ### 架构图 -以下 Mermaid 图展示了 HeurAMS 的主要组件及其关系: +以下 Mermaid 图展示了 HeurAMS 的主要组件及其关系: ```mermaid graph TB @@ -175,8 +175,8 @@ src/heurams/ ## 贡献 -欢迎贡献!请参阅 [CONTRIBUTING.md](CONTRIBUTING.md) 了解贡献指南。 +欢迎贡献!请参阅 [CONTRIBUTING.md](CONTRIBUTING.md) 了解贡献指南. ## 许可证 -本项目基于 AGPL-3.0 许可证开源。详见 [LICENSE](LICENSE) 文件。 \ No newline at end of file +本项目基于 AGPL-3.0 许可证开源. 详见 [LICENSE](LICENSE) 文件. \ No newline at end of file diff --git a/data/template/template_1.toml b/data/template/template_1.toml index 8ce3e46..c5e774f 100644 --- a/data/template/template_1.toml +++ b/data/template/template_1.toml @@ -32,359 +32,359 @@ final_review = [["FillBlank", "0.7"], ["SelectMeaning", "0.7"], ["recognition", ["秦孝公据崤函之固, 拥雍州之地,"] note = [] content = "秦孝公/据/崤函/之固/, 拥/雍州/之地,/" -translation = "秦孝公占据着崤山和函谷关的险固地势,拥有雍州的土地," +translation = "秦孝公占据着崤山和函谷关的险固地势, 拥有雍州的土地, " keyword_note = {"据"="占据", "崤函"="崤山和函谷关", "雍州"="古代九州之一"} ["君臣固守以窥周室,"] note = [] content = "君臣/固守/以窥/周室,/" -translation = "君臣牢固地守卫着,借以窥视周王室的权力," +translation = "君臣牢固地守卫着, 借以窥视周王室的权力, " keyword_note = {"窥"="窥视"} ["有席卷天下, 包举宇内, 囊括四海之意, 并吞八荒之心."] note = [] content = "有/席卷/天下/, 包举/宇内/, 囊括/四海/之意/, 并吞/八荒/之心./" -translation = "有席卷天下,包办天宇之间,囊括四海的意图,并统天下的雄心。" +translation = "有席卷天下, 包办天宇之间, 囊括四海的意图, 并统天下的雄心. " keyword_note = {"席卷"="像卷席子一样全部卷进去", "包举"="像打包一样全部拿走", "囊括"="像装口袋一样全部装进去", "八荒"="八方荒远之地"} ["当是时也, 商君佐之,"] note = [] content = "当是时也/, 商君/佐之,/" -translation = "正当这时,商鞅辅佐他," +translation = "正当这时, 商鞅辅佐他, " keyword_note = {"商君"="商鞅"} ["内立法度, 务耕织, 修守战之具,"] note = [] content = "内/立法度/, 务/耕织/, 修/守战/之具,/" -translation = "对内建立法规制度,从事耕作纺织,修造防守和进攻的器械;" +translation = "对内建立法规制度, 从事耕作纺织, 修造防守和进攻的器械; " keyword_note = {"法度"="法规制度", "务"="从事", "耕织"="耕作纺织", "守战之具"="防守和进攻的器械"} ["外连衡而斗诸侯."] note = [] content = "外/连衡/而斗/诸侯./" -translation = "对外实行连衡策略,使诸侯自相争斗。" +translation = "对外实行连衡策略, 使诸侯自相争斗. " keyword_note = {"连衡"="连横策略", "斗"="使...相斗"} ["于是秦人拱手而取西河之外."] note = [] content = "于是/秦人/拱手/而取/西河/之外./" -translation = "因此,秦人轻而易举地夺取了黄河以西的土地。" -keyword_note = {"拱手"="两手相合,形容毫不费力", "西河"="黄河以西地区"} +translation = "因此, 秦人轻而易举地夺取了黄河以西的土地. " +keyword_note = {"拱手"="两手相合, 形容毫不费力", "西河"="黄河以西地区"} ["孝公既没, 惠文、武、昭襄蒙故业, 因遗策,"] note = [] content = "孝公/既没/, 惠文/、武/、昭襄/蒙/故业/, 因/遗策,/" -translation = "秦孝公死了以后,惠文王、武王、昭襄王承继先前的基业,沿袭前代的策略," +translation = "秦孝公死了以后, 惠文王、武王、昭襄王承继先前的基业, 沿袭前代的策略, " keyword_note = {"既没"="死后", "蒙"="承继", "故业"="先前的基业", "因"="沿袭", "遗策"="前代的策略"} ["南取汉中, 西举巴、蜀, 东割膏腴之地, 北收要害之郡."] note = [] content = "南取/汉中/, 西举/巴/、蜀/, 东割/膏腴/之地/, 北收/要害/之郡./" -translation = "向南夺取汉中,向西攻取巴、蜀,向东割取肥沃的地区,向北占领非常重要的地区。" +translation = "向南夺取汉中, 向西攻取巴、蜀, 向东割取肥沃的地区, 向北占领非常重要的地区. " keyword_note = {"膏腴"="肥沃", "要害"="非常重要"} ["诸侯恐惧, 会盟而谋弱秦,"] note = [] content = "诸侯/恐惧/, 会盟/而谋/弱秦,/" -translation = "诸侯恐慌害怕,集会结盟,商议削弱秦国。" +translation = "诸侯恐慌害怕, 集会结盟, 商议削弱秦国. " keyword_note = {"会盟"="集会结盟", "弱秦"="削弱秦国"} ["不爱珍器重宝肥饶之地, 以致天下之士,"] note = [] content = "不爱/珍器/重宝/肥饶/之地/, 以致/天下/之士,/" -translation = "不吝惜奇珍贵重的器物和肥沃富饶的土地,用来招纳天下的优秀人才," +translation = "不吝惜奇珍贵重的器物和肥沃富饶的土地, 用来招纳天下的优秀人才, " keyword_note = {"不爱"="不吝惜", "珍器重宝"="奇珍贵重的器物", "以致"="用来招纳"} ["合从缔交, 相与为一."] note = [] content = "合从/缔交/, 相与/为一./" -translation = "采用合纵的策略缔结盟约,互相援助,成为一体。" +translation = "采用合纵的策略缔结盟约, 互相援助, 成为一体. " keyword_note = {"合从"="合纵策略", "缔交"="缔结盟约"} ["当此之时, 齐有孟尝, 赵有平原, 楚有春申, 魏有信陵."] note = [] content = "当此/之时/, 齐有/孟尝/, 赵有/平原/, 楚有/春申/, 魏有/信陵./" -translation = "在这个时候,齐国有孟尝君,赵国有平原君,楚国有春申君,魏国有信陵君。" +translation = "在这个时候, 齐国有孟尝君, 赵国有平原君, 楚国有春申君, 魏国有信陵君. " keyword_note = {"孟尝"="孟尝君田文", "平原"="平原君赵胜", "春申"="春申君黄歇", "信陵"="信陵君魏无忌"} ["此四君者, 皆明智而忠信, 宽厚而爱人, 尊贤而重士,"] note = [] content = "此/四君/者/, 皆/明智/而/忠信/, 宽厚/而/爱人/, 尊贤/而/重士,/" -translation = "这四位封君,都见识英明有智谋,心地诚而讲信义,待人宽宏厚道而爱惜人民,尊重贤才而重用士人," +translation = "这四位封君, 都见识英明有智谋, 心地诚而讲信义, 待人宽宏厚道而爱惜人民, 尊重贤才而重用士人, " keyword_note = {"明智"="见识英明有智谋", "忠信"="心地诚而讲信义", "爱人"="爱惜人民", "尊贤"="尊重贤才", "重士"="重用士人"} ["约从离衡, 兼韩、魏、燕、楚、齐、赵、宋、卫、中山之众."] note = [] content = "约从/离衡/, 兼/韩/、魏/、燕/、楚/、齐/、赵/、宋/、卫/、中山/之众./" -translation = "以合纵之约击破秦的连横之策,联合韩、魏、燕、楚、齐、赵、宋、卫、中山的部队。" +translation = "以合纵之约击破秦的连横之策, 联合韩、魏、燕、楚、齐、赵、宋、卫、中山的部队. " keyword_note = {"约从"="采用合纵策略", "离衡"="破坏连横策略", "兼"="联合"} ["于是六国之士, 有甯越、徐尚、苏秦、杜赫之属为之谋,"] note = [] content = "于是/六国/之士/, 有/甯越/、徐尚/、苏秦/、杜赫/之属/为之/谋,/" -translation = "在这时,六国的士人,有宁越、徐尚、苏秦、杜赫等人为他们出谋划策," +translation = "在这时, 六国的士人, 有宁越、徐尚、苏秦、杜赫等人为他们出谋划策, " keyword_note = {"之属"="等人", "为之谋"="为他们出谋划策"} ["齐明、周最、陈轸、召滑、楼缓、翟景、苏厉、乐毅之徒通其意,"] note = [] content = "齐明/、周最/、陈轸/、召滑/、楼缓/、翟景/、苏厉/、乐毅/之徒/通其/意,/" -translation = "齐明、周最、陈轸、召滑、楼缓、翟景、苏厉、乐毅等人沟通他们的意见," +translation = "齐明、周最、陈轸、召滑、楼缓、翟景、苏厉、乐毅等人沟通他们的意见, " keyword_note = {"之徒"="等人", "通其意"="沟通他们的意见"} ["吴起、孙膑、带佗、倪良、王廖、田忌、廉颇、赵奢之伦制其兵."] note = [] content = "吴起/、孙膑/、带佗/、倪良/、王廖/、田忌/、廉颇/、赵奢/之伦/制其/兵./" -translation = "吴起、孙膑、带佗、倪良、王廖、田忌、廉颇、赵奢等人统率他们的军队。" +translation = "吴起、孙膑、带佗、倪良、王廖、田忌、廉颇、赵奢等人统率他们的军队. " keyword_note = {"之伦"="等人", "制其兵"="统率他们的军队"} ["尝以十倍之地, 百万之众, 叩关而攻秦."] note = [] content = "尝以/十倍/之地/, 百万/之众/, 叩关/而攻/秦./" -translation = "他们曾经用十倍于秦的土地,上百万的军队,攻打函谷关来攻打秦国。" +translation = "他们曾经用十倍于秦的土地, 上百万的军队, 攻打函谷关来攻打秦国. " keyword_note = {"尝"="曾经", "以"="用", "叩关"="攻打函谷关"} ["秦人开关延敌, 九国之师, 逡巡而不敢进."] note = [] content = "秦人/开关/延敌/, 九国/之师/, 逡巡/而不敢/进./" -translation = "秦人打开函谷关口迎战敌人,九国的军队有所顾虑徘徊不敢入关。" +translation = "秦人打开函谷关口迎战敌人, 九国的军队有所顾虑徘徊不敢入关. " keyword_note = {"开关"="打开函谷关", "延敌"="迎战敌人", "九国"="九个国家", "逡巡"="有所顾虑徘徊"} ["秦无亡矢遗镞之费, 而天下诸侯已困矣."] note = [] content = "秦/无/亡矢/遗镞/之费/, 而/天下/诸侯/已困/矣./" -translation = "秦人没有一兵一卒的耗费,然而天下的诸侯就已窘迫不堪了。" +translation = "秦人没有一兵一卒的耗费, 然而天下的诸侯就已窘迫不堪了. " keyword_note = {"亡矢"="丢失箭矢", "遗镞"="遗失箭头", "费"="耗费", "困"="窘迫不堪"} ["于是从散约败, 争割地而赂秦."] note = [] content = "于是/从散/约败/, 争/割地/而赂/秦./" -translation = "因此,纵约失败了,各诸侯国争着割地来贿赂秦国。" +translation = "因此, 纵约失败了, 各诸侯国争着割地来贿赂秦国. " keyword_note = {"从散"="纵约失败", "约败"="盟约破坏", "赂"="贿赂"} ["秦有余力而制其弊, 追亡逐北, 伏尸百万, 流血漂橹;"] note = [] content = "秦/有余力/而制/其弊/, 追亡/逐北/, 伏尸/百万/, 流血/漂橹; /" -translation = "秦有剩余的力量趁他们困乏而制服他们,追赶逃走的败兵,百万败兵横尸道路,流淌的血液可以漂浮盾牌;" +translation = "秦有剩余的力量趁他们困乏而制服他们, 追赶逃走的败兵, 百万败兵横尸道路, 流淌的血液可以漂浮盾牌; " keyword_note = {"制其弊"="趁他们困乏而制服他们", "追亡"="追赶逃兵", "逐北"="追逐败兵", "伏尸"="横尸", "漂橹"="漂浮盾牌"} ["因利乘便, 宰割天下, 分裂山河."] note = [] content = "因利/乘便/, 宰割/天下/, 分裂/山河./" -translation = "秦国凭借这便利的形势,割取天下的土地,重新划分山河的区域。" +translation = "秦国凭借这便利的形势, 割取天下的土地, 重新划分山河的区域. " keyword_note = {"因利乘便"="凭借便利的形势", "宰割"="割取", "分裂"="划分"} ["强国请服, 弱国入朝."] note = [] content = "强国/请服/, 弱国/入朝./" -translation = "强国主动表示臣服,弱国入秦朝拜。" +translation = "强国主动表示臣服, 弱国入秦朝拜. " keyword_note = {"请服"="请求臣服", "入朝"="入秦朝拜"} ["延及孝文王、庄襄王, 享国之日浅, 国家无事."] note = [] content = "延及/孝文王/、庄襄王/, 享国/之日/浅/, 国家/无事./" -translation = "延续到孝文王、庄襄王,统治的时间不长,秦国并没有什么大事发生。" +translation = "延续到孝文王、庄襄王, 统治的时间不长, 秦国并没有什么大事发生. " keyword_note = {"延及"="延续到", "享国"="统治国家", "浅"="时间短", "无事"="没有大事发生"} ["及至始皇, 奋六世之余烈, 振长策而御宇内,"] note = [] content = "及至/始皇/, 奋/六世/之余烈/, 振/长策/而御/宇内,/" -translation = "到始皇的时候,发展六世遗留下来的功业,以武力来统治各国," +translation = "到始皇的时候, 发展六世遗留下来的功业, 以武力来统治各国, " keyword_note = {"奋"="发展", "余烈"="遗留下来的功业", "振长策"="挥动长鞭", "御宇内"="统治天下"} ["吞二周而亡诸侯, 履至尊而制六合,"] note = [] content = "吞/二周/而亡/诸侯/, 履/至尊/而制/六合,/" -translation = "将东周,西周和各诸侯国统统消灭,登上皇帝的宝座来统治天下," +translation = "将东周, 西周和各诸侯国统统消灭, 登上皇帝的宝座来统治天下, " keyword_note = {"吞"="吞并", "二周"="东周和西周", "履至尊"="登上皇位", "制六合"="统治天下"} ["执敲扑而鞭笞天下, 威振四海."] note = [] content = "执/敲扑/而鞭笞/天下/, 威振/四海./" -translation = "用严酷的刑罚来奴役天下的百姓,威风震慑四海。" -keyword_note = {"敲扑"="刑具", "鞭笞"="鞭打,奴役", "威振"="威风震慑"} +translation = "用严酷的刑罚来奴役天下的百姓, 威风震慑四海. " +keyword_note = {"敲扑"="刑具", "鞭笞"="鞭打, 奴役", "威振"="威风震慑"} ["南取百越之地, 以为桂林、象郡;"] note = [] content = "南取/百越/之地/, 以为/桂林/、象郡; /" -translation = "秦始皇向南攻取百越的土地,把它划为桂林郡和象郡;" +translation = "秦始皇向南攻取百越的土地, 把它划为桂林郡和象郡; " keyword_note = {"百越"="古代南方少数民族", "以为"="把它作为"} ["百越之君, 俯首系颈, 委命下吏."] note = [] content = "百越/之君/, 俯首/系颈/, 委命/下吏./" -translation = "百越的君主低着头,颈上捆着绳子愿意服从投降,把性命交给司法官吏。" +translation = "百越的君主低着头, 颈上捆着绳子愿意服从投降, 把性命交给司法官吏. " keyword_note = {"俯首"="低头", "系颈"="颈上捆着绳子", "委命"="把性命交给", "下吏"="司法官吏"} ["乃使蒙恬北筑长城而守藩篱, 却匈奴七百余里;"] note = [] content = "乃使/蒙恬/北筑/长城/而守/藩篱/, 却/匈奴/七百/余里; /" -translation = "秦始皇于是又命令蒙恬在北方修筑长城,守卫边境,使匈奴退却七百多里;" +translation = "秦始皇于是又命令蒙恬在北方修筑长城, 守卫边境, 使匈奴退却七百多里; " keyword_note = {"蒙恬"="秦朝名将", "藩篱"="边境", "却"="使...退却", "匈奴"="北方少数民族"} ["胡人不敢南下而牧马, 士不敢弯弓而报怨."] note = [] content = "胡人/不敢/南下/而牧马/, 士/不敢/弯弓/而报怨./" -translation = "胡人不敢向下到南边来放牧,勇士不敢拉弓射箭来报仇。" +translation = "胡人不敢向下到南边来放牧, 勇士不敢拉弓射箭来报仇. " keyword_note = {"胡人"="指匈奴人", "牧马"="放牧", "弯弓"="拉弓", "报怨"="报仇"} ["于是废先王之道, 焚百家之言, 以愚黔首;"] note = [] content = "于是/废/先王/之道/, 焚/百家/之言/, 以愚/黔首; /" -translation = "秦始皇接着就废除古代帝王的治世之道,焚烧诸子百家的著作,来使百姓愚蠢;" +translation = "秦始皇接着就废除古代帝王的治世之道, 焚烧诸子百家的著作, 来使百姓愚蠢; " keyword_note = {"先王"="古代帝王", "道"="治世之道", "百家之言"="诸子百家的著作", "愚"="使...愚蠢", "黔首"="百姓"} ["隳名城, 杀豪杰;"] note = [] content = "隳/名城/, 杀/豪杰; /" -translation = "毁坏高大的城墙,杀掉英雄豪杰;" +translation = "毁坏高大的城墙, 杀掉英雄豪杰; " keyword_note = {"隳"="毁坏", "名城"="高大的城墙"} ["收天下之兵, 聚之咸阳, 销锋镝, 铸以为金人十二, 以弱天下之民."] note = [] content = "收/天下/之兵/, 聚之/咸阳/, 销/锋镝/, 铸以为/金人/十二/, 以弱/天下/之民./" -translation = "收缴天下的兵器,集中在咸阳,销毁兵刃和箭头,冶炼它们铸造十二个铜人,以便削弱百姓的反抗力量。" +translation = "收缴天下的兵器, 集中在咸阳, 销毁兵刃和箭头, 冶炼它们铸造十二个铜人, 以便削弱百姓的反抗力量. " keyword_note = {"兵"="兵器", "销"="销毁", "锋镝"="兵刃和箭头", "铸以为"="铸造成为", "金人"="铜人", "弱"="削弱"} ["然后践华为城, 因河为池,"] note = [] content = "然后/践华/为城/, 因河/为池,/" -translation = "然后凭借华山为城墙,依据黄河为城池," +translation = "然后凭借华山为城墙, 依据黄河为城池, " keyword_note = {"践华"="凭借华山", "因河"="依据黄河", "为城"="作为城墙", "为池"="作为护城河"} ["据亿丈之城, 临不测之渊, 以为固."] note = [] content = "据/亿丈/之城/, 临/不测/之渊/, 以为/固./" -translation = "凭借着高耸的华山,往下看着深不可测的黄河,认为这是险固的地方。" +translation = "凭借着高耸的华山, 往下看着深不可测的黄河, 认为这是险固的地方. " keyword_note = {"亿丈"="形容极高", "不测"="深不可测", "渊"="深水", "固"="险固"} ["良将劲弩守要害之处, 信臣精卒陈利兵而谁何."] note = [] content = "良将/劲弩/守/要害/之处/, 信臣/精卒/陈/利兵/而谁何./" -translation = "好的将领手执强弩,守卫着要害的地方,可靠的官员和精锐的士卒,拿着锋利的兵器,盘问过往行人。" -keyword_note = {"劲弩"="强弩", "要害"="重要关键", "信臣"="可靠的官员", "精卒"="精锐的士卒", "陈"="陈列,拿着", "利兵"="锋利的兵器", "谁何"="盘问行人"} +translation = "好的将领手执强弩, 守卫着要害的地方, 可靠的官员和精锐的士卒, 拿着锋利的兵器, 盘问过往行人. " +keyword_note = {"劲弩"="强弩", "要害"="重要关键", "信臣"="可靠的官员", "精卒"="精锐的士卒", "陈"="陈列, 拿着", "利兵"="锋利的兵器", "谁何"="盘问行人"} ["天下已定, 始皇之心, 自以为关中之固, 金城千里, 子孙帝王万世之业也."] note = [] content = "天下/已定/, 始皇/之心/, 自以为/关中/之固/, 金城/千里/, 子孙/帝王/万世/之业/也./" -translation = "天下已经安定,始皇心里自己认为这关中的险固地势、方圆千里的坚固的城防,是子子孙孙称帝称王直至万代的基业。" +translation = "天下已经安定, 始皇心里自己认为这关中的险固地势、方圆千里的坚固的城防, 是子子孙孙称帝称王直至万代的基业. " keyword_note = {"自以为"="自己认为", "关中"="函谷关以西地区", "固"="险固地势", "金城"="坚固的城池", "帝王"="称帝称王", "万世"="万代"} ["始皇既没, 余威震于殊俗."] note = [] content = "始皇/既没/, 余威/震于/殊俗./" -translation = "始皇去世之后,他的余威依然震慑着边远地区。" -keyword_note = {"既没"="死后", "余威"="剩余的威势", "震"="震慑", "殊俗"="不同的风俗,指边远地区"} +translation = "始皇去世之后, 他的余威依然震慑着边远地区. " +keyword_note = {"既没"="死后", "余威"="剩余的威势", "震"="震慑", "殊俗"="不同的风俗, 指边远地区"} ["然陈涉瓮牖绳枢之子, 氓隶之人, 而迁徙之徒也;"] note = [] content = "然/陈涉/瓮牖/绳枢/之子/, 氓隶/之人/, 而/迁徙/之徒/也; /" -translation = "可是,陈涉不过是个破瓮做窗户、草绳做户枢的贫家子弟,是氓、隶一类的人,后来做了被迁谪戍边的卒子;" +translation = "可是, 陈涉不过是个破瓮做窗户、草绳做户枢的贫家子弟, 是氓、隶一类的人, 后来做了被迁谪戍边的卒子; " keyword_note = {"瓮牖"="用破瓮做窗户", "绳枢"="用草绳系户枢", "氓隶"="平民和奴隶", "迁徙之徒"="被征发戍边的人"} ["才能不及中人, 非有仲尼、墨翟之贤, 陶朱、猗顿之富;"] note = [] content = "才能/不及/中人/, 非有/仲尼/、墨翟/之贤/, 陶朱/、猗顿/之富; /" -translation = "才能不如普通人,并没有孔丘、墨翟那样的贤德,也不像陶朱、猗顿那样富有。" +translation = "才能不如普通人, 并没有孔丘、墨翟那样的贤德, 也不像陶朱、猗顿那样富有. " keyword_note = {"中人"="普通人", "仲尼"="孔子", "墨翟"="墨子", "陶朱"="范蠡", "猗顿"="春秋时富商"} ["蹑足行伍之间, 而倔起阡陌之中,"] note = [] content = "蹑足/行伍/之间/, 而/倔起/阡陌/之中,/" -translation = "他跻身于戍卒的队伍中,从田野间突然奋起发难," +translation = "他跻身于戍卒的队伍中, 从田野间突然奋起发难, " keyword_note = {"蹑足"="置身于", "行伍"="军队", "倔起"="突然奋起", "阡陌"="田野"} ["率疲弊之卒, 将数百之众, 转而攻秦;"] note = [] content = "率/疲弊/之卒/, 将/数百/之众/, 转而/攻秦; /" -translation = "率领着疲惫无力的士兵,指挥着几百人的队伍,掉转头来进攻秦国;" +translation = "率领着疲惫无力的士兵, 指挥着几百人的队伍, 掉转头来进攻秦国; " keyword_note = {"疲弊"="疲惫无力", "将"="率领"} ["斩木为兵, 揭竿为旗,"] note = [] content = "斩木/为兵/, 揭竿/为旗,/" -translation = "砍下树木作武器,举起竹竿当旗帜," +translation = "砍下树木作武器, 举起竹竿当旗帜, " keyword_note = {"斩木为兵"="砍树木作武器", "揭竿为旗"="举竹竿当旗帜"} ["天下云集响应, 赢粮而景从."] note = [] content = "天下/云集/响应/, 赢粮/而景从./" -translation = "天下豪杰像云一样聚集,回声似的应和他,许多人都背着粮食,如影随形。" +translation = "天下豪杰像云一样聚集, 回声似的应和他, 许多人都背着粮食, 如影随形. " keyword_note = {"云集"="像云一样聚集", "响应"="像回声一样应和", "赢粮"="背着粮食", "景从"="如影随形"} ["山东豪俊遂并起而亡秦族矣."] note = [] content = "山东/豪俊/遂/并起/而亡/秦族/矣./" -translation = "崤山以东的英雄豪杰于是一齐起事,消灭了秦的家族。" +translation = "崤山以东的英雄豪杰于是一齐起事, 消灭了秦的家族. " keyword_note = {"山东"="崤山以东", "豪俊"="英雄豪杰", "并起"="一齐起事", "亡"="消灭", "秦族"="秦的家族"} ["且夫天下非小弱也, 雍州之地, 崤函之固, 自若也."] note = [] content = "且夫/天下/非/小弱/也/, 雍州/之地/, 崤函/之固/, 自若/也./" -translation = "况且那天下并没有缩小削弱,雍州的地势,崤山和函谷关的险固,是保持原来的样子。" +translation = "况且那天下并没有缩小削弱, 雍州的地势, 崤山和函谷关的险固, 是保持原来的样子. " keyword_note = {"且夫"="况且", "小弱"="变小削弱", "自若"="保持原样"} ["陈涉之位, 非尊于齐、楚、燕、赵、韩、魏、宋、卫、中山之君也;"] note = [] content = "陈涉/之位/, 非/尊于/齐/、楚/、燕/、赵/、韩/、魏/、宋/、卫/、中山/之君/也; /" -translation = "陈涉的地位,没有比齐、楚、燕、赵、韩、魏、宋、卫、中山的国君更加尊贵;" +translation = "陈涉的地位, 没有比齐、楚、燕、赵、韩、魏、宋、卫、中山的国君更加尊贵; " keyword_note = {"尊于"="比...尊贵"} ["锄櫌棘矜, 非铦于钩戟长铩也;"] note = [] content = "锄櫌/棘矜/, 非/铦于/钩戟/长铩/也; /" -translation = "锄头木棍也不比钩戟长矛更锋利;" +translation = "锄头木棍也不比钩戟长矛更锋利; " keyword_note = {"锄櫌"="锄头", "棘矜"="木棍", "铦于"="比...锋利", "钩戟"="带钩的戟", "长铩"="长矛"} ["谪戍之众, 非抗于九国之师也;"] note = [] content = "谪戍/之众/, 非/抗于/九国/之师/也; /" -translation = "那迁谪戍边的士兵也不能和九国部队抗衡;" +translation = "那迁谪戍边的士兵也不能和九国部队抗衡; " keyword_note = {"谪戍"="被贬戍边", "抗于"="和...抗衡", "九国"="九个国家"} ["深谋远虑, 行军用兵之道, 非及乡时之士也."] note = [] content = "深谋/远虑/, 行军/用兵/之道/, 非及/乡时/之士/也./" -translation = "深谋远虑,行军用兵的方法,也比不上先前九国的武将谋臣。" +translation = "深谋远虑, 行军用兵的方法, 也比不上先前九国的武将谋臣. " keyword_note = {"深谋远虑"="深谋远虑", "行军用兵"="行军作战", "非及"="比不上", "乡时"="先前"} ["然而成败异变, 功业相反, 何也?"] note = [] content = "然而/成败/异变/, 功业/相反/, 何也?/" -translation = "可是条件好者失败而条件差者成功,功业完全相反,为什么呢?" +translation = "可是条件好者失败而条件差者成功, 功业完全相反, 为什么呢? " keyword_note = {"成败异变"="成功失败发生变化", "功业相反"="功业完全相反"} ["试使山东之国与陈涉度长絜大, 比权量力,"] note = [] content = "试使/山东/之国/与/陈涉/度长/絜大/, 比权/量力,/" -translation = "假使拿东方诸侯国跟陈涉比一比长短大小,量一量权势力量," +translation = "假使拿东方诸侯国跟陈涉比一比长短大小, 量一量权势力量, " keyword_note = {"试使"="假使", "度长絜大"="衡量长短大小", "比权量力"="比较权势力量"} ["则不可同年而语矣."] note = [] content = "则/不可/同年/而语/矣./" -translation = "就更不能相提并论了。" +translation = "就更不能相提并论了. " keyword_note = {"同年而语"="相提并论"} ["然秦以区区之地, 致万乘之势, 序八州而朝同列, 百有余年矣;"] note = [] content = "然/秦/以/区区/之地/, 致/万乘/之势/, 序/八州/而朝/同列/, 百有/余年/矣; /" -translation = "然而秦凭借着它的小小的地方,发展到兵车万乘的国势,管辖全国,使六国诸侯都来朝见,已经一百多年了;" +translation = "然而秦凭借着它的小小的地方, 发展到兵车万乘的国势, 管辖全国, 使六国诸侯都来朝见, 已经一百多年了; " keyword_note = {"区区"="小小", "致"="达到", "万乘"="兵车万乘", "序八州"="管辖全国", "朝同列"="使同列来朝拜", "百有余年"="一百多年"} ["然后以六合为家, 崤函为宫;"] note = [] content = "然后/以/六合/为家/, 崤函/为宫; /" -translation = "这之后把天下作为家业,用崤山、函谷关作为自己的内宫;" +translation = "这之后把天下作为家业, 用崤山、函谷关作为自己的内宫; " keyword_note = {"六合为家"="把天下作为家业", "崤函为宫"="把崤山函谷关作为内宫"} ["一夫作难而七庙隳, 身死人手, 为天下笑者, 何也?"] note = [] content = "一夫/作难/而/七庙/隳/, 身死/人手/, 为/天下/笑者/, 何也?/" -translation = "陈涉一人起义国家就灭亡了,秦王子婴死在别人项羽手里,被天下人耻笑,这是为什么呢?" -keyword_note = {"一夫作难"="一人起义", "七庙隳"="宗庙毁灭,国家灭亡", "身死人手"="死在别人手里", "为天下笑"="被天下人耻笑"} +translation = "陈涉一人起义国家就灭亡了, 秦王子婴死在别人项羽手里, 被天下人耻笑, 这是为什么呢? " +keyword_note = {"一夫作难"="一人起义", "七庙隳"="宗庙毁灭, 国家灭亡", "身死人手"="死在别人手里", "为天下笑"="被天下人耻笑"} ["仁义不施而攻守之势异也."] note = [] content = "仁义/不施/而/攻守/之势/异也./" -translation = "就因为不施行仁政而使攻守的形势发生了变化啊。" +translation = "就因为不施行仁政而使攻守的形势发生了变化啊. " keyword_note = {"仁义"="仁政", "不施"="不施行", "攻守之势"="进攻和防守的形势", "异"="发生变化"} \ No newline at end of file diff --git a/src/heurams/context.py b/src/heurams/context.py index 86b007a..0ca87bd 100644 --- a/src/heurams/context.py +++ b/src/heurams/context.py @@ -27,10 +27,10 @@ try: "config_var", default=ConfigFile(workdir / "config" / "config.toml") ) # 配置文件 print("已加载自定义用户配置") - logger.info("已加载自定义用户配置,路径: %s", workdir / "config" / "config.toml") + logger.info("已加载自定义用户配置, 路径: %s", workdir / "config" / "config.toml") except Exception as e: print("未能加载自定义用户配置") - logger.warning("未能加载自定义用户配置,错误: %s", e) + logger.warning("未能加载自定义用户配置, 错误: %s", e) # runtime_var: ContextVar = ContextVar('runtime_var', default=dict()) # 运行时共享数据 diff --git a/src/heurams/interface/screens/nucreator.py b/src/heurams/interface/screens/nucreator.py index c232c09..2126eab 100644 --- a/src/heurams/interface/screens/nucreator.py +++ b/src/heurams/interface/screens/nucreator.py @@ -121,7 +121,7 @@ class NucleonCreatorScreen(Screen): if selected is None: self.notify("请选择一个模板", severity="error") return - # selected 是描述字符串,格式如 "描述 (filename.toml)" + # selected 是描述字符串, 格式如 "描述 (filename.toml)" # 提取文件名 import re diff --git a/src/heurams/interface/widgets/basic_puzzle.py b/src/heurams/interface/widgets/basic_puzzle.py index 21a2efa..4d51c6d 100644 --- a/src/heurams/interface/widgets/basic_puzzle.py +++ b/src/heurams/interface/widgets/basic_puzzle.py @@ -52,7 +52,7 @@ class BasicEvaluation(BasePuzzleWidget): yield Label(self.atom.registry["nucleon"]["content"], id="main") # 显示评估说明(可选) - yield Static("请评估你对这个内容的记忆程度:", classes="instruction") + yield Static("请评估你对这个内容的记忆程度: ", classes="instruction") # 按钮容器 with ScrollableContainer(id="button_container"): diff --git a/src/heurams/kernel/algorithms/__init__.py b/src/heurams/kernel/algorithms/__init__.py index e5f0052..5c85232 100644 --- a/src/heurams/kernel/algorithms/__init__.py +++ b/src/heurams/kernel/algorithms/__init__.py @@ -12,4 +12,4 @@ algorithms = { "supermemo2": SM2Algorithm, } -logger.debug("算法模块初始化完成,注册的算法: %s", list(algorithms.keys())) +logger.debug("算法模块初始化完成, 注册的算法: %s", list(algorithms.keys())) diff --git a/src/heurams/kernel/algorithms/base.py b/src/heurams/kernel/algorithms/base.py index c9f1dbd..c4e8142 100644 --- a/src/heurams/kernel/algorithms/base.py +++ b/src/heurams/kernel/algorithms/base.py @@ -34,7 +34,7 @@ class BaseAlgorithm: ) -> None: """迭代记忆数据""" logger.debug( - "BaseAlgorithm.revisor 被调用,algodata keys: %s, feedback: %d, is_new_activation: %s", + "BaseAlgorithm.revisor 被调用, algodata keys: %s, feedback: %d, is_new_activation: %s", list(algodata.keys()) if algodata else [], feedback, is_new_activation, @@ -45,7 +45,7 @@ class BaseAlgorithm: def is_due(cls, algodata) -> int: """是否应该复习""" logger.debug( - "BaseAlgorithm.is_due 被调用,algodata keys: %s", + "BaseAlgorithm.is_due 被调用, algodata keys: %s", list(algodata.keys()) if algodata else [], ) return 1 @@ -54,7 +54,7 @@ class BaseAlgorithm: def rate(cls, algodata) -> str: """获取评分信息""" logger.debug( - "BaseAlgorithm.rate 被调用,algodata keys: %s", + "BaseAlgorithm.rate 被调用, algodata keys: %s", list(algodata.keys()) if algodata else [], ) return "" @@ -63,7 +63,7 @@ class BaseAlgorithm: def nextdate(cls, algodata) -> int: """获取下一次记忆时间戳""" logger.debug( - "BaseAlgorithm.nextdate 被调用,algodata keys: %s", + "BaseAlgorithm.nextdate 被调用, algodata keys: %s", list(algodata.keys()) if algodata else [], ) return -1 diff --git a/src/heurams/kernel/algorithms/sm2.py b/src/heurams/kernel/algorithms/sm2.py index 74e4b63..ed46b89 100644 --- a/src/heurams/kernel/algorithms/sm2.py +++ b/src/heurams/kernel/algorithms/sm2.py @@ -42,13 +42,13 @@ class SM2Algorithm(BaseAlgorithm): quality (int): 记忆保留率量化参数 """ logger.debug( - "SM2.revisor 开始,feedback: %d, is_new_activation: %s", + "SM2.revisor 开始, feedback: %d, is_new_activation: %s", feedback, is_new_activation, ) if feedback == -1: - logger.debug("feedback 为 -1,跳过更新") + logger.debug("feedback 为 -1, 跳过更新") return algodata[cls.algo_name]["efactor"] = algodata[cls.algo_name]["efactor"] + ( @@ -62,7 +62,7 @@ class SM2Algorithm(BaseAlgorithm): if feedback < 3: algodata[cls.algo_name]["rept"] = 0 algodata[cls.algo_name]["interval"] = 0 - logger.debug("feedback < 3,重置 rept 和 interval") + logger.debug("feedback < 3, 重置 rept 和 interval") else: algodata[cls.algo_name]["rept"] += 1 logger.debug("递增 rept: %d", algodata[cls.algo_name]["rept"]) @@ -73,20 +73,20 @@ class SM2Algorithm(BaseAlgorithm): if is_new_activation: algodata[cls.algo_name]["rept"] = 0 algodata[cls.algo_name]["efactor"] = 2.5 - logger.debug("新激活,重置 rept 和 efactor") + logger.debug("新激活, 重置 rept 和 efactor") if algodata[cls.algo_name]["rept"] == 0: algodata[cls.algo_name]["interval"] = 1 - logger.debug("rept=0,设置 interval=1") + logger.debug("rept=0, 设置 interval=1") elif algodata[cls.algo_name]["rept"] == 1: algodata[cls.algo_name]["interval"] = 6 - logger.debug("rept=1,设置 interval=6") + logger.debug("rept=1, 设置 interval=6") else: algodata[cls.algo_name]["interval"] = round( algodata[cls.algo_name]["interval"] * algodata[cls.algo_name]["efactor"] ) logger.debug( - "rept>1,计算 interval: %d", algodata[cls.algo_name]["interval"] + "rept>1, 计算 interval: %d", algodata[cls.algo_name]["interval"] ) algodata[cls.algo_name]["last_date"] = timer.get_daystamp() diff --git a/src/heurams/kernel/particles/atom.py b/src/heurams/kernel/particles/atom.py index 37de584..6c47d5c 100644 --- a/src/heurams/kernel/particles/atom.py +++ b/src/heurams/kernel/particles/atom.py @@ -41,10 +41,10 @@ class Atom: """ def __init__(self, ident=""): - logger.debug("创建 Atom 实例,ident: '%s'", ident) + logger.debug("创建 Atom 实例, ident: '%s'", ident) self.ident = ident atom_registry[ident] = self - logger.debug("Atom 已注册到全局注册表,当前注册表大小: %d", len(atom_registry)) + logger.debug("Atom 已注册到全局注册表, 当前注册表大小: %d", len(atom_registry)) # self.is_evaled = False self.registry: AtomRegister = { # type: ignore "nucleon": None, @@ -65,7 +65,7 @@ class Atom: logger.debug("Atom.link: key='%s', value type: %s", key, type(value).__name__) if key in self.registry.keys(): self.registry[key] = value - logger.debug("键 '%s' 已链接,触发 do_eval", key) + logger.debug("键 '%s' 已链接, 触发 do_eval", key) self.do_eval() else: logger.error("尝试链接不受支持的键: '%s'", key) @@ -120,8 +120,8 @@ class Atom: default = config_var.get()["puzzles"] metadata = nucleon.metadata except Exception: - # 如果无法获取配置或元数据,使用空字典 - logger.debug("无法获取配置或元数据,使用空字典") + # 如果无法获取配置或元数据, 使用空字典 + logger.debug("无法获取配置或元数据, 使用空字典") pass try: eval_value = eval(s) @@ -157,19 +157,19 @@ class Atom: return modifier(data[5:]) return data - # 如果 nucleon 存在且有 do_eval 方法,调用它 + # 如果 nucleon 存在且有 do_eval 方法, 调用它 nucleon = self.registry["nucleon"] if nucleon is not None and hasattr(nucleon, "do_eval"): nucleon.do_eval() logger.debug("已调用 nucleon.do_eval") - # 如果 electron 存在且其 algodata 包含 eval 字符串,遍历它 + # 如果 electron 存在且其 algodata 包含 eval 字符串, 遍历它 electron = self.registry["electron"] if electron is not None and hasattr(electron, "algodata"): traverse(electron.algodata, eval_with_env) logger.debug("已处理 electron algodata eval") - # 如果 orbital 存在且是字典,遍历它 + # 如果 orbital 存在且是字典, 遍历它 orbital = self.registry["orbital"] if orbital is not None and isinstance(orbital, dict): traverse(orbital, eval_with_env) diff --git a/src/heurams/kernel/particles/electron.py b/src/heurams/kernel/particles/electron.py index fc790b6..50344cb 100644 --- a/src/heurams/kernel/particles/electron.py +++ b/src/heurams/kernel/particles/electron.py @@ -18,7 +18,7 @@ class Electron: algo: 使用的算法模块标识 """ logger.debug( - "创建 Electron 实例,ident: '%s', algo_name: '%s'", ident, algo_name + "创建 Electron 实例, ident: '%s', algo_name: '%s'", ident, algo_name ) self.algodata = algodata self.ident = ident @@ -27,20 +27,20 @@ class Electron: if self.algo not in self.algodata.keys(): self.algodata[self.algo.algo_name] = {} - logger.debug("算法键 '%s' 不存在,已创建空字典", self.algo) + logger.debug("算法键 '%s' 不存在, 已创建空字典", self.algo) if not self.algodata[self.algo.algo_name]: - logger.debug("算法数据为空,使用默认值初始化") + logger.debug("算法数据为空, 使用默认值初始化") self._default_init(self.algo.defaults) else: - logger.debug("算法数据已存在,跳过默认初始化") + logger.debug("算法数据已存在, 跳过默认初始化") logger.debug( - "Electron 初始化完成,algodata keys: %s", list(self.algodata.keys()) + "Electron 初始化完成, algodata keys: %s", list(self.algodata.keys()) ) def _default_init(self, defaults: dict): """默认初始化包装""" logger.debug( - "Electron._default_init: 使用默认值,keys: %s", list(defaults.keys()) + "Electron._default_init: 使用默认值, keys: %s", list(defaults.keys()) ) self.algodata[self.algo.algo_name] = defaults.copy() @@ -49,7 +49,7 @@ class Electron: logger.debug("Electron.activate: 激活 ident='%s'", self.ident) self.algodata[self.algo.algo_name]["is_activated"] = 1 self.algodata[self.algo.algo_name]["last_modify"] = timer.get_timestamp() - logger.debug("电子已激活,is_activated=1") + logger.debug("电子已激活, is_activated=1") def modify(self, var: str, value): """修改 algodata[algo] 中子字典数据""" @@ -57,7 +57,7 @@ class Electron: if var in self.algodata[self.algo.algo_name]: self.algodata[self.algo.algo_name][var] = value self.algodata[self.algo.algo_name]["last_modify"] = timer.get_timestamp() - logger.debug("变量 '%s' 已修改,更新 last_modify", var) + logger.debug("变量 '%s' 已修改, 更新 last_modify", var) else: logger.warning("'%s' 非已知元数据字段", var) print(f"警告: '{var}' 非已知元数据字段") @@ -74,7 +74,7 @@ class Electron: logger.debug("Electron.is_activated: ident='%s', 结果: %d", self.ident, result) return result - def rate(self): + def get_rate(self): "评价" logger.debug("Electron.rate: ident='%s'", self.ident) result = self.algo.rate(self.algodata) @@ -102,7 +102,7 @@ class Electron: ) self.algo.revisor(self.algodata, quality, is_new_activation) logger.debug( - "revisor 完成,更新后的 algodata: %s", self.algodata.get(self.algo, {}) + "revisor 完成, 更新后的 algodata: %s", self.algodata.get(self.algo, {}) ) def __str__(self): diff --git a/src/heurams/kernel/particles/loader.py b/src/heurams/kernel/particles/loader.py index a7ce025..6ac8eb9 100644 --- a/src/heurams/kernel/particles/loader.py +++ b/src/heurams/kernel/particles/loader.py @@ -15,7 +15,7 @@ def load_nucleon(path: pathlib.Path, fmt="toml"): with open(path, "r") as f: dictdata = dict() dictdata = toml.load(f) # type: ignore - logger.debug("TOML 解析成功,keys: %s", list(dictdata.keys())) + logger.debug("TOML 解析成功, keys: %s", list(dictdata.keys())) lst = list() nested_data = dict() # 修正 toml 解析器的不管嵌套行为 @@ -32,7 +32,7 @@ def load_nucleon(path: pathlib.Path, fmt="toml"): logger.debug("处理元数据键: %s", key) else: nested_data[key] = value - logger.debug("嵌套数据处理完成,keys: %s", list(nested_data.keys())) + logger.debug("嵌套数据处理完成, keys: %s", list(nested_data.keys())) # print(nested_data) for item, attr in nested_data.items(): if item == "__metadata__": @@ -44,7 +44,7 @@ def load_nucleon(path: pathlib.Path, fmt="toml"): deepcopy(nested_data["__metadata__"]["orbital"]), ) ) - logger.debug("load_nucleon 完成,加载了 %d 个 Nucleon 对象", len(lst)) + logger.debug("load_nucleon 完成, 加载了 %d 个 Nucleon 对象", len(lst)) return lst @@ -62,10 +62,10 @@ def load_electron(path: pathlib.Path, fmt="json") -> dict: with open(path, "r") as f: dictdata = dict() dictdata = json.load(f) # type: ignore - logger.debug("JSON 解析成功,keys: %s", list(dictdata.keys())) + logger.debug("JSON 解析成功, keys: %s", list(dictdata.keys())) dic = dict() for item, attr in dictdata.items(): logger.debug("处理电子项目: %s", item) dic[item] = Electron(item, attr) - logger.debug("load_electron 完成,加载了 %d 个 Electron 对象", len(dic)) + logger.debug("load_electron 完成, 加载了 %d 个 Electron 对象", len(dic)) return dic diff --git a/src/heurams/kernel/particles/nucleon.py b/src/heurams/kernel/particles/nucleon.py index cdd090b..cad9613 100644 --- a/src/heurams/kernel/particles/nucleon.py +++ b/src/heurams/kernel/particles/nucleon.py @@ -15,7 +15,7 @@ class Nucleon: metadata: 可选元数据信息 """ logger.debug( - "创建 Nucleon 实例,ident: '%s', payload keys: %s, metadata keys: %s", + "创建 Nucleon 实例, ident: '%s', payload keys: %s, metadata keys: %s", ident, list(payload.keys()) if payload else [], list(metadata.keys()) if metadata else [], diff --git a/src/heurams/kernel/particles/probe.py b/src/heurams/kernel/particles/probe.py index 6b61ded..901e029 100644 --- a/src/heurams/kernel/particles/probe.py +++ b/src/heurams/kernel/particles/probe.py @@ -33,7 +33,7 @@ def probe_all(is_stem=1): Returns: dict: 有三项, 每一项的键名都是文件组类型, 值都是文件组列表, 只包含文件名 """ - logger.debug("probe_all: 开始探测,is_stem=%d", is_stem) + logger.debug("probe_all: 开始探测, is_stem=%d", is_stem) paths: dict = config_var.get().get("paths") logger.debug("配置路径: %s", paths) result = {} @@ -50,7 +50,7 @@ def probe_all(is_stem=1): else: result[item.replace("_dir", "")].append(str(i.name)) logger.debug("目录 %s 中找到 %d 个文件", attr, file_count) - logger.debug("probe_all 完成,结果 keys: %s", list(result.keys())) + logger.debug("probe_all 完成, 结果 keys: %s", list(result.keys())) return result diff --git a/src/heurams/kernel/puzzles/__init__.py b/src/heurams/kernel/puzzles/__init__.py index 2d4342e..5300648 100644 --- a/src/heurams/kernel/puzzles/__init__.py +++ b/src/heurams/kernel/puzzles/__init__.py @@ -1,7 +1,7 @@ """ Puzzle 模块 - 谜题生成系统 -提供多种类型的谜题生成器,支持从字符串、字典等数据源导入题目 +提供多种类型的谜题生成器, 支持从字符串、字典等数据源导入题目 """ from heurams.services.logger import get_logger @@ -34,7 +34,7 @@ def create_by_dict(config_dict: dict) -> BasePuzzle: 根据配置字典创建谜题 Args: - config_dict: 配置字典,包含谜题类型和参数 + config_dict: 配置字典, 包含谜题类型和参数 Returns: BasePuzzle: 谜题实例 diff --git a/src/heurams/kernel/puzzles/cloze.py b/src/heurams/kernel/puzzles/cloze.py index 5ee5db4..b31c947 100644 --- a/src/heurams/kernel/puzzles/cloze.py +++ b/src/heurams/kernel/puzzles/cloze.py @@ -48,7 +48,7 @@ class ClozePuzzle(BasePuzzle): answer.append(words[index]) self.answer = answer self.wording = "".join(blanked_words) - logger.debug("ClozePuzzle.refresh 完成,生成 %d 个填空", len(answer)) + logger.debug("ClozePuzzle.refresh 完成, 生成 %d 个填空", len(answer)) def __str__(self): logger.debug("ClozePuzzle.__str__ 被调用") diff --git a/src/heurams/kernel/reactor/phaser.py b/src/heurams/kernel/reactor/phaser.py index af509a8..37dd8f0 100644 --- a/src/heurams/kernel/reactor/phaser.py +++ b/src/heurams/kernel/reactor/phaser.py @@ -35,7 +35,7 @@ class Phaser: logger.debug("创建新记忆 Procession") self.processions.append(Procession(atoms, PhaserState.FINAL_REVIEW, "总体复习")) logger.debug("创建总体复习 Procession") - logger.debug("Phaser 初始化完成,processions 数量=%d", len(self.processions)) + logger.debug("Phaser 初始化完成, processions 数量=%d", len(self.processions)) def current_procession(self): logger.debug("Phaser.current_procession 被调用") @@ -46,5 +46,5 @@ class Phaser: logger.debug("找到未完成的 Procession: phase=%s", i.phase) return i self.state = PhaserState.FINISHED - logger.debug("所有 Procession 已完成,状态设置为 FINISHED") + logger.debug("所有 Procession 已完成, 状态设置为 FINISHED") return 0 diff --git a/src/heurams/kernel/reactor/procession.py b/src/heurams/kernel/reactor/procession.py index 84c180f..ab8533f 100644 --- a/src/heurams/kernel/reactor/procession.py +++ b/src/heurams/kernel/reactor/procession.py @@ -22,7 +22,7 @@ class Procession: self.name = name self.phase = phase self.state: ProcessionState = ProcessionState.RUNNING - logger.debug("Procession 初始化完成,队列长度=%d", len(self.queue)) + logger.debug("Procession 初始化完成, 队列长度=%d", len(self.queue)) def forward(self, step=1): logger.debug("Procession.forward: step=%d, 当前 cursor=%d", step, self.cursor) @@ -49,7 +49,7 @@ class Procession: logger.debug("Procession.append: atom=%s", atom.ident if atom else "None") if self.queue[len(self.queue) - 1] != atom or len(self) <= 1: self.queue.append(atom) - logger.debug("原子已追加到队列,新队列长度=%d", len(self.queue)) + logger.debug("原子已追加到队列, 新队列长度=%d", len(self.queue)) else: logger.debug("原子未追加(重复或队列长度<=1)") diff --git a/src/heurams/providers/tts/base.py b/src/heurams/providers/tts/base.py index 563aa38..5ac0fd2 100644 --- a/src/heurams/providers/tts/base.py +++ b/src/heurams/providers/tts/base.py @@ -11,5 +11,5 @@ class BaseTTS: def convert(cls, text: str, path: pathlib.Path | str = "") -> pathlib.Path: """path 是可选参数, 不填则自动返回生成文件路径""" logger.debug("BaseTTS.convert: text length=%d, path=%s", len(text), path) - logger.warning("BaseTTS.convert 是基类方法,未实现具体功能") + logger.warning("BaseTTS.convert 是基类方法, 未实现具体功能") return path # type: ignore diff --git a/src/heurams/providers/tts/edge_tts.py b/src/heurams/providers/tts/edge_tts.py index e5fdab1..df7d16c 100644 --- a/src/heurams/providers/tts/edge_tts.py +++ b/src/heurams/providers/tts/edge_tts.py @@ -17,7 +17,7 @@ class EdgeTTS(BaseTTS): text, "zh-CN-YunjianNeural", ) - logger.debug("EdgeTTS 通信对象创建成功,正在保存音频") + logger.debug("EdgeTTS 通信对象创建成功, 正在保存音频") communicate.save_sync(str(path)) logger.debug("EdgeTTS 音频已保存到: %s", path) return path # type: ignore diff --git a/src/heurams/services/audio_service.py b/src/heurams/services/audio_service.py index 27c85c0..9f92e25 100644 --- a/src/heurams/services/audio_service.py +++ b/src/heurams/services/audio_service.py @@ -8,5 +8,5 @@ logger = get_logger(__name__) play_by_path: Callable = prov[config_var.get()["services"]["audio"]].play_by_path logger.debug( - "音频服务初始化完成,使用 provider: %s", config_var.get()["services"]["audio"] + "音频服务初始化完成, 使用 provider: %s", config_var.get()["services"]["audio"] ) diff --git a/src/heurams/services/config.py b/src/heurams/services/config.py index 84cf9d7..d6e4787 100644 --- a/src/heurams/services/config.py +++ b/src/heurams/services/config.py @@ -40,7 +40,7 @@ class ConfigFile: self.logger.debug("配置文件已保存: %s", save_path) def get(self, key: str, default: typing.Any = None) -> typing.Any: - """获取配置值,如果不存在返回默认值""" + """获取配置值, 如果不存在返回默认值""" return self.data.get(key, default) def __getitem__(self, key: str) -> typing.Any: diff --git a/src/heurams/services/logger.py b/src/heurams/services/logger.py index 4357c17..e5a3147 100644 --- a/src/heurams/services/logger.py +++ b/src/heurams/services/logger.py @@ -68,10 +68,10 @@ def setup_logging( app_logger.setLevel(log_level) # 保持DEBUG级别 app_logger.addHandler(file_handler) - # 禁止传播到root logger,避免双重记录 + # 禁止传播到root logger, 避免双重记录 app_logger.propagate = False - # 设置第三方库的日志级别为WARNING,避免调试信息干扰 + # 设置第三方库的日志级别为WARNING, 避免调试信息干扰 third_party_loggers = [ "markdown_it", "markdown_it.rules_block", @@ -101,7 +101,7 @@ def get_logger(name: Optional[str] = None) -> logging.Logger: if name is None: return logging.getLogger() - # 确保使用 heurams 作为前缀,继承应用logger的配置 + # 确保使用 heurams 作为前缀, 继承应用logger的配置 if not name.startswith("heurams") and name != "": logger_name = f"heurams.{name}" else: diff --git a/src/heurams/services/tts_service.py b/src/heurams/services/tts_service.py index 0df8fb6..ce0d214 100644 --- a/src/heurams/services/tts_service.py +++ b/src/heurams/services/tts_service.py @@ -8,5 +8,5 @@ logger = get_logger(__name__) convert: Callable = TTSs[config_var.get().get("tts_provider")] logger.debug( - "TTS服务初始化完成,使用 provider: %s", config_var.get().get("tts_provider") + "TTS服务初始化完成, 使用 provider: %s", config_var.get().get("tts_provider") ) diff --git a/tests/interface/test_dashboard.py b/tests/interface/test_dashboard.py index 7999fa8..bec0c77 100644 --- a/tests/interface/test_dashboard.py +++ b/tests/interface/test_dashboard.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ -DashboardScreen 的测试,包括单元测试和 pilot 测试。 +DashboardScreen 的测试, 包括单元测试和 pilot 测试. """ import unittest import tempfile @@ -16,15 +16,15 @@ from heurams.interface.screens.dashboard import DashboardScreen class TestDashboardScreenUnit(unittest.TestCase): - """DashboardScreen 的单元测试(不启动完整应用)。""" + """DashboardScreen 的单元测试(不启动完整应用). """ def setUp(self): - """在每个测试之前运行,设置临时目录和配置。""" + """在每个测试之前运行, 设置临时目录和配置. """ # 创建临时目录用于测试数据 self.temp_dir = tempfile.TemporaryDirectory() self.temp_path = pathlib.Path(self.temp_dir.name) - # 创建默认配置,并修改路径指向临时目录 + # 创建默认配置, 并修改路径指向临时目录 default_config_path = ( pathlib.Path(__file__).parent.parent.parent / "src/heurams/default/config/config.toml" @@ -36,7 +36,7 @@ class TestDashboardScreenUnit(unittest.TestCase): config_data["paths"]["electron_dir"] = str(self.temp_path / "electron") config_data["paths"]["orbital_dir"] = str(self.temp_path / "orbital") config_data["paths"]["cache_dir"] = str(self.temp_path / "cache") - # 禁用快速通过,避免测试干扰 + # 禁用快速通过, 避免测试干扰 config_data["quick_pass"] = 0 # 禁用时间覆盖 config_data["daystamp_override"] = -1 @@ -53,12 +53,12 @@ class TestDashboardScreenUnit(unittest.TestCase): self.config_ctx.__enter__() def tearDown(self): - """在每个测试之后清理。""" + """在每个测试之后清理. """ self.config_ctx.__exit__(None, None, None) self.temp_dir.cleanup() def test_compose(self): - """测试 compose 方法返回正确的部件。""" + """测试 compose 方法返回正确的部件. """ screen = DashboardScreen() # 手动调用 compose 并收集部件 from textual.app import ComposeResult @@ -77,14 +77,14 @@ class TestDashboardScreenUnit(unittest.TestCase): container_present = any(isinstance(w, ScrollableContainer) for w in widgets) self.assertTrue(container_present) - # 使用 query_one 查找 union-list,即使屏幕未挂载也可能有效 + # 使用 query_one 查找 union-list, 即使屏幕未挂载也可能有效 list_view = screen.query_one("#union-list") self.assertIsNotNone(list_view) self.assertEqual(list_view.id, "union-list") self.assertEqual(list_view.__class__.__name__, "ListView") def test_item_desc_generator(self): - """测试 item_desc_generator 函数。""" + """测试 item_desc_generator 函数. """ screen = DashboardScreen() # 模拟一个文件名 filename = "test.toml" @@ -94,16 +94,16 @@ class TestDashboardScreenUnit(unittest.TestCase): self.assertIn(1, result) # 检查内容 self.assertIn("test.toml", result[0]) - # 由于 electron 文件不存在,应显示“尚未激活” + # 由于 electron 文件不存在, 应显示“尚未激活” self.assertIn("尚未激活", result[1]) -@unittest.skip("Pilot 测试需要进一步配置,暂不运行") +@unittest.skip("Pilot 测试需要进一步配置, 暂不运行") class TestDashboardScreenPilot(unittest.TestCase): - """使用 Textual Pilot 的集成测试。""" + """使用 Textual Pilot 的集成测试. """ def setUp(self): - """配置临时目录和配置。""" + """配置临时目录和配置. """ self.temp_dir = tempfile.TemporaryDirectory() self.temp_path = pathlib.Path(self.temp_dir.name) @@ -134,11 +134,11 @@ class TestDashboardScreenPilot(unittest.TestCase): self.temp_dir.cleanup() def test_dashboard_loads_with_pilot(self): - """使用 Pilot 测试 DashboardScreen 加载。""" + """使用 Pilot 测试 DashboardScreen 加载. """ with patch("heurams.interface.__main__.environment_check"): app = HeurAMSApp() - # 注意:Pilot 在 Textual 6.9.0 中的用法可能不同 - # 以下为示例代码,可能需要调整 + # 注意: Pilot 在 Textual 6.9.0 中的用法可能不同 + # 以下为示例代码, 可能需要调整 pilot = Pilot(app) # 等待应用启动 pilot.pause() diff --git a/tests/kernel/algorithms/test_sm2.py b/tests/kernel/algorithms/test_sm2.py index 71cdca2..a1ce190 100644 --- a/tests/kernel/algorithms/test_sm2.py +++ b/tests/kernel/algorithms/test_sm2.py @@ -36,7 +36,7 @@ class TestSM2Algorithm(unittest.TestCase): self.assertEqual(defaults["last_date"], 0) self.assertEqual(defaults["next_date"], 0) self.assertEqual(defaults["is_activated"], 0) - # last_modify 是动态的,仅检查存在性 + # last_modify 是动态的, 仅检查存在性 self.assertIn("last_modify", defaults) def test_revisor_feedback_minus_one(self): @@ -129,12 +129,12 @@ class TestSM2Algorithm(unittest.TestCase): } } SM2Algorithm.revisor(algodata, feedback=4) - # rept 从 0 递增到 1,因此 interval 应为 6 + # rept 从 0 递增到 1, 因此 interval 应为 6 self.assertEqual(algodata[SM2Algorithm.algo_name]["interval"], 6) - # 现在 rept=1,再次调用 revisor 递增到 2 + # 现在 rept=1, 再次调用 revisor 递增到 2 SM2Algorithm.revisor(algodata, feedback=4) - # rept=2,interval = round(6 * 2.5) = 15 + # rept=2, interval = round(6 * 2.5) = 15 self.assertEqual(algodata[SM2Algorithm.algo_name]["interval"], 15) # 单独测试 rept=1 的情况 @@ -147,7 +147,7 @@ class TestSM2Algorithm(unittest.TestCase): } } SM2Algorithm.revisor(algodata2, feedback=4) - # rept 递增到 2,interval = round(0 * 2.5) = 0 + # rept 递增到 2, interval = round(0 * 2.5) = 0 self.assertEqual(algodata2[SM2Algorithm.algo_name]["interval"], 0) def test_revisor_updates_dates(self): diff --git a/tests/kernel/particles/test_electron.py b/tests/kernel/particles/test_electron.py index 1fa8f7b..a395e57 100644 --- a/tests/kernel/particles/test_electron.py +++ b/tests/kernel/particles/test_electron.py @@ -31,7 +31,7 @@ class TestElectron(unittest.TestCase): defaults = electron.algo.defaults for key, value in defaults.items(): if key == "last_modify": - # last_modify 是动态的,只检查存在性 + # last_modify 是动态的, 只检查存在性 self.assertIn(key, electron.algodata[electron.algo]) elif key == "is_activated": # TODO: 调查为什么 is_activated 是 1 @@ -45,7 +45,7 @@ class TestElectron(unittest.TestCase): electron = Electron("test_electron", algodata=algodata) self.assertEqual(electron.algodata[electron.algo]["efactor"], 2.5) self.assertEqual(electron.algodata[electron.algo]["interval"], 1) - # 其他字段可能不存在,因为未提供默认初始化 + # 其他字段可能不存在, 因为未提供默认初始化 # 检查 real_rept 不存在 self.assertNotIn("real_rept", electron.algodata[electron.algo]) @@ -98,7 +98,7 @@ class TestElectron(unittest.TestCase): electron = Electron("test_electron") with patch.object(electron.algo, "rate") as mock_rate: mock_rate.return_value = "good" - result = electron.rate() + result = electron.get_rate() mock_rate.assert_called_once_with(electron.algodata) self.assertEqual(result, "good") diff --git a/tests/kernel/puzzles/test_cloze.py b/tests/kernel/puzzles/test_cloze.py index 8e9417a..1f5baaf 100644 --- a/tests/kernel/puzzles/test_cloze.py +++ b/tests/kernel/puzzles/test_cloze.py @@ -26,7 +26,7 @@ class TestClozePuzzle(unittest.TestCase): # 检查 wording 和 answer self.assertNotEqual(puzzle.wording, "填空题 - 尚未刷新谜题") self.assertNotEqual(puzzle.answer, ["填空题 - 尚未刷新谜题"]) - # 根据模拟,应该有两个填空 + # 根据模拟, 应该有两个填空 self.assertEqual(len(puzzle.answer), 2) self.assertEqual(puzzle.answer, ["hello", "test"]) # wording 应包含下划线 diff --git a/tests/kernel/puzzles/test_mcq.py b/tests/kernel/puzzles/test_mcq.py index b7dcbbf..3acb9f1 100644 --- a/tests/kernel/puzzles/test_mcq.py +++ b/tests/kernel/puzzles/test_mcq.py @@ -34,9 +34,9 @@ class TestMCQPuzzle(unittest.TestCase): def test_init_jammer_ensures_minimum(self): """测试干扰项至少保证 4 个""" puzzle = MCQPuzzle({}, []) - # 正确答案为空,干扰项为空,应填充空格 + # 正确答案为空, 干扰项为空, 应填充空格 self.assertEqual(len(puzzle.jammer), 4) - self.assertEqual(set(puzzle.jammer), {" "}) # 三个空格?实际上循环填充空格 + self.assertEqual(set(puzzle.jammer), {" "}) # 三个空格? 实际上循环填充空格 @patch("random.sample") @patch("random.shuffle") diff --git a/tests/kernel/reactor/test_phaser.py b/tests/kernel/reactor/test_phaser.py index 7e1eba0..304ce58 100644 --- a/tests/kernel/reactor/test_phaser.py +++ b/tests/kernel/reactor/test_phaser.py @@ -32,7 +32,7 @@ class TestPhaser(unittest.TestCase): atoms = [self.atom_old, self.atom_new, self.atom_old] phaser = Phaser(atoms) - # 应该创建两个 Procession:一个用于旧原子,一个用于新原子,以及一个总体复习 + # 应该创建两个 Procession: 一个用于旧原子, 一个用于新原子, 以及一个总体复习 self.assertEqual(self.mock_procession_class.call_count, 3) # 检查调用参数 @@ -52,7 +52,7 @@ class TestPhaser(unittest.TestCase): atoms = [self.atom_old, self.atom_old] phaser = Phaser(atoms) - # 应该创建两个 Procession:一个初始复习,一个总体复习 + # 应该创建两个 Procession: 一个初始复习, 一个总体复习 self.assertEqual(self.mock_procession_class.call_count, 2) calls = self.mock_procession_class.call_args_list self.assertEqual(calls[0][0][0], atoms)