Compare commits
16 Commits
d5ef5e84d0
...
v0.3.1
Author | SHA1 | Date | |
---|---|---|---|
39459a0f6e | |||
cccf7189e3 | |||
2c51f2cea3 | |||
2ad014fcd8 | |||
4ad289d02d | |||
28ccfdd227 | |||
f83d5c934d | |||
4f9eb3b7d1 | |||
c44a38f3c8 | |||
f760e7f0fa | |||
30eb45e1cb | |||
2a30f136cb | |||
051c4847b2 | |||
0873caa5fc | |||
6d3d2e665c | |||
edf2f0868a |
2
.playsound.py
Normal file
2
.playsound.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
def playsound(p):
|
||||||
|
print(p)
|
@@ -0,0 +1,7 @@
|
|||||||
|
# 贡献指南
|
||||||
|
## 使用 Nuitka 静态编译
|
||||||
|
运行
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nuitka --clang --jobs=6 --standalone --onefile main.py
|
||||||
|
```
|
30
README.md
30
README.md
@@ -1,10 +1,9 @@
|
|||||||
# 潜进 (HeurAMS) - 实验型辅助记忆程序
|
# 潜进 (HeurAMS) - 启发式辅助记忆程序
|
||||||
> 形人而我无形,**则我专而敌分**
|
> 形人而我无形,**则我专而敌分**
|
||||||
|
|
||||||
## 概述
|
## 概述
|
||||||
|
|
||||||
"潜进" (HeurAMS, 中文含义: 启发式辅助记忆软件) 是为习题册, 古诗词, 及其他问答/记忆/理解型题目设计的记忆辅助软件, 提供优化记忆方案
|
"潜进" (HeurAMS) 是为习题册, 古诗词, 及其他问答/记忆/理解型知识设计的辅助记忆软件, 提供动态规划的优化记忆方案
|
||||||
|
|
||||||
|
|
||||||
## 技术集成与特性
|
## 技术集成与特性
|
||||||
|
|
||||||
@@ -13,10 +12,10 @@
|
|||||||
- 采用经实证的 SM-2 间隔迭代算法, 此算法亦用作 Anki 闪卡记忆软件的默认闪卡调度器
|
- 采用经实证的 SM-2 间隔迭代算法, 此算法亦用作 Anki 闪卡记忆软件的默认闪卡调度器
|
||||||
> 计划: 将添加 FSRS 算法 (Anki 的新可选闪卡调度器) 与一种 SM-15 变体算法作为后续替代
|
> 计划: 将添加 FSRS 算法 (Anki 的新可选闪卡调度器) 与一种 SM-15 变体算法作为后续替代
|
||||||
> 参考 https://github.com/slaypni/SM-15
|
> 参考 https://github.com/slaypni/SM-15
|
||||||
> 为什么使用 SM-15 的变体?
|
> 使用 SM-15 的变体:
|
||||||
> SM-2 后续算法仅有论文, 无具体方程, 故使用一种基于 SM-15 描述实现的变体算法
|
> SM-2 后续算法并非完全开放, 故使用一种基于 SM-15 描述实现的变体算法
|
||||||
- 动态优化每首诗词的记忆间隔时间表
|
- 动态规划每个记忆单元的记忆间隔时间表
|
||||||
- 实时跟踪记忆曲线,优化长期记忆保留率与稳定性
|
- 动态跟踪记忆反馈数据,优化长期记忆保留率与稳定性
|
||||||
|
|
||||||
### 学习进程优化
|
### 学习进程优化
|
||||||
- 逐字解析:支持逐字详细释义解析
|
- 逐字解析:支持逐字详细释义解析
|
||||||
@@ -30,12 +29,19 @@
|
|||||||
- 简洁直观的复习流程设计
|
- 简洁直观的复习流程设计
|
||||||
|
|
||||||
## 屏幕截图
|
## 屏幕截图
|
||||||

|
|
||||||

|
> 单击图片以放大
|
||||||
|
|
||||||
|
<img src="./readme_src/img1.png" alt="img1" style="zoom: 33%;" />
|
||||||
|
<img src="./readme_src/img2.png" alt="img2" style="zoom:33%;" />
|
||||||
|
<img src="./readme_src/img3.png" alt="img3" style="zoom:33%;" />
|
||||||
|
<img src="./readme_src/img4.png" alt="img4" style="zoom:33%;" />
|
||||||
|
|
||||||
## 技术架构
|
## 技术架构
|
||||||
|
|
||||||
> 有关技术与实现的细节, 请参阅 CONTRIBUTING.md
|
> 有关技术与实现的细节, 请参阅 CONTRIBUTING.md
|
||||||
> 提交拉取请求以参与到此开放源代码项目
|
> 提交拉取请求以参与到此开放源代码项目
|
||||||
|
|
||||||
``` mermaid
|
``` mermaid
|
||||||
graph TD
|
graph TD
|
||||||
subgraph 后端
|
subgraph 后端
|
||||||
@@ -63,9 +69,3 @@ graph TD
|
|||||||
|
|
||||||
- 平台支持:Windows / macOS / Linux / Android (需要 Termux 或 Linux) (终端或浏览器)
|
- 平台支持:Windows / macOS / Linux / Android (需要 Termux 或 Linux) (终端或浏览器)
|
||||||
- 网络连接:可预缓存语音文件, 需联网使用大模型服务功能
|
- 网络连接:可预缓存语音文件, 需联网使用大模型服务功能
|
||||||
|
|
||||||
## 使用 Nuitka 静态编译
|
|
||||||
运行
|
|
||||||
```bash
|
|
||||||
nuitka --clang --jobs=6 --standalone --onefile main.py
|
|
||||||
```
|
|
14
auxiliary.py
14
auxiliary.py
@@ -2,6 +2,9 @@ import time
|
|||||||
import pathlib
|
import pathlib
|
||||||
import toml
|
import toml
|
||||||
import typing
|
import typing
|
||||||
|
import playsound
|
||||||
|
import threading
|
||||||
|
import edge_tts as tts
|
||||||
|
|
||||||
class ConfigFile:
|
class ConfigFile:
|
||||||
def __init__(self, path: str):
|
def __init__(self, path: str):
|
||||||
@@ -34,6 +37,17 @@ class ConfigFile:
|
|||||||
"""获取配置值,如果不存在返回默认值"""
|
"""获取配置值,如果不存在返回默认值"""
|
||||||
return self.data.get(key, default)
|
return self.data.get(key, default)
|
||||||
|
|
||||||
|
def action_play_voice(content):
|
||||||
|
def play():
|
||||||
|
communicate = tts.Communicate(
|
||||||
|
content,
|
||||||
|
"zh-CN-YunjianNeural",
|
||||||
|
)
|
||||||
|
communicate.save_sync(
|
||||||
|
f"./cache/voice/{content}"
|
||||||
|
)
|
||||||
|
playsound()
|
||||||
|
threading.Thread(target=play).start()
|
||||||
|
|
||||||
def get_daystamp() -> int:
|
def get_daystamp() -> int:
|
||||||
"""获取当前日戳(以天为单位的整数时间戳)"""
|
"""获取当前日戳(以天为单位的整数时间戳)"""
|
||||||
|
@@ -124,9 +124,8 @@ class Recognition(Composition):
|
|||||||
def handler(self, event, type_):
|
def handler(self, event, type_):
|
||||||
if type_ == "button":
|
if type_ == "button":
|
||||||
if event.button.id == self.getid("ok"):
|
if event.button.id == self.getid("ok"):
|
||||||
|
self.reactor.report(self.atom, 5)
|
||||||
return 0
|
return 0
|
||||||
if type_ == 1:
|
|
||||||
pass
|
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
|
||||||
@@ -189,6 +188,7 @@ class FillBlank(Composition):
|
|||||||
yield Button("退格", id=self.regid(f"delete"))
|
yield Button("退格", id=self.regid(f"delete"))
|
||||||
|
|
||||||
def handler(self, event, type_):
|
def handler(self, event, type_):
|
||||||
|
# TODO: 改动:在线错误纠正
|
||||||
if type_ == "button":
|
if type_ == "button":
|
||||||
if self.recid(event.button.id) == "delete":
|
if self.recid(event.button.id) == "delete":
|
||||||
if len(self.inputlist) > 0:
|
if len(self.inputlist) > 0:
|
||||||
@@ -201,9 +201,11 @@ class FillBlank(Composition):
|
|||||||
return 1
|
return 1
|
||||||
else:
|
else:
|
||||||
if self.inputlist == self.puzzle.answer:
|
if self.inputlist == self.puzzle.answer:
|
||||||
|
self.reactor.report(self.atom, 4)
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
self.inputlist = []
|
self.inputlist = []
|
||||||
|
self.reactor.report(self.atom, 2)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
@@ -240,9 +242,11 @@ class DrawCard(Composition):
|
|||||||
return 1
|
return 1
|
||||||
else:
|
else:
|
||||||
if self.inputlist == self.puzzle.answer:
|
if self.inputlist == self.puzzle.answer:
|
||||||
|
self.reactor.report(self.atom, 4)
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
self.inputlist = []
|
self.inputlist = []
|
||||||
|
self.reactor.report(self.atom, 2)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
@@ -276,7 +280,7 @@ class TestScreen(Screen):
|
|||||||
|
|
||||||
|
|
||||||
class AppLauncher(App):
|
class AppLauncher(App):
|
||||||
CSS_PATH = "styles.tcss"
|
CSS_PATH = "styles.css"
|
||||||
TITLE = "测试布局"
|
TITLE = "测试布局"
|
||||||
BINDINGS = [("escape", "quit", "退出"), ("d", "toggle_dark", "改变色调")]
|
BINDINGS = [("escape", "quit", "退出"), ("d", "toggle_dark", "改变色调")]
|
||||||
SCREENS = {
|
SCREENS = {
|
||||||
@@ -290,4 +294,4 @@ class AppLauncher(App):
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app = AppLauncher()
|
app = AppLauncher()
|
||||||
app.run()
|
app.run()
|
||||||
|
10
config.toml
10
config.toml
@@ -1,8 +1,14 @@
|
|||||||
# [调试] 将更改保存到文件
|
# [调试] 将更改保存到文件
|
||||||
save = 1
|
save = 1
|
||||||
|
|
||||||
# [调试] 覆写时间
|
# [调试] 覆写时间
|
||||||
time_override = 10
|
time_override = -1
|
||||||
|
|
||||||
|
# [调试] 一键通过
|
||||||
|
quick_pass = 0
|
||||||
|
|
||||||
# 对于每个项目的新记忆核子数量
|
# 对于每个项目的新记忆核子数量
|
||||||
tasked_number = 8
|
tasked_number = 8
|
||||||
# 竖屏适配
|
|
||||||
|
# 竖屏适配 (未完成)
|
||||||
mobile_mode = 1
|
mobile_mode = 1
|
42
main.py
42
main.py
@@ -22,18 +22,7 @@ import auxiliary as aux
|
|||||||
import compositions as compo
|
import compositions as compo
|
||||||
import builtins
|
import builtins
|
||||||
|
|
||||||
_original_open = builtins.open
|
ver = "0.3.1"
|
||||||
|
|
||||||
|
|
||||||
def _open(*args, **kwargs):
|
|
||||||
if "encoding" not in kwargs:
|
|
||||||
kwargs["encoding"] = "utf-8"
|
|
||||||
return _original_open(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
builtins.open = _open
|
|
||||||
|
|
||||||
ver = "0.3.0b"
|
|
||||||
|
|
||||||
config = aux.ConfigFile("config.toml")
|
config = aux.ConfigFile("config.toml")
|
||||||
|
|
||||||
@@ -43,19 +32,9 @@ class MemScreen(Screen):
|
|||||||
("d", "toggle_dark", "改变色调"),
|
("d", "toggle_dark", "改变色调"),
|
||||||
("q", "pop_screen", "返回主菜单"),
|
("q", "pop_screen", "返回主菜单"),
|
||||||
("v", "play_voice", "朗读"),
|
("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),
|
|
||||||
]
|
]
|
||||||
|
if config.get("quick_pass"):
|
||||||
|
BINDINGS.append(("k", "quick_pass", "快速通过[调试]"))
|
||||||
btn = dict()
|
btn = dict()
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -72,6 +51,8 @@ class MemScreen(Screen):
|
|||||||
self.compo = next(self.reactor.current_appar)
|
self.compo = next(self.reactor.current_appar)
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
|
if type(self.compo).__name__ == "Recognition":
|
||||||
|
self.action_play_voice()
|
||||||
yield Header(show_clock=True)
|
yield Header(show_clock=True)
|
||||||
with Center():
|
with Center():
|
||||||
yield Static(
|
yield Static(
|
||||||
@@ -126,12 +107,10 @@ class MemScreen(Screen):
|
|||||||
|
|
||||||
def refresh_ui(self):
|
def refresh_ui(self):
|
||||||
self.call_later(self.recompose)
|
self.call_later(self.recompose)
|
||||||
|
print(type(self.compo).__name__)
|
||||||
def report(self, quality):
|
|
||||||
assessment = self.reactor.report(self.reactor.current_atom, quality)
|
|
||||||
return assessment
|
|
||||||
|
|
||||||
def action_play_voice(self):
|
def action_play_voice(self):
|
||||||
|
print("VOICE")
|
||||||
def play():
|
def play():
|
||||||
cache_dir = pathlib.Path(f"./cache/voice/")
|
cache_dir = pathlib.Path(f"./cache/voice/")
|
||||||
cache_dir.mkdir(parents=True, exist_ok=True)
|
cache_dir.mkdir(parents=True, exist_ok=True)
|
||||||
@@ -148,6 +127,9 @@ class MemScreen(Screen):
|
|||||||
|
|
||||||
threading.Thread(target=play).start()
|
threading.Thread(target=play).start()
|
||||||
|
|
||||||
|
def action_quick_pass(self):
|
||||||
|
self.reactor.report(self.reactor.current_atom, 5)
|
||||||
|
self._forward_judge(0)
|
||||||
def action_toggle_dark(self):
|
def action_toggle_dark(self):
|
||||||
self.app.action_toggle_dark()
|
self.app.action_toggle_dark()
|
||||||
|
|
||||||
@@ -183,7 +165,7 @@ class PreparationScreen(Screen):
|
|||||||
classes="start-button",
|
classes="start-button",
|
||||||
)
|
)
|
||||||
yield Static(f"\n全文如下:\n")
|
yield Static(f"\n全文如下:\n")
|
||||||
yield Static(self._get_full_content(), classes="full")
|
yield Static(self._get_full_content().replace("/", ""), classes="full")
|
||||||
yield Footer()
|
yield Footer()
|
||||||
|
|
||||||
def _get_full_content(self):
|
def _get_full_content(self):
|
||||||
@@ -261,7 +243,7 @@ class FileSelectorScreen(Screen):
|
|||||||
|
|
||||||
|
|
||||||
class AppLauncher(App):
|
class AppLauncher(App):
|
||||||
CSS_PATH = "styles.tcss"
|
CSS_PATH = "styles.css"
|
||||||
TITLE = "潜进 - 辅助记忆程序"
|
TITLE = "潜进 - 辅助记忆程序"
|
||||||
BINDINGS = [("escape", "quit", "退出"), ("d", "toggle_dark", "改变色调")]
|
BINDINGS = [("escape", "quit", "退出"), ("d", "toggle_dark", "改变色调")]
|
||||||
SCREENS = {
|
SCREENS = {
|
||||||
|
@@ -8,7 +8,7 @@ translation = "语句翻译"
|
|||||||
["testdata"]
|
["testdata"]
|
||||||
# 记忆时显示的额外信息
|
# 记忆时显示的额外信息
|
||||||
additional_inf = ["translation","keyword_note", "note"]
|
additional_inf = ["translation","keyword_note", "note"]
|
||||||
# 填空测试, content指代键名
|
# 填空测试, content 指代键名
|
||||||
fill_blank_test = {"from"=["content"], "hint"=["translation"]}
|
fill_blank_test = {"from"=["content"], "hint"=["translation"]}
|
||||||
# 选择题测试
|
# 选择题测试
|
||||||
draw_card_test = {"from"=["keyword_note"]}
|
draw_card_test = {"from"=["keyword_note"]}
|
||||||
|
0
nucleon_todo/临安春雨初霁.toml
Normal file
0
nucleon_todo/临安春雨初霁.toml
Normal file
0
nucleon_todo/书愤.toml
Normal file
0
nucleon_todo/书愤.toml
Normal file
0
nucleon_todo/五代史伶官传序.toml
Normal file
0
nucleon_todo/五代史伶官传序.toml
Normal file
0
nucleon_todo/六国论.toml
Normal file
0
nucleon_todo/六国论.toml
Normal file
0
nucleon_todo/劝学.toml
Normal file
0
nucleon_todo/劝学.toml
Normal file
0
nucleon_todo/声声慢.toml
Normal file
0
nucleon_todo/声声慢.toml
Normal file
0
nucleon_todo/子路曾皙冉有公西华侍坐.toml
Normal file
0
nucleon_todo/子路曾皙冉有公西华侍坐.toml
Normal file
0
nucleon_todo/客至.toml
Normal file
0
nucleon_todo/客至.toml
Normal file
0
nucleon_todo/将进酒.toml
Normal file
0
nucleon_todo/将进酒.toml
Normal file
0
nucleon_todo/屈原列传.toml
Normal file
0
nucleon_todo/屈原列传.toml
Normal file
0
nucleon_todo/山居秋暝.toml
Normal file
0
nucleon_todo/山居秋暝.toml
Normal file
0
nucleon_todo/师说.toml
Normal file
0
nucleon_todo/师说.toml
Normal file
0
nucleon_todo/归去来兮辞.toml
Normal file
0
nucleon_todo/归去来兮辞.toml
Normal file
0
nucleon_todo/归田园居.toml
Normal file
0
nucleon_todo/归田园居.toml
Normal file
0
nucleon_todo/念奴娇赤壁怀古.toml
Normal file
0
nucleon_todo/念奴娇赤壁怀古.toml
Normal file
0
nucleon_todo/念奴娇过洞庭.toml
Normal file
0
nucleon_todo/念奴娇过洞庭.toml
Normal file
0
nucleon_todo/扬州慢.toml
Normal file
0
nucleon_todo/扬州慢.toml
Normal file
0
nucleon_todo/报任安书.toml
Normal file
0
nucleon_todo/报任安书.toml
Normal file
0
nucleon_todo/拟行路难.toml
Normal file
0
nucleon_todo/拟行路难.toml
Normal file
0
nucleon_todo/无衣.toml
Normal file
0
nucleon_todo/无衣.toml
Normal file
0
nucleon_todo/春江花月夜.toml
Normal file
0
nucleon_todo/春江花月夜.toml
Normal file
0
nucleon_todo/望海潮.toml
Normal file
0
nucleon_todo/望海潮.toml
Normal file
0
nucleon_todo/朝天子.toml
Normal file
0
nucleon_todo/朝天子.toml
Normal file
0
nucleon_todo/李凭箜篌引.toml
Normal file
0
nucleon_todo/李凭箜篌引.toml
Normal file
0
nucleon_todo/桂枝香.toml
Normal file
0
nucleon_todo/桂枝香.toml
Normal file
0
nucleon_todo/梦游天姥吟留别.toml
Normal file
0
nucleon_todo/梦游天姥吟留别.toml
Normal file
0
nucleon_todo/永遇乐.toml
Normal file
0
nucleon_todo/永遇乐.toml
Normal file
0
nucleon_todo/江城子.toml
Normal file
0
nucleon_todo/江城子.toml
Normal file
0
nucleon_todo/涉江采芙蓉.toml
Normal file
0
nucleon_todo/涉江采芙蓉.toml
Normal file
0
nucleon_todo/燕歌行.toml
Normal file
0
nucleon_todo/燕歌行.toml
Normal file
0
nucleon_todo/琵琶行.toml
Normal file
0
nucleon_todo/琵琶行.toml
Normal file
0
nucleon_todo/登岳阳楼.toml
Normal file
0
nucleon_todo/登岳阳楼.toml
Normal file
0
nucleon_todo/登快阁.toml
Normal file
0
nucleon_todo/登快阁.toml
Normal file
0
nucleon_todo/登泰山记.toml
Normal file
0
nucleon_todo/登泰山记.toml
Normal file
0
nucleon_todo/登高.toml
Normal file
0
nucleon_todo/登高.toml
Normal file
0
nucleon_todo/短歌行.toml
Normal file
0
nucleon_todo/短歌行.toml
Normal file
0
nucleon_todo/石钟山记.toml
Normal file
0
nucleon_todo/石钟山记.toml
Normal file
0
nucleon_todo/礼运.toml
Normal file
0
nucleon_todo/礼运.toml
Normal file
0
nucleon_todo/离骚.toml
Normal file
0
nucleon_todo/离骚.toml
Normal file
0
nucleon_todo/种树郭橐驼传.toml
Normal file
0
nucleon_todo/种树郭橐驼传.toml
Normal file
0
nucleon_todo/答司马谏议书.toml
Normal file
0
nucleon_todo/答司马谏议书.toml
Normal file
0
nucleon_todo/苏幕遮.toml
Normal file
0
nucleon_todo/苏幕遮.toml
Normal file
0
nucleon_todo/菩萨蛮.toml
Normal file
0
nucleon_todo/菩萨蛮.toml
Normal file
0
nucleon_todo/虞美人.toml
Normal file
0
nucleon_todo/虞美人.toml
Normal file
0
nucleon_todo/蜀相.toml
Normal file
0
nucleon_todo/蜀相.toml
Normal file
0
nucleon_todo/蜀道难.toml
Normal file
0
nucleon_todo/蜀道难.toml
Normal file
0
nucleon_todo/论语.toml
Normal file
0
nucleon_todo/论语.toml
Normal file
0
nucleon_todo/谏太宗十思疏.toml
Normal file
0
nucleon_todo/谏太宗十思疏.toml
Normal file
0
nucleon_todo/贺新郎.toml
Normal file
0
nucleon_todo/贺新郎.toml
Normal file
0
nucleon_todo/赤壁赋.toml
Normal file
0
nucleon_todo/赤壁赋.toml
Normal file
0
nucleon_todo/过秦论.toml
Normal file
0
nucleon_todo/过秦论.toml
Normal file
0
nucleon_todo/锦瑟.toml
Normal file
0
nucleon_todo/锦瑟.toml
Normal file
0
nucleon_todo/长亭送别.toml
Normal file
0
nucleon_todo/长亭送别.toml
Normal file
0
nucleon_todo/阿房宫赋.toml
Normal file
0
nucleon_todo/阿房宫赋.toml
Normal file
0
nucleon_todo/青玉案.toml
Normal file
0
nucleon_todo/青玉案.toml
Normal file
0
nucleon_todo/静女.toml
Normal file
0
nucleon_todo/静女.toml
Normal file
0
nucleon_todo/项脊轩志.toml
Normal file
0
nucleon_todo/项脊轩志.toml
Normal file
0
nucleon_todo/鹊桥仙.toml
Normal file
0
nucleon_todo/鹊桥仙.toml
Normal file
@@ -48,6 +48,7 @@ class Electron:
|
|||||||
Args:
|
Args:
|
||||||
quality (int): 记忆保留率量化参数
|
quality (int): 记忆保留率量化参数
|
||||||
"""
|
"""
|
||||||
|
print(f"REVISOR: {quality}, {is_new_activation}")
|
||||||
if quality == -1:
|
if quality == -1:
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
@@ -21,8 +21,8 @@ def proc_file(path: Path):
|
|||||||
c = 0
|
c = 0
|
||||||
for i in nu.nucleons:
|
for i in nu.nucleons:
|
||||||
c += 1
|
c += 1
|
||||||
print(f"预缓存 [{nu.name}] ({c}/{len(nu)}): {i['content']}")
|
print(f"预缓存 [{nu.name}] ({c}/{len(nu)}): {i['content'].replace('/', '')}")
|
||||||
precache(i['content'])
|
precache(i['content'].replace('/', ''))
|
||||||
|
|
||||||
|
|
||||||
def walk(path_str: str):
|
def walk(path_str: str):
|
||||||
@@ -49,4 +49,4 @@ if __name__ == "__main__":
|
|||||||
walk("./nucleon")
|
walk("./nucleon")
|
||||||
elif choice == "C":
|
elif choice == "C":
|
||||||
shutil.rmtree("./cache/voice", ignore_errors=True)
|
shutil.rmtree("./cache/voice", ignore_errors=True)
|
||||||
print("缓存已清空")
|
print("缓存已清空")
|
22
puzzles.py
22
puzzles.py
@@ -108,14 +108,14 @@ class SelectionPuzzle(Puzzle):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.wording}\n正确答案: {', '.join(self.answer)}"
|
return f"{self.wording}\n正确答案: {', '.join(self.answer)}"
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
puz = SelectionPuzzle(
|
puz = SelectionPuzzle(
|
||||||
{"1+1": "2", "1+2": "3", "1+3": "4"},
|
{"1+1": "2", "1+2": "3", "1+3": "4"},
|
||||||
["2", "5", "0"],
|
["2", "5", "0"],
|
||||||
3,
|
3,
|
||||||
'求值: '
|
'求值: '
|
||||||
)
|
)
|
||||||
puz.refresh()
|
puz.refresh()
|
||||||
print(puz.wording)
|
print(puz.wording)
|
||||||
print(puz.answer)
|
print(puz.answer)
|
||||||
print(puz.options)
|
print(puz.options)
|
29
reactor.py
29
reactor.py
@@ -32,7 +32,6 @@ class Reactor():
|
|||||||
"""反应堆对象, 处理和分配一次文件记忆流程的资源与策略"""
|
"""反应堆对象, 处理和分配一次文件记忆流程的资源与策略"""
|
||||||
def __init__(self, nucleon_file: pt.NucleonUnion, electron_file: pt.ElectronUnion, screen, tasked_num):
|
def __init__(self, nucleon_file: pt.NucleonUnion, electron_file: pt.ElectronUnion, screen, tasked_num):
|
||||||
# 导入原子对象
|
# 导入原子对象
|
||||||
self.reported = set()
|
|
||||||
self.nucleon_file = nucleon_file
|
self.nucleon_file = nucleon_file
|
||||||
self.electron_file = electron_file
|
self.electron_file = electron_file
|
||||||
self.tasked_num = tasked_num
|
self.tasked_num = tasked_num
|
||||||
@@ -41,6 +40,7 @@ class Reactor():
|
|||||||
counter = self.tasked_num
|
counter = self.tasked_num
|
||||||
self.screen = screen
|
self.screen = screen
|
||||||
self.electron_dict = electron_file.electrons_dict
|
self.electron_dict = electron_file.electrons_dict
|
||||||
|
self.quality_dict = {}
|
||||||
def electron_dict_get_fallback(key) -> pt.Electron:
|
def electron_dict_get_fallback(key) -> pt.Electron:
|
||||||
value = self.electron_dict.get(key)
|
value = self.electron_dict.get(key)
|
||||||
# 如果值不存在,则设置默认值
|
# 如果值不存在,则设置默认值
|
||||||
@@ -71,7 +71,6 @@ class Reactor():
|
|||||||
self.procession: list
|
self.procession: list
|
||||||
self.failed: list
|
self.failed: list
|
||||||
self.round_title: str
|
self.round_title: str
|
||||||
self.reported: set
|
|
||||||
self.current_atom: typing.Tuple[pt.Electron, pt.Nucleon, dict]
|
self.current_atom: typing.Tuple[pt.Electron, pt.Nucleon, dict]
|
||||||
self.round_set = 0
|
self.round_set = 0
|
||||||
self.current_atom = pt.Atom.placeholder()
|
self.current_atom = pt.Atom.placeholder()
|
||||||
@@ -127,23 +126,25 @@ class Reactor():
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
|
self._deploy_report()
|
||||||
print("Progress saved")
|
print("Progress saved")
|
||||||
# self.nucleon_file.save()
|
# self.nucleon_file.save()
|
||||||
self.electron_file.save()
|
self.electron_file.save()
|
||||||
|
|
||||||
|
def _deploy_report(self):
|
||||||
|
"部署所有 _report"
|
||||||
|
for e, q in self.quality_dict.items():
|
||||||
|
if q == -1:
|
||||||
|
e.revisor(5, True)
|
||||||
|
continue
|
||||||
|
e.revisor(q)
|
||||||
def report(self, atom, quality):
|
def report(self, atom, quality):
|
||||||
"""
|
"向反应器和最低质量记录汇报"
|
||||||
0: 初次激活/通过
|
|
||||||
1: 不通过
|
|
||||||
"""
|
|
||||||
if atom in self.atoms_new:
|
if atom in self.atoms_new:
|
||||||
atom[0].revisor(quality, True)
|
self.quality_dict[atom[0]] = -1
|
||||||
return 0
|
print(self.quality_dict)
|
||||||
if atom[0] not in self.reported:
|
return
|
||||||
atom[0].revisor(quality)
|
self.quality_dict[atom[0]] = min(quality, self.quality_dict.get(atom[0], 5))
|
||||||
self.reported.add(atom[0])
|
|
||||||
if quality <= 3:
|
if quality <= 3:
|
||||||
self.failed.append(atom)
|
self.failed.append(atom)
|
||||||
return 1
|
print(self.quality_dict)
|
||||||
else:
|
|
||||||
return 0
|
|
Binary file not shown.
Before Width: | Height: | Size: 102 KiB |
Binary file not shown.
Before Width: | Height: | Size: 66 KiB |
BIN
readme_src/img1.png
Normal file
BIN
readme_src/img1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 120 KiB |
BIN
readme_src/img2.png
Normal file
BIN
readme_src/img2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 559 KiB |
BIN
readme_src/img3.png
Normal file
BIN
readme_src/img3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 177 KiB |
BIN
readme_src/img4.png
Normal file
BIN
readme_src/img4.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 161 KiB |
17
webshare/static/js/script.js
Normal file
17
webshare/static/js/script.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
function getStartUrl() {
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
const params = new URLSearchParams(url.search);
|
||||||
|
params.delete("delay");
|
||||||
|
return url.pathname + "?" + params.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function refresh() {
|
||||||
|
const ping_url = document.body.dataset.pingurl;
|
||||||
|
if (ping_url) {
|
||||||
|
await fetch(ping_url, {
|
||||||
|
method: "GET",
|
||||||
|
mode: "no-cors",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
window.location.href = getStartUrl();
|
||||||
|
}
|
@@ -4,6 +4,7 @@
|
|||||||
<link rel="stylesheet" href="{{ config.static.url }}css/xterm.css" />
|
<link rel="stylesheet" href="{{ config.static.url }}css/xterm.css" />
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto%20Mono"/>
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto%20Mono"/>
|
||||||
<script src="{{ config.static.url }}js/textual.js"></script>
|
<script src="{{ config.static.url }}js/textual.js"></script>
|
||||||
|
<script src="{{ config.static.url }}js/script.js"></script>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
background: #000000;
|
background: #000000;
|
||||||
@@ -99,24 +100,6 @@
|
|||||||
z-index: 5;
|
z-index: 5;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script>
|
|
||||||
function getStartUrl() {
|
|
||||||
const url = new URL(window.location.href);
|
|
||||||
const params = new URLSearchParams(url.search);
|
|
||||||
params.delete("delay");
|
|
||||||
return url.pathname + "?" + params.toString();
|
|
||||||
}
|
|
||||||
async function refresh() {
|
|
||||||
const ping_url = document.body.dataset.pingurl;
|
|
||||||
if (ping_url) {
|
|
||||||
await fetch(ping_url, {
|
|
||||||
method: "GET",
|
|
||||||
mode: "no-cors",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
window.location.href = getStartUrl();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</head>
|
</head>
|
||||||
<body data-pingurl="{{ ping_url }}">
|
<body data-pingurl="{{ ping_url }}">
|
||||||
<div class="dialog-container intro-dialog">
|
<div class="dialog-container intro-dialog">
|
||||||
@@ -145,4 +128,4 @@
|
|||||||
data-font-size="{{ font_size }}"
|
data-font-size="{{ font_size }}"
|
||||||
></div>
|
></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Reference in New Issue
Block a user