This commit is contained in:
2025-10-26 11:33:08 +08:00
parent 809a6dbe75
commit 98f225efe4
13 changed files with 95 additions and 57 deletions

2
.gitignore vendored
View File

@@ -10,6 +10,7 @@ electron/test.toml
*.egg-info/ *.egg-info/
build/ build/
dist/ dist/
old/
# Project specific directories # Project specific directories
# config/ # config/
@@ -70,6 +71,7 @@ coverage.xml
.hypothesis/ .hypothesis/
.pytest_cache/ .pytest_cache/
cover/ cover/
.claude/
# Translations # Translations
*.mo *.mo

View File

@@ -23,11 +23,11 @@ def list_algorithms() -> list[str]:
return list(_algorithms.keys()) return list(_algorithms.keys())
# 导入注册 # 导入注册
from . import supermemo2 from . import sm2
register_algorithm( register_algorithm(
algo_name=supermemo2.algo_name, algo_name=sm2.algo_name,
defaults=supermemo2.defaults, defaults=sm2.defaults,
revisor=supermemo2.revisor revisor=sm2.revisor
) )
__all__ = ['get_algorithm', 'list_algorithms', 'register_algorithm', 'AlgorithmConfig'] __all__ = ['get_algorithm', 'list_algorithms', 'register_algorithm', 'AlgorithmConfig']

View File

@@ -0,0 +1 @@
# FSRS 算法模块, 尚未就绪

View File

@@ -1,7 +1,7 @@
import heurams.services.timer as timer import heurams.services.timer as timer
from typing import TypedDict from typing import TypedDict
algo_name = "supermemo2" algo_name = "SM-2"
class AlgodataDict(TypedDict): class AlgodataDict(TypedDict):
efactor: float efactor: float

View File

@@ -1,4 +1,5 @@
from .electron import Electron from .electron import Electron
from .nucleon import Nucleon from .nucleon import Nucleon
from .orbital import Orbital
from .atom import Atom from .atom import Atom
from .probe import probe_all, probe_by_filename from .probe import probe_all, probe_by_filename

View File

@@ -1,5 +1,6 @@
from .electron import Electron from .electron import Electron
from .nucleon import Nucleon from .nucleon import Nucleon
from .orbital import Orbital
from typing import TypedDict from typing import TypedDict
import pathlib import pathlib
import typing import typing
@@ -13,7 +14,7 @@ class AtomRegister(TypedDict):
electron: Electron electron: Electron
electron_path: pathlib.Path electron_path: pathlib.Path
electron_fmt: str electron_fmt: str
orbital: dict orbital: Orbital
orbital_path: pathlib.Path orbital_path: pathlib.Path
orbital_fmt: str orbital_fmt: str
@@ -26,8 +27,6 @@ class Atom():
以及关联路径 以及关联路径
""" """
def __init__(self, ident = ""): def __init__(self, ident = ""):
self.ident = ident self.ident = ident
self.register: AtomRegister = { # type: ignore self.register: AtomRegister = { # type: ignore

View File

@@ -0,0 +1,18 @@
from typing import TypedDict
class Orbital(TypedDict):
quick_view: list
recognition: list
final_review: list
puzzle_config: dict
"""一份示例
["__metadata__.orbital"] # 内置的推荐学习方案
quick_review = [["cloze", 1], ["mcq", 0.5], ["recognition", 1]]
recognition = [["recognition", 1]]
final_review = [["cloze", 0.7], ["mcq", 0.7], ["recognition", 1]]
["__metadata__.orbital.puzzle_config"]
cloze = { from = "content"}
mcq = { from = "keyword_note" }
"""

View File

@@ -1,2 +1,18 @@
# base.py
class BasePuzzle: class BasePuzzle:
pass """谜题基类"""
def refresh(self):
"""刷新谜题, 子类必须实现"""
raise NotImplementedError("谜题对象没有实现 refresh 方法")
def __str__(self):
"""字符串表示, 子类应该实现"""
return f"谜题: {type(self).__name__}"
@classmethod
def register(cls, name: str = None): # type: ignore
"""谜题注册装饰器"""
from registry import registry
puzzle_name = name or cls.__name__
return registry.register(puzzle_name, cls)

View File

@@ -1,15 +1,10 @@
# mcq.py
from base import BasePuzzle from base import BasePuzzle
import random import random
@BasePuzzle.register("multiple_choice")
class MCQPuzzle(BasePuzzle): class MCQPuzzle(BasePuzzle):
"""选择题谜题生成器 """选择题谜题生成器"""
Args:
mapping: 正确选项映射 {问题: 答案}
jammer: 干扰项列表
max_riddles_num: 最大生成谜题数 (默认2个)
prefix: 问题前缀
"""
def __init__( def __init__(
self, self,

View File

@@ -0,0 +1,31 @@
# registry.py
from typing import Dict, Type, Any
from base import BasePuzzle
class PuzzleRegistry:
"""谜题注册表"""
def __init__(self):
self._puzzles: Dict[str, Type[BasePuzzle]] = {}
def register(self, name: str, puzzle_class: Type[BasePuzzle]):
"""注册谜题类"""
self._puzzles[name] = puzzle_class
return puzzle_class
def create(self, name: str, **kwargs) -> BasePuzzle:
"""创建谜题实例"""
if name not in self._puzzles:
raise ValueError(f"未知的谜题类型: {name}")
return self._puzzles[name](**kwargs)
def list_available(self) -> list:
"""获取可用的谜题类型列表"""
return list(self._puzzles.keys())
def get_class(self, name: str) -> Type[BasePuzzle]:
"""获取谜题类"""
return self._puzzles.get(name) # type: ignore
# 全局注册表实例
registry = PuzzleRegistry()

View File

@@ -1,32 +0,0 @@
# 单个原子处理器
import heurams.kernel.particles as pt
import typing
class Apparatus():
"""反应器对象, 决策一个原子的不同记忆方式, 并反馈到布局"""
def __init__(self, screen, reactor, atom, is_review = 0):
self.electron: pt.Electron = atom[0]
self.nucleon: pt.Nucleon = atom[1]
self.positron: dict = atom[2]
self.testdata = self.positron["testdata"]
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, reactor, atom))
return
for i in self.positron["testdata"].keys():
if i == "additional_inf":
continue
if i == "fill_blank_test": # 加深
self.procession.append(comps.registry[i](screen, reactor, atom))
# self.procession.append(comps.registry[i](screen, reactor, atom))
self.procession.append(comps.registry[i](screen, reactor, atom))
# self.procession.reverse()
random.shuffle(self.procession)
if self.positron["is_new_activation"] == 0:
self.procession.append(comps.registry['recognition'](screen, reactor, atom))
if is_review == 1:
self.procession = [self.procession[-2], self.procession[-1]]
def iterator(self):
yield from self.procession

View File

@@ -3,15 +3,15 @@
import heurams.kernel.particles as pt import heurams.kernel.particles as pt
import heurams.services.timer as timer import heurams.services.timer as timer
from typing import Tuple from typing import Tuple
from .apparatus import Apparatus
class Core(): class Procession():
"""堆芯: 记忆流程核心状态机""" """队列: 记忆流程核心状态机"""
def __init__(self, atoms: list, stage = ""): def __init__(self, atoms: list, phase: str = ""):
self.atoms = atoms self.atoms = atoms
self.queue = atoms.copy() self.queue = atoms.copy()
self.current_atom = atoms[0] self.current_atom = atoms[0]
self.cursor = 0 self.cursor = 0
self.phase = phase
def forward(self, step = 1): def forward(self, step = 1):
self.cursor += step self.cursor += step
@@ -21,8 +21,11 @@ class Core():
except IndexError: except IndexError:
return 0 return 0
def append(self, atom): def append(self, atom = None):
if atom == None:
self.queue.append(self.current_atom) self.queue.append(self.current_atom)
else:
self.queue.append(atom)
def __len__(self): def __len__(self):
return (len(self.queue) - self.cursor) return (len(self.queue) - self.cursor)
@@ -32,9 +35,13 @@ class Core():
class Fission(): class Fission():
"""裂变器: 单原子调度展开器""" """裂变器: 单原子调度展开器"""
def __init__(self, atom: pt.Atom): def __init__(self, atom: pt.Atom, stage = ""):
self.atom = atom self.atom = atom
atom.register["orbital"] atom.register["orbital"]["puzzle_config"]
class Phaser():
"""移相器: 全局调度阶段管理器"""
class Reactork(): class Reactork():
"""反应堆对象, 处理和分配一次文件记忆流程的资源与策略""" """反应堆对象, 处理和分配一次文件记忆流程的资源与策略"""