You've already forked HeurAMS-legacy
format
This commit is contained in:
@@ -82,5 +82,6 @@ app = HeurAMSApp()
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
||||
|
||||
|
||||
def main():
|
||||
app.run()
|
||||
|
||||
@@ -113,7 +113,7 @@ class DashboardScreen(Screen):
|
||||
return
|
||||
|
||||
selected_label = event.item.query_one(Label)
|
||||
if "未找到任何 .toml 文件" in str(selected_label.renderable): # type: ignore
|
||||
if "未找到任何 .toml 文件" in str(selected_label.renderable): # type: ignore
|
||||
return
|
||||
|
||||
selected_filename = pathlib.Path(
|
||||
|
||||
@@ -25,7 +25,7 @@ logger = get_logger(__name__)
|
||||
class MemScreen(Screen):
|
||||
BINDINGS = [
|
||||
("q", "pop_screen", "返回"),
|
||||
# ("p", "prev", "复习上一个"),
|
||||
# ("p", "prev", "复习上一个"),
|
||||
("d", "toggle_dark", ""),
|
||||
("v", "play_voice", "朗读"),
|
||||
("0,1,2,3", "app.push_screen('about')", ""),
|
||||
|
||||
@@ -21,6 +21,7 @@ from heurams.context import config_var
|
||||
class NucleonCreatorScreen(Screen):
|
||||
BINDINGS = [("q", "go_back", "返回")]
|
||||
SUB_TITLE = "单元集创建向导"
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__(name=None, id=None, classes=None)
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ class PrecachingScreen(Screen):
|
||||
nucleons (list): 可选列表, 仅包含 Nucleon 对象
|
||||
desc (list): 可选字符串, 包含对此次调用的文字描述
|
||||
"""
|
||||
|
||||
SUB_TITLE = "缓存管理器"
|
||||
BINDINGS = [("q", "go_back", "返回")]
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ class PreparationScreen(Screen):
|
||||
("0,1,2,3", "app.push_screen('about')", ""),
|
||||
]
|
||||
|
||||
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:
|
||||
super().__init__(name=None, id=None, classes=None)
|
||||
@@ -45,8 +45,12 @@ class PreparationScreen(Screen):
|
||||
yield Header(show_clock=True)
|
||||
with ScrollableContainer(id="vice_container"):
|
||||
yield Label(f"准备就绪: [b]{self.nucleon_file.stem}[/b]\n")
|
||||
yield Label(f"内容源文件: {config_var.get()['paths']['nucleon_dir']}/[b]{self.nucleon_file.name}[/b]")
|
||||
yield Label(f"元数据文件: {config_var.get()['paths']['electron_dir']}/[b]{self.electron_file.name}[/b]")
|
||||
yield Label(
|
||||
f"内容源文件: {config_var.get()['paths']['nucleon_dir']}/[b]{self.nucleon_file.name}[/b]"
|
||||
)
|
||||
yield Label(
|
||||
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")
|
||||
|
||||
@@ -67,7 +71,7 @@ class PreparationScreen(Screen):
|
||||
yield Markdown(self._get_full_content().replace("/", ""), classes="full")
|
||||
yield Footer()
|
||||
|
||||
#def watch_scheduled_num(self, old_scheduled_num, new_scheduled_num):
|
||||
# def watch_scheduled_num(self, old_scheduled_num, new_scheduled_num):
|
||||
# logger.debug("响应", old_scheduled_num, "->", new_scheduled_num)
|
||||
# try:
|
||||
# one = self.query_one("#schnum_label")
|
||||
@@ -133,6 +137,7 @@ class PreparationScreen(Screen):
|
||||
atoms_to_provide.append(i)
|
||||
logger.debug(f"ATP: {atoms_to_provide}")
|
||||
from .memorizor import MemScreen
|
||||
|
||||
memscreen = MemScreen(atoms_to_provide)
|
||||
self.app.push_screen(memscreen)
|
||||
elif event.button.id == "precache_button":
|
||||
|
||||
@@ -29,4 +29,4 @@ class BasePuzzleWidget(Widget):
|
||||
return super().compose()
|
||||
|
||||
def handler(self, rating) -> None:
|
||||
pass
|
||||
pass
|
||||
|
||||
@@ -101,9 +101,9 @@ class ClozePuzzle(BasePuzzleWidget):
|
||||
if not is_correct:
|
||||
self.inputlist = []
|
||||
self.update_display()
|
||||
|
||||
|
||||
def handler(self, rating):
|
||||
if self.atom.lock():
|
||||
pass
|
||||
else:
|
||||
self.atom.minimize(rating)
|
||||
self.atom.minimize(rating)
|
||||
|
||||
@@ -152,10 +152,9 @@ class MCQPuzzle(BasePuzzleWidget):
|
||||
self.hashmap[button_id] = option
|
||||
new_button = Button(option, id=button_id)
|
||||
container.mount(new_button)
|
||||
|
||||
|
||||
def handler(self, rating):
|
||||
if self.atom.lock():
|
||||
pass
|
||||
else:
|
||||
self.atom.minimize(rating)
|
||||
|
||||
@@ -17,6 +17,7 @@ from heurams.services.logger import get_logger
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class RecognitionConfig(TypedDict):
|
||||
__origin__: str
|
||||
__hint__: str
|
||||
@@ -112,4 +113,4 @@ class Recognition(BasePuzzleWidget):
|
||||
self.atom.lock(1)
|
||||
self.atom.minimize(5)
|
||||
else:
|
||||
pass
|
||||
pass
|
||||
|
||||
@@ -12,9 +12,11 @@ from heurams.services.logger import get_logger
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class AtomRegister_runtime(TypedDict):
|
||||
locked: bool # 只读锁定标识符
|
||||
min_rate: int # 最低评分
|
||||
locked: bool # 只读锁定标识符
|
||||
min_rate: int # 最低评分
|
||||
|
||||
|
||||
class AtomRegister(TypedDict):
|
||||
nucleon: Nucleon
|
||||
@@ -54,7 +56,7 @@ class Atom:
|
||||
"orbital": None,
|
||||
"orbital_path": None, # 允许设置为 None, 此时使用 nucleon 文件内的推荐配置
|
||||
"orbital_fmt": "toml",
|
||||
"runtime": {"locked": False, "min_rate": 0x3f3f3f3f}
|
||||
"runtime": {"locked": False, "min_rate": 0x3F3F3F3F},
|
||||
}
|
||||
self.do_eval()
|
||||
logger.debug("Atom 初始化完成")
|
||||
@@ -75,19 +77,20 @@ class Atom:
|
||||
Args:
|
||||
rating (int): 评分
|
||||
"""
|
||||
self.registry['runtime']['min_rate'] = min(rating, self.registry['runtime']['min_rate'])
|
||||
|
||||
def lock(self, locked = -1):
|
||||
"""锁定, 效果等同于 self.registry['runtime']['locked'] = locked 或者返回是否锁定
|
||||
"""
|
||||
self.registry["runtime"]["min_rate"] = min(
|
||||
rating, self.registry["runtime"]["min_rate"]
|
||||
)
|
||||
|
||||
def lock(self, locked=-1):
|
||||
"""锁定, 效果等同于 self.registry['runtime']['locked'] = locked 或者返回是否锁定"""
|
||||
if locked == 1:
|
||||
self.registry['runtime']['locked'] = True
|
||||
self.registry["runtime"]["locked"] = True
|
||||
return 1
|
||||
elif locked == 0:
|
||||
self.registry['runtime']['locked'] = False
|
||||
self.registry["runtime"]["locked"] = False
|
||||
return 1
|
||||
elif locked == -1:
|
||||
return self.registry['runtime']["locked"]
|
||||
return self.registry["runtime"]["locked"]
|
||||
return 0
|
||||
|
||||
def revise(self):
|
||||
@@ -96,11 +99,10 @@ class Atom:
|
||||
"""
|
||||
if self.registry["runtime"]["locked"]:
|
||||
logger.debug(f"允许总评分: {self.registry['runtime']['min_rate']}")
|
||||
self.registry["electron"].revisor(self.registry['runtime']["min_rate"])
|
||||
self.registry["electron"].revisor(self.registry["runtime"]["min_rate"])
|
||||
else:
|
||||
logger.debug("禁止总评分")
|
||||
|
||||
|
||||
def do_eval(self):
|
||||
"""
|
||||
执行并以结果替换当前单元的所有 eval 语句
|
||||
|
||||
@@ -67,7 +67,7 @@ class Electron:
|
||||
logger.debug("Electron.is_due: 检查 ident='%s'", self.ident)
|
||||
result = self.algo.is_due(self.algodata)
|
||||
logger.debug("is_due 结果: %s", result)
|
||||
return (result and self.is_activated())
|
||||
return result and self.is_activated()
|
||||
|
||||
def is_activated(self):
|
||||
result = self.algodata[self.algo.algo_name]["is_activated"]
|
||||
|
||||
@@ -44,7 +44,9 @@ class TestDashboardScreenUnit(unittest.TestCase):
|
||||
|
||||
# 创建目录
|
||||
for dir_key in ["nucleon_dir", "electron_dir", "orbital_dir", "cache_dir"]:
|
||||
pathlib.Path(config_data["paths"][dir_key]).mkdir(parents=True, exist_ok=True)
|
||||
pathlib.Path(config_data["paths"][dir_key]).mkdir(
|
||||
parents=True, exist_ok=True
|
||||
)
|
||||
|
||||
# 使用 ConfigContext 设置配置
|
||||
self.config_ctx = ConfigContext(self.config)
|
||||
@@ -60,16 +62,19 @@ class TestDashboardScreenUnit(unittest.TestCase):
|
||||
screen = DashboardScreen()
|
||||
# 手动调用 compose 并收集部件
|
||||
from textual.app import ComposeResult
|
||||
|
||||
result = screen.compose()
|
||||
widgets = list(result)
|
||||
# 检查是否包含 Header 和 Footer
|
||||
from textual.widgets import Header, Footer
|
||||
|
||||
header_present = any(isinstance(w, Header) for w in widgets)
|
||||
footer_present = any(isinstance(w, Footer) for w in widgets)
|
||||
self.assertTrue(header_present)
|
||||
self.assertTrue(footer_present)
|
||||
# 检查是否有 ScrollableContainer
|
||||
from textual.containers import ScrollableContainer
|
||||
|
||||
container_present = any(isinstance(w, ScrollableContainer) for w in widgets)
|
||||
self.assertTrue(container_present)
|
||||
# 使用 query_one 查找 union-list,即使屏幕未挂载也可能有效
|
||||
@@ -117,7 +122,9 @@ class TestDashboardScreenPilot(unittest.TestCase):
|
||||
config_data["timestamp_override"] = -1
|
||||
|
||||
for dir_key in ["nucleon_dir", "electron_dir", "orbital_dir", "cache_dir"]:
|
||||
pathlib.Path(config_data["paths"][dir_key]).mkdir(parents=True, exist_ok=True)
|
||||
pathlib.Path(config_data["paths"][dir_key]).mkdir(
|
||||
parents=True, exist_ok=True
|
||||
)
|
||||
|
||||
self.config_ctx = ConfigContext(self.config)
|
||||
self.config_ctx.__enter__()
|
||||
@@ -128,7 +135,7 @@ class TestDashboardScreenPilot(unittest.TestCase):
|
||||
|
||||
def test_dashboard_loads_with_pilot(self):
|
||||
"""使用 Pilot 测试 DashboardScreen 加载。"""
|
||||
with patch('heurams.interface.__main__.environment_check'):
|
||||
with patch("heurams.interface.__main__.environment_check"):
|
||||
app = HeurAMSApp()
|
||||
# 注意:Pilot 在 Textual 6.9.0 中的用法可能不同
|
||||
# 以下为示例代码,可能需要调整
|
||||
@@ -142,4 +149,4 @@ class TestDashboardScreenPilot(unittest.TestCase):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user