feat: 完成部分界面重构
This commit is contained in:
@@ -31,13 +31,11 @@ max_riddles_num = 2
|
|||||||
min_denominator = 3
|
min_denominator = 3
|
||||||
|
|
||||||
[paths] # 相对于配置文件的 ".." (即工作目录) 而言 或绝对路径
|
[paths] # 相对于配置文件的 ".." (即工作目录) 而言 或绝对路径
|
||||||
nucleon_dir = "./data/nucleon"
|
data = "./data"
|
||||||
electron_dir = "./data/electron"
|
cache = "./data/cache"
|
||||||
global_dir = "./data/global" # 全局数据路径, SM-15 等算法需要
|
config = "./data/config"
|
||||||
orbital_dir = "./data/orbital"
|
global = "./data/global"
|
||||||
cache_dir = "./data/cache"
|
repo = "./data/repo"
|
||||||
template_dir = "./data/template"
|
|
||||||
|
|
||||||
[services] # 定义服务到提供者的映射
|
[services] # 定义服务到提供者的映射
|
||||||
audio = "playsound" # 可选项: playsound(通用), termux(仅用于支持 Android Termux), mpg123(TODO)
|
audio = "playsound" # 可选项: playsound(通用), termux(仅用于支持 Android Termux), mpg123(TODO)
|
||||||
tts = "edgetts" # 可选项: edgetts
|
tts = "edgetts" # 可选项: edgetts
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
title = "测试单元: 过秦论"
|
title = "测试单元 (过秦论)"
|
||||||
author = "__heurams__"
|
author = "__heurams__"
|
||||||
desc = "高考古诗文: 过秦论"
|
desc = "高考古诗文: 过秦论"
|
||||||
@@ -21,10 +21,27 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 1,
|
||||||
"id": "a5ed9864",
|
"id": "a5ed9864",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"\u001b[01;34m.\u001b[0m\n",
|
||||||
|
"├── \u001b[00mrepo.ipynb\u001b[0m\n",
|
||||||
|
"└── \u001b[01;34mtest_repo\u001b[0m\n",
|
||||||
|
" ├── \u001b[00malgodata.json\u001b[0m\n",
|
||||||
|
" ├── \u001b[00mmanifest.toml\u001b[0m\n",
|
||||||
|
" ├── \u001b[00mpayload.toml\u001b[0m\n",
|
||||||
|
" ├── \u001b[00mschedule.toml\u001b[0m\n",
|
||||||
|
" └── \u001b[00mtypedef.toml\u001b[0m\n",
|
||||||
|
"\n",
|
||||||
|
"2 directories, 6 files\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"!tree # 了解文件结构"
|
"!tree # 了解文件结构"
|
||||||
]
|
]
|
||||||
@@ -39,10 +56,18 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 2,
|
||||||
"id": "9777730e",
|
"id": "9777730e",
|
||||||
"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*"
|
||||||
@@ -60,10 +85,21 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 3,
|
||||||
"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",
|
||||||
@@ -82,10 +118,18 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 4,
|
||||||
"id": "897b62d7",
|
"id": "897b62d7",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"这是一个 合规 的 repo!\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"is_vaild = repolib.Repo.check_repodir(Path(\"./test_repo\"))\n",
|
"is_vaild = repolib.Repo.check_repodir(Path(\"./test_repo\"))\n",
|
||||||
"print(f\"这是一个 {'合规' if is_vaild else '不合规'} 的 repo!\")"
|
"print(f\"这是一个 {'合规' if is_vaild else '不合规'} 的 repo!\")"
|
||||||
@@ -102,7 +146,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 5,
|
||||||
"id": "708ae7e4",
|
"id": "708ae7e4",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
@@ -123,10 +167,67 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 6,
|
||||||
"id": "a11115fb",
|
"id": "a11115fb",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"{'algodata': [('君臣固守以窥周室,', {}), ('秦孝公据崤函之固, 拥雍州之地,', {})],\n",
|
||||||
|
" 'manifest': {'author': '__heurams__',\n",
|
||||||
|
" 'desc': '高考古诗文: 过秦论',\n",
|
||||||
|
" 'title': '测试单元: 过秦论'},\n",
|
||||||
|
" 'payload': [('君臣固守以窥周室,',\n",
|
||||||
|
" {'content': '君臣/固守/以窥/周室,/',\n",
|
||||||
|
" 'keyword_note': {'窥': '窥视'},\n",
|
||||||
|
" 'note': [],\n",
|
||||||
|
" 'translation': '君臣牢固地守卫着,借以窥视周王室的权力,'}),\n",
|
||||||
|
" ('秦孝公据崤函之固, 拥雍州之地,',\n",
|
||||||
|
" {'content': '秦孝公/据/崤函/之固/, 拥/雍州/之地,/',\n",
|
||||||
|
" 'keyword_note': {'崤函': '崤山和函谷关', '据': '占据', '雍州': '古代九州之一'},\n",
|
||||||
|
" 'note': [],\n",
|
||||||
|
" 'translation': '秦孝公占据着崤山和函谷关的险固地势,拥有雍州的土地,'})],\n",
|
||||||
|
" 'schedule': {'phases': {'final_review': [['FillBlank', '0.7'],\n",
|
||||||
|
" ['SelectMeaning', '0.7'],\n",
|
||||||
|
" ['Recognition', '1.0']],\n",
|
||||||
|
" 'quick_review': [['FillBlank', '1.0'],\n",
|
||||||
|
" ['SelectMeaning', '0.5'],\n",
|
||||||
|
" ['Recognition', '1.0']],\n",
|
||||||
|
" 'recognition': [['Recognition', '1.0']]},\n",
|
||||||
|
" 'schedule': ['quick_review', 'recognition', 'final_review']},\n",
|
||||||
|
" 'source': PosixPath('test_repo'),\n",
|
||||||
|
" 'typedef': {'annotation': {'content': '内容',\n",
|
||||||
|
" 'delimiter': '分隔符',\n",
|
||||||
|
" 'keyword_note': '关键词翻译',\n",
|
||||||
|
" 'note': '笔记',\n",
|
||||||
|
" 'translation': '语句翻译',\n",
|
||||||
|
" 'tts_text': '文本转语音文本'},\n",
|
||||||
|
" 'common': {'delimiter': '/',\n",
|
||||||
|
" 'tts_text': \"eval:payload['content'].replace('/', '')\"},\n",
|
||||||
|
" 'puzzles': {'FillBlank': {'__hint__': '',\n",
|
||||||
|
" '__origin__': 'cloze',\n",
|
||||||
|
" 'delimiter': \"eval:metadata['formation']['delimiter']\",\n",
|
||||||
|
" 'min_denominator': \"eval:default['cloze']['min_denominator']\",\n",
|
||||||
|
" 'text': \"eval:payload['content']\"},\n",
|
||||||
|
" 'Recognition': {'__hint__': '',\n",
|
||||||
|
" '__origin__': 'recognition',\n",
|
||||||
|
" 'primary': \"eval:payload['content']\",\n",
|
||||||
|
" 'secondary': [\"eval:payload['keyword_note']\",\n",
|
||||||
|
" \"eval:payload['note']\"],\n",
|
||||||
|
" 'top_dim': [\"eval:payload['translation']\"]},\n",
|
||||||
|
" 'SelectMeaning': {'__hint__': \"eval:payload['content']\",\n",
|
||||||
|
" '__origin__': 'mcq',\n",
|
||||||
|
" 'jammer': \"eval:list(payload['keyword_note'].values())\",\n",
|
||||||
|
" 'mapping': \"eval:payload['keyword_note']\",\n",
|
||||||
|
" 'max_riddles_num': \"eval:default['mcq']['max_riddles_num']\",\n",
|
||||||
|
" 'prefix': '选择正确项: ',\n",
|
||||||
|
" 'primary': \"eval:payload['content']\"}},\n",
|
||||||
|
" '古文句': {}}}\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"test_repo_dic = test_repo.export_to_single_dict()\n",
|
"test_repo_dic = test_repo.export_to_single_dict()\n",
|
||||||
"from pprint import pprint\n",
|
"from pprint import pprint\n",
|
||||||
@@ -157,10 +258,34 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 7,
|
||||||
"id": "05eeaacc",
|
"id": "05eeaacc",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"\u001b[01;34m.\u001b[0m\n",
|
||||||
|
"├── \u001b[00mheurams.log\u001b[0m\n",
|
||||||
|
"├── \u001b[00mrepo.ipynb\u001b[0m\n",
|
||||||
|
"├── \u001b[01;34mtest_new_repo\u001b[0m\n",
|
||||||
|
"│ ├── \u001b[00malgodata.json\u001b[0m\n",
|
||||||
|
"│ ├── \u001b[00mmanifest.toml\u001b[0m\n",
|
||||||
|
"│ ├── \u001b[00mpayload.toml\u001b[0m\n",
|
||||||
|
"│ ├── \u001b[00mschedule.toml\u001b[0m\n",
|
||||||
|
"│ └── \u001b[00mtypedef.toml\u001b[0m\n",
|
||||||
|
"└── \u001b[01;34mtest_repo\u001b[0m\n",
|
||||||
|
" ├── \u001b[00malgodata.json\u001b[0m\n",
|
||||||
|
" ├── \u001b[00mmanifest.toml\u001b[0m\n",
|
||||||
|
" ├── \u001b[00mpayload.toml\u001b[0m\n",
|
||||||
|
" ├── \u001b[00mschedule.toml\u001b[0m\n",
|
||||||
|
" └── \u001b[00mtypedef.toml\u001b[0m\n",
|
||||||
|
"\n",
|
||||||
|
"3 directories, 12 files\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"test_repo.persist_to_repodir(save_list=[\"schedule\", \"payload\", \"manifest\", \"typedef\", \"algodata\"], source=Path(\"test_new_repo\"))\n",
|
"test_repo.persist_to_repodir(save_list=[\"schedule\", \"payload\", \"manifest\", \"typedef\", \"algodata\"], source=Path(\"test_new_repo\"))\n",
|
||||||
"!tree"
|
"!tree"
|
||||||
@@ -196,10 +321,19 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 8,
|
||||||
"id": "7e88bd7c",
|
"id": "7e88bd7c",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"[('age', 12), ('enemy', 'jerry'), ('name', 'tom')]\n",
|
||||||
|
"[('age', 12), ('enemy', 'jerry'), ('name', 'tom')]\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"from heurams.utils.lict import Lict\n",
|
"from heurams.utils.lict import Lict\n",
|
||||||
"lct = Lict() # 空的\n",
|
"lct = Lict() # 空的\n",
|
||||||
@@ -221,10 +355,18 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 9,
|
||||||
"id": "248f6cba",
|
"id": "248f6cba",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"{'name': 'tom', 'age': 12, 'enemy': 'jerry'}\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"print(lct.dicted_data)"
|
"print(lct.dicted_data)"
|
||||||
]
|
]
|
||||||
@@ -243,10 +385,20 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 10,
|
||||||
"id": "a0eb07a7",
|
"id": "a0eb07a7",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"[('age', 12), ('enemy', 'jerry'), ('name', 'tom')]\n",
|
||||||
|
"[('age', 12), ('enemy', 'jerry'), ('name', 'tom'), ('type', 'cat')]\n",
|
||||||
|
"[('age', 12), ('enemy', 'jerry'), ('is_human', False), ('name', 'tom'), ('type', 'cat')]\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"# 由于 jupyter 的环境处理, 请不要重复运行此单元格, 如果想再看一遍, 请重启 jupyter 后再全部运行\n",
|
"# 由于 jupyter 的环境处理, 请不要重复运行此单元格, 如果想再看一遍, 请重启 jupyter 后再全部运行\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -278,10 +430,18 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 11,
|
||||||
"id": "0ab442d4",
|
"id": "0ab442d4",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"{'age': 12, 'enemy': 'jerry', 'is_human': False, 'name': 'tom', 'type': 'cat', 'enemy_2': 'spike'}\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"# 由于 jupyter 的环境处理, 请不要重复运行此单元格, 如果想再看一遍, 请重启 jupyter 后再全部运行\n",
|
"# 由于 jupyter 的环境处理, 请不要重复运行此单元格, 如果想再看一遍, 请重启 jupyter 后再全部运行\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -303,10 +463,49 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 12,
|
||||||
"id": "f3ca752f",
|
"id": "f3ca752f",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"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",
|
||||||
|
"------\n",
|
||||||
|
"('age', 12)\n",
|
||||||
|
"('enemy', 'jerry')\n",
|
||||||
|
"('enemy_2', 'spike')\n",
|
||||||
|
"('is_human', False)\n",
|
||||||
|
"('name', 'tom')\n",
|
||||||
|
"('type', 'cat')\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",
|
||||||
|
"[('age', 12), ('enemy', 'jerry')]\n",
|
||||||
|
"('enemy', 'jerry')\n",
|
||||||
|
"[('age', 12)]\n",
|
||||||
|
"('age', 12)\n",
|
||||||
|
"[]\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"Ellipsis"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 12,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"lct = Lict(initdict={'age': 12, 'enemy': 'jerry', 'is_human': False, 'name': 'tom', 'type': 'cat', 'enemy_2': 'spike'})\n",
|
"lct = Lict(initdict={'age': 12, 'enemy': 'jerry', 'is_human': False, 'name': 'tom', 'type': 'cat', 'enemy_2': 'spike'})\n",
|
||||||
"print(lct)\n",
|
"print(lct)\n",
|
||||||
@@ -332,7 +531,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 13,
|
||||||
"id": "773bf99c",
|
"id": "773bf99c",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
@@ -340,6 +539,131 @@
|
|||||||
"!rm -rf test_new_repo\n",
|
"!rm -rf test_new_repo\n",
|
||||||
"!rm -rf heurams.log*"
|
"!rm -rf heurams.log*"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 14,
|
||||||
|
"id": "8645c5a2",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"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",
|
||||||
|
" '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.7534873,\n",
|
||||||
|
" 'next_date': 20455,\n",
|
||||||
|
" 'real_rept': 1,\n",
|
||||||
|
" 'rept': 0}}\n",
|
||||||
|
"{ 'algodata': [ ( '君臣固守以窥周室,',\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",
|
||||||
|
" ( '秦孝公据崤函之固, 拥雍州之地,',\n",
|
||||||
|
" { 'SM-2': { 'efactor': 2.5,\n",
|
||||||
|
" 'interval': 1,\n",
|
||||||
|
" 'is_activated': 1,\n",
|
||||||
|
" 'last_date': 20454,\n",
|
||||||
|
" 'last_modify': 1767274438.7534873,\n",
|
||||||
|
" 'next_date': 20455,\n",
|
||||||
|
" 'real_rept': 1,\n",
|
||||||
|
" 'rept': 0}})],\n",
|
||||||
|
" 'manifest': { 'author': '__heurams__',\n",
|
||||||
|
" 'desc': '高考古诗文: 过秦论',\n",
|
||||||
|
" 'title': '测试单元: 过秦论'},\n",
|
||||||
|
" 'payload': [ ( '君臣固守以窥周室,',\n",
|
||||||
|
" { 'content': '君臣/固守/以窥/周室,/',\n",
|
||||||
|
" 'keyword_note': {'窥': '窥视'},\n",
|
||||||
|
" 'note': [],\n",
|
||||||
|
" 'translation': '君臣牢固地守卫着,借以窥视周王室的权力,'}),\n",
|
||||||
|
" ( '秦孝公据崤函之固, 拥雍州之地,',\n",
|
||||||
|
" { 'content': '秦孝公/据/崤函/之固/, 拥/雍州/之地,/',\n",
|
||||||
|
" 'keyword_note': { '崤函': '崤山和函谷关',\n",
|
||||||
|
" '据': '占据',\n",
|
||||||
|
" '雍州': '古代九州之一'},\n",
|
||||||
|
" 'note': [],\n",
|
||||||
|
" 'translation': '秦孝公占据着崤山和函谷关的险固地势,拥有雍州的土地,'})],\n",
|
||||||
|
" 'schedule': { 'phases': { 'final_review': [ ['FillBlank', '0.7'],\n",
|
||||||
|
" ['SelectMeaning', '0.7'],\n",
|
||||||
|
" ['Recognition', '1.0']],\n",
|
||||||
|
" 'quick_review': [ ['FillBlank', '1.0'],\n",
|
||||||
|
" ['SelectMeaning', '0.5'],\n",
|
||||||
|
" ['Recognition', '1.0']],\n",
|
||||||
|
" 'recognition': [['Recognition', '1.0']]},\n",
|
||||||
|
" 'schedule': [ 'quick_review',\n",
|
||||||
|
" 'recognition',\n",
|
||||||
|
" 'final_review']},\n",
|
||||||
|
" 'source': PosixPath('test_repo'),\n",
|
||||||
|
" 'typedef': { 'annotation': { 'content': '内容',\n",
|
||||||
|
" 'delimiter': '分隔符',\n",
|
||||||
|
" 'keyword_note': '关键词翻译',\n",
|
||||||
|
" 'note': '笔记',\n",
|
||||||
|
" 'translation': '语句翻译',\n",
|
||||||
|
" 'tts_text': '文本转语音文本'},\n",
|
||||||
|
" 'common': { 'delimiter': '/',\n",
|
||||||
|
" 'tts_text': \"eval:payload['content'].replace('/', \"\n",
|
||||||
|
" \"'')\"},\n",
|
||||||
|
" 'puzzles': { 'FillBlank': { '__hint__': '',\n",
|
||||||
|
" '__origin__': 'cloze',\n",
|
||||||
|
" 'delimiter': \"eval:metadata['formation']['delimiter']\",\n",
|
||||||
|
" 'min_denominator': \"eval:default['cloze']['min_denominator']\",\n",
|
||||||
|
" 'text': \"eval:payload['content']\"},\n",
|
||||||
|
" 'Recognition': { '__hint__': '',\n",
|
||||||
|
" '__origin__': 'recognition',\n",
|
||||||
|
" 'primary': \"eval:payload['content']\",\n",
|
||||||
|
" 'secondary': [ \"eval:payload['keyword_note']\",\n",
|
||||||
|
" \"eval:payload['note']\"],\n",
|
||||||
|
" 'top_dim': [ \"eval:payload['translation']\"]},\n",
|
||||||
|
" 'SelectMeaning': { '__hint__': \"eval:payload['content']\",\n",
|
||||||
|
" '__origin__': 'mcq',\n",
|
||||||
|
" 'jammer': \"eval:list(payload['keyword_note'].values())\",\n",
|
||||||
|
" 'mapping': \"eval:payload['keyword_note']\",\n",
|
||||||
|
" 'max_riddles_num': \"eval:default['mcq']['max_riddles_num']\",\n",
|
||||||
|
" 'prefix': '选择正确项: ',\n",
|
||||||
|
" 'primary': \"eval:payload['content']\"}},\n",
|
||||||
|
" '古文句': {}}}\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"repo = repolib.Repo.create_from_repodir(Path('./test_repo'))\n",
|
||||||
|
"for i in repo.ident_index:\n",
|
||||||
|
" n = pt.Nucleon.create_on_nucleonic_data(nucleonic_data=repo.nucleonic_data_lict.get_itemic_unit(i))\n",
|
||||||
|
" e = pt.Electron.create_on_electonic_data(electronic_data=repo.electronic_data_lict.get_itemic_unit(i))\n",
|
||||||
|
" e.activate()\n",
|
||||||
|
" e.revisor(5, True)\n",
|
||||||
|
" print(repr(n))\n",
|
||||||
|
" print(repr(e))\n",
|
||||||
|
"print(repo)"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
|||||||
12
examples/simplemem.py
Normal file
12
examples/simplemem.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import heurams.kernel.repolib as repolib
|
||||||
|
import heurams.kernel.particles as pt
|
||||||
|
from pathlib import Path
|
||||||
|
repo = repolib.Repo.create_from_repodir(Path('./test_repo'))
|
||||||
|
for i in repo.ident_index:
|
||||||
|
n = pt.Nucleon.create_on_nucleonic_data(nucleonic_data=repo.nucleonic_data_lict.get_itemic_unit(i))
|
||||||
|
e = pt.Electron.create_on_electonic_data(electronic_data=repo.electronic_data_lict.get_itemic_unit(i))
|
||||||
|
e.activate()
|
||||||
|
e.revisor(5, True)
|
||||||
|
print(repr(n))
|
||||||
|
print(repr(e))
|
||||||
|
print(repo)
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
import pathlib
|
import pathlib
|
||||||
from contextvars import ContextVar
|
from contextvars import ContextVar
|
||||||
|
import shutil
|
||||||
|
|
||||||
from heurams.services.config import ConfigFile
|
from heurams.services.config import ConfigFile
|
||||||
from heurams.services.logger import get_logger
|
from heurams.services.logger import get_logger
|
||||||
@@ -14,32 +15,33 @@ from heurams.services.logger import get_logger
|
|||||||
# 数据文件路径规定: 以运行目录为准
|
# 数据文件路径规定: 以运行目录为准
|
||||||
|
|
||||||
rootdir = pathlib.Path(__file__).parent
|
rootdir = pathlib.Path(__file__).parent
|
||||||
print(f"rootdir: {rootdir}")
|
print(f"项目根目录: {rootdir}")
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
logger.debug(f"项目根目录: {rootdir}")
|
logger.debug(f"项目根目录: {rootdir}")
|
||||||
workdir = pathlib.Path.cwd()
|
workdir = pathlib.Path.cwd()
|
||||||
print(f"workdir: {workdir}")
|
print(f"工作目录: {workdir}")
|
||||||
logger.debug(f"工作目录: {workdir}")
|
logger.debug(f"工作目录: {workdir}")
|
||||||
config_var: ContextVar[ConfigFile] = ContextVar(
|
|
||||||
"config_var", default=ConfigFile(rootdir / "default" / "config" / "config.toml")
|
if pathlib.Path(workdir / "data" / "config" / "config_dev.toml").exists():
|
||||||
)
|
|
||||||
try:
|
|
||||||
config_var: ContextVar[ConfigFile] = ContextVar(
|
|
||||||
"config_var", default=ConfigFile(workdir / "config" / "config.toml")
|
|
||||||
) # 配置文件
|
|
||||||
print("已加载自定义用户配置")
|
|
||||||
logger.info("已加载自定义用户配置, 路径: %s", workdir / "config" / "config.toml")
|
|
||||||
except Exception as e:
|
|
||||||
print("未能加载自定义用户配置")
|
|
||||||
logger.warning("未能加载自定义用户配置, 错误: %s", e)
|
|
||||||
if pathlib.Path(workdir / "config" / "config_dev.toml").exists():
|
|
||||||
print("使用开发设置")
|
print("使用开发设置")
|
||||||
logger.debug("使用开发设置")
|
logger.debug("使用开发设置")
|
||||||
config_var: ContextVar[ConfigFile] = ContextVar(
|
config_var: ContextVar[ConfigFile] = ContextVar(
|
||||||
"config_var", default=ConfigFile(workdir / "config" / "config_dev.toml")
|
"config_var", default=ConfigFile(workdir / "data" / "config" / "config_dev.toml")
|
||||||
)
|
)
|
||||||
# runtime_var: ContextVar = ContextVar('runtime_var', default=dict()) # 运行时共享数据
|
else:
|
||||||
|
try:
|
||||||
|
config_var: ContextVar[ConfigFile] = ContextVar(
|
||||||
|
"config_var", default=ConfigFile(workdir / "data" / "config" / "config.toml")
|
||||||
|
) # 配置文件
|
||||||
|
except Exception as e:
|
||||||
|
input("按下回车以创建新的配置文件, 或按下 Ctrl + C 以终止程序 ")
|
||||||
|
(workdir / "data" / 'config').mkdir(parents=True, exist_ok=True)
|
||||||
|
(workdir / "data" / 'config' / 'config').unlink(missing_ok=True)
|
||||||
|
shutil.copy((rootdir / 'default' / 'config' / 'config.toml'), workdir / "data" / "config" / "config.toml")
|
||||||
|
finally:
|
||||||
|
config_var: ContextVar[ConfigFile] = ContextVar(
|
||||||
|
"config_var", default=ConfigFile(workdir / "data" / "config" / "config.toml")
|
||||||
|
) # 配置文件
|
||||||
|
|
||||||
class ConfigContext:
|
class ConfigContext:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -31,12 +31,7 @@ max_riddles_num = 2
|
|||||||
min_denominator = 3
|
min_denominator = 3
|
||||||
|
|
||||||
[paths] # 相对于配置文件的 ".." (即工作目录) 而言 或绝对路径
|
[paths] # 相对于配置文件的 ".." (即工作目录) 而言 或绝对路径
|
||||||
nucleon_dir = "./data/nucleon"
|
data = "./data"
|
||||||
electron_dir = "./data/electron"
|
|
||||||
global_dir = "./data/global" # 全局数据路径, SM-15 等算法需要
|
|
||||||
orbital_dir = "./data/orbital"
|
|
||||||
cache_dir = "./data/cache"
|
|
||||||
template_dir = "./data/template"
|
|
||||||
|
|
||||||
[services] # 定义服务到提供者的映射
|
[services] # 定义服务到提供者的映射
|
||||||
audio = "playsound" # 可选项: playsound(通用), termux(仅用于支持 Android Termux), mpg123(TODO)
|
audio = "playsound" # 可选项: playsound(通用), termux(仅用于支持 Android Termux), mpg123(TODO)
|
||||||
|
|||||||
@@ -7,12 +7,11 @@ from heurams.services.logger import get_logger
|
|||||||
from .screens.about import AboutScreen
|
from .screens.about import AboutScreen
|
||||||
from .screens.dashboard import DashboardScreen
|
from .screens.dashboard import DashboardScreen
|
||||||
from .screens.precache import PrecachingScreen
|
from .screens.precache import PrecachingScreen
|
||||||
from .screens.repocreator import NucleonCreatorScreen
|
from .screens.repocreator import RepoCreatorScreen
|
||||||
from .screens.synctool import SyncScreen
|
from .screens.synctool import SyncScreen
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def environment_check():
|
def environment_check():
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -39,13 +38,13 @@ class HeurAMSApp(App):
|
|||||||
("d", "toggle_dark", "切换色调"),
|
("d", "toggle_dark", "切换色调"),
|
||||||
("1", "app.push_screen('dashboard')", "仪表盘"),
|
("1", "app.push_screen('dashboard')", "仪表盘"),
|
||||||
("2", "app.push_screen('precache_all')", "缓存管理器"),
|
("2", "app.push_screen('precache_all')", "缓存管理器"),
|
||||||
("3", "app.push_screen('nucleon_creator')", "创建新单元"),
|
("3", "app.push_screen('nucleon_creator')", "创建新仓库"),
|
||||||
# ("4", "app.push_screen('synctool')", "同步工具"),
|
# ("4", "app.push_screen('synctool')", "同步工具"),
|
||||||
("0", "app.push_screen('about')", "版本信息"),
|
("0", "app.push_screen('about')", "版本信息"),
|
||||||
]
|
]
|
||||||
SCREENS = {
|
SCREENS = {
|
||||||
"dashboard": DashboardScreen,
|
"dashboard": DashboardScreen,
|
||||||
"nucleon_creator": NucleonCreatorScreen,
|
"repo_creator": RepoCreatorScreen,
|
||||||
"precache_all": PrecachingScreen,
|
"precache_all": PrecachingScreen,
|
||||||
"synctool": SyncScreen,
|
"synctool": SyncScreen,
|
||||||
"about": AboutScreen,
|
"about": AboutScreen,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from heurams.services.logger import get_logger
|
|||||||
from .screens.about import AboutScreen
|
from .screens.about import AboutScreen
|
||||||
from .screens.dashboard import DashboardScreen
|
from .screens.dashboard import DashboardScreen
|
||||||
from .screens.precache import PrecachingScreen
|
from .screens.precache import PrecachingScreen
|
||||||
from .screens.repocreator import NucleonCreatorScreen
|
from .screens.repocreator import RepoCreatorScreen
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import heurams.services.timer as timer
|
|||||||
import heurams.services.version as version
|
import heurams.services.version as version
|
||||||
from heurams.context import *
|
from heurams.context import *
|
||||||
from heurams.kernel.particles import *
|
from heurams.kernel.particles import *
|
||||||
|
from heurams.kernel.repolib import *
|
||||||
from heurams.services.logger import get_logger
|
from heurams.services.logger import get_logger
|
||||||
|
|
||||||
from .about import AboutScreen
|
from .about import AboutScreen
|
||||||
@@ -32,9 +33,10 @@ class DashboardScreen(Screen):
|
|||||||
classes: str | None = None,
|
classes: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(name, id, classes)
|
super().__init__(name, id, classes)
|
||||||
self.nextdates = {}
|
self.repostat = {}
|
||||||
self.texts = {}
|
self.title2dirname = {}
|
||||||
self.stay_enabled = {}
|
self.title2repo = {}
|
||||||
|
self._load_data()
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
"""组合界面组件"""
|
"""组合界面组件"""
|
||||||
@@ -44,119 +46,86 @@ class DashboardScreen(Screen):
|
|||||||
Label(f"当前 UNIX 日时间戳: {timer.get_daystamp()}"),
|
Label(f"当前 UNIX 日时间戳: {timer.get_daystamp()}"),
|
||||||
Label(f'时区修正: UTC+{config_var.get()["timezone_offset"] / 3600}'),
|
Label(f'时区修正: UTC+{config_var.get()["timezone_offset"] / 3600}'),
|
||||||
Label(f"使用算法: {config_var.get()['algorithm']['default']}"),
|
Label(f"使用算法: {config_var.get()['algorithm']['default']}"),
|
||||||
Label("选择待学习或待修改的记忆单元集:", classes="title-label"),
|
Label("选择待学习或待修改的仓库:", classes="title-label"),
|
||||||
ListView(id="union-list", classes="union-list-view"),
|
ListView(id="repo-list", classes="repo-list-view"),
|
||||||
Label(
|
Label(
|
||||||
f'"潜进" 启发式辅助记忆调度器 | 版本 {version.ver} '
|
f'"潜进" 启发式辅助记忆调度器 | 版本 {version.ver} '
|
||||||
f"{version.codename.capitalize()} 2025"
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
yield Footer()
|
yield Footer()
|
||||||
|
|
||||||
def analyser(self, filename: str) -> dict:
|
def _load_data(self):
|
||||||
"""分析文件状态以生成显示文本
|
self.repo_dirs = Repo.probe_vaild_repos_in_dir(Path(config_var.get()['paths']['data']) / 'repo')
|
||||||
|
for repo_dir in self.repo_dirs:
|
||||||
|
repo = Repo.create_from_repodir(repo_dir)
|
||||||
|
self._analyse_repo(repo)
|
||||||
|
|
||||||
Args:
|
def _analyse_repo(self, repo: Repo):
|
||||||
filename: 要分析的文件名
|
dirname = repo.source.name # type: ignore
|
||||||
|
title = repo.manifest["title"]
|
||||||
Returns:
|
|
||||||
dict: 包含显示文本的字典,键为行号
|
|
||||||
"""
|
|
||||||
from heurams.kernel.repository.particle_loader import (load_electron,
|
|
||||||
load_nucleon)
|
|
||||||
|
|
||||||
result = {}
|
|
||||||
filestem = pathlib.Path(filename).stem
|
|
||||||
|
|
||||||
# 构建电子文件路径
|
|
||||||
electron_dir = config_var.get()["paths"]["electron_dir"]
|
|
||||||
electron_file_path = pathlib.Path(electron_dir) / f"{filestem}.json"
|
|
||||||
|
|
||||||
logger.debug(f"电子文件路径: {electron_file_path}")
|
|
||||||
|
|
||||||
# 确保电子文件存在
|
|
||||||
if not electron_file_path.exists():
|
|
||||||
electron_file_path.touch()
|
|
||||||
electron_file_path.write_text("{}")
|
|
||||||
|
|
||||||
# 加载电子数据
|
|
||||||
electron_dict = load_electron(path=electron_file_path)
|
|
||||||
logger.debug(f"电子数据: {electron_dict}")
|
|
||||||
|
|
||||||
# 分析电子状态
|
|
||||||
is_due = 0
|
is_due = 0
|
||||||
is_activated = 0
|
unit_sum = len(repo)
|
||||||
nextdate = 0x3F3F3F3F
|
activated_sum = 0
|
||||||
|
nextdate = 0x3f3f3f3f
|
||||||
for electron in electron_dict.values():
|
is_unfinished = (unit_sum > activated_sum)
|
||||||
logger.debug(f"{electron}, 是否到期: {electron.is_due()}")
|
for i in repo.ident_index:
|
||||||
|
nucleon = pt.Nucleon.create_on_nucleonic_data(nucleonic_data=repo.nucleonic_data_lict.get_itemic_unit(i))
|
||||||
if electron.is_due():
|
electron = pt.Electron.create_on_electonic_data(electronic_data=repo.electronic_data_lict.get_itemic_unit(i))
|
||||||
is_due = 1
|
|
||||||
if electron.is_activated():
|
if electron.is_activated():
|
||||||
is_activated = 1
|
activated_sum += 1
|
||||||
nextdate = min(nextdate, electron.nextdate())
|
if electron.is_due():
|
||||||
|
is_due = 1
|
||||||
# 检查是否需要更多复习
|
nextdate = min(nextdate, electron.nextdate())
|
||||||
nucleon_dir = config_var.get()["paths"]["nucleon_dir"]
|
if is_unfinished:
|
||||||
nucleon_path = pathlib.Path(nucleon_dir) / f"{filestem}.toml"
|
nextdate = min(nextdate, timer.get_daystamp())
|
||||||
nucleon_count = len(load_nucleon(nucleon_path))
|
need_to_study = is_due or is_unfinished
|
||||||
electron_count = len(electron_dict)
|
prompt = f"{title}\0\n 进度: {activated_sum}/{unit_sum}\n {"需要学习" if need_to_study else "无需操作"}"
|
||||||
is_more = not (electron_count >= nucleon_count)
|
stat = {
|
||||||
|
"is_due": is_due,
|
||||||
logger.debug(f"是否需要更多复习: {is_more}")
|
"unit_sum": unit_sum,
|
||||||
|
"title": title,
|
||||||
# 更新状态
|
"activated_sum": activated_sum,
|
||||||
self.nextdates[filename] = nextdate
|
"nextdate": nextdate,
|
||||||
self.stay_enabled[filename] = is_due or is_more
|
"is_unfinished": is_unfinished,
|
||||||
|
"need_to_study": need_to_study,
|
||||||
# 构建返回结果
|
"prompt": prompt,
|
||||||
result[0] = f"{filename}\0"
|
"dirname": dirname,
|
||||||
|
}
|
||||||
if not is_activated:
|
self.repostat[dirname] = stat
|
||||||
result[1] = " 尚未激活"
|
self.title2dirname[title] = dirname
|
||||||
else:
|
self.title2repo[title] = repo
|
||||||
status_text = "需要复习" if is_due else "当前无需复习"
|
|
||||||
result[1] = f"下一次复习: {nextdate}\n{status_text}"
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def on_mount(self) -> None:
|
def on_mount(self) -> None:
|
||||||
"""挂载组件时初始化"""
|
"""挂载组件时初始化"""
|
||||||
union_list_widget = self.query_one("#union-list", ListView)
|
repo_list_widget = self.query_one("#repo-list", ListView)
|
||||||
probe = probe_all(0)
|
|
||||||
|
|
||||||
# 分析所有文件
|
|
||||||
for file in probe["nucleon"]:
|
|
||||||
self.texts[file] = self.analyser(file)
|
|
||||||
|
|
||||||
# 按下次复习时间排序
|
# 按下次复习时间排序
|
||||||
nucleon_files = sorted(
|
repodirs = sorted(
|
||||||
probe["nucleon"],
|
self.repo_dirs,
|
||||||
key=lambda f: self.nextdates[f],
|
key=lambda f: self.repostat[f.name]['nextdate'],
|
||||||
reverse=True,
|
reverse=True,
|
||||||
)
|
)
|
||||||
|
repotitles = map(lambda f: self.repostat[f.name]['title'], repodirs)
|
||||||
# 填充列表
|
# 填充列表
|
||||||
if not probe["nucleon"]:
|
if not repodirs:
|
||||||
union_list_widget.append(
|
repo_list_widget.append(
|
||||||
ListItem(
|
ListItem(
|
||||||
Static(
|
Static(
|
||||||
"在 ./nucleon/ 中未找到任何内容源数据文件。\n"
|
"在 ./data/repo/ 中未找到任何仓库.\n"
|
||||||
"请放置文件后重启应用,或者新建空的单元集。"
|
"请导入仓库后重启应用, 或者新建空的仓库."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
union_list_widget.disabled = True
|
repo_list_widget.disabled = True
|
||||||
return
|
return
|
||||||
|
|
||||||
for file in nucleon_files:
|
for repotitle in repotitles:
|
||||||
text = self.texts[file]
|
prompt = self.repostat[self.title2dirname[repotitle]]['prompt']
|
||||||
list_item = ListItem(Label(f"{text[0]}\n{text[1]}"))
|
list_item = ListItem(Label(prompt))
|
||||||
union_list_widget.append(list_item)
|
repo_list_widget.append(list_item)
|
||||||
|
|
||||||
if not self.stay_enabled[file]:
|
#if not self.stay_enabled[repodir]:
|
||||||
list_item.disabled = True
|
# list_item.disabled = True
|
||||||
|
|
||||||
def on_list_view_selected(self, event) -> None:
|
def on_list_view_selected(self, event) -> None:
|
||||||
"""处理列表项选择事件"""
|
"""处理列表项选择事件"""
|
||||||
@@ -166,32 +135,25 @@ class DashboardScreen(Screen):
|
|||||||
selected_label = event.item.query_one(Label)
|
selected_label = event.item.query_one(Label)
|
||||||
label_text = str(selected_label.renderable)
|
label_text = str(selected_label.renderable)
|
||||||
|
|
||||||
if "未找到任何 .toml 文件" in label_text:
|
if "未找到任何仓库" in label_text:
|
||||||
return
|
return
|
||||||
|
|
||||||
# 提取文件名
|
# 提取文件名
|
||||||
selected_filename = pathlib.Path(label_text.partition("\0")[0].replace("*", ""))
|
selected_repotitle = label_text.partition("\0")[0].replace("*", "")
|
||||||
|
selected_repo = self.title2repo[label_text.partition("\0")[0].replace("*", "")]
|
||||||
# 构建文件路径
|
|
||||||
nucleon_dir = config_var.get()["paths"]["nucleon_dir"]
|
|
||||||
electron_dir = config_var.get()["paths"]["electron_dir"]
|
|
||||||
|
|
||||||
nucleon_file_path = pathlib.Path(nucleon_dir) / selected_filename
|
|
||||||
electron_file_path = (
|
|
||||||
pathlib.Path(electron_dir) / f"{selected_filename.stem}.json"
|
|
||||||
)
|
|
||||||
|
|
||||||
# 跳转到准备屏幕
|
# 跳转到准备屏幕
|
||||||
self.app.push_screen(PreparationScreen(nucleon_file_path, electron_file_path))
|
self.app.push_screen(PreparationScreen(selected_repo, self.repostat[self.title2dirname[selected_repotitle]]))
|
||||||
|
|
||||||
def on_button_pressed(self, event) -> None:
|
def on_button_pressed(self, event) -> None:
|
||||||
"""处理按钮点击事件"""
|
"""处理按钮点击事件"""
|
||||||
button_id = event.button.id
|
button_id = event.button.id
|
||||||
|
|
||||||
if button_id == "new_nucleon_button":
|
if button_id == "new_nucleon_button":
|
||||||
from .repocreator import NucleonCreatorScreen
|
from .repocreator import RepoCreatorScreen
|
||||||
|
|
||||||
new_screen = NucleonCreatorScreen()
|
new_screen = RepoCreatorScreen()
|
||||||
self.app.push_screen(new_screen)
|
self.app.push_screen(new_screen)
|
||||||
|
|
||||||
elif button_id == "precache_all_button":
|
elif button_id == "precache_all_button":
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import heurams.services.hasher as hasher
|
|||||||
from heurams.context import *
|
from heurams.context import *
|
||||||
from heurams.context import config_var
|
from heurams.context import config_var
|
||||||
from heurams.services.logger import get_logger
|
from heurams.services.logger import get_logger
|
||||||
|
from heurams.kernel.repolib import *
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
@@ -29,24 +30,19 @@ class PreparationScreen(Screen):
|
|||||||
|
|
||||||
scheduled_num = reactive(config_var.get()["scheduled_num"])
|
scheduled_num = reactive(config_var.get()["scheduled_num"])
|
||||||
|
|
||||||
def __init__(self, nucleon_file: pathlib.Path, electron_file: pathlib.Path) -> None:
|
def __init__(self, repo: Repo, repostat: dict) -> None:
|
||||||
super().__init__(name=None, id=None, classes=None)
|
super().__init__(name=None, id=None, classes=None)
|
||||||
self.nucleon_file = nucleon_file
|
self.repo = repo
|
||||||
self.electron_file = electron_file
|
self.repostat = repostat
|
||||||
self.nucleons_with_orbital = pt.load_nucleon(self.nucleon_file)
|
|
||||||
self.electrons = pt.load_electron(self.electron_file)
|
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
yield Header(show_clock=True)
|
yield Header(show_clock=True)
|
||||||
with ScrollableContainer(id="vice_container"):
|
with ScrollableContainer(id="vice_container"):
|
||||||
yield Label(f"准备就绪: [b]{self.nucleon_file.stem}[/b]\n")
|
yield Label(f"准备就绪: [b]{self.repostat['title']}[/b]\n")
|
||||||
yield Label(
|
yield Label(
|
||||||
f"内容源文件: {config_var.get()['paths']['nucleon_dir']}/[b]{self.nucleon_file.name}[/b]"
|
f"仓库路径: {config_var.get()['paths']['data']}/repo/[b]{self.repostat['dirname']}[/b]"
|
||||||
)
|
)
|
||||||
yield Label(
|
yield Label(f"\n单元数量: {len(self.repo)}\n")
|
||||||
f"元数据文件: {config_var.get()['paths']['electron_dir']}/[b]{self.electron_file.name}[/b]"
|
|
||||||
)
|
|
||||||
yield Label(f"\n单元数量: {len(self.nucleons_with_orbital)}\n")
|
|
||||||
yield Label(f"单次记忆数量: {self.scheduled_num}", id="schnum_label")
|
yield Label(f"单次记忆数量: {self.scheduled_num}", id="schnum_label")
|
||||||
|
|
||||||
yield Button(
|
yield Button(
|
||||||
@@ -76,10 +72,9 @@ class PreparationScreen(Screen):
|
|||||||
|
|
||||||
def _get_full_content(self):
|
def _get_full_content(self):
|
||||||
content = ""
|
content = ""
|
||||||
for nucleon, orbital in self.nucleons_with_orbital:
|
for i in self.repo.ident_index:
|
||||||
nucleon: pt.Nucleon
|
n = pt.Nucleon.create_on_nucleonic_data(nucleonic_data=self.repo.nucleonic_data_lict.get_itemic_unit(i))
|
||||||
# print(nucleon.payload)
|
content += f"- {n['content']} \n"
|
||||||
content += " - " + nucleon["content"] + " \n"
|
|
||||||
return content
|
return content
|
||||||
|
|
||||||
def action_go_back(self):
|
def action_go_back(self):
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ from heurams.context import config_var
|
|||||||
from heurams.services.version import ver
|
from heurams.services.version import ver
|
||||||
|
|
||||||
|
|
||||||
class NucleonCreatorScreen(Screen):
|
class RepoCreatorScreen(Screen):
|
||||||
BINDINGS = [("q", "go_back", "返回")]
|
BINDINGS = [("q", "go_back", "返回")]
|
||||||
SUB_TITLE = "单元集创建向导"
|
SUB_TITLE = "仓库创建向导"
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__(name=None, id=None, classes=None)
|
super().__init__(name=None, id=None, classes=None)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from heurams.kernel.algorithms.sm15m_calc import (MAX_AF, MIN_AF, NOTCH_AF,
|
|||||||
|
|
||||||
# 全局状态文件路径
|
# 全局状态文件路径
|
||||||
_GLOBAL_STATE_FILE = os.path.expanduser(
|
_GLOBAL_STATE_FILE = os.path.expanduser(
|
||||||
pathlib.Path(config_var.get()["paths"]["global_dir"]) / "sm15m_global_state.json"
|
pathlib.Path(config_var.get()["paths"]["data"]) / 'global' / "sm15m_global_state.json"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class Electron:
|
|||||||
algo_name: 使用的算法模块标识
|
algo_name: 使用的算法模块标识
|
||||||
"""
|
"""
|
||||||
if algo_name == "":
|
if algo_name == "":
|
||||||
algo_name = "sm-2"
|
algo_name = "SM-2"
|
||||||
self.algodata = algodata
|
self.algodata = algodata
|
||||||
self.ident = ident
|
self.ident = ident
|
||||||
self.algo: algolib.BaseAlgorithm = algorithms[algo_name]
|
self.algo: algolib.BaseAlgorithm = algorithms[algo_name]
|
||||||
@@ -29,6 +29,11 @@ class Electron:
|
|||||||
if not self.algo.check_integrity(self.algodata):
|
if not self.algo.check_integrity(self.algodata):
|
||||||
self.algodata[self.algo.algo_name] = deepcopy(self.algo.defaults)
|
self.algodata[self.algo.algo_name] = deepcopy(self.algo.defaults)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
from pprint import pformat
|
||||||
|
s = pformat(self.algodata, indent=4)
|
||||||
|
return s
|
||||||
|
|
||||||
def activate(self):
|
def activate(self):
|
||||||
"""激活此电子"""
|
"""激活此电子"""
|
||||||
self.algodata[self.algo.algo_name]["is_activated"] = 1
|
self.algodata[self.algo.algo_name]["is_activated"] = 1
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ class Nucleon:
|
|||||||
return len(self.data)
|
return len(self.data)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return repr(self.data)
|
from pprint import pformat
|
||||||
|
s = pformat(self.data, indent=4)
|
||||||
|
return s
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_on_nucleonic_data(nucleonic_data: tuple):
|
def create_on_nucleonic_data(nucleonic_data: tuple):
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
from heurams.services.logger import get_logger
|
|
||||||
|
|
||||||
from .fission import Fission
|
|
||||||
from .phaser import Phaser
|
|
||||||
from .procession import Procession
|
|
||||||
from .states import PhaserState, ProcessionState
|
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
|
||||||
|
|
||||||
__all__ = ["PhaserState", "ProcessionState", "Procession", "Fission", "Phaser"]
|
|
||||||
|
|
||||||
logger.debug("反应堆模块已加载")
|
|
||||||
|
|||||||
@@ -1,51 +1,24 @@
|
|||||||
# 移相器类定义
|
from enum import Enum
|
||||||
|
from typing import Any, Sequence, Type
|
||||||
|
from transitions import Machine, State, Event, EventData
|
||||||
|
|
||||||
import heurams.kernel.particles as pt
|
class Phaser(Machine):
|
||||||
from heurams.services.logger import get_logger
|
def __init__(self, schedule: list):
|
||||||
|
state_words = ["init"] + schedule.copy()
|
||||||
|
state_objects = list()
|
||||||
|
for name in state_words:
|
||||||
|
state_objects.append(State(
|
||||||
|
name=name,
|
||||||
|
on_enter=["on_enter"]
|
||||||
|
))
|
||||||
|
Machine.__init__(self, states=state_objects, initial="init", send_event=True)
|
||||||
|
self.add_ordered_transitions(loop=False)
|
||||||
|
|
||||||
from .procession import Procession
|
def on_enter(self, event_data: EventData):
|
||||||
from .states import PhaserState, ProcessionState
|
print(event_data.transition.source, "->", event_data.transition.dest) # type: ignore
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
if __name__ == "__main__":
|
||||||
|
p = Phaser(["a", "b"])
|
||||||
|
p.next_state()
|
||||||
class Phaser:
|
p.next_state()
|
||||||
"""移相器: 全局调度阶段管理器"""
|
print(p.state)
|
||||||
|
|
||||||
def __init__(self, atoms: list[pt.Atom]) -> None:
|
|
||||||
logger.debug("Phaser.__init__: 原子数量=%d", len(atoms))
|
|
||||||
new_atoms = list()
|
|
||||||
old_atoms = list()
|
|
||||||
self.state = PhaserState.UNSURE
|
|
||||||
for i in atoms:
|
|
||||||
if not i.registry["electron"].is_activated():
|
|
||||||
new_atoms.append(i)
|
|
||||||
else:
|
|
||||||
old_atoms.append(i)
|
|
||||||
logger.debug("新原子数量=%d, 旧原子数量=%d", len(new_atoms), len(old_atoms))
|
|
||||||
self.processions = list()
|
|
||||||
if len(old_atoms):
|
|
||||||
self.processions.append(
|
|
||||||
Procession(old_atoms, PhaserState.QUICK_REVIEW, "初始复习")
|
|
||||||
)
|
|
||||||
logger.debug("创建初始复习 Procession")
|
|
||||||
if len(new_atoms):
|
|
||||||
self.processions.append(
|
|
||||||
Procession(new_atoms, PhaserState.RECOGNITION, "新记忆")
|
|
||||||
)
|
|
||||||
logger.debug("创建新记忆 Procession")
|
|
||||||
self.processions.append(Procession(atoms, PhaserState.FINAL_REVIEW, "总体复习"))
|
|
||||||
logger.debug("创建总体复习 Procession")
|
|
||||||
logger.debug("Phaser 初始化完成, processions 数量=%d", len(self.processions))
|
|
||||||
|
|
||||||
def current_procession(self):
|
|
||||||
logger.debug("Phaser.current_procession 被调用")
|
|
||||||
for i in self.processions:
|
|
||||||
i: Procession
|
|
||||||
if not i.state == ProcessionState.FINISHED:
|
|
||||||
self.state = i.phase
|
|
||||||
logger.debug("找到未完成的 Procession: phase=%s", i.phase)
|
|
||||||
return i
|
|
||||||
self.state = PhaserState.FINISHED
|
|
||||||
logger.debug("所有 Procession 已完成, 状态设置为 FINISHED")
|
|
||||||
return 0
|
|
||||||
|
|||||||
@@ -1,74 +1,24 @@
|
|||||||
import heurams.kernel.particles as pt
|
from enum import Enum
|
||||||
from heurams.services.logger import get_logger
|
from typing import Any, Sequence, Type
|
||||||
|
from transitions import Machine, State, Event, EventData
|
||||||
|
|
||||||
from .states import PhaserState, ProcessionState
|
class Phaser(Machine):
|
||||||
|
def __init__(self, schedule: list):
|
||||||
|
state_words = ["init"] + schedule.copy()
|
||||||
|
state_objects = list()
|
||||||
|
for name in state_words:
|
||||||
|
state_objects.append(State(
|
||||||
|
name=name,
|
||||||
|
on_enter=["on_enter"]
|
||||||
|
))
|
||||||
|
Machine.__init__(self, states=state_objects, initial="init", send_event=True)
|
||||||
|
self.add_ordered_transitions(loop=False)
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
def on_enter(self, event_data: EventData):
|
||||||
|
print(event_data.transition.source, "->", event_data.transition.dest) # type: ignore
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
class Procession:
|
p = Phaser(["a", "b"])
|
||||||
"""队列: 标识单次记忆流程"""
|
p.next_state()
|
||||||
|
p.next_state()
|
||||||
def __init__(self, atoms: list, phase: PhaserState, name: str = ""):
|
print(p.state)
|
||||||
logger.debug(
|
|
||||||
"Procession.__init__: 原子数量=%d, phase=%s, name='%s'",
|
|
||||||
len(atoms),
|
|
||||||
phase.value,
|
|
||||||
name,
|
|
||||||
)
|
|
||||||
self.atoms = atoms
|
|
||||||
self.queue = atoms.copy()
|
|
||||||
self.current_atom = atoms[0]
|
|
||||||
self.cursor = 0
|
|
||||||
self.name = name
|
|
||||||
self.phase = phase
|
|
||||||
self.state: ProcessionState = ProcessionState.RUNNING
|
|
||||||
logger.debug("Procession 初始化完成, 队列长度=%d", len(self.queue))
|
|
||||||
|
|
||||||
def forward(self, step=1):
|
|
||||||
logger.debug("Procession.forward: step=%d, 当前 cursor=%d", step, self.cursor)
|
|
||||||
self.cursor += step
|
|
||||||
if self.cursor == len(self.queue):
|
|
||||||
self.state = ProcessionState.FINISHED
|
|
||||||
logger.debug("Procession 已完成")
|
|
||||||
else:
|
|
||||||
self.state = ProcessionState.RUNNING
|
|
||||||
try:
|
|
||||||
logger.debug("cursor 更新为: %d", self.cursor)
|
|
||||||
self.current_atom = self.queue[self.cursor]
|
|
||||||
logger.debug("当前原子更新为: %s", self.current_atom.ident)
|
|
||||||
return 1 # 成功
|
|
||||||
except IndexError as e:
|
|
||||||
logger.debug("IndexError: %s", e)
|
|
||||||
self.state = ProcessionState.FINISHED
|
|
||||||
logger.debug("Procession 因索引错误而完成")
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def append(self, atom=None):
|
|
||||||
if atom == None:
|
|
||||||
atom = self.current_atom
|
|
||||||
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))
|
|
||||||
else:
|
|
||||||
logger.debug("原子未追加(重复或队列长度<=1)")
|
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
length = len(self.queue) - self.cursor
|
|
||||||
logger.debug("Procession.__len__: 剩余长度=%d", length)
|
|
||||||
return length
|
|
||||||
|
|
||||||
def process(self):
|
|
||||||
logger.debug("Procession.process: cursor=%d", self.cursor)
|
|
||||||
return self.cursor
|
|
||||||
|
|
||||||
def total_length(self):
|
|
||||||
total = len(self.queue)
|
|
||||||
logger.debug("Procession.total_length: %d", total)
|
|
||||||
return total
|
|
||||||
|
|
||||||
def is_empty(self):
|
|
||||||
empty = len(self.queue)
|
|
||||||
logger.debug("Procession.is_empty: %d", empty)
|
|
||||||
return empty
|
|
||||||
|
|||||||
12
src/heurams/kernel/reactor1/__init__.py
Normal file
12
src/heurams/kernel/reactor1/__init__.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
from heurams.services.logger import get_logger
|
||||||
|
|
||||||
|
from .fission import Fission
|
||||||
|
from .phaser import Phaser
|
||||||
|
from .procession import Procession
|
||||||
|
from .states import PhaserState, ProcessionState
|
||||||
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
__all__ = ["PhaserState", "ProcessionState", "Procession", "Fission", "Phaser"]
|
||||||
|
|
||||||
|
logger.debug("反应堆模块已加载")
|
||||||
51
src/heurams/kernel/reactor1/phaser.py
Normal file
51
src/heurams/kernel/reactor1/phaser.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# 移相器类定义
|
||||||
|
|
||||||
|
import heurams.kernel.particles as pt
|
||||||
|
from heurams.services.logger import get_logger
|
||||||
|
|
||||||
|
from .procession import Procession
|
||||||
|
from .states import PhaserState, ProcessionState
|
||||||
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class Phaser:
|
||||||
|
"""全局调度阶段管理器"""
|
||||||
|
|
||||||
|
def __init__(self, atoms: list[pt.Atom]) -> None:
|
||||||
|
logger.debug("Phaser.__init__: 原子数量=%d", len(atoms))
|
||||||
|
new_atoms = list()
|
||||||
|
old_atoms = list()
|
||||||
|
self.state = PhaserState.UNSURE
|
||||||
|
for i in atoms:
|
||||||
|
if not i.registry["electron"].is_activated():
|
||||||
|
new_atoms.append(i)
|
||||||
|
else:
|
||||||
|
old_atoms.append(i)
|
||||||
|
logger.debug("新原子数量=%d, 旧原子数量=%d", len(new_atoms), len(old_atoms))
|
||||||
|
self.processions = list()
|
||||||
|
if len(old_atoms):
|
||||||
|
self.processions.append(
|
||||||
|
Procession(old_atoms, PhaserState.QUICK_REVIEW, "初始复习")
|
||||||
|
)
|
||||||
|
logger.debug("创建初始复习 Procession")
|
||||||
|
if len(new_atoms):
|
||||||
|
self.processions.append(
|
||||||
|
Procession(new_atoms, PhaserState.RECOGNITION, "新记忆")
|
||||||
|
)
|
||||||
|
logger.debug("创建新记忆 Procession")
|
||||||
|
self.processions.append(Procession(atoms, PhaserState.FINAL_REVIEW, "总体复习"))
|
||||||
|
logger.debug("创建总体复习 Procession")
|
||||||
|
logger.debug("Phaser 初始化完成, processions 数量=%d", len(self.processions))
|
||||||
|
|
||||||
|
def current_procession(self):
|
||||||
|
logger.debug("Phaser.current_procession 被调用")
|
||||||
|
for i in self.processions:
|
||||||
|
i: Procession
|
||||||
|
if not i.state == ProcessionState.FINISHED:
|
||||||
|
self.state = i.phase
|
||||||
|
logger.debug("找到未完成的 Procession: phase=%s", i.phase)
|
||||||
|
return i
|
||||||
|
self.state = PhaserState.FINISHED
|
||||||
|
logger.debug("所有 Procession 已完成, 状态设置为 FINISHED")
|
||||||
|
return 0
|
||||||
74
src/heurams/kernel/reactor1/procession.py
Normal file
74
src/heurams/kernel/reactor1/procession.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import heurams.kernel.particles as pt
|
||||||
|
from heurams.services.logger import get_logger
|
||||||
|
|
||||||
|
from .states import PhaserState, ProcessionState
|
||||||
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class Procession:
|
||||||
|
"""队列: 标识单次记忆流程"""
|
||||||
|
|
||||||
|
def __init__(self, atoms: list, phase: PhaserState, name: str = ""):
|
||||||
|
logger.debug(
|
||||||
|
"Procession.__init__: 原子数量=%d, phase=%s, name='%s'",
|
||||||
|
len(atoms),
|
||||||
|
phase.value,
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
self.atoms = atoms
|
||||||
|
self.queue = atoms.copy()
|
||||||
|
self.current_atom = atoms[0]
|
||||||
|
self.cursor = 0
|
||||||
|
self.name = name
|
||||||
|
self.phase = phase
|
||||||
|
self.state: ProcessionState = ProcessionState.RUNNING
|
||||||
|
logger.debug("Procession 初始化完成, 队列长度=%d", len(self.queue))
|
||||||
|
|
||||||
|
def forward(self, step=1):
|
||||||
|
logger.debug("Procession.forward: step=%d, 当前 cursor=%d", step, self.cursor)
|
||||||
|
self.cursor += step
|
||||||
|
if self.cursor == len(self.queue):
|
||||||
|
self.state = ProcessionState.FINISHED
|
||||||
|
logger.debug("Procession 已完成")
|
||||||
|
else:
|
||||||
|
self.state = ProcessionState.RUNNING
|
||||||
|
try:
|
||||||
|
logger.debug("cursor 更新为: %d", self.cursor)
|
||||||
|
self.current_atom = self.queue[self.cursor]
|
||||||
|
logger.debug("当前原子更新为: %s", self.current_atom.ident)
|
||||||
|
return 1 # 成功
|
||||||
|
except IndexError as e:
|
||||||
|
logger.debug("IndexError: %s", e)
|
||||||
|
self.state = ProcessionState.FINISHED
|
||||||
|
logger.debug("Procession 因索引错误而完成")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def append(self, atom=None):
|
||||||
|
if atom == None:
|
||||||
|
atom = self.current_atom
|
||||||
|
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))
|
||||||
|
else:
|
||||||
|
logger.debug("原子未追加(重复或队列长度<=1)")
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
length = len(self.queue) - self.cursor
|
||||||
|
logger.debug("Procession.__len__: 剩余长度=%d", length)
|
||||||
|
return length
|
||||||
|
|
||||||
|
def process(self):
|
||||||
|
logger.debug("Procession.process: cursor=%d", self.cursor)
|
||||||
|
return self.cursor
|
||||||
|
|
||||||
|
def total_length(self):
|
||||||
|
total = len(self.queue)
|
||||||
|
logger.debug("Procession.total_length: %d", total)
|
||||||
|
return total
|
||||||
|
|
||||||
|
def is_empty(self):
|
||||||
|
empty = len(self.queue)
|
||||||
|
logger.debug("Procession.is_empty: %d", empty)
|
||||||
|
return empty
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import TypedDict
|
||||||
|
|
||||||
import toml
|
import toml
|
||||||
|
|
||||||
@@ -8,6 +9,10 @@ import heurams.kernel.particles as pt
|
|||||||
|
|
||||||
from ...utils.lict import Lict
|
from ...utils.lict import Lict
|
||||||
|
|
||||||
|
class RepoManifest(TypedDict):
|
||||||
|
title: str
|
||||||
|
author: str
|
||||||
|
desc: str
|
||||||
|
|
||||||
class Repo:
|
class Repo:
|
||||||
file_mapping = {
|
file_mapping = {
|
||||||
@@ -38,7 +43,7 @@ class Repo:
|
|||||||
source=None,
|
source=None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.schedule: dict = schedule
|
self.schedule: dict = schedule
|
||||||
self.manifest: dict = manifest
|
self.manifest: RepoManifest = manifest # type: ignore
|
||||||
self.typedef: dict = typedef
|
self.typedef: dict = typedef
|
||||||
self.payload: Lict = payload
|
self.payload: Lict = payload
|
||||||
self.algodata: Lict = algodata
|
self.algodata: Lict = algodata
|
||||||
@@ -60,8 +65,11 @@ class Repo:
|
|||||||
self._nucleonic_proc,
|
self._nucleonic_proc,
|
||||||
self.payload))
|
self.payload))
|
||||||
)
|
)
|
||||||
self.electronic_data_lict = self.algodata
|
|
||||||
self.orbitic_data = self.schedule
|
self.orbitic_data = self.schedule
|
||||||
|
self.ident_index = self.nucleonic_data_lict.keys()
|
||||||
|
for i in self.ident_index:
|
||||||
|
self.algodata.append_new((i, {}))
|
||||||
|
self.electronic_data_lict = self.algodata
|
||||||
|
|
||||||
def _nucleonic_proc(self, unit):
|
def _nucleonic_proc(self, unit):
|
||||||
ident = unit[0]
|
ident = unit[0]
|
||||||
@@ -78,6 +86,11 @@ class Repo:
|
|||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self.payload)
|
return len(self.payload)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
from pprint import pformat
|
||||||
|
s = pformat(self.database, indent=4)
|
||||||
|
return s
|
||||||
|
|
||||||
def persist_to_repodir(
|
def persist_to_repodir(
|
||||||
self, save_list: list | None = None, source: Path | None = None
|
self, save_list: list | None = None, source: Path | None = None
|
||||||
):
|
):
|
||||||
@@ -151,3 +164,12 @@ class Repo:
|
|||||||
return 1
|
return 1
|
||||||
except:
|
except:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def probe_vaild_repos_in_dir(cls, folder: Path):
|
||||||
|
lst = list()
|
||||||
|
for i in folder.iterdir():
|
||||||
|
if i.is_dir():
|
||||||
|
if cls.check_repodir(i):
|
||||||
|
lst.append(i)
|
||||||
|
return lst
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
class Evalizer:
|
class Evalizer():
|
||||||
"""几乎无副作用的模板系统
|
"""几乎无副作用的模板系统
|
||||||
|
|
||||||
接受环境信息并创建一个模板解析工具, 工具传入参数支持list, dict及其嵌套
|
接受环境信息并创建一个模板解析工具, 工具传入参数支持list, dict及其嵌套
|
||||||
@@ -6,7 +6,6 @@ class Evalizer:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# TODO: 弃用风险极高的 eval
|
# TODO: 弃用风险极高的 eval
|
||||||
# 理论上已经限制了全局函数 但eval仍有风险
|
|
||||||
# TODO: 异步/多线程执行避免堵塞
|
# TODO: 异步/多线程执行避免堵塞
|
||||||
def __init__(self, environment: dict) -> None:
|
def __init__(self, environment: dict) -> None:
|
||||||
self.env = environment
|
self.env = environment
|
||||||
@@ -19,6 +18,8 @@ class Evalizer:
|
|||||||
return list(map(self.travel, anyobj))
|
return list(map(self.travel, anyobj))
|
||||||
elif isinstance(anyobj, dict):
|
elif isinstance(anyobj, dict):
|
||||||
return dict(map(self.travel, anyobj.items()))
|
return dict(map(self.travel, anyobj.items()))
|
||||||
|
elif isinstance(anyobj, tuple):
|
||||||
|
return tuple(map(self.travel, anyobj))
|
||||||
elif isinstance(anyobj, str):
|
elif isinstance(anyobj, str):
|
||||||
if anyobj.startswith("eval:"):
|
if anyobj.startswith("eval:"):
|
||||||
return self.eval_with_env(anyobj[5:])
|
return self.eval_with_env(anyobj[5:])
|
||||||
@@ -28,7 +29,7 @@ class Evalizer:
|
|||||||
return anyobj
|
return anyobj
|
||||||
|
|
||||||
def eval_with_env(self, s: str):
|
def eval_with_env(self, s: str):
|
||||||
ret = eval(s, {}, self.env)
|
ret = eval(s, globals(), self.env)
|
||||||
if not isinstance(ret, str):
|
if not isinstance(ret, str):
|
||||||
ret = str(ret)
|
ret = str(ret)
|
||||||
return ret
|
return ret
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ class Lict(UserList): # TODO: 优化同步(惰性同步), 当前性能为 O(n)
|
|||||||
else:
|
else:
|
||||||
return super().__getitem__(i)
|
return super().__getitem__(i)
|
||||||
|
|
||||||
|
def get_itemic_unit(self, i):
|
||||||
|
return (i, self.dicted_data[i])
|
||||||
|
|
||||||
def __setitem__(self, i, item):
|
def __setitem__(self, i, item):
|
||||||
if isinstance(i, str):
|
if isinstance(i, str):
|
||||||
self.dicted_data[i] = item
|
self.dicted_data[i] = item
|
||||||
@@ -81,6 +84,15 @@ class Lict(UserList): # TODO: 优化同步(惰性同步), 当前性能为 O(n)
|
|||||||
if self.forced_order:
|
if self.forced_order:
|
||||||
self.data.sort()
|
self.data.sort()
|
||||||
|
|
||||||
|
def append_new(self, item: Any):
|
||||||
|
if item != (item[0], item[1]):
|
||||||
|
raise NotImplementedError
|
||||||
|
if item[0] not in self:
|
||||||
|
super().append(item)
|
||||||
|
self._sync_based_on_list()
|
||||||
|
if self.forced_order:
|
||||||
|
self.data.sort()
|
||||||
|
|
||||||
def insert(self, i: int, item: Any) -> None:
|
def insert(self, i: int, item: Any) -> None:
|
||||||
if item != (item[0], item[1]): # 确保 item 是遵从限制的元组
|
if item != (item[0], item[1]): # 确保 item 是遵从限制的元组
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from unittest.mock import MagicMock, Mock, patch
|
|||||||
|
|
||||||
from heurams.kernel.particles.atom import Atom
|
from heurams.kernel.particles.atom import Atom
|
||||||
from heurams.kernel.particles.electron import Electron
|
from heurams.kernel.particles.electron import Electron
|
||||||
from heurams.kernel.reactor.phaser import Phaser
|
from heurams.kernel.reactor.procession import Phaser
|
||||||
from heurams.kernel.reactor.states import PhaserState, ProcessionState
|
from heurams.kernel.reactor.states import PhaserState, ProcessionState
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user