整合子模块

This commit is contained in:
2025-11-10 03:01:42 +08:00
parent 07dc70df93
commit 0a0fb73e52
12 changed files with 142 additions and 28 deletions

View File

@@ -14,6 +14,14 @@ tasked_number = 8
# UTC 时间戳修正 仅用于 UNIX 日时间戳的生成修正, 单位为秒
timezone_offset = +28800 # 中国标准时间 (UTC+8)
[puzzles] # 谜题默认配置
[puzzles.mcq]
max_riddles_num = 2
[puzzles.cloze]
min_denominator = 3
[paths] # 相对于配置文件的 ".." (即工作目录) 而言 或绝对路径
nucleon_dir = "./data/nucleon"
electron_dir = "./data/electron"

View File

@@ -8,7 +8,7 @@ from .screens.precache import PrecachingScreen
class HeurAMSApp(App):
TITLE = "潜进"
SUB_TITLE = "启发式辅助记忆调度器"
SUB_TITLE = "启发式先进记忆调度器"
BINDINGS = [("q", "quit", "退出"),
("d", "toggle_dark", "改变色调"),
("1", "app.push_screen('dashboard')", "仪表盘"),

View File

@@ -0,0 +1,90 @@
#!/usr/bin/env python3
from textual.app import ComposeResult
from textual.widgets import (
Header,
Footer,
Label,
Static,
Button,
Markdown,
)
from textual.containers import Container
from textual.screen import Screen
import heurams.services.version as version
from heurams.context import *
class AboutScreen(Screen):
BINDINGS = [
("q", "go_back", "返回"),
("escape", "quit_app", "退出"),
]
def compose(self) -> ComposeResult:
yield Header(show_clock=True)
with Container(id="about_container"):
yield Label("关于 '潜进' 启发式先进记忆调度器", classes="title-label")
yield Static(f"\n版本: {version.ver} {version.codename.capitalize()}")
yield Static(f"开发者名单: Wang Zhiyu") # TODO: 取消硬编码, 和 git/vcs 集成
yield Static(f"Copyright 2025")
yield Static("\n")
about_text = f"""
## 关于 "潜进"
版本 {version.ver} {version.stage}
开发代号: {version.codename}
一个基于启发式算法的开放源代码记忆调度器, 旨在帮助用户更高效地进行记忆工作与学习规划.
以 AGPL-3.0 开放源代码
## 参与贡献
我们是一个年轻且包容的社区, 由技术人员, 设计师, 文书工作者, 以及创意人员共同构成,
通过我们协力开发的软件为所有人谋取福祉.
此项目不是 KDE 软件, 但上述工作不可避免地让我们确立了和 KDE 宣言相同的下列价值观:
- 开放治理 确保更多人能参与我们的领导和决策进程;
- 自由软件 确保我们的工作成果随时能为所有人所用;
- 多样包容 确保所有人都能加入社区并参加工作;
- 创新精神 确保新思路能不断涌现并服务于所有人;
- 共同产权 确保我们能团结一致;
- 迎合用户 确保我们的成果对所有人有用.
综上所述, 在为我们共同目标奋斗的过程中, 我们认为上述价值观反映了我们社区的本质, 是我们始终如一地保持初心的关键所在.
这是一项立足于协作精神的事业, 它的运作和产出不受任何单一个人或者机构的操纵.
我们的共同目标是为人人带来高品质的辅助记忆 & 学习软件.
不管您来自何方, 我们都欢迎您加入社区并做出贡献.
"""
yield Markdown(about_text, classes="about-markdown")
yield Button(
"返回主界面",
id="back_button",
variant="primary",
classes="back-button",
)
yield Footer()
def action_go_back(self):
self.app.pop_screen()
def action_quit_app(self):
self.app.exit()
def on_button_pressed(self, event) -> None:
if event.button.id == "back_button":
self.action_go_back()

View File

@@ -23,7 +23,7 @@ class DashboardScreen(Screen):
def compose(self) -> ComposeResult:
yield Header(show_clock=True)
yield Container(
Label(f'欢迎使用 "潜进" 启发式辅助记忆调度器', classes="title-label"),
Label(f'欢迎使用 "潜进" 启发式先进记忆调度器', classes="title-label"),
Label(f"当前的 UNIX 日时间戳: {timer.get_daystamp()}"),
Label(f'时区修正: UTC+{config_var.get()["timezone_offset"] / 3600}'),
Label("选择待学习或待修改的记忆单元集:", classes="title-label"),

View File

@@ -33,9 +33,11 @@ class MemScreen(Screen):
def current_widget(self):
self.fission = Fission(self.procession.current_atom, self.phaser.state)
puzzle: pz.BasePuzzle = next(self.fission.generate())
print(shim.puzzle2widget[puzzle])
return shim.puzzle2widget[puzzle](atom = self.procession.current_atom)
puzzle_info = next(self.fission.generate())
#print(puzzle_info)
#print(shim.puzzle2widget[puzzle_info["puzzle"]])
print(puzzle_info)
return shim.puzzle2widget[puzzle_info["puzzle"]](atom = self.procession.current_atom, alia = puzzle_info["alia"])
def compose(self) -> ComposeResult:
yield Header(show_clock=True)
@@ -57,9 +59,9 @@ class MemScreen(Screen):
def action_precache_current(self):
"""预缓存当前单元集的音频"""
from .precache import PrecachingScreen
precache_screen = PrecachingScreen(self.nucleon_file)
self.app.push_screen(precache_screen)
#from .precache import PrecachingScreen
#precache_screen = PrecachingScreen(self.nucleon_file)
#self.app.push_screen(precache_screen)
def action_toggle_dark(self):
self.app.action_toggle_dark()

View File

@@ -1,4 +1,4 @@
"""Kernel 操作辅助函数库"""
"""Kernel 操作先进函数库"""
import random
import heurams.kernel.particles as pt
import heurams.kernel.puzzles as pz
@@ -21,4 +21,4 @@ puzzle2widget = {
pz.ClozePuzzle: pzw.ClozePuzzle,
pz.MCQPuzzle: pzw.MCQPuzzle,
pz.BasePuzzle: pzw.BasePuzzleWidget,
}
}

View File

@@ -51,10 +51,10 @@ class Recognition(BasePuzzleWidget):
nucleon = self.atom.registry['nucleon']
metadata = self.atom.registry['nucleon'].metadata
primary = nucleon[cfg["primary"]]
primary = cfg["primary"]
with Center():
yield Static(f"[dim]{nucleon[cfg['top_dim']]}[/]")
yield Static(f"[dim]{cfg['top_dim']}[/]")
yield Label("")
for old, new in replace_dict.items():
@@ -67,7 +67,7 @@ class Recognition(BasePuzzleWidget):
id="sentence" + str(hash(item)),
)
for item in nucleon[cfg["secondary"]]:
for item in cfg["secondary"]:
if isinstance(item, list):
for j in item:
yield Markdown(f"### {metadata['annotation'][item]}: {j}")

View File

@@ -61,13 +61,16 @@ class Atom():
"""
# eval 环境设置
def eval_with_env(s: str):
nucleon = self.registry['nucleon']
default = config_var.get()["puzzles"]
metadata = nucleon.metadata
try:
nucleon = self.registry['nucleon']
default = config_var.get()["puzzles"]
metadata = nucleon.metadata
except:
ret = "尚未链接对象"
try:
ret = str(eval(s))
except:
ret = "此 eval 实例发生错误"
except Exception as e:
ret = f"此 eval 实例发生错误: {e}"
return ret
def traverse(data, modifier):
@@ -82,7 +85,10 @@ class Atom():
elif isinstance(data, tuple):
return tuple(traverse(item, modifier) for item in data)
else:
return modifier(data)
if isinstance(data, str):
if data.startswith("eval:"):
return modifier(data[5:])
return data
traverse(self.registry["nucleon"], eval_with_env)
traverse(self.registry["orbital"], eval_with_env)

View File

@@ -7,17 +7,23 @@ class Fission():
"""裂变器: 单原子调度展开器"""
def __init__(self, atom: pt.Atom, phase = PhaserState.RECOGNITION):
self.atom = atom
self.orbital = atom.registry["orbital"][phase.value]
print(self.orbital)
self.orbital_schedule = atom.registry["orbital"]["schedule"][phase.value] # type: ignore
self.orbital_puzzles = atom.registry["orbital"]["puzzles"]
#print(self.orbital_schedule)
self.puzzles = list()
for item, possibility in self.orbital: # type: ignore
for item, possibility in self.orbital_schedule: # type: ignore
if not isinstance(possibility, float):
possibility = float(possibility)
while possibility > 1:
self.puzzles.append(puz.puzzles[item])
self.puzzles.append({
"puzzle": puz.puzzles[self.orbital_puzzles[item]["__origin__"]],
"alia": item
})
possibility -= 1
if random.random() <= possibility:
self.puzzles.append(puz.puzzles[item])
self.puzzles.append({
"puzzle": puz.puzzles[self.orbital_puzzles[item]["__origin__"]],
"alia": item
})
def generate(self):
yield from self.puzzles
yield from self.puzzles

View File

@@ -21,7 +21,8 @@ class Procession():
try:
self.current_atom = self.queue[self.cursor]
return 1 # 成功
except IndexError:
except IndexError as e:
print(f"{e}")
return 0
def append(self, atom = None):

View File

@@ -16,7 +16,8 @@ class ConfigFile:
with open(self.path, 'r') as f:
try:
self.data = toml.load(f)
except toml.TomlDecodeError:
except toml.TomlDecodeError as e:
print(f"{e}")
self.data = {}
def modify(self, key: str, value: typing.Any):