This commit is contained in:
2025-08-02 17:48:42 +08:00
parent 4d6d1f1b60
commit 445e15646b
11 changed files with 122 additions and 55 deletions

View File

@@ -4,10 +4,11 @@ from textual.widgets import Header, Footer, ListView, ListItem, Label, Static, B
from textual.containers import Container, Horizontal
from textual.screen import Screen
import pathlib
from typing import Tuple, Dict
import particles as pt
class Composition():
def __init__(self, screen: Screen, atom):
def __init__(self, screen: Screen, atom: Tuple[pt.Electron, pt.Nucleon, Dict]):
self.screen = screen
self.atom = atom
def compose(self):
@@ -17,16 +18,55 @@ class Composition():
print(event.button.id)
self.screen.query_one("#testlabel", Label).update("hi")
class Placeholder(Composition):
def __init__(self, screen: Screen):
self.screen = screen
def compose(self):
yield Label("示例标签", id="testlabel")
yield Button("示例按钮", id="testbtn")
def handler(self, event):
print(event.button.id)
self.screen.query_one("#testlabel", Label).update("hi")
class Recognition(Composition):
def __init__(self, screen: Screen, atom):
pass
def __init__(self, screen: Screen, atom: Tuple[pt.Electron, pt.Nucleon, Dict]):
super().__init__(screen, atom)
def compose(self):
yield Label(self.atom[1]["content"], id="sentence")
for i in self.atom[2]["testdata"]["additional_inf"]:
yield Label("[" + self.atom[2]["keydata"][i] + "] " + str(self.atom[1][i]), id=f"label_{i}")
yield Button("我已知晓", id="ok")
def handler(self, event):
if event.button.id == "ok":
return 1
class FillBlank(Composition):
def __init__(self, screen: Screen, atom: Tuple[pt.Electron, pt.Nucleon, Dict]):
super().__init__(screen, atom)
def compose(self):
yield Label(self.atom[1]["content"], id="sentence")
for i in self.atom[2]["testdata"]["additional_inf"]:
yield Label(f"{self.atom[2]["keydata"][i]}: {self.atom[1][i]}", id=f"label_{i}")
yield Button("我已知晓", id="ok")
def handler(self, event):
if event.button.id == "ok":
return 1
registry = {
"sample": Composition,
"recognition": Recognition,
"fill_blank_test": FillBlank,
"draw_card_test": Composition,
}
# TEST
class TestScreen(Screen):
def __init__(self):
super().__init__(name=None, id=None, classes=None)
self.comp = Composition(self, pt.Atom.advanced_placeholder())
self.comp = Recognition(self, pt.Atom.advanced_placeholder())
def compose(self) -> ComposeResult:
yield Header(show_clock=True)
yield from self.comp.compose()

51
main.py
View File

@@ -1,5 +1,5 @@
from textual.app import App, ComposeResult
from textual.widgets import Header, Footer, ListView, ListItem, Label, Static, Button
from textual.widgets import Header, Footer, ListView, DirectoryTree, ListItem, Label, Static, Button
from textual.containers import Container, Horizontal
from textual.screen import Screen
import pathlib
@@ -9,8 +9,9 @@ from playsound import playsound
from textual.logging import TextualHandler
import particles as pt
from reactor import Reactor
from reactor import Reactor, Apparatus
import auxiliary as aux
import compositions as compo
ver = '0.3.0'
@@ -42,57 +43,32 @@ class MemScreen(Screen):
tasked_num
):
super().__init__(name=None, id=None, classes=None)
self.reactor = Reactor(nucleon_file, electron_file, tasked_num)
self.reactor = Reactor(nucleon_file, electron_file, self, tasked_num)
self.stage = 1
self.stage += self.reactor.set_round_templated(self.stage)
#print(self.reactor.procession)
self.reactor.forward()
self.compo:compo.Composition = compo.Placeholder(self)
def compose(self) -> ComposeResult:
self.compo = next(self.reactor.current_appar)
yield Header(show_clock=True)
with Container(id="main_container"):
yield Label(self.reactor.round_title, id="round_title")
yield Label("记住了吗?", id="question")
yield Static(self.reactor.current_atom[1].content, id="sentence")
yield Static("", id="feedback") # 用于显示反馈
yield Label(self._get_progress_text(), id="progress")
with Container(id="button_container"):
if 1:
self.btn['5'] = Button("完美回想", variant="success", id="q5", classes="choice")
self.btn['4'] = Button("犹豫后正确", variant="success", id="q4", classes="choice")
self.btn['3'] = Button("困难地正确", variant="warning", id="q3", classes="choice")
self.btn['2'] = Button("错误但熟悉", variant="warning", id="q2", classes="choice")
self.btn['1'] = Button("错误且不熟", variant="error", id="q1", classes="choice")
self.btn['0'] = Button("完全空白", variant="error", id="q0", classes="choice")
yield Horizontal(self.btn['5'], self.btn['4'])
yield Horizontal(self.btn['3'], self.btn['2'])
yield Horizontal(self.btn['1'], self.btn['0'])
yield from self.compo.compose()
yield Footer()
"""
def _get_progress_text(self):
return f"{len(self.reactor.procession) - self.reactor.index}/{len(self.reactor.procession)}"
"""
def on_mount(self):
# 首次挂载时调用
self._update_ui()
def _update_ui(self):
self.query_one("#round_title", Label).update(self.reactor.round_title)
self.query_one("#sentence", Static).update(self.reactor.current_atom[1].content)
self.query_one("#progress", Label).update(self._get_progress_text())
self.query_one("#feedback", Static).update("") # 清除任何之前的反馈消息
def _show_finished_screen(self, message):
self.query_one("#question", Label).update(message)
self.query_one("#sentence", Static).update("已经完成记忆任务")
self.query_one("#round_title").display = False
self.query_one("#progress").display = False
for i in range(6):
self.query_one(f"#q{i}", Button).display = False
pass
def on_button_pressed(self, event):
feedback_label = self.query_one("#feedback", Static)
self.compo.handler(event)
"""feedback_label = self.query_one("#feedback", Static)
if type(event) == str:
btnid = event
else:
@@ -119,7 +95,8 @@ class MemScreen(Screen):
self.stage += 1
return
#feedback_label.update("") # 清除反馈消息
self._update_ui()
self._update_ui()"""
def action_press(self, btnid):
self.on_button_pressed(btnid)

View File

@@ -258,7 +258,7 @@ class Atom():
"keyword_note": "关键词翻译",
"translation": "语句翻译"},
"testdata":{
"additional_inf": ["translation", "note"],
"additional_inf": ["translation", "note", "keyword_note"],
"fill_blank_test": ["translation"],
"draw_card_test": ["keyword_note"]
},

View File

@@ -0,0 +1,44 @@
import random
class Puzzle():
pass
class BlankPuzzle(Puzzle):
"""填空题谜题生成器
Args:
text: 原始字符串(需要 "/" 分割句子, 末尾应有 "/")
min_denominator: 最小概率倒数(如占所有可生成填空数的 1/7 中的 7, 若期望值小于 1, 则取 1)
"""
def __init__(self, text, min_denominator):
self.text = text
self.min_denominator = min_denominator
self.wording = "填空题 - 尚未刷新谜题"
self.answer = ["填空题 - 尚未刷新谜题"]
def refresh(self): # 刷新谜题
placeholder = "___SLASH___"
tmp_text = self.text.replace("/", placeholder)
words = tmp_text.split(placeholder)
if not words:
return ""
words = [word for word in words if word]
num_blanks = min(max(1, len(words) // self.min_denominator), len(words))
indices_to_blank = random.sample(range(len(words)), num_blanks)
indices_to_blank.sort()
blanked_words = list(words)
answer = list()
for index in indices_to_blank:
blanked_words[index] = "__" * len(words[index])
answer.append(words[index])
result = []
for word in blanked_words:
result.append(word)
self.answer = answer
self.wording = "".join(result)
def __str__(self):
return f"{self.wording}\n{str(self.answer)}"
class SelectionPuzzle(Puzzle):
"选择题谜题生成器"

View File

@@ -2,30 +2,35 @@ import typing
import particles as pt
import pathlib
import auxiliary as aux
import compositions
import compositions as comps
import random
class Apparatus():
"""反应器对象, 处理一个原子的记忆工作, 并反馈到布局"""
def __init__(self, atom):
"""反应器对象, 决策一个原子的不同记忆方式, 并反馈到布局"""
def __init__(self, screen, atom):
self.electron: pt.Electron = atom[0]
self.nucleon: pt.Nucleon = atom[1]
self.positron: dict = atom[2]
self.testdata = self.positron["testdata"]
def iterator(self):
pass
def composer(self):
self.procession: typing.List[comps.Composition] = list()
if self.positron["is_new_activation"] == 1:
self.positron["is_new_activation"] = 0
self.procession.append(comps.registry["recognition"](screen, atom))
return
for i in self.positron["testdata"].keys():
if i == "additional_inf":
continue
self.procession.append(comps.registry[i](screen, atom))
# self.procession.reverse()
random.shuffle(self.procession)
def updater(self):
pass
def iterator(self):
yield from self.procession
class Reactor():
"""反应堆对象, 处理和分配一次文件记忆流程的资源与策略"""
def __init__(self, nucleon_file: pt.NucleonUnion, electron_file: pt.ElectronUnion, tasked_num):
def __init__(self, nucleon_file: pt.NucleonUnion, electron_file: pt.ElectronUnion, screen, tasked_num):
# 导入原子对象
self.reported = set()
self.nucleon_file = nucleon_file
@@ -34,7 +39,7 @@ class Reactor():
self.atoms_new = list()
self.atoms_review = list()
counter = self.tasked_num
self.screen = screen
self.electron_dict = electron_file.electrons_dict
def electron_dict_get_fallback(key) -> pt.Electron:
@@ -113,6 +118,7 @@ class Reactor():
return -1 # 此轮已完成
self.index += step
self.current_atom = self.procession[self.index]
self.current_appar = Apparatus(self.screen, self.current_atom).iterator()
return 0
def save(self):