Compare commits

2 Commits

Author SHA1 Message Date
47c14e520b feat(interface): 完成队列式记忆模块更新 2026-01-06 20:32:27 +08:00
ca7ef92b05 fix: 修复完成屏幕问题 2026-01-06 19:58:46 +08:00
10 changed files with 278 additions and 201 deletions

View File

@@ -6,7 +6,8 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"# 演练场\n", "# 演练场\n",
"此笔记本将带你了解 repomgr 与 particles 对象相关操作" "此笔记本将带你了解 repomgr 与 particles 对象相关操作 \n",
"此笔记本内含的系统命令默认仅存在于 Linux 操作系统, 如果你使用 Windows, 请在安装 busybox 或 cygwin 或 WSL 的环境下执行此笔记本"
] ]
}, },
{ {
@@ -21,7 +22,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 1, "execution_count": 29,
"id": "a5ed9864", "id": "a5ed9864",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -30,7 +31,12 @@
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"\u001b[01;34m.\u001b[0m\n", "\u001b[01;34m.\u001b[0m\n",
"├── \u001b[01;34mdata\u001b[0m\n",
"│   └── \u001b[01;34mconfig\u001b[0m\n",
"│   └── \u001b[00mconfig.toml\u001b[0m\n",
"├── \u001b[00mjiebatest.py\u001b[0m\n",
"├── \u001b[00mrepo.ipynb\u001b[0m\n", "├── \u001b[00mrepo.ipynb\u001b[0m\n",
"├── \u001b[00msimplemem.py\u001b[0m\n",
"└── \u001b[01;34mtest_repo\u001b[0m\n", "└── \u001b[01;34mtest_repo\u001b[0m\n",
" ├── \u001b[00malgodata.json\u001b[0m\n", " ├── \u001b[00malgodata.json\u001b[0m\n",
" ├── \u001b[00mmanifest.toml\u001b[0m\n", " ├── \u001b[00mmanifest.toml\u001b[0m\n",
@@ -38,7 +44,7 @@
" ├── \u001b[00mschedule.toml\u001b[0m\n", " ├── \u001b[00mschedule.toml\u001b[0m\n",
" └── \u001b[00mtypedef.toml\u001b[0m\n", " └── \u001b[00mtypedef.toml\u001b[0m\n",
"\n", "\n",
"2 directories, 6 files\n" "4 directories, 9 files\n"
] ]
} }
], ],
@@ -56,7 +62,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 30,
"id": "9777730e", "id": "9777730e",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -85,21 +91,10 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 31,
"id": "bf1b00c8", "id": "bf1b00c8",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [],
{
"name": "stdout",
"output_type": "stream",
"text": [
"欢迎使用 HeurAMS 及其组件!\n",
"rootdir: /mnt/data/Devel/HeurAMS/HeurAMS/src/heurams\n",
"workdir: /mnt/data/Devel/HeurAMS/HeurAMS/examples\n",
"未能加载自定义用户配置\n"
]
}
],
"source": [ "source": [
"import heurams.kernel.repolib as repolib # 这是 RepoLib 子模块, 用于管理和结构化 repo(中文含义: 仓库) 数据结构与本地文件间的联系\n", "import heurams.kernel.repolib as repolib # 这是 RepoLib 子模块, 用于管理和结构化 repo(中文含义: 仓库) 数据结构与本地文件间的联系\n",
"import heurams.kernel.particles as pt # 这是 Particles(中文含义: 粒子) 子模块, 用于运行时的记忆管理操作\n", "import heurams.kernel.particles as pt # 这是 Particles(中文含义: 粒子) 子模块, 用于运行时的记忆管理操作\n",
@@ -120,7 +115,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 32,
"id": "897b62d7", "id": "897b62d7",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -148,7 +143,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 33,
"id": "708ae7e4", "id": "708ae7e4",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
@@ -169,7 +164,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 34,
"id": "a11115fb", "id": "a11115fb",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -177,20 +172,20 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"{'algodata': [('君臣固守以窥周室,', {}), ('秦孝公据崤函之固, 拥雍州之地,', {})],\n", "{'algodata': [('秦孝公据崤函之固, 拥雍州之地,', {}), ('君臣固守以窥周室,', {})],\n",
" 'manifest': {'author': '__heurams__',\n", " 'manifest': {'author': '__heurams__',\n",
" 'desc': '高考古诗文: 过秦论',\n", " 'desc': '高考古诗文: 过秦论',\n",
" 'title': '测试单元: 过秦论'},\n", " 'title': '测试单元: 过秦论'},\n",
" 'payload': [('君臣固守以窥周室,',\n", " 'payload': [('秦孝公据崤函之固, 拥雍州之地,',\n",
" {'content': '君臣/固守/以窥/周室,/',\n",
" 'keyword_note': {'窥': '窥视'},\n",
" 'note': [],\n",
" 'translation': '君臣牢固地守卫着,借以窥视周王室的权力,'}),\n",
" ('秦孝公据崤函之固, 拥雍州之地,',\n",
" {'content': '秦孝公/据/崤函/之固/, 拥/雍州/之地,/',\n", " {'content': '秦孝公/据/崤函/之固/, 拥/雍州/之地,/',\n",
" 'keyword_note': {'崤函': '崤山和函谷关', '据': '占据', '雍州': '古代九州之一'},\n", " 'keyword_note': {'崤函': '崤山和函谷关', '据': '占据', '雍州': '古代九州之一'},\n",
" 'note': [],\n", " 'note': [],\n",
" 'translation': '秦孝公占据着崤山和函谷关的险固地势,拥有雍州的土地,'})],\n", " 'translation': '秦孝公占据着崤山和函谷关的险固地势,拥有雍州的土地,'}),\n",
" ('君臣固守以窥周室,',\n",
" {'content': '君臣/固守/以窥/周室,/',\n",
" 'keyword_note': {'窥': '窥视'},\n",
" 'note': [],\n",
" 'translation': '君臣牢固地守卫着,借以窥视周王室的权力,'})],\n",
" 'schedule': {'phases': {'final_review': [['FillBlank', '0.7'],\n", " 'schedule': {'phases': {'final_review': [['FillBlank', '0.7'],\n",
" ['SelectMeaning', '0.7'],\n", " ['SelectMeaning', '0.7'],\n",
" ['Recognition', '1.0']],\n", " ['Recognition', '1.0']],\n",
@@ -207,10 +202,9 @@
" 'translation': '语句翻译',\n", " 'translation': '语句翻译',\n",
" 'tts_text': '文本转语音文本'},\n", " 'tts_text': '文本转语音文本'},\n",
" 'common': {'delimiter': '/',\n", " 'common': {'delimiter': '/',\n",
" 'tts_text': \"eval:payload['content'].replace('/', '')\"},\n",
" 'puzzles': {'FillBlank': {'__hint__': '',\n", " 'puzzles': {'FillBlank': {'__hint__': '',\n",
" '__origin__': 'cloze',\n", " '__origin__': 'cloze',\n",
" 'delimiter': \"eval:metadata['formation']['delimiter']\",\n", " 'delimiter': \"eval:nucleon['delimiter']\",\n",
" 'min_denominator': \"eval:default['cloze']['min_denominator']\",\n", " 'min_denominator': \"eval:default['cloze']['min_denominator']\",\n",
" 'text': \"eval:payload['content']\"},\n", " 'text': \"eval:payload['content']\"},\n",
" 'Recognition': {'__hint__': '',\n", " 'Recognition': {'__hint__': '',\n",
@@ -226,7 +220,8 @@
" 'max_riddles_num': \"eval:default['mcq']['max_riddles_num']\",\n", " 'max_riddles_num': \"eval:default['mcq']['max_riddles_num']\",\n",
" 'prefix': '选择正确项: ',\n", " 'prefix': '选择正确项: ',\n",
" 'primary': \"eval:payload['content']\"}},\n", " 'primary': \"eval:payload['content']\"}},\n",
" '古文句': {}}}\n" " 'tts_text': \"eval:payload['content'].replace('/', \"\n",
" \"'')\"}}}\n"
] ]
} }
], ],
@@ -255,13 +250,13 @@
"- save_list: 默认为 [\"algodata\"], 是要持久化的数据.\n", "- save_list: 默认为 [\"algodata\"], 是要持久化的数据.\n",
"- source: 默认为原目录, 你也可以手动指定为其他文件夹(通过 Path)\n", "- source: 默认为原目录, 你也可以手动指定为其他文件夹(通过 Path)\n",
"\n", "\n",
"现在做一些演练, 我们将创建一个位于 test_new_repo 的\"克隆\", 此时我们!\n", "现在做一些演练, 我们将创建一个位于 test_new_repo 的\"克隆\". \n",
"除非文件夹已经存在, Repo 对象将会为你自动创建新文件夹." "除非文件夹已经存在, Repo 对象将会为你自动创建新文件夹."
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 7, "execution_count": 35,
"id": "05eeaacc", "id": "05eeaacc",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -270,8 +265,12 @@
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"\u001b[01;34m.\u001b[0m\n", "\u001b[01;34m.\u001b[0m\n",
"├── \u001b[00mheurams.log\u001b[0m\n", "├── \u001b[01;34mdata\u001b[0m\n",
"│   └── \u001b[01;34mconfig\u001b[0m\n",
"│   └── \u001b[00mconfig.toml\u001b[0m\n",
"├── \u001b[00mjiebatest.py\u001b[0m\n",
"├── \u001b[00mrepo.ipynb\u001b[0m\n", "├── \u001b[00mrepo.ipynb\u001b[0m\n",
"├── \u001b[00msimplemem.py\u001b[0m\n",
"├── \u001b[01;34mtest_new_repo\u001b[0m\n", "├── \u001b[01;34mtest_new_repo\u001b[0m\n",
"│   ├── \u001b[00malgodata.json\u001b[0m\n", "│   ├── \u001b[00malgodata.json\u001b[0m\n",
"│   ├── \u001b[00mmanifest.toml\u001b[0m\n", "│   ├── \u001b[00mmanifest.toml\u001b[0m\n",
@@ -285,7 +284,7 @@
" ├── \u001b[00mschedule.toml\u001b[0m\n", " ├── \u001b[00mschedule.toml\u001b[0m\n",
" └── \u001b[00mtypedef.toml\u001b[0m\n", " └── \u001b[00mtypedef.toml\u001b[0m\n",
"\n", "\n",
"3 directories, 12 files\n" "5 directories, 14 files\n"
] ]
} }
], ],
@@ -327,7 +326,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 36,
"id": "7e88bd7c", "id": "7e88bd7c",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -335,8 +334,8 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"[('age', 12), ('enemy', 'jerry'), ('name', 'tom')]\n", "[('name', 'tom'), ('age', 12), ('enemy', 'jerry')]\n",
"[('age', 12), ('enemy', 'jerry'), ('name', 'tom')]\n" "[('name', 'tom'), ('age', 12), ('enemy', 'jerry')]\n"
] ]
} }
], ],
@@ -356,13 +355,13 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"### 输出形式\n", "### 输出形式\n",
"lct 的\"官方\"输出形式是列表形式\n", "Lict 的\"官方\"输出形式是列表形式\n",
"你也可以选择输出字典形式" "你也可以选择输出字典形式"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 37,
"id": "248f6cba", "id": "248f6cba",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -392,7 +391,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 10, "execution_count": 38,
"id": "a0eb07a7", "id": "a0eb07a7",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -400,9 +399,9 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"[('age', 12), ('enemy', 'jerry'), ('name', 'tom')]\n", "[('name', 'tom'), ('age', 12), ('enemy', 'jerry')]\n",
"[('age', 12), ('enemy', 'jerry'), ('name', 'tom'), ('type', 'cat')]\n", "[('name', 'tom'), ('age', 12), ('enemy', 'jerry'), ('type', 'cat')]\n",
"[('age', 12), ('enemy', 'jerry'), ('is_human', False), ('name', 'tom'), ('type', 'cat')]\n" "[('name', 'tom'), ('age', 12), ('enemy', 'jerry'), ('type', 'cat'), ('is_human', False)]\n"
] ]
} }
], ],
@@ -437,7 +436,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 11, "execution_count": null,
"id": "0ab442d4", "id": "0ab442d4",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -445,12 +444,12 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"{'age': 12, 'enemy': 'jerry', 'is_human': False, 'name': 'tom', 'type': 'cat', 'enemy_2': 'spike'}\n" "{'name': 'tom', 'age': 12, 'enemy': 'jerry', 'type': 'cat', 'is_human': False, 'enemy_2': 'spike'}\n"
] ]
} }
], ],
"source": [ "source": [
"# 由于 jupyter 的环境处理, 请不要重复运行此单元格, 如果想再看一遍, 请重启 jupyter 后再全部运行\n", "# 由于 Jupyter 的环境处理(环境状态会累积), 请不要重复运行此单元格, 如果想再看一遍, 请重启 jupyter 后再全部运行\n",
"\n", "\n",
"# 唯一推荐方式\n", "# 唯一推荐方式\n",
"lct.append((\"enemy_2\", \"spike\"))\n", "lct.append((\"enemy_2\", \"spike\"))\n",
@@ -470,7 +469,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 12, "execution_count": 40,
"id": "f3ca752f", "id": "f3ca752f",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -478,23 +477,23 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"[('age', 12), ('enemy', 'jerry'), ('enemy_2', 'spike'), ('is_human', False), ('name', 'tom'), ('type', 'cat')]\n", "[('age', 12), ('enemy', 'jerry'), ('is_human', False), ('name', 'tom'), ('type', 'cat'), ('enemy_2', 'spike')]\n",
"{'age': 12, 'enemy': 'jerry', 'is_human': False, 'name': 'tom', 'type': 'cat', 'enemy_2': 'spike'}\n", "{'age': 12, 'enemy': 'jerry', 'is_human': False, 'name': 'tom', 'type': 'cat', 'enemy_2': 'spike'}\n",
"------\n", "------\n",
"('age', 12)\n", "('age', 12)\n",
"('enemy', 'jerry')\n", "('enemy', 'jerry')\n",
"('enemy_2', 'spike')\n",
"('is_human', False)\n", "('is_human', False)\n",
"('name', 'tom')\n", "('name', 'tom')\n",
"('type', 'cat')\n", "('type', 'cat')\n",
"('enemy_2', 'spike')\n",
"6\n", "6\n",
"('type', 'cat')\n",
"[('age', 12), ('enemy', 'jerry'), ('enemy_2', 'spike'), ('is_human', False), ('name', 'tom')]\n",
"('name', 'tom')\n",
"[('age', 12), ('enemy', 'jerry'), ('enemy_2', 'spike'), ('is_human', False)]\n",
"('is_human', False)\n",
"[('age', 12), ('enemy', 'jerry'), ('enemy_2', 'spike')]\n",
"('enemy_2', 'spike')\n", "('enemy_2', 'spike')\n",
"[('age', 12), ('enemy', 'jerry'), ('is_human', False), ('name', 'tom'), ('type', 'cat')]\n",
"('type', 'cat')\n",
"[('age', 12), ('enemy', 'jerry'), ('is_human', False), ('name', 'tom')]\n",
"('name', 'tom')\n",
"[('age', 12), ('enemy', 'jerry'), ('is_human', False)]\n",
"('is_human', False)\n",
"[('age', 12), ('enemy', 'jerry')]\n", "[('age', 12), ('enemy', 'jerry')]\n",
"('enemy', 'jerry')\n", "('enemy', 'jerry')\n",
"[('age', 12)]\n", "[('age', 12)]\n",
@@ -508,7 +507,7 @@
"Ellipsis" "Ellipsis"
] ]
}, },
"execution_count": 12, "execution_count": 40,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@@ -556,10 +555,18 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 13, "execution_count": 41,
"id": "773bf99c", "id": "773bf99c",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"zsh:1: no matches found: heurams.log*\n"
]
}
],
"source": [ "source": [
"!rm -rf test_new_repo\n", "!rm -rf test_new_repo\n",
"!rm -rf heurams.log*" "!rm -rf heurams.log*"
@@ -567,7 +574,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 14, "execution_count": 42,
"id": "8645c5a2", "id": "8645c5a2",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -575,67 +582,106 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"{ 'content': '君臣/固守/以窥/周室,/',\n",
" 'delimiter': '/',\n",
" 'keyword_note': {'窥': '窥视'},\n",
" 'note': [],\n",
" 'translation': '君臣牢固地守卫着,借以窥视周王室的权力,',\n",
" 'tts_text': '君臣固守以窥周室,'}\n",
"{ 'SM-2': { 'efactor': 2.5,\n",
" 'interval': 1,\n",
" 'is_activated': 1,\n",
" 'last_date': 20454,\n",
" 'last_modify': 1767274438.752494,\n",
" 'next_date': 20455,\n",
" 'real_rept': 1,\n",
" 'rept': 0}}\n",
"{ 'content': '秦孝公/据/崤函/之固/, 拥/雍州/之地,/',\n", "{ 'content': '秦孝公/据/崤函/之固/, 拥/雍州/之地,/',\n",
" 'delimiter': '/',\n", " 'delimiter': '/',\n",
" 'keyword_note': {'崤函': '崤山和函谷关', '据': '占据', '雍州': '古代九州之一'},\n", " 'keyword_note': {'崤函': '崤山和函谷关', '据': '占据', '雍州': '古代九州之一'},\n",
" 'note': [],\n", " 'note': [],\n",
" 'puzzles': { 'FillBlank': { '__hint__': '',\n",
" '__origin__': 'cloze',\n",
" 'delimiter': '/',\n",
" 'min_denominator': 3,\n",
" 'text': '秦孝公/据/崤函/之固/, 拥/雍州/之地,/'},\n",
" 'Recognition': { '__hint__': '',\n",
" '__origin__': 'recognition',\n",
" 'primary': '秦孝公/据/崤函/之固/, 拥/雍州/之地,/',\n",
" 'secondary': [ { '崤函': '崤山和函谷关',\n",
" '据': '占据',\n",
" '雍州': '古代九州之一'},\n",
" []],\n",
" 'top_dim': [ '秦孝公占据着崤山和函谷关的险固地势,拥有雍州的土地,']},\n",
" 'SelectMeaning': { '__hint__': '秦孝公/据/崤函/之固/, 拥/雍州/之地,/',\n",
" '__origin__': 'mcq',\n",
" 'jammer': ['占据', '崤山和函谷关', '古代九州之一'],\n",
" 'mapping': { '崤函': '崤山和函谷关',\n",
" '据': '占据',\n",
" '雍州': '古代九州之一'},\n",
" 'max_riddles_num': 2,\n",
" 'prefix': '选择正确项: ',\n",
" 'primary': '秦孝公/据/崤函/之固/, 拥/雍州/之地,/'}},\n",
" 'translation': '秦孝公占据着崤山和函谷关的险固地势,拥有雍州的土地,',\n", " 'translation': '秦孝公占据着崤山和函谷关的险固地势,拥有雍州的土地,',\n",
" 'tts_text': '秦孝公据崤函之固, 拥雍州之地,'}\n", " 'tts_text': '秦孝公据崤函之固, 拥雍州之地,'}\n",
"{ 'SM-2': { 'efactor': 2.5,\n", "{ 'SM-2': { 'efactor': 2.5,\n",
" 'interval': 1,\n", " 'interval': 1,\n",
" 'is_activated': 1,\n", " 'is_activated': 1,\n",
" 'last_date': 20454,\n", " 'last_date': 20459,\n",
" 'last_modify': 1767274438.7534873,\n", " 'last_modify': 1767700296.4950516,\n",
" 'next_date': 20455,\n", " 'next_date': 20460,\n",
" 'real_rept': 1,\n", " 'real_rept': 1,\n",
" 'rept': 0}}\n", " 'rept': 0}}\n",
"{ 'algodata': [ ( '君臣固守以窥周室,',\n", "{ 'content': '君臣/固守/以窥/周室,/',\n",
" 'delimiter': '/',\n",
" 'keyword_note': {'窥': '窥视'},\n",
" 'note': [],\n",
" 'puzzles': { 'FillBlank': { '__hint__': '',\n",
" '__origin__': 'cloze',\n",
" 'delimiter': '/',\n",
" 'min_denominator': 3,\n",
" 'text': '君臣/固守/以窥/周室,/'},\n",
" 'Recognition': { '__hint__': '',\n",
" '__origin__': 'recognition',\n",
" 'primary': '君臣/固守/以窥/周室,/',\n",
" 'secondary': [{'窥': '窥视'}, []],\n",
" 'top_dim': ['君臣牢固地守卫着,借以窥视周王室的权力,']},\n",
" 'SelectMeaning': { '__hint__': '君臣/固守/以窥/周室,/',\n",
" '__origin__': 'mcq',\n",
" 'jammer': ['窥视'],\n",
" 'mapping': {'窥': '窥视'},\n",
" 'max_riddles_num': 2,\n",
" 'prefix': '选择正确项: ',\n",
" 'primary': '君臣/固守/以窥/周室,/'}},\n",
" 'translation': '君臣牢固地守卫着,借以窥视周王室的权力,',\n",
" 'tts_text': '君臣固守以窥周室,'}\n",
"{ 'SM-2': { 'efactor': 2.5,\n",
" 'interval': 1,\n",
" 'is_activated': 1,\n",
" 'last_date': 20459,\n",
" 'last_modify': 1767700296.4968777,\n",
" 'next_date': 20460,\n",
" 'real_rept': 1,\n",
" 'rept': 0}}\n",
"{ 'algodata': [ ( '秦孝公据崤函之固, 拥雍州之地,',\n",
" { 'SM-2': { 'efactor': 2.5,\n", " { 'SM-2': { 'efactor': 2.5,\n",
" 'interval': 1,\n", " 'interval': 1,\n",
" 'is_activated': 1,\n", " 'is_activated': 1,\n",
" 'last_date': 20454,\n", " 'last_date': 20459,\n",
" 'last_modify': 1767274438.752494,\n", " 'last_modify': 1767700296.4950516,\n",
" 'next_date': 20455,\n", " 'next_date': 20460,\n",
" 'real_rept': 1,\n", " 'real_rept': 1,\n",
" 'rept': 0}}),\n", " 'rept': 0}}),\n",
" ( '秦孝公据崤函之固, 拥雍州之地,',\n", " ( '君臣固守以窥周室,',\n",
" { 'SM-2': { 'efactor': 2.5,\n", " { 'SM-2': { 'efactor': 2.5,\n",
" 'interval': 1,\n", " 'interval': 1,\n",
" 'is_activated': 1,\n", " 'is_activated': 1,\n",
" 'last_date': 20454,\n", " 'last_date': 20459,\n",
" 'last_modify': 1767274438.7534873,\n", " 'last_modify': 1767700296.4968777,\n",
" 'next_date': 20455,\n", " 'next_date': 20460,\n",
" 'real_rept': 1,\n", " 'real_rept': 1,\n",
" 'rept': 0}})],\n", " 'rept': 0}})],\n",
" 'manifest': { 'author': '__heurams__',\n", " 'manifest': { 'author': '__heurams__',\n",
" 'desc': '高考古诗文: 过秦论',\n", " 'desc': '高考古诗文: 过秦论',\n",
" 'title': '测试单元: 过秦论'},\n", " 'title': '测试单元: 过秦论'},\n",
" 'payload': [ ( '君臣固守以窥周室,',\n", " 'payload': [ ( '秦孝公据崤函之固, 拥雍州之地,',\n",
" { 'content': '君臣/固守/以窥/周室,/',\n",
" 'keyword_note': {'窥': '窥视'},\n",
" 'note': [],\n",
" 'translation': '君臣牢固地守卫着,借以窥视周王室的权力,'}),\n",
" ( '秦孝公据崤函之固, 拥雍州之地,',\n",
" { 'content': '秦孝公/据/崤函/之固/, 拥/雍州/之地,/',\n", " { 'content': '秦孝公/据/崤函/之固/, 拥/雍州/之地,/',\n",
" 'keyword_note': { '崤函': '崤山和函谷关',\n", " 'keyword_note': { '崤函': '崤山和函谷关',\n",
" '据': '占据',\n", " '据': '占据',\n",
" '雍州': '古代九州之一'},\n", " '雍州': '古代九州之一'},\n",
" 'note': [],\n", " 'note': [],\n",
" 'translation': '秦孝公占据着崤山和函谷关的险固地势,拥有雍州的土地,'})],\n", " 'translation': '秦孝公占据着崤山和函谷关的险固地势,拥有雍州的土地,'}),\n",
" ( '君臣固守以窥周室,',\n",
" { 'content': '君臣/固守/以窥/周室,/',\n",
" 'keyword_note': {'窥': '窥视'},\n",
" 'note': [],\n",
" 'translation': '君臣牢固地守卫着,借以窥视周王室的权力,'})],\n",
" 'schedule': { 'phases': { 'final_review': [ ['FillBlank', '0.7'],\n", " 'schedule': { 'phases': { 'final_review': [ ['FillBlank', '0.7'],\n",
" ['SelectMeaning', '0.7'],\n", " ['SelectMeaning', '0.7'],\n",
" ['Recognition', '1.0']],\n", " ['Recognition', '1.0']],\n",
@@ -654,11 +700,9 @@
" 'translation': '语句翻译',\n", " 'translation': '语句翻译',\n",
" 'tts_text': '文本转语音文本'},\n", " 'tts_text': '文本转语音文本'},\n",
" 'common': { 'delimiter': '/',\n", " 'common': { 'delimiter': '/',\n",
" 'tts_text': \"eval:payload['content'].replace('/', \"\n",
" \"'')\"},\n",
" 'puzzles': { 'FillBlank': { '__hint__': '',\n", " 'puzzles': { 'FillBlank': { '__hint__': '',\n",
" '__origin__': 'cloze',\n", " '__origin__': 'cloze',\n",
" 'delimiter': \"eval:metadata['formation']['delimiter']\",\n", " 'delimiter': \"eval:nucleon['delimiter']\",\n",
" 'min_denominator': \"eval:default['cloze']['min_denominator']\",\n", " 'min_denominator': \"eval:default['cloze']['min_denominator']\",\n",
" 'text': \"eval:payload['content']\"},\n", " 'text': \"eval:payload['content']\"},\n",
" 'Recognition': { '__hint__': '',\n", " 'Recognition': { '__hint__': '',\n",
@@ -674,7 +718,8 @@
" 'max_riddles_num': \"eval:default['mcq']['max_riddles_num']\",\n", " 'max_riddles_num': \"eval:default['mcq']['max_riddles_num']\",\n",
" 'prefix': '选择正确项: ',\n", " 'prefix': '选择正确项: ',\n",
" 'primary': \"eval:payload['content']\"}},\n", " 'primary': \"eval:payload['content']\"}},\n",
" '古文句': {}}}\n" " 'tts_text': \"eval:payload['content'].replace('/', \"\n",
" \"'')\"}}}\n"
] ]
} }
], ],

View File

@@ -1,6 +1,7 @@
"""队列式记忆工作界面""" """队列式记忆工作界面"""
from enum import Enum, auto from enum import Enum, auto
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
@@ -42,15 +43,18 @@ class MemScreen(Screen):
def __init__( def __init__(
self, self,
phaser: Phaser, phaser: Phaser,
save_func: Callable,
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.phaser = phaser
self.save_func = save_func
self.update_state() self.update_state()
self.fission: Fission self.fission: Fission
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
yield Header(show_clock=True) yield Header(show_clock=True)
with ScrollableContainer(): with ScrollableContainer():
@@ -80,27 +84,28 @@ class MemScreen(Screen):
def _get_progress_text(self): def _get_progress_text(self):
s = f"阶段: {self.procession.phase.name}\n" s = f"阶段: {self.procession.phase.name}\n"
if config_var.get().get("debug_topline", 0):
try: try:
alia = self.fission.get_current_puzzle_inf()['alia'] # type: ignore alia = self.fission.get_current_puzzle_inf()["alia"] # type: ignore
s += f"谜题: {alia}\n" s += f"谜题: {alia}\n"
except: except:
pass pass
try: try:
stat = self.phaser.__repr__('simple', '') stat = self.phaser.__repr__("simple", "")
s += f"{stat}\n" s += f"{stat}\n"
except: except:
pass pass
try: try:
stat = self.procession.__repr__('simple', '') stat = self.procession.__repr__("simple", "")
s += f"{stat}\n" s += f"{stat}\n"
except: except:
pass pass
try: try:
stat = self.fission.__repr__('simple', '') stat = self.fission.__repr__("simple", "")
s += f"{stat}\n" s += f"{stat}\n"
except Exception as e: except Exception as e:
s = str(e) s = str(e)
#s += f"当前进度: {self.procession.process() + 1}/{self.procession.total_length()}" # s += f"当前进度: {self.procession.process() + 1}/{self.procession.total_length()}"
return s return s
def update_display(self): def update_display(self):
@@ -110,6 +115,9 @@ class MemScreen(Screen):
def mount_puzzle(self): def mount_puzzle(self):
"""挂载当前谜题组件""" """挂载当前谜题组件"""
if self.procession.phase == PhaserState.FINISHED:
self.mount_finished_widget()
return
container = self.query_one("#puzzle-container") container = self.query_one("#puzzle-container")
for i in container.children: for i in container.children:
i.remove() i.remove()
@@ -121,8 +129,9 @@ class MemScreen(Screen):
for i in container.children: for i in container.children:
i.remove() i.remove()
from heurams.interface.widgets.finished import Finished from heurams.interface.widgets.finished import Finished
if config_var.get().get("persist_to_file", 0):
container.mount(Finished()) self.save_func()
container.mount(Finished(is_saved=config_var.get().get("persist_to_file", 0)))
def on_button_pressed(self, event): def on_button_pressed(self, event):
event.stop() event.stop()
@@ -150,6 +159,10 @@ class MemScreen(Screen):
def watch_rating(self, old_rating, new_rating) -> None: def watch_rating(self, old_rating, new_rating) -> None:
if new_rating == -1: # 安全值 if new_rating == -1: # 安全值
return return
self.update_state()
if self.procession.phase == PhaserState.FINISHED:
rating = -1
return
self.fission.report(new_rating) self.fission.report(new_rating)
self.forward(new_rating) self.forward(new_rating)
self.rating = -1 self.rating = -1
@@ -159,23 +172,32 @@ class MemScreen(Screen):
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.fission.forward()
if self.fission.state == 'retronly': if self.fission.state == "retronly":
self.forward_atom(self.fission.get_quality()) self.forward_atom(self.fission.get_quality())
self.update_state() self.update_state()
self.mount_puzzle() self.mount_puzzle()
self.update_display() self.update_display()
def atom_reporter(self, quality):
if not self.atom.registry["runtime"]["locked"]:
if not self.atom.registry["electron"].is_activated():
self.atom.registry["electron"].activate()
logger.debug(f"激活原子 {self.atom}")
self.atom.lock(1)
self.atom.minimize(5)
else:
self.atom.minimize(quality)
else:
pass
def forward_atom(self, quality): def forward_atom(self, quality):
logger.debug(f"Quality: {quality}") logger.debug(f"Quality: {quality}")
self.atom_reporter(quality)
if quality <= 3: if quality <= 3:
self.procession.append() self.procession.append()
self.update_state() # 刷新状态 self.update_state() # 刷新状态
self.procession.forward(1) self.procession.forward(1)
self.update_state() # 刷新状态 self.update_state() # 刷新状态
if self.procession.phase == PhaserState.FINISHED: # 若所有队列都结束了
logger.debug(f"记忆进程结束")
self.mount_finished_widget()
return
self.fission = self.procession.get_fission() self.fission = self.procession.get_fission()
def action_go_back(self): def action_go_back(self):

View File

@@ -130,8 +130,10 @@ class PreparationScreen(Screen):
import heurams.kernel.reactor as rt import heurams.kernel.reactor as rt
pheser = rt.Phaser(atoms_to_provide) pheser = rt.Phaser(atoms_to_provide)
memscreen = MemScreen(pheser) save_func = self.repo.persist_to_repodir
memscreen = MemScreen(pheser, save_func)
self.app.push_screen(memscreen) self.app.push_screen(memscreen)
elif event.button.id == "precache_button": elif event.button.id == "precache_button":
self.action_precache() self.action_precache()

View File

@@ -7,6 +7,7 @@ class Finished(Widget):
self, self,
*children: Widget, *children: Widget,
alia="", alia="",
is_saved = 0,
name: str | None = None, name: str | None = None,
id: str | None = None, id: str | None = None,
classes: str | None = None, classes: str | None = None,
@@ -14,6 +15,7 @@ class Finished(Widget):
markup: bool = True markup: bool = True
) -> None: ) -> None:
self.alia = alia self.alia = alia
self.is_saved = is_saved
super().__init__( super().__init__(
*children, *children,
name=name, name=name,
@@ -25,6 +27,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 Button("返回上一级", id="back-to-menu") yield Button("返回上一级", id="back-to-menu")
def on_button_pressed(self, event): def on_button_pressed(self, event):

View File

@@ -107,13 +107,3 @@ class Recognition(BasePuzzleWidget):
if event.button.id == "ok": if event.button.id == "ok":
self.screen.rating = 5 # type: ignore self.screen.rating = 5 # type: ignore
self.handler(5) self.handler(5)
def handler(self, rating):
if not self.atom.registry["runtime"]["locked"]:
if not self.atom.registry["electron"].is_activated():
self.atom.registry["electron"].activate()
logger.debug(f"激活原子 {self.atom}")
self.atom.lock(1)
self.atom.minimize(5)
else:
pass

View File

@@ -11,6 +11,7 @@ from .states import FissionState, PhaserState
logger = get_logger(__name__) logger = get_logger(__name__)
class Fission(Machine): class Fission(Machine):
"""单原子调度展开器""" """单原子调度展开器"""
@@ -21,6 +22,26 @@ class Fission(Machine):
self.current_puzzle_inf: dict self.current_puzzle_inf: dict
# phase 为 PhaserState 枚举实例, 需要获取其value # phase 为 PhaserState 枚举实例, 需要获取其value
phase_value = phase.value phase_value = phase.value
states = [
{"name": FissionState.EXAMMODE.value},
{"name": FissionState.RETRONLY.value},
]
transitions = [
{
"trigger": "finish",
"source": FissionState.EXAMMODE.value,
"dest": FissionState.RETRONLY.value,
},
]
if phase == PhaserState.FINISHED:
Machine.__init__(
self,
states=states,
transitions=transitions,
initial=FissionState.EXAMMODE.value,
)
return
orbital_schedule = atom.registry["orbital"]["phases"][phase_value] # type: ignore orbital_schedule = atom.registry["orbital"]["phases"][phase_value] # type: ignore
orbital_puzzles = atom.registry["nucleon"]["puzzles"] orbital_puzzles = atom.registry["nucleon"]["puzzles"]
self.puzzles_inf = list() self.puzzles_inf = list()
@@ -47,21 +68,9 @@ class Fission(Machine):
} }
) )
self.current_puzzle_inf = self.puzzles_inf[0] self.current_puzzle_inf = self.puzzles_inf[0]
states = [
{"name": FissionState.EXAMMODE.value},
{"name": FissionState.RETRONLY.value},
]
transitions = [
{
"trigger": "finish",
"source": FissionState.EXAMMODE.value,
"dest": FissionState.RETRONLY.value,
},
]
for i in range(len(self.puzzles_inf)): for i in range(len(self.puzzles_inf)):
self.min_ratings.append(0x3f3f3f3f) self.min_ratings.append(0x3F3F3F3F)
Machine.__init__( Machine.__init__(
self, self,
@@ -71,35 +80,33 @@ class Fission(Machine):
) )
def get_puzzles_inf(self): def get_puzzles_inf(self):
if self.state == 'retronly': if self.state == "retronly":
return [{"puzzle": puz.puzzles['recognition'], "alia": "Recognition"}] return [{"puzzle": puz.puzzles["recognition"], "alia": "Recognition"}]
return self.puzzles_inf return self.puzzles_inf
def get_current_puzzle_inf(self): def get_current_puzzle_inf(self):
if self.state == 'retronly': if self.state == "retronly":
return {"puzzle": puz.puzzles['recognition'], "alia": "Recognition"} return {"puzzle": puz.puzzles["recognition"], "alia": "Recognition"}
return self.current_puzzle_inf return self.current_puzzle_inf
def report(self, rating): def report(self, rating):
self.min_ratings[self.cursor] = min(rating, self.min_ratings[self.cursor]) self.min_ratings[self.cursor] = min(rating, self.min_ratings[self.cursor])
def get_quality(self): def get_quality(self):
logger.debug(f"CState: {self.state}")
if self.is_state("retronly", self): if self.is_state("retronly", self):
return reduce(lambda x,y: min(x, y), self.min_ratings) return reduce(lambda x, y: min(x, y), self.min_ratings)
raise IndexError raise IndexError
def forward(self, step=1): def forward(self, step=1):
"""将谜题指针向前移动并依情况更新或完成""" """将谜题指针向前移动并依情况更新或完成"""
logger.debug("Procession.forward: step=%d, 当前 cursor=%d", step, self.cursor)
self.cursor += step self.cursor += step
if self.cursor >= len(self.puzzles_inf): if self.cursor >= len(self.puzzles_inf):
if self.state != 'retronly': if self.state != "retronly":
self.finish() self.finish()
else: else:
self.current_puzzle_inf = self.puzzles_inf[self.cursor] self.current_puzzle_inf = self.puzzles_inf[self.cursor]
def __repr__(self, style="pipe", ends = "\n") -> str: def __repr__(self, style="pipe", ends="\n") -> str:
from heurams.services.textproc import truncate from heurams.services.textproc import truncate
dic = [ dic = [
@@ -108,7 +115,7 @@ class Fission(Machine):
"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)}",
"Queue": list(map(lambda f: truncate(f['alia']), self.puzzles_inf)), "Queue": list(map(lambda f: truncate(f["alia"]), self.puzzles_inf)),
"Current Puzzle": f"{self.current_puzzle_inf['alia']}@{self.current_puzzle_inf['puzzle'].__name__}", # type: ignore "Current Puzzle": f"{self.current_puzzle_inf['alia']}@{self.current_puzzle_inf['puzzle'].__name__}", # type: ignore
} }
] ]

View File

@@ -16,6 +16,7 @@ class Phaser(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("Phaser.__init__: 原子数量=%d", len(atoms))
self.atoms = atoms
new_atoms = list() new_atoms = list()
old_atoms = list() old_atoms = list()
@@ -105,6 +106,9 @@ class Phaser(Machine):
def on_finished(self): def on_finished(self):
"""进入FINISHED状态时的回调""" """进入FINISHED状态时的回调"""
for i in self.atoms:
i.lock(1)
i.revise()
logger.debug("Phaser 进入 FINISHED 状态") logger.debug("Phaser 进入 FINISHED 状态")
def current_procession(self): def current_procession(self):
@@ -112,7 +116,7 @@ class Phaser(Machine):
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 == PhaserState.UNSURE: 此判断是不必要的 因为没有这种 Procession
if i.phase == PhaserState.QUICK_REVIEW: if i.phase == PhaserState.QUICK_REVIEW:
self.to_quick_review() self.to_quick_review()
elif i.phase == PhaserState.RECOGNITION: elif i.phase == PhaserState.RECOGNITION:
@@ -128,7 +132,7 @@ class Phaser(Machine):
logger.debug("所有 Procession 已完成, 状态设置为 FINISHED") logger.debug("所有 Procession 已完成, 状态设置为 FINISHED")
return Procession([AtomPlaceholder()], PhaserState.FINISHED) return Procession([AtomPlaceholder()], PhaserState.FINISHED)
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
from tabulate import tabulate as tabu from tabulate import tabulate as tabu

View File

@@ -8,6 +8,7 @@ from .states import PhaserState, ProcessionState
logger = get_logger(__name__) logger = get_logger(__name__)
class Procession(Machine): class Procession(Machine):
"""队列: 标识单次记忆流程""" """队列: 标识单次记忆流程"""
@@ -114,7 +115,7 @@ class Procession(Machine):
def get_fission(self): def get_fission(self):
return Fission(atom=self.current_atom, phase=self.phase) # type: ignore return Fission(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
dic = [ dic = [

View File

@@ -12,12 +12,15 @@ class PhaserState(Enum):
FINAL_REVIEW = "final_review" FINAL_REVIEW = "final_review"
FINISHED = "finished" FINISHED = "finished"
class ProcessionState(Enum): class ProcessionState(Enum):
ACTIVE = "active" ACTIVE = "active"
FINISHED = "finished" FINISHED = "finished"
class FissionState(Enum): class FissionState(Enum):
EXAMMODE = "exammode" EXAMMODE = "exammode"
RETRONLY = "retronly" RETRONLY = "retronly"
logger.debug("状态枚举定义已加载") logger.debug("状态枚举定义已加载")

View File

@@ -101,7 +101,7 @@ class Repo:
source = self.source source = self.source
if source == None: if source == None:
raise FileNotFoundError("不存在仓库到文件的映射") raise FileNotFoundError("不存在仓库到文件的映射")
source.mkdir(parents=True, exist_ok=False) source.mkdir(parents=True, exist_ok=True)
for keyname in save_list: for keyname in save_list:
filename = self.file_mapping[keyname] filename = self.file_mapping[keyname]
with open(source / filename, "w") as f: with open(source / filename, "w") as f:
@@ -112,7 +112,7 @@ class Repo:
if filename.endswith("toml"): if filename.endswith("toml"):
toml.dump(dict_data, f) toml.dump(dict_data, f)
elif filename.endswith("json"): elif filename.endswith("json"):
json.dump(dict_data, f) json.dump(dict_data, f, ensure_ascii=False, indent=4)
else: else:
raise ValueError(f"不支持的文件类型: {filename}") raise ValueError(f"不支持的文件类型: {filename}")