diff --git a/auxiliary.py b/auxiliary.py index 2dc73a2..9894bd3 100644 --- a/auxiliary.py +++ b/auxiliary.py @@ -30,4 +30,4 @@ def get_daystamp() -> int: #print(f"TIME OVERRIDEED TO {time_override}") return int(time_override) - return int(time.time() // (24 * 3600)) + return int(time.time() // (24 * 3600)) \ No newline at end of file diff --git a/compositions.py b/compositions.py index 22e6f01..9edfa84 100644 --- a/compositions.py +++ b/compositions.py @@ -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() diff --git a/main.py b/main.py index 8538e7e..c5e96b1 100644 --- a/main.py +++ b/main.py @@ -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) diff --git a/particles.py b/particles.py index 6380d09..4e7bb50 100644 --- a/particles.py +++ b/particles.py @@ -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"] }, diff --git a/puzzles.py b/puzzles.py index e69de29..36df324 100644 --- a/puzzles.py +++ b/puzzles.py @@ -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): + "选择题谜题生成器" \ No newline at end of file diff --git a/reactor.py b/reactor.py index df387e9..a27461f 100644 --- a/reactor.py +++ b/reactor.py @@ -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): diff --git a/webshare/__pycache__/__init__.cpython-313.pyc b/webshare/__pycache__/__init__.cpython-313.pyc deleted file mode 100644 index 9d3fd28..0000000 Binary files a/webshare/__pycache__/__init__.cpython-313.pyc and /dev/null differ diff --git a/webshare/__pycache__/_binary_encode.cpython-313.pyc b/webshare/__pycache__/_binary_encode.cpython-313.pyc deleted file mode 100644 index d286748..0000000 Binary files a/webshare/__pycache__/_binary_encode.cpython-313.pyc and /dev/null differ diff --git a/webshare/__pycache__/app_service.cpython-313.pyc b/webshare/__pycache__/app_service.cpython-313.pyc deleted file mode 100644 index b012df1..0000000 Binary files a/webshare/__pycache__/app_service.cpython-313.pyc and /dev/null differ diff --git a/webshare/__pycache__/download_manager.cpython-313.pyc b/webshare/__pycache__/download_manager.cpython-313.pyc deleted file mode 100644 index 8369951..0000000 Binary files a/webshare/__pycache__/download_manager.cpython-313.pyc and /dev/null differ diff --git a/webshare/__pycache__/server.cpython-313.pyc b/webshare/__pycache__/server.cpython-313.pyc deleted file mode 100644 index 4309205..0000000 Binary files a/webshare/__pycache__/server.cpython-313.pyc and /dev/null differ