refactor: 开始翻新状态机
This commit is contained in:
@@ -1 +0,0 @@
|
|||||||
{}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
title = "测试单元: 过秦论"
|
|
||||||
author = "__heurams__"
|
|
||||||
desc = "高考古诗文: 过秦论"
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
["秦孝公据崤函之固, 拥雍州之地,"]
|
|
||||||
note = []
|
|
||||||
content = "秦孝公/据/崤函/之固/, 拥/雍州/之地,/"
|
|
||||||
translation = "秦孝公占据着崤山和函谷关的险固地势,拥有雍州的土地,"
|
|
||||||
keyword_note = {"据"="占据", "崤函"="崤山和函谷关", "雍州"="古代九州之一"}
|
|
||||||
|
|
||||||
["君臣固守以窥周室,"]
|
|
||||||
note = []
|
|
||||||
content = "君臣/固守/以窥/周室,/"
|
|
||||||
translation = "君臣牢固地守卫着,借以窥视周王室的权力,"
|
|
||||||
keyword_note = {"窥"="窥视"}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
schedule = ["quick_review", "recognition", "final_review"]
|
|
||||||
[phases]
|
|
||||||
quick_review = [["FillBlank", "1.0"], ["SelectMeaning", "0.5"], ["Recognition", "1.0"]]
|
|
||||||
recognition = [["Recognition", "1.0"]]
|
|
||||||
final_review = [["FillBlank", "0.7"], ["SelectMeaning", "0.7"], ["Recognition", "1.0"]]
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
[annotation]
|
|
||||||
note = "笔记"
|
|
||||||
keyword_note = "关键词翻译"
|
|
||||||
translation = "语句翻译"
|
|
||||||
delimiter = "分隔符"
|
|
||||||
content = "内容"
|
|
||||||
tts_text = "文本转语音文本"
|
|
||||||
|
|
||||||
[common]
|
|
||||||
delimiter = "/"
|
|
||||||
tts_text = "eval:payload['content'].replace('/', '')"
|
|
||||||
|
|
||||||
[common.puzzles] # 谜题定义
|
|
||||||
# 我们称 "Recognition" 为 recognition 谜题的 alia
|
|
||||||
"Recognition" = { __origin__ = "recognition", __hint__ = "", primary = "eval:payload['content']", secondary = ["eval:payload['keyword_note']", "eval:payload['note']"], top_dim = ["eval:payload['translation']"] }
|
|
||||||
"SelectMeaning" = { __origin__ = "mcq", __hint__ = "eval:payload['content']", primary = "eval:payload['content']", mapping = "eval:payload['keyword_note']", jammer = "eval:list(payload['keyword_note'].values())", max_riddles_num = "eval:default['mcq']['max_riddles_num']", prefix = "选择正确项: " }
|
|
||||||
"FillBlank" = { __origin__ = "cloze", __hint__ = "", text = "eval:payload['content']", delimiter = "eval:nucleon['delimiter']", min_denominator = "eval:default['cloze']['min_denominator']"}
|
|
||||||
4
src/heurams/interface/css/screens/memoqueue.tcss
Normal file
4
src/heurams/interface/css/screens/memoqueue.tcss
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#puzzle_container > * {
|
||||||
|
height: auto;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
@@ -5,14 +5,14 @@ from pathlib import Path
|
|||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
|
||||||
from textual.app import ComposeResult
|
from textual.app import ComposeResult
|
||||||
from textual.containers import Center, ScrollableContainer
|
from textual.containers import Center, ScrollableContainer, Container
|
||||||
from textual.reactive import reactive
|
from textual.reactive import reactive
|
||||||
from textual.screen import Screen
|
from textual.screen import Screen
|
||||||
from textual.widgets import Button, Footer, Header, Label, Static
|
from textual.widgets import Button, Footer, Header, Label, Static
|
||||||
|
|
||||||
import heurams.kernel.particles as pt
|
import heurams.kernel.particles as pt
|
||||||
import heurams.kernel.puzzles as pz
|
import heurams.kernel.puzzles as pz
|
||||||
from heurams.context import config_var
|
from heurams.context import config_var, rootdir
|
||||||
from heurams.kernel.reactor import *
|
from heurams.kernel.reactor import *
|
||||||
from heurams.services.favorite_service import favorite_manager
|
from heurams.services.favorite_service import favorite_manager
|
||||||
from heurams.services.logger import get_logger
|
from heurams.services.logger import get_logger
|
||||||
@@ -28,8 +28,13 @@ class MemScreen(Screen):
|
|||||||
("d", "toggle_dark", ""),
|
("d", "toggle_dark", ""),
|
||||||
("v", "play_voice", "朗读"),
|
("v", "play_voice", "朗读"),
|
||||||
("*", "toggle_favorite", "收藏"),
|
("*", "toggle_favorite", "收藏"),
|
||||||
|
("n", "block_prompt"),
|
||||||
|
("s", "block_prompt"),
|
||||||
|
("z", "block_prompt"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
CSS_PATH = rootdir / 'interface' / 'css' / 'screens' / 'memoqueue.tcss'
|
||||||
|
|
||||||
if config_var.get()["interface"]["global"]["quick_pass"]:
|
if config_var.get()["interface"]["global"]["quick_pass"]:
|
||||||
BINDINGS.append(("k", "quick_pass", "正确应答"))
|
BINDINGS.append(("k", "quick_pass", "正确应答"))
|
||||||
BINDINGS.append(("f", "quick_fail", "错误应答"))
|
BINDINGS.append(("f", "quick_fail", "错误应答"))
|
||||||
@@ -38,17 +43,17 @@ class MemScreen(Screen):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
phaser: Phaser,
|
router: Router,
|
||||||
repo=None,
|
repo=None,
|
||||||
name=None,
|
name=None,
|
||||||
id=None,
|
id=None,
|
||||||
classes=None,
|
classes=None,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(name, id, classes)
|
super().__init__(name, id, classes)
|
||||||
self.phaser = phaser
|
self.router = router
|
||||||
self.repo = repo
|
self.repo = repo
|
||||||
self.update_state()
|
self.update_state()
|
||||||
self.fission: Fission
|
self.expander: Expander
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
yield Header(show_clock=True)
|
yield Header(show_clock=True)
|
||||||
@@ -59,17 +64,17 @@ class MemScreen(Screen):
|
|||||||
|
|
||||||
def update_state(self):
|
def update_state(self):
|
||||||
"""更新状态机"""
|
"""更新状态机"""
|
||||||
self.procession: Procession = self.phaser.current_procession() # type: ignore
|
self.procession: Procession = self.router.current_procession() # type: ignore
|
||||||
self.atom: pt.Atom = self.procession.current_atom # type: ignore
|
self.atom: pt.Atom = self.procession.current_atom # type: ignore
|
||||||
|
|
||||||
def on_mount(self):
|
def on_mount(self):
|
||||||
self.fission = self.procession.get_fission()
|
self.expander = self.procession.get_expander()
|
||||||
self.mount_puzzle()
|
self.mount_puzzle()
|
||||||
self.update_display()
|
self.update_display()
|
||||||
|
|
||||||
def puzzle_widget(self):
|
def puzzle_widget(self):
|
||||||
try:
|
try:
|
||||||
puzzle = self.fission.get_current_puzzle_inf()
|
puzzle = self.expander.get_current_puzzle_inf()
|
||||||
return shim.puzzle2widget[puzzle["puzzle"]]( # type: ignore
|
return shim.puzzle2widget[puzzle["puzzle"]]( # type: ignore
|
||||||
atom=self.atom, alia=puzzle["alia"] # type: ignore
|
atom=self.atom, alia=puzzle["alia"] # type: ignore
|
||||||
)
|
)
|
||||||
@@ -93,7 +98,7 @@ class MemScreen(Screen):
|
|||||||
|
|
||||||
def mount_puzzle(self):
|
def mount_puzzle(self):
|
||||||
"""挂载当前谜题组件"""
|
"""挂载当前谜题组件"""
|
||||||
if self.procession.phase == PhaserState.FINISHED:
|
if self.procession.phase == RouterState.FINISHED:
|
||||||
self.mount_finished_widget()
|
self.mount_finished_widget()
|
||||||
return
|
return
|
||||||
container = self.query_one("#puzzle_container")
|
container = self.query_one("#puzzle_container")
|
||||||
@@ -139,10 +144,10 @@ class MemScreen(Screen):
|
|||||||
if new_rating == -1: # 安全值
|
if new_rating == -1: # 安全值
|
||||||
return
|
return
|
||||||
self.update_state()
|
self.update_state()
|
||||||
if self.procession.phase == PhaserState.FINISHED:
|
if self.procession.phase == RouterState.FINISHED:
|
||||||
rating = -1
|
rating = -1
|
||||||
return
|
return
|
||||||
self.fission.report(new_rating)
|
self.expander.report(new_rating)
|
||||||
self.forward(new_rating)
|
self.forward(new_rating)
|
||||||
self.rating = -1
|
self.rating = -1
|
||||||
|
|
||||||
@@ -150,9 +155,9 @@ class MemScreen(Screen):
|
|||||||
self.update_state()
|
self.update_state()
|
||||||
allow_forward = 1 if rating >= 4 else 0
|
allow_forward = 1 if rating >= 4 else 0
|
||||||
if allow_forward:
|
if allow_forward:
|
||||||
self.fission.forward()
|
self.expander.forward()
|
||||||
if self.fission.state == "retronly":
|
if self.expander.state == "retronly":
|
||||||
self.forward_atom(self.fission.get_quality())
|
self.forward_atom(self.expander.get_quality())
|
||||||
self.update_state()
|
self.update_state()
|
||||||
self.mount_puzzle()
|
self.mount_puzzle()
|
||||||
self.update_display()
|
self.update_display()
|
||||||
@@ -177,7 +182,7 @@ class MemScreen(Screen):
|
|||||||
self.update_state() # 刷新状态
|
self.update_state() # 刷新状态
|
||||||
self.procession.forward(1)
|
self.procession.forward(1)
|
||||||
self.update_state() # 刷新状态
|
self.update_state() # 刷新状态
|
||||||
self.fission = self.procession.get_fission()
|
self.expander = self.procession.get_expander()
|
||||||
|
|
||||||
def action_go_back(self):
|
def action_go_back(self):
|
||||||
self.app.pop_screen()
|
self.app.pop_screen()
|
||||||
@@ -224,3 +229,6 @@ class MemScreen(Screen):
|
|||||||
self.app.notify(f"已收藏:{ident}", severity="information")
|
self.app.notify(f"已收藏:{ident}", severity="information")
|
||||||
# 更新显示(如果需要)
|
# 更新显示(如果需要)
|
||||||
self.update_display()
|
self.update_display()
|
||||||
|
|
||||||
|
def action_block_prompt(self):
|
||||||
|
self.app.notify("功能在记忆界面中不可用, 完成或返回后再试", severity="error")
|
||||||
@@ -181,6 +181,6 @@ def launch(repo, app, scheduled_num):
|
|||||||
|
|
||||||
from .memoqueue import MemScreen
|
from .memoqueue import MemScreen
|
||||||
|
|
||||||
pheser = rt.Phaser(atoms_to_provide)
|
router = rt.Router(atoms_to_provide)
|
||||||
memscreen = MemScreen(pheser, repo=repo)
|
memscreen = MemScreen(router=router, repo=repo)
|
||||||
app.push_screen(memscreen)
|
app.push_screen(memscreen)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import copy
|
|||||||
import random
|
import random
|
||||||
from typing import TypedDict
|
from typing import TypedDict
|
||||||
|
|
||||||
from textual.containers import Container
|
from textual.containers import Container, ScrollableContainer
|
||||||
from textual.message import Message
|
from textual.message import Message
|
||||||
from textual.widget import Widget
|
from textual.widget import Widget
|
||||||
from textual.widgets import Button, Label, Markdown
|
from textual.widgets import Button, Label, Markdown
|
||||||
@@ -68,7 +68,7 @@ class ClozePuzzle(BasePuzzleWidget):
|
|||||||
yield Label(self.puzzle.wording, id="sentence")
|
yield Label(self.puzzle.wording, id="sentence")
|
||||||
yield Markdown(f"> {self.listprint(self.inputlist)}", id="inputpreview")
|
yield Markdown(f"> {self.listprint(self.inputlist)}", id="inputpreview")
|
||||||
# 渲染当前问题的选项
|
# 渲染当前问题的选项
|
||||||
with Container(id="btn-container"):
|
with ScrollableContainer(id="btn-container"):
|
||||||
for i in self.ans:
|
for i in self.ans:
|
||||||
h = str(hash(i))
|
h = str(hash(i))
|
||||||
self.hashmap[h] = i
|
self.hashmap[h] = i
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class Finished(Widget):
|
|||||||
def compose(self):
|
def compose(self):
|
||||||
yield Label("本次记忆进程结束", id="finished_msg")
|
yield Label("本次记忆进程结束", id="finished_msg")
|
||||||
yield Label(f"算法数据{'已保存' if self.is_saved else "未能保存"}")
|
yield Label(f"算法数据{'已保存' if self.is_saved else "未能保存"}")
|
||||||
yield Button("返回上一级", id="back-to-menu")
|
yield Button("返回上一级", flat=True, id="back-to-menu")
|
||||||
|
|
||||||
def on_button_pressed(self, event):
|
def on_button_pressed(self, event):
|
||||||
button_id = event.button.id
|
button_id = event.button.id
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class MCQPuzzle(BasePuzzleWidget):
|
|||||||
yield Label(f"当前输入: {self.inputlist}", id="inputpreview")
|
yield Label(f"当前输入: {self.inputlist}", id="inputpreview")
|
||||||
|
|
||||||
# 渲染当前问题的选项
|
# 渲染当前问题的选项
|
||||||
with Container(id="btn-container"):
|
with ScrollableContainer(id="btn-container"):
|
||||||
for i in current_options:
|
for i in current_options:
|
||||||
self.hashmap[str(hash(i))] = i
|
self.hashmap[str(hash(i))] = i
|
||||||
btnid = f"sel{str(self.cursor).zfill(3)}-{hash(i)}"
|
btnid = f"sel{str(self.cursor).zfill(3)}-{hash(i)}"
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
Reactor 是 HeurAMS 的记忆流程状态机模块, 和界面 (interface) 的实现是解耦的, 以便后期与其他框架的适配.\
|
Reactor 是 HeurAMS 的记忆流程状态机模块, 和界面 (interface) 的实现是解耦的, 以便后期与其他框架的适配.\
|
||||||
得益于 Pickle, 状态机模块支持快照!
|
得益于 Pickle, 状态机模块支持快照!
|
||||||
|
|
||||||
## Phaser - 全局阶段控制器
|
## Router - 全局阶段控制器
|
||||||
|
|
||||||
在一次队列记忆流程中, Phaser 代表记忆流程本身.
|
在一次队列记忆流程中, Router 代表记忆流程本身.
|
||||||
|
|
||||||
### 属性
|
### 属性
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ Reactor 是 HeurAMS 的记忆流程状态机模块, 和界面 (interface) 的实
|
|||||||
|
|
||||||
在初始化 Procession 时, 每个 Procession 被赋予一个不重复的状态属性 作为"阶段状态"属性, 以此标识 Procession 的阶段属性, 因为每个 Procession 管理一个阶段下的复习进程.
|
在初始化 Procession 时, 每个 Procession 被赋予一个不重复的状态属性 作为"阶段状态"属性, 以此标识 Procession 的阶段属性, 因为每个 Procession 管理一个阶段下的复习进程.
|
||||||
|
|
||||||
你可以用 state 属性获取 Phaser 的当前状态.
|
你可以用 state 属性获取 Router 的当前状态.
|
||||||
|
|
||||||
#### Procession 属性
|
#### Procession 属性
|
||||||
|
|
||||||
@@ -34,26 +34,26 @@ Reactor 是 HeurAMS 的记忆流程状态机模块, 和界面 (interface) 的实
|
|||||||
|
|
||||||
### 初始化
|
### 初始化
|
||||||
|
|
||||||
Phaser 接受一个存储 Atom 对象的列表, 作为组织记忆流程的材料\
|
Router 接受一个存储 Atom 对象的列表, 作为组织记忆流程的材料\
|
||||||
在内部, 根据是否激活将其分为 new_atoms 与 old_atoms.\
|
在内部, 根据是否激活将其分为 new_atoms 与 old_atoms.\
|
||||||
因此, 如果你传入的列表中有算法上"无所事事"的 Atom, 流程会对其进行"加强复习"
|
因此, 如果你传入的列表中有算法上"无所事事"的 Atom, 流程会对其进行"加强复习"
|
||||||
由此创建 Procession.
|
由此创建 Procession.
|
||||||
|
|
||||||
### 直接输出呈现形式
|
### 直接输出呈现形式
|
||||||
|
|
||||||
Phaser 的 __repr__ 定义了此对象"官方的显示"用作直观的调试.\
|
Router 的 __repr__ 定义了此对象"官方的显示"用作直观的调试.\
|
||||||
其以 ascii 表格形式输出, 格式也符合 markdown 表格规范, 你可以直接复制到 markdown.\
|
其以 ascii 表格形式输出, 格式也符合 markdown 表格规范, 你可以直接复制到 markdown.\
|
||||||
示例:
|
示例:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
| Type | State | Processions | Current Procession |
|
| Type | State | Processions | Current Procession |
|
||||||
|:-------|:--------|:-----------------------|:---------------------|
|
| :----- | :----- | :--------------------- | :----------------- |
|
||||||
| Phaser | unsure | ['新记忆', '总体复习'] | 新记忆 |
|
| Router | unsure | ['新记忆', '总体复习'] | 新记忆 |
|
||||||
```
|
```
|
||||||
|
|
||||||
| Type | State | Processions | Current Procession |
|
| Type | State | Processions | Current Procession |
|
||||||
|:-------|:--------|:-----------------------|:---------------------|
|
| :----- | :----- | :--------------------- | :----------------- |
|
||||||
| Phaser | unsure | ['新记忆', '总体复习'] | 新记忆 |
|
| Router | unsure | ['新记忆', '总体复习'] | 新记忆 |
|
||||||
|
|
||||||
### 方法
|
### 方法
|
||||||
|
|
||||||
@@ -85,29 +85,29 @@ Phaser 的 __repr__ 定义了此对象"官方的显示"用作直观的调试.\
|
|||||||
- cursor: 指针, 是当前原子在 atoms 列表中的索引
|
- cursor: 指针, 是当前原子在 atoms 列表中的索引
|
||||||
- phase: "阶段属性"
|
- phase: "阶段属性"
|
||||||
|
|
||||||
> 注意区分 "Phaser" 和 "Phase", 其中 "Phase" 表示 "Phaser State".
|
> 注意区分 "Router" 和 "Phase", 其中 "Phase" 表示 "Router State".
|
||||||
|
|
||||||
- name\_: 阶段的命名
|
- name\_: 阶段的命名
|
||||||
- state: 当前状态属性
|
- state: 当前状态属性
|
||||||
|
|
||||||
### 初始化
|
### 初始化
|
||||||
|
|
||||||
接受一个 atoms 列表与 phase_state (PhaserState Enum 类型)对象
|
接受一个 atoms 列表与 phase_state (RouterState Enum 类型)对象
|
||||||
|
|
||||||
### 直接输出呈现形式
|
### 直接输出呈现形式
|
||||||
|
|
||||||
同 Phaser, 但显示数据有所不同\
|
同 Router, 但显示数据有所不同\
|
||||||
与 Phaser 不同, Procession 显示队列会对过长的 atom.ident 进行缩略(末尾 `>` 符号)
|
与 Router 不同, Procession 显示队列会对过长的 atom.ident 进行缩略(末尾 `>` 符号)
|
||||||
|
|
||||||
```text
|
```text
|
||||||
| Type | Name | State | Progress | Queue | Current Atom |
|
| Type | Name | State | Progress | Queue | Current Atom |
|
||||||
|:-----------|:-------|:--------|:-----------|:-----------------------|:------------------------------|
|
| :--------- | :----- | :----- | :------- | :--------------------- | :---------------------------- |
|
||||||
| Procession | 新记忆 | active | 1 / 2 | ['秦孝公>', '君臣固>'] | 秦孝公据崤函之固, 拥雍州之地, |
|
| Procession | 新记忆 | active | 1 / 2 | ['秦孝公>', '君臣固>'] | 秦孝公据崤函之固, 拥雍州之地, |
|
||||||
```
|
```
|
||||||
|
|
||||||
| Type | Name | State | Progress | Queue | Current Atom |
|
| Type | Name | State | Progress | Queue | Current Atom |
|
||||||
|:-----------|:-------|:--------|:-----------|:-----------------------|:------------------------------|
|
| :--------- | :----- | :----- | :------- | :--------------------- | :---------------------------- |
|
||||||
| Procession | 新记忆 | active | 1 / 2 | ['秦孝公>', '君臣固>'] | 秦孝公据崤函之固, 拥雍州之地, |
|
| Procession | 新记忆 | active | 1 / 2 | ['秦孝公>', '君臣固>'] | 秦孝公据崤函之固, 拥雍州之地, |
|
||||||
|
|
||||||
### 方法
|
### 方法
|
||||||
|
|
||||||
@@ -142,11 +142,11 @@ Phaser 的 __repr__ 定义了此对象"官方的显示"用作直观的调试.\
|
|||||||
|
|
||||||
判断是否为空队列(传入原子列表对象是空列表的队列)
|
判断是否为空队列(传入原子列表对象是空列表的队列)
|
||||||
|
|
||||||
#### get_fission(self)
|
#### get_expander(self)
|
||||||
|
|
||||||
获取当前原子的 Fission 对象, 用于单原子调度展开
|
获取当前原子的 Expander 对象, 用于单原子调度展开
|
||||||
|
|
||||||
## Fission - 单原子调度控制器
|
## Expander - 单原子调度控制器
|
||||||
|
|
||||||
### 属性
|
### 属性
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
from heurams.services.logger import get_logger
|
from heurams.services.logger import get_logger
|
||||||
|
|
||||||
from .fission import Fission
|
from .expander import Expander
|
||||||
from .phaser import Phaser
|
from .router import Router
|
||||||
from .procession import Procession
|
from .procession import Procession
|
||||||
from .states import PhaserState, ProcessionState
|
from .states import RouterState, ProcessionState
|
||||||
|
|
||||||
__all__ = ["PhaserState", "ProcessionState", "Procession", "Fission", "Phaser"]
|
__all__ = ["RouterState", "ProcessionState", "Procession", "Expander", "Router"]
|
||||||
|
|||||||
@@ -8,39 +8,39 @@ import heurams.kernel.particles as pt
|
|||||||
import heurams.kernel.puzzles as puz
|
import heurams.kernel.puzzles as puz
|
||||||
from heurams.services.logger import get_logger
|
from heurams.services.logger import get_logger
|
||||||
|
|
||||||
from .states import FissionState, PhaserState
|
from .states import ExpanderState, RouterState
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Fission(Machine):
|
class Expander(Machine):
|
||||||
"""单原子调度展开器"""
|
"""单原子调度展开器"""
|
||||||
|
|
||||||
def __init__(self, atom: pt.Atom, phase=PhaserState.RECOGNITION):
|
def __init__(self, atom: pt.Atom, phase=RouterState.RECOGNITION):
|
||||||
self.phase = phase
|
self.phase = phase
|
||||||
self.cursor = 0
|
self.cursor = 0
|
||||||
self.atom = atom
|
self.atom = atom
|
||||||
self.current_puzzle_inf: dict
|
self.current_puzzle_inf: dict
|
||||||
# phase 为 PhaserState 枚举实例, 需要获取其value
|
# phase 为 RouterState 枚举实例, 需要获取其value
|
||||||
phase_value = phase.value
|
phase_value = phase.value
|
||||||
states = [
|
states = [
|
||||||
{"name": FissionState.EXAMMODE.value},
|
{"name": ExpanderState.EXAMMODE.value},
|
||||||
{"name": FissionState.RETRONLY.value},
|
{"name": ExpanderState.RETRONLY.value},
|
||||||
]
|
]
|
||||||
|
|
||||||
transitions = [
|
transitions = [
|
||||||
{
|
{
|
||||||
"trigger": "finish",
|
"trigger": "finish",
|
||||||
"source": FissionState.EXAMMODE.value,
|
"source": ExpanderState.EXAMMODE.value,
|
||||||
"dest": FissionState.RETRONLY.value,
|
"dest": ExpanderState.RETRONLY.value,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
if phase == PhaserState.FINISHED:
|
if phase == RouterState.FINISHED:
|
||||||
Machine.__init__(
|
Machine.__init__(
|
||||||
self,
|
self,
|
||||||
states=states,
|
states=states,
|
||||||
transitions=transitions,
|
transitions=transitions,
|
||||||
initial=FissionState.EXAMMODE.value,
|
initial=ExpanderState.EXAMMODE.value,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
orbital_schedule = atom.registry["orbital"]["phases"][phase_value] # type: ignore
|
orbital_schedule = atom.registry["orbital"]["phases"][phase_value] # type: ignore
|
||||||
@@ -81,7 +81,7 @@ class Fission(Machine):
|
|||||||
self,
|
self,
|
||||||
states=states,
|
states=states,
|
||||||
transitions=transitions,
|
transitions=transitions,
|
||||||
initial=FissionState.EXAMMODE.value,
|
initial=ExpanderState.EXAMMODE.value,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_puzzles_inf(self):
|
def get_puzzles_inf(self):
|
||||||
@@ -118,7 +118,7 @@ class Fission(Machine):
|
|||||||
|
|
||||||
dic = [
|
dic = [
|
||||||
{
|
{
|
||||||
"Type": "Fission",
|
"Type": "Expander",
|
||||||
"Atom": truncate(self.atom.ident),
|
"Atom": truncate(self.atom.ident),
|
||||||
"State": self.state,
|
"State": self.state,
|
||||||
"Progress": f"{self.cursor + 1} / {len(self.puzzles_inf)}",
|
"Progress": f"{self.cursor + 1} / {len(self.puzzles_inf)}",
|
||||||
@@ -4,8 +4,8 @@ from transitions import Machine
|
|||||||
import heurams.kernel.particles as pt
|
import heurams.kernel.particles as pt
|
||||||
from heurams.services.logger import get_logger
|
from heurams.services.logger import get_logger
|
||||||
|
|
||||||
from .fission import Fission
|
from .expander import Expander
|
||||||
from .states import PhaserState, ProcessionState
|
from .states import RouterState, ProcessionState
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ logger = get_logger(__name__)
|
|||||||
class Procession(Machine):
|
class Procession(Machine):
|
||||||
"""队列: 标识单次记忆流程"""
|
"""队列: 标识单次记忆流程"""
|
||||||
|
|
||||||
def __init__(self, atoms: list, phase_state: PhaserState, name_: str = ""):
|
def __init__(self, atoms: list, phase_state: RouterState, name_: str = ""):
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Procession.__init__: 原子数量=%d, phase=%s, name='%s'",
|
"Procession.__init__: 原子数量=%d, phase=%s, name='%s'",
|
||||||
len(atoms),
|
len(atoms),
|
||||||
@@ -113,8 +113,8 @@ class Procession(Machine):
|
|||||||
logger.debug("Procession.is_empty: %s", empty)
|
logger.debug("Procession.is_empty: %s", empty)
|
||||||
return empty
|
return empty
|
||||||
|
|
||||||
def get_fission(self):
|
def get_expander(self):
|
||||||
return Fission(atom=self.current_atom, phase=self.phase) # type: ignore
|
return Expander(atom=self.current_atom, phase=self.phase) # type: ignore
|
||||||
|
|
||||||
def __repr__(self, style="pipe", ends="\n"):
|
def __repr__(self, style="pipe", ends="\n"):
|
||||||
from heurams.services.textproc import truncate
|
from heurams.services.textproc import truncate
|
||||||
|
|||||||
@@ -5,16 +5,16 @@ from heurams.kernel.particles.placeholders import AtomPlaceholder
|
|||||||
from heurams.services.logger import get_logger
|
from heurams.services.logger import get_logger
|
||||||
|
|
||||||
from .procession import Procession
|
from .procession import Procession
|
||||||
from .states import PhaserState, ProcessionState
|
from .states import RouterState, ProcessionState
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Phaser(Machine):
|
class Router(Machine):
|
||||||
"""全局调度阶段管理器"""
|
"""全局调度阶段管理器"""
|
||||||
|
|
||||||
def __init__(self, atoms: list[pt.Atom]) -> None:
|
def __init__(self, atoms: list[pt.Atom]) -> None:
|
||||||
logger.debug("Phaser.__init__: 原子数量=%d", len(atoms))
|
logger.debug("Router.__init__: 原子数量=%d", len(atoms))
|
||||||
|
|
||||||
self.atoms = atoms
|
self.atoms = atoms
|
||||||
new_atoms = list()
|
new_atoms = list()
|
||||||
@@ -32,50 +32,50 @@ class Phaser(Machine):
|
|||||||
# TODO: 改进为基于配置文件的可选复习阶段
|
# TODO: 改进为基于配置文件的可选复习阶段
|
||||||
if len(old_atoms):
|
if len(old_atoms):
|
||||||
self.processions.append(
|
self.processions.append(
|
||||||
Procession(old_atoms, PhaserState.QUICK_REVIEW, "初始复习")
|
Procession(old_atoms, RouterState.QUICK_REVIEW, "初始复习")
|
||||||
)
|
)
|
||||||
logger.debug("创建初始复习 Procession")
|
logger.debug("创建初始复习 Procession")
|
||||||
|
|
||||||
if len(new_atoms):
|
if len(new_atoms):
|
||||||
self.processions.append(
|
self.processions.append(
|
||||||
Procession(new_atoms, PhaserState.RECOGNITION, "新记忆")
|
Procession(new_atoms, RouterState.RECOGNITION, "新记忆")
|
||||||
)
|
)
|
||||||
logger.debug("创建新记忆 Procession")
|
logger.debug("创建新记忆 Procession")
|
||||||
|
|
||||||
self.processions.append(Procession(atoms, PhaserState.FINAL_REVIEW, "总体复习"))
|
self.processions.append(Procession(atoms, RouterState.FINAL_REVIEW, "总体复习"))
|
||||||
logger.debug("创建总体复习 Procession")
|
logger.debug("创建总体复习 Procession")
|
||||||
logger.debug("Phaser 初始化完成, processions 数量=%d", len(self.processions))
|
logger.debug("Router 初始化完成, processions 数量=%d", len(self.processions))
|
||||||
|
|
||||||
# 设置transitions状态机
|
# 设置transitions状态机
|
||||||
states = [
|
states = [
|
||||||
{"name": PhaserState.UNSURE.value, "on_enter": "on_unsure"},
|
{"name": RouterState.UNSURE.value, "on_enter": "on_unsure"},
|
||||||
{"name": PhaserState.QUICK_REVIEW.value, "on_enter": "on_quick_review"},
|
{"name": RouterState.QUICK_REVIEW.value, "on_enter": "on_quick_review"},
|
||||||
{"name": PhaserState.RECOGNITION.value, "on_enter": "on_recognition"},
|
{"name": RouterState.RECOGNITION.value, "on_enter": "on_recognition"},
|
||||||
{"name": PhaserState.FINAL_REVIEW.value, "on_enter": "on_final_review"},
|
{"name": RouterState.FINAL_REVIEW.value, "on_enter": "on_final_review"},
|
||||||
{"name": PhaserState.FINISHED.value, "on_enter": "on_finished"},
|
{"name": RouterState.FINISHED.value, "on_enter": "on_finished"},
|
||||||
]
|
]
|
||||||
|
|
||||||
transitions = [
|
transitions = [
|
||||||
{"trigger": "to_unsure", "source": "*", "dest": PhaserState.UNSURE.value},
|
{"trigger": "to_unsure", "source": "*", "dest": RouterState.UNSURE.value},
|
||||||
{
|
{
|
||||||
"trigger": "to_quick_review",
|
"trigger": "to_quick_review",
|
||||||
"source": "*",
|
"source": "*",
|
||||||
"dest": PhaserState.QUICK_REVIEW.value,
|
"dest": RouterState.QUICK_REVIEW.value,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"trigger": "to_recognition",
|
"trigger": "to_recognition",
|
||||||
"source": "*",
|
"source": "*",
|
||||||
"dest": PhaserState.RECOGNITION.value,
|
"dest": RouterState.RECOGNITION.value,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"trigger": "to_final_review",
|
"trigger": "to_final_review",
|
||||||
"source": "*",
|
"source": "*",
|
||||||
"dest": PhaserState.FINAL_REVIEW.value,
|
"dest": RouterState.FINAL_REVIEW.value,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"trigger": "to_finished",
|
"trigger": "to_finished",
|
||||||
"source": "*",
|
"source": "*",
|
||||||
"dest": PhaserState.FINISHED.value,
|
"dest": RouterState.FINISHED.value,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -83,45 +83,45 @@ class Phaser(Machine):
|
|||||||
self,
|
self,
|
||||||
states=states,
|
states=states,
|
||||||
transitions=transitions,
|
transitions=transitions,
|
||||||
initial=PhaserState.UNSURE.value,
|
initial=RouterState.UNSURE.value,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.to_unsure()
|
self.to_unsure()
|
||||||
|
|
||||||
def on_unsure(self):
|
def on_unsure(self):
|
||||||
"""进入UNSURE状态时的回调"""
|
"""进入UNSURE状态时的回调"""
|
||||||
logger.debug("Phaser 进入 UNSURE 状态")
|
logger.debug("Router 进入 UNSURE 状态")
|
||||||
|
|
||||||
def on_quick_review(self):
|
def on_quick_review(self):
|
||||||
"""进入QUICK_REVIEW状态时的回调"""
|
"""进入QUICK_REVIEW状态时的回调"""
|
||||||
logger.debug("Phaser 进入 QUICK_REVIEW 状态")
|
logger.debug("Router 进入 QUICK_REVIEW 状态")
|
||||||
|
|
||||||
def on_recognition(self):
|
def on_recognition(self):
|
||||||
"""进入RECOGNITION状态时的回调"""
|
"""进入RECOGNITION状态时的回调"""
|
||||||
logger.debug("Phaser 进入 RECOGNITION 状态")
|
logger.debug("Router 进入 RECOGNITION 状态")
|
||||||
|
|
||||||
def on_final_review(self):
|
def on_final_review(self):
|
||||||
"""进入FINAL_REVIEW状态时的回调"""
|
"""进入FINAL_REVIEW状态时的回调"""
|
||||||
logger.debug("Phaser 进入 FINAL_REVIEW 状态")
|
logger.debug("Router 进入 FINAL_REVIEW 状态")
|
||||||
|
|
||||||
def on_finished(self):
|
def on_finished(self):
|
||||||
"""进入FINISHED状态时的回调"""
|
"""进入FINISHED状态时的回调"""
|
||||||
for i in self.atoms:
|
for i in self.atoms:
|
||||||
i.lock(1)
|
i.lock(1)
|
||||||
i.revise()
|
i.revise()
|
||||||
logger.debug("Phaser 进入 FINISHED 状态")
|
logger.debug("Router 进入 FINISHED 状态")
|
||||||
|
|
||||||
def current_procession(self):
|
def current_procession(self):
|
||||||
logger.debug("Phaser.current_procession 被调用")
|
logger.debug("Router.current_procession 被调用")
|
||||||
for i in self.processions:
|
for i in self.processions:
|
||||||
i: Procession
|
i: Procession
|
||||||
if i.state != ProcessionState.FINISHED.value:
|
if i.state != ProcessionState.FINISHED.value:
|
||||||
# if i.phase == PhaserState.UNSURE: 此判断是不必要的 因为没有这种 Procession
|
# if i.phase == RouterState.UNSURE: 此判断是不必要的 因为没有这种 Procession
|
||||||
if i.phase == PhaserState.QUICK_REVIEW:
|
if i.phase == RouterState.QUICK_REVIEW:
|
||||||
self.to_quick_review()
|
self.to_quick_review()
|
||||||
elif i.phase == PhaserState.RECOGNITION:
|
elif i.phase == RouterState.RECOGNITION:
|
||||||
self.to_recognition()
|
self.to_recognition()
|
||||||
elif i.phase == PhaserState.FINAL_REVIEW:
|
elif i.phase == RouterState.FINAL_REVIEW:
|
||||||
self.to_final_review()
|
self.to_final_review()
|
||||||
|
|
||||||
logger.debug("找到未完成的 Procession: phase=%s", i.phase)
|
logger.debug("找到未完成的 Procession: phase=%s", i.phase)
|
||||||
@@ -130,7 +130,7 @@ class Phaser(Machine):
|
|||||||
# 所有Procession都已完成
|
# 所有Procession都已完成
|
||||||
self.to_finished()
|
self.to_finished()
|
||||||
logger.debug("所有 Procession 已完成, 状态设置为 FINISHED")
|
logger.debug("所有 Procession 已完成, 状态设置为 FINISHED")
|
||||||
return Procession([AtomPlaceholder()], PhaserState.FINISHED)
|
return Procession([AtomPlaceholder()], RouterState.FINISHED)
|
||||||
|
|
||||||
def __repr__(self, style="pipe", ends="\n"):
|
def __repr__(self, style="pipe", ends="\n"):
|
||||||
from tabulate import tabulate as tabu
|
from tabulate import tabulate as tabu
|
||||||
@@ -139,7 +139,7 @@ class Phaser(Machine):
|
|||||||
|
|
||||||
lst = [
|
lst = [
|
||||||
{
|
{
|
||||||
"Type": "Phaser",
|
"Type": "Router",
|
||||||
"State": self.state,
|
"State": self.state,
|
||||||
"Processions": list(map(lambda f: (f.name_), self.processions)),
|
"Processions": list(map(lambda f: (f.name_), self.processions)),
|
||||||
"Current Procession": "None" if not self.current_procession() else self.current_procession().name_, # type: ignore
|
"Current Procession": "None" if not self.current_procession() else self.current_procession().name_, # type: ignore
|
||||||
@@ -5,7 +5,7 @@ from heurams.services.logger import get_logger
|
|||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class PhaserState(Enum):
|
class RouterState(Enum):
|
||||||
UNSURE = "unsure"
|
UNSURE = "unsure"
|
||||||
QUICK_REVIEW = "quick_review"
|
QUICK_REVIEW = "quick_review"
|
||||||
RECOGNITION = "recognition"
|
RECOGNITION = "recognition"
|
||||||
@@ -18,7 +18,7 @@ class ProcessionState(Enum):
|
|||||||
FINISHED = "finished"
|
FINISHED = "finished"
|
||||||
|
|
||||||
|
|
||||||
class FissionState(Enum):
|
class ExpanderState(Enum):
|
||||||
EXAMMODE = "exammode"
|
EXAMMODE = "exammode"
|
||||||
RETRONLY = "retronly"
|
RETRONLY = "retronly"
|
||||||
|
|
||||||
|
|||||||
1
src/heurams/services/session.py
Normal file
1
src/heurams/services/session.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""会话记录模块"""
|
||||||
Reference in New Issue
Block a user