diff --git a/__pycache__/particles.cpython-313.pyc b/__pycache__/particles.cpython-313.pyc new file mode 100644 index 0000000..c0b3a3e Binary files /dev/null and b/__pycache__/particles.cpython-313.pyc differ diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..f4795b1 --- /dev/null +++ b/config.toml @@ -0,0 +1 @@ +tasked_number = 8 # 新记忆核子数量 \ No newline at end of file diff --git a/electron/陈情表.toml b/electron/陈情表.toml new file mode 100644 index 0000000..e69de29 diff --git a/main.py b/main.py index e69de29..53f8d9c 100644 --- a/main.py +++ b/main.py @@ -0,0 +1,236 @@ +from textual.app import App, ComposeResult +from textual.widgets import Header, Footer, ListView, ListItem, Label, Static, Button +from textual.containers import Container +from textual.screen import Screen +import particles as parti +import pathlib + +ver = '0.2.1' + +class MemScreen(Screen): + BINDINGS = [ + ("d", "toggle_dark", "改变色调"), + ("q", "pop_screen", "返回主菜单"), + ("v", "play_voice", "朗读"), + ("0", "press('q0')", None), + ("1", "press('q1')", None), + ("2", "press('q2')", None), + ("3", "press('q3')", None), + ("4", "press('q4')", None), + ("5", "press('q5')", None), + ("[", "press('q5')", None), + ("]", "press('q4')", None), + (";", "press('q3')", None), + ("'", "press('q2')", None), + (".", "press('q1')", None), + ("/", "press('q0')", None), + ] + btn = dict() + def __init__( + self, + atoms_file: str = 'test_atoms.json', + tasked_num: int = 8, # 记忆最小单元数目 + ): + super().__init__(name=None, id=None, classes=None) + self.memobj = MemObject(atoms_file=atoms_file, tasked_num=tasked_num) + self.memobj.next_round() + self.memobj.update_runtime(1) + def compose(self) -> ComposeResult: + yield Header(show_clock=True) + with Container(id="main_container"): + yield Label("", id="round_label") + yield Label("记住了吗?", id="question") + yield Static(self.memobj.runtime['current_atom'].content, id="sentence") + yield Static("", id="feedback") # 用于显示反馈 + yield Label(self._get_progress_text(), id="progress") + with Container(id="button_container"): + 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 Footer() + + + def _get_progress_text(self): + return f"{self.memobj.runtime['left'] + 1}/{self.memobj.runtime['total']}" + + def _get_round_text(self): + t = { + 'A': "复习模式", + 'B': "建立新记忆", + 'C': "总复习" + } + return "当前模式: " + t[self.memobj.runtime['stage']] + + def on_mount(self): + # 首次挂载时调用 + self._update_ui() + + def _update_ui(self): + self.query_one("#round_label", Label).update(self._get_round_text()) + self.query_one("#sentence", Static).update(self.memobj.runtime['current_atom'].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_label").display = False + self.query_one("#progress").display = False + for i in range(6): + self.query_one(f"#q{i}", Button).display = False + + def on_button_pressed(self, event): + feedback_label = self.query_one("#feedback", Static) + if type(event) == str: + btnid = event + else: + btnid = event.button.id + btnid = str(btnid) + quality = int(btnid.replace('q', '')) + assessment = self.memobj.report(self.memobj.runtime['current_atom'], quality) + if assessment == 1: + # 需要复习 + feedback_label.update(f"评分为 {quality}, 已经加入至复习, 请重复记忆") + else: + ret = self.memobj.update_runtime(1) + if ret == 1: + self.memobj.switch_to_extra_review() + self.memobj.update_runtime(1) + elif ret == 2: + self.memobj.next_round() + self.memobj.update_runtime(1) + elif ret == 3: + self.memobj.save() + self._show_finished_screen("今日目标已完成") + return + #feedback_label.update("") # 清除反馈消息 + self._update_ui() + def action_press(self, btnid): + self.on_button_pressed(btnid) + + def action_play_voice(self): + def play(): + cache = Path(f"./cache/voice/{self.memobj.runtime['current_atom'].content}.wav") + if not cache.exists(): + communicate = tts.Communicate(self.memobj.runtime['current_atom'].content, "zh-CN-YunjianNeural") + communicate.save_sync(f"./cache/voice/{self.memobj.runtime['current_atom'].content}.wav") + playsound(str(cache)) + threading.Thread(target=play).start() + + def action_toggle_dark(self): + self.app.action_toggle_dark() + + def action_pop_screen(self): + """返回到上一个屏幕""" + self.app.pop_screen() + +class PreparationScreen(Screen): + BINDINGS = [ + ("q", "go_back", "返回"), + ("escape", "quit_app", "退出") + ] + + def __init__(self, nucleon_file: parti.AtomicFile, electron_file: parti.AtomicFile) -> None: + super().__init__(name=None, id=None, classes=None) + self.nucleon_file = nucleon_file + self.electron_file = electron_file + + def compose(self) -> ComposeResult: + yield Header(show_clock=True) + with Container(id="learning_screen_container"): + yield Label(f"记忆项目: [b]{self.nucleon_file.name}[/b]\n") + yield Label(f"核子文件对象: ./nucleon/[b]{self.nucleon_file.name}[/b].toml") + yield Label(f"电子文件对象: ./electron/[b]{self.electron_file.name}[/b].toml") + yield Label(f"核子数量:{self.nucleon_file.get_len()}") + yield Button("开始记忆", id="start_memorizing_button", variant="primary", classes="start-button") + yield Static(f"\n全文如下:\n") + yield Static(self.nucleon_file.get_full_content(), classes="full") + 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: Button.Pressed) -> None: + pass + #if event.button.id == "start_memorizing_button": + # #init_file(Path(self.atom_file).name) + # newscr = proc.MemScreen(Path(self.atom_file).name) + # self.app.push_screen( + # newscr + # ) + #if event.button.id == "edit_metadata_button": + # init_file(Path(self.atom_file).name) + # os.system("reset;nano ./data/" + str(Path(self.atom_file).name.replace(".txt", "_atoms.json"))) + +class FileSelectorScreen(Screen): + global ver + def compose(self) -> ComposeResult: + yield Header(show_clock=True) + yield Container( + Label(f'欢迎使用 "潜进" 辅助记忆软件, 版本 {ver}', classes="title-label"), + Label("选择要学习的文件:", classes="title-label"), + ListView(id="file-list", classes="file-list-view") + ) + yield Footer() + + def on_mount(self) -> None: + file_list_widget = self.query_one("#file-list", ListView) + nucleon_path = pathlib.Path("./nucleon") + nucleon_files = sorted([f.name for f in nucleon_path.iterdir() if f.suffix == ".toml"]) + + if nucleon_files: + for filename in nucleon_files: + file_list_widget.append(ListItem(Label(filename))) + else: + file_list_widget.append(ListItem(Static("在 ./nucleon/ 中未找到任何核子文件. 请放置文件后重启应用."))) + file_list_widget.disabled = True + + def on_list_view_selected(self, event: ListView.Selected) -> None: + if not isinstance(event.item, ListItem): + self.notify("无法选择此项。", severity="error") + return + + selected_label = event.item.query_one(Label) + if "未找到任何 .toml 文件" in str(selected_label.renderable): + self.notify("请先在 `./atoms/` 目录中放置 .toml 文件。", severity="warning") + return + + selected_filename = str(selected_label.renderable) + nucleon_file = parti.AtomicFile(pathlib.Path("./nucleon") / selected_filename, "nucleon") + electron_file_path = pathlib.Path("./electron") / selected_filename + if electron_file_path.exists(): + pass + else: + electron_file_path.touch() + electron_file = parti.AtomicFile(pathlib.Path("./electron") / selected_filename, "electron") + # self.notify(f"已选择: {selected_filename}", timeout=2) + self.app.push_screen(PreparationScreen(nucleon_file, electron_file)) + + def action_quit_app(self) -> None: + self.app.exit() + +class AppLauncher(App): + CSS_PATH = "styles.tcss" + TITLE = '潜进 - 辅助记忆程序' + BINDINGS = [("escape", "quit", "退出"), ("d", "toggle_dark", "改变色调")] + SCREENS = { + "file_selection_screen": FileSelectorScreen, + } + + def on_mount(self) -> None: + self.action_toggle_dark() + self.push_screen("file_selection_screen") + +if __name__ == "__main__": + css_path = pathlib.Path("styles_dashboard.tcss") + app = AppLauncher() + app.run() diff --git a/nucleon/陈情表.toml b/nucleon/陈情表.toml index 1f55a29..6618f2c 100644 --- a/nucleon/陈情表.toml +++ b/nucleon/陈情表.toml @@ -1,139 +1,139 @@ ["臣密言:臣以险衅, 夙遭闵凶."] note = [] translation = "臣子李密陈言:我因命运不好,小时候遭遇到了不幸" -keyword_note = {"险衅":"凶险祸患(这里指命运不好)", "夙":"早时,这里指年幼的时候", "闵":"通'悯',指可忧患的事", "凶":"不幸,指丧父"} +keyword_note = {"险衅"="凶险祸患(这里指命运不好)", "夙"="早时,这里指年幼的时候", "闵"="通'悯',指可忧患的事", "凶"="不幸,指丧父"} ["生孩六月, 慈父见背;行年四岁, 舅夺母志."] note = [] translation = "刚出生六个月,我慈爱的父亲就不幸去世了。经过了四年,舅父逼母亲改嫁" -keyword_note = {"见背":"死的委婉说法", "行年":"经历的年岁", "母志":"母亲守节之志(改嫁的委婉说法)"} +keyword_note = {"见背"="死的委婉说法", "行年"="经历的年岁", "母志"="母亲守节之志(改嫁的委婉说法)"} ["祖母刘愍臣孤弱, 躬亲抚养."] note = [] translation = "我的祖母刘氏,怜悯我从小丧父,便亲自对我加以抚养" -keyword_note = {"愍":"怜悯", "躬亲":"亲身"} +keyword_note = {"愍"="怜悯", "躬亲"="亲身"} ["臣少多疾病, 九岁不行, 零丁孤苦, 至于成立."] note = [] translation = "臣小的时候经常生病,九岁时还不会行走。孤独无靠,一直到成人自立" -keyword_note = {"成立":"成人自立"} +keyword_note = {"成立"="成人自立"} ["既无伯叔, 终鲜兄弟, 门衰祚薄, 晚有儿息."] note = [] translation = "既没有叔叔伯伯,又没什么兄弟,门庭衰微而福分浅薄,很晚才有儿子" -keyword_note = {"鲜":"少,这里指'无'", "祚薄":"福分浅薄", "儿息":"亲生子女"} +keyword_note = {"鲜"="少,这里指'无'", "祚薄"="福分浅薄", "儿息"="亲生子女"} ["外无期功强近之亲, 内无应门五尺之僮, 茕茕孑立, 形影相吊."] note = [] translation = "在外面没有比较亲近的亲戚,在家里又没有照应门户的童仆。生活孤单没有依靠,每天只有自己的身体和影子相互安慰" -keyword_note = {"期功":"指关系较近的亲属", "茕茕孑立":"孤单无依靠的样子", "吊":"安慰"} +keyword_note = {"期功"="指关系较近的亲属", "茕茕孑立"="孤单无依靠的样子", "吊"="安慰"} ["而刘夙婴疾病, 常在床蓐, 臣侍汤药, 未曾废离."] note = [] translation = "但祖母又早被疾病缠绕,常年卧床不起,我侍奉她吃饭喝药,从来就没有停止侍奉而离开她" -keyword_note = {"婴":"被...缠绕", "蓐":"通'褥',床垫", "废":"停止服侍", "离":"离开"} +keyword_note = {"婴"="被...缠绕", "蓐"="通'褥',床垫", "废"="停止服侍", "离"="离开"} ["逮奉圣朝, 沐浴清化."] note = [] translation = "到了晋朝建立,我蒙受着清明的政治教化" -keyword_note = {"逮":"及,到", "奉":"承奉", "圣朝":"指当时的晋朝", "沐浴清化":"蒙受清平教化"} +keyword_note = {"逮"="及,到", "奉"="承奉", "圣朝"="指当时的晋朝", "沐浴清化"="蒙受清平教化"} ["前太守臣逵察臣孝廉;后刺史臣荣举臣秀才."] note = [] translation = "前任太守逵,考察后推举臣下为孝廉,后任刺史荣又推举臣下为优秀人才" -keyword_note = {"察":"考察和推举", "孝廉":"孝顺,品性纯洁", "举":"推举", "秀才":"优秀人才"} +keyword_note = {"察"="考察和推举", "孝廉"="孝顺,品性纯洁", "举"="推举", "秀才"="优秀人才"} ["臣以供养无主, 辞不赴命."] note = [] translation = "臣下因为供奉赡养祖母的事无人承担,辞谢不接受任命" -keyword_note = {"无主":"无人承担"} +keyword_note = {"无主"="无人承担"} ["诏书特下, 拜臣郎中, 寻蒙国恩, 除臣洗马."] note = [] translation = "朝廷又特地下了诏书,任命我为郎中,不久又蒙受国家恩命,任命我为太子洗马" -keyword_note = {"拜":"授予官职", "郎中":"尚书省的属官", "寻":"不久", "除":"拜官受职", "洗马":"太子的属官"} +keyword_note = {"拜"="授予官职", "郎中"="尚书省的属官", "寻"="不久", "除"="拜官受职", "洗马"="太子的属官"} ["猥以微贱, 当侍东宫, 非臣陨首所能上报."] note = [] translation = "像我这样出身微贱地位卑下的人,担当侍奉太子的职务,这实在不是我杀身捐躯所能报答朝廷的" -keyword_note = {"猥":"谦词", "微贱":"卑微低贱", "东宫":"太子居处", "陨首":"杀身"} +keyword_note = {"猥"="谦词", "微贱"="卑微低贱", "东宫"="太子居处", "陨首"="杀身"} ["臣具以表闻, 辞不就职."] note = [] translation = "我将以上苦衷上表报告,加以推辞不去就职" -keyword_note = {"具":"详细", "闻":"使...知道"} +keyword_note = {"具"="详细", "闻"="使...知道"} ["诏书切峻, 责臣逋慢;郡县逼迫, 催臣上道;州司临门, 急于星火."] note = [] translation = "但是诏书急切严峻,责备我逃避命令,有意拖延,态度傲慢。郡县长官催促我立刻上路;州官登门督促,比流星坠落还要急迫" -keyword_note = {"切峻":"急切而严厉", "逋慢":"逃避怠慢", "星火":"流星的光,喻急迫"} +keyword_note = {"切峻"="急切而严厉", "逋慢"="逃避怠慢", "星火"="流星的光,喻急迫"} ["臣欲奉诏奔驰, 则刘病日笃, 欲苟顺私情, 则告诉不许."] note = [] translation = "我很想遵从皇上的旨意赴京就职,但祖母刘氏的病却一天比一天重;想要姑且顺从自己的私情,但报告申诉不被允许" -keyword_note = {"日笃":"病情日益加重", "苟":"姑且", "告诉":"报告申诉"} +keyword_note = {"日笃"="病情日益加重", "苟"="姑且", "告诉"="报告申诉"} ["臣之进退, 实为狼狈."] note = [] translation = "我是进退两难,十分狼狈" -keyword_note = {"狼狈":"进退两难的样子"} +keyword_note = {"狼狈"="进退两难的样子"} ["伏惟圣朝以孝治天下, 凡在故老, 犹蒙矜育, 况臣孤苦, 特为尤甚."] note = [] translation = "我俯伏思量晋朝是用孝道来治理天下的,凡是年老而德高的旧臣,尚且还受到怜悯养育,何况我的孤苦程度更为严重呢" -keyword_note = {"伏惟":"下对上的敬辞", "故老":"年老德高的旧臣", "矜育":"怜悯养育"} +keyword_note = {"伏惟"="下对上的敬辞", "故老"="年老德高的旧臣", "矜育"="怜悯养育"} ["且臣少仕伪朝, 历职郎署, 本图宦达, 不矜名节."] note = [] translation = "况且我年轻的时候曾经做过蜀汉的官,担任过郎官职务,本来就希望做官显达,并不顾惜名声节操" -keyword_note = {"伪朝":"对前朝的蔑称", "历职":"连续任职", "郎署":"尚书郎的官衙", "宦达":"官场上显达"} +keyword_note = {"伪朝"="对前朝的蔑称", "历职"="连续任职", "郎署"="尚书郎的官衙", "宦达"="官场上显达"} ["今臣亡国贱俘, 至微至陋, 过蒙拔擢, 宠命优渥, 岂敢盘桓, 有所希冀!"] note = [] translation = "现在我是一个低贱的亡国俘虏,十分卑微浅陋,受到过分提拔,恩宠优厚,怎敢犹豫不决而有非分的企求呢" -keyword_note = {"拔擢":"提拔", "优渥":"优厚", "盘桓":"徘徊不前", "希冀":"非分的企求"} +keyword_note = {"拔擢"="提拔", "优渥"="优厚", "盘桓"="徘徊不前", "希冀"="非分的企求"} ["但以刘日薄西山, 气息奄奄, 人命危浅, 朝不虑夕."] note = [] translation = "只是因为祖母刘氏寿命即将终了,气息微弱,生命垂危,早上不能想到晚上怎样" -keyword_note = {"日薄西山":"太阳接近西山,喻人寿命将终", "危浅":"生命垂危"} +keyword_note = {"日薄西山"="太阳接近西山,喻人寿命将终", "危浅"="生命垂危"} ["臣无祖母, 无以至今日, 祖母无臣, 无以终余年."] note = [] translation = "臣下我如果没有祖母,就没有今天的样子;祖母如果没有我的照料,也无法度过她的余生" -keyword_note = {"终余年":"度过余生"} +keyword_note = {"终余年"="度过余生"} ["母孙二人, 更相为命, 是以区区不能废远."] note = [] translation = "我们祖孙二人,互相依靠而维持生命,因此我的内心不愿废止奉养,远离祖母" -keyword_note = {"更相":"相互", "区区":"自己的私情", "废远":"废止奉养而远离"} +keyword_note = {"更相"="相互", "区区"="自己的私情", "废远"="废止奉养而远离"} ["臣密今年四十有四, 祖母今年九十有六, 是臣尽节于陛下之日长, 报养刘之日短."] note = [] translation = "臣下我现在的年龄四十四岁了,祖母现在的年龄九十六岁了,臣下我在陛下面前尽忠尽节的日子还长着呢,而在祖母刘氏面前尽孝尽心的日子已经不多了" -keyword_note = {"有":"又", "尽节":"尽忠节"} +keyword_note = {"有"="又", "尽节"="尽忠节"} ["乌鸟私情, 愿乞终养."] note = [] translation = "我怀着乌鸦反哺的私情,乞求能够准许我完成对祖母养老送终的心愿" -keyword_note = {"乌鸟私情":"乌鸦反哺之情,喻孝心", "终养":"养老至终"} +keyword_note = {"乌鸟私情"="乌鸦反哺之情,喻孝心", "终养"="养老至终"} ["臣之辛苦, 非独蜀之人士及二州牧伯所见明知, 皇天后土, 实所共鉴."] note = [] translation = "我的辛酸苦楚,并不仅仅被蜀地的百姓及益州、梁州的长官所亲眼目睹、内心明白,连天地神明也都看得清清楚楚" -keyword_note = {"辛苦":"辛酸苦楚", "牧伯":"州郡长官", "皇天后土":"天地神明", "鉴":"明察"} +keyword_note = {"辛苦"="辛酸苦楚", "牧伯"="州郡长官", "皇天后土"="天地神明", "鉴"="明察"} ["愿陛下矜悯愚诚, 听臣微志, 庶刘侥幸, 保卒余年."] note = [] translation = "希望陛下能怜悯我愚昧诚心,请允许我完成臣下一点小小的心愿,使祖母刘氏能够侥幸地保全她的余生" -keyword_note = {"矜悯":"怜悯", "听":"准许", "庶":"或许(表希望)", "卒余年":"终老"} +keyword_note = {"矜悯"="怜悯", "听"="准许", "庶"="或许(表希望)", "卒余年"="终老"} ["臣生当陨首, 死当结草."] note = [] translation = "我活着应当杀身报效朝廷,死了也要结草衔环来报答陛下的恩情" -keyword_note = {"陨首":"掉脑袋,指献出生命", "结草":"死后报恩的典故"} +keyword_note = {"陨首"="掉脑袋,指献出生命", "结草"="死后报恩的典故"} ["臣不胜犬马怖惧之情, 谨拜表以闻."] note = [] translation = "臣下我怀着牛马一样不胜恐惧的心情,恭敬地呈上此表来使陛下知道这件事" -keyword_note = {"不胜":"禁不住", "犬马怖惧":"臣子谦卑的自比", "闻":"使...知道"} \ No newline at end of file +keyword_note = {"不胜"="禁不住", "犬马怖惧"="臣子谦卑的自比", "闻"="使...知道"} \ No newline at end of file diff --git a/particles.py b/particles.py index c478d44..13022e2 100644 --- a/particles.py +++ b/particles.py @@ -5,6 +5,11 @@ import copy import datetime import json +class Aux(): + @staticmethod + def get_daystamp(): + return (time.time() // (24*3600)) + class Atom(): """原子: 由电子(分析数据)和核子(材料元数据)组成的反应(运行时)中间对象""" @@ -18,7 +23,7 @@ class Electron(): real_rept = 0 # (实际)重复次数 rept = 0 # (有效)重复次数 interval = 0 # 最佳间隔 -ept', last_date = 0 # 上一次复习的时间戳 + last_date = 0 # 上一次复习的时间戳 next_date = 0 # 将要复习的时间戳 is_activated = 0 # 激活状态 # *NOTE: 这里的"时间戳" 是以天为单位的整数, 即 UNIX 时间戳除以一天的秒数取整 @@ -42,6 +47,47 @@ ept', last_date = 0 # 上一次复习的时间戳 setattr(self, var, value) self.last_modify = time.time() + def update(self, quality): + """ + 根据 quality(0 ~ 5) 进行参数迭代 + quality 由主程序评估 + """ + if quality == -1: + return -1 + self.efactor = self.efactor + (0.1 - (5 - quality) * (0.08 + (5 - quality) * 0.02)) + self.efactor = max(1.3, self.efactor) + + if quality < 3: + # 如果回忆质量低于 3,重置重复次数 + self.rept = 0 + self.interval = 0 # 设为0,以便下面重新计算I(1) + else: + self.rept += 1 + self.real_rept += 1 + + if self.rept == 0: # 刚被重置或首次遇到 + self.interval = 1 # I(1) + elif self.rept == 1: + self.interval = 6 # I(2) 经验公式 + else: + self.interval = round(self.interval * self.efactor) + + self.last_date = Aux.get_daystamp() + self.next_date = self.last_date + self.interval + + def __str__(self): + return (f"记忆单元预览 \n" + f"内容: '{self.content}' \n" + f"易度系数: {self.efactor:.2f} \n" + f"已经重复的次数: {self.rept} \n" + f"下次间隔: {self.interval} 天 \n" + f"下次复习日期时间戳: {self.next_date}") + + def __eq__(self, other): + if self.content == other.content: + return 1 + return 0 + def __hash__(self): return hash(self.content) @@ -80,4 +126,26 @@ class Nucleon(): def save_to_file(nucleon_list, path: pathlib.Path): with open(path, 'w') as f: toml.dump(nucleon_list, f) - \ No newline at end of file + +class AtomicFile(): + def __init__(self, path, type_="unknown"): + self.path = path + self.type_ = type_ + if type_ == "nucleon": + self.name, self.datalist = Nucleon.import_from_file(pathlib.Path(path)) + if type_ == "electron": + self.name, self.datalist = Electron.import_from_file(pathlib.Path(path)) + def save(self): + if self.type_ == "nucleon": + Nucleon.save_to_file(self.datalist, self.path) + if self.type_ == "electron": + Electron.save_to_file(self.datalist, self.path) + def get_full_content(self): + if self.type_ == "nucleon": + text = "" + for i in self.datalist: + text += i.content + return text + return "" + def get_len(self): + return len(self.datalist) \ No newline at end of file diff --git a/reactor.py b/reactor.py index e69de29..284b2ca 100644 --- a/reactor.py +++ b/reactor.py @@ -0,0 +1 @@ +class Reactor(tasked_num): \ No newline at end of file diff --git a/styles.tcss b/styles.tcss new file mode 100644 index 0000000..8e7c265 --- /dev/null +++ b/styles.tcss @@ -0,0 +1,55 @@ + +Screen { + align: center middle; +} + +#main_container { + align: center middle; + width: 80%; + height: auto; + border: thick $primary-lighten-2; + padding: 2; +} + +#sentence { + content-align: center middle; + width: 100%; + height: 5; + margin-bottom: 2; + text-style: bold; +} + +#progress { + width: 100%; + content-align: center middle; + margin-bottom: 1; + color: $text-muted; +} + + + +Button { + align-horizontal: center; + width: 50%; + margin: 0 0; +} +.choice { + align-horizontal: center; + width: 50%; + margin: 0 0; + height: auto; +} +/* no_margin.tcss */ + +#button_container { + align-horizontal: center; + height: 9; +} + +/* 选中 #button_container 下所有的 Horizontal 子元素 */ +#button_container > Horizontal { + margin-top: 0; + margin-bottom: 0; + align-horizontal: center; + width: 40%; +} \ No newline at end of file