import heurams.services.timer as timer from heurams.context import config_var class Electron: """电子: 记忆分析元数据及算法""" algo = "SM-2" def __init__(self, ident: str, algodata: dict = {}): """初始化电子对象 (记忆数据) Args: ident: 算法的唯一标识符, 用于区分不同的算法实例, 使用 algodata[ident] 获取 algodata: 算法数据字典, 包含算法的各项参数和设置 """ self.algodata = algodata self.ident = ident if self.algo not in self.algodata.keys(): self.algodata[self.algo] = {} if algodata[self.algo] == {}: self._default_init() def _default_init(self): """默认初始化包装 """ defaults = { 'efactor': 2.5, # 易度系数, 越大越简单, 最大为5 'real_rept': 0, # (实际)重复次数 'rept': 0, # (有效)重复次数 'interval': 0, # 最佳间隔 'last_date': 0, # 上一次复习的时间戳 'next_date': 0, # 将要复习的时间戳 'is_activated': 0, # 激活状态 # *NOTE: 此处"时间戳"是以天为单位的整数, 即 UNIX 时间戳除以一天的秒数取整 'last_modify': timer.get_timestamp() # 最后修改时间戳(此处是UNIX时间戳) } self.algodata[self.algo] = defaults def activate(self): """激活此电子 """ self.algodata[self.algo]['is_activated'] = 1 self.algodata[self.algo]['last_modify'] = timer.get_timestamp() def modify(self, var: str, value): """修改 algodata[algo] 中子字典数据 """ if var in self.algodata[self.algo]: self.algodata[self.algo][var] = value self.algodata[self.algo]['last_modify'] = timer.get_timestamp() else: print(f"警告: '{var}' 非已知元数据字段") def revisor(self, quality: int = 5, is_new_activation: bool = False): """SM-2 算法迭代决策机制实现 根据 quality(0 ~ 5) 进行参数迭代最佳间隔 quality 由主程序评估 Args: quality (int): 记忆保留率量化参数 """ print(f"REVISOR: {quality}, {is_new_activation}") if quality == -1: return -1 self.algodata[self.algo]['efactor'] = self.algodata[self.algo]['efactor'] + ( 0.1 - (5 - quality) * (0.08 + (5 - quality) * 0.02) ) self.algodata[self.algo]['efactor'] = max(1.3, self.algodata[self.algo]['efactor']) if quality < 3: # 若保留率低于 3,重置重复次数 self.algodata[self.algo]['rept'] = 0 self.algodata[self.algo]['interval'] = 0 # 设为0,以便下面重新计算 I(1) else: self.algodata[self.algo]['rept'] += 1 self.algodata[self.algo]['real_rept'] += 1 if is_new_activation: # 初次激活 self.algodata[self.algo]['rept'] = 0 self.algodata[self.algo]['efactor'] = 2.5 if self.algodata[self.algo]['rept'] == 0: # 刚被重置或初次激活后复习 self.algodata[self.algo]['interval'] = 1 # I(1) elif self.algodata[self.algo]['rept'] == 1: self.algodata[self.algo]['interval'] = 6 # I(2) 经验公式 else: self.algodata[self.algo]['interval'] = round( self.algodata[self.algo]['interval'] * self.algodata[self.algo]['efactor'] ) self.algodata[self.algo]['last_date'] = timer.get_daystamp() self.algodata[self.algo]['next_date'] = timer.get_daystamp() + self.algodata[self.algo]['interval'] self.algodata[self.algo]['last_modify'] = timer.get_timestamp() def __str__(self): return ( f"记忆单元预览 \n" f"标识符: '{self.ident}' \n" f"易度系数: {self.algodata[self.algo]['efactor']:.2f} \n" f"已经重复的次数: {self.algodata[self.algo]['rept']} \n" f"下次间隔: {self.algodata[self.algo]['interval']} 天 \n" f"下次复习日期时间戳: {self.algodata[self.algo]['next_date']}" ) def __eq__(self, other): if self.ident == other.ident: return True return False def __hash__(self): return hash(self.ident) def __getitem__(self, key): if key == "ident": return self.ident if key in self.algodata[self.algo]: return self.algodata[self.algo][key] else: raise KeyError(f"Key '{key}' not found in algodata[self.algo].") def __setitem__(self, key, value): if key == "ident": raise AttributeError("ident should be readonly") self.algodata[self.algo][key] = value self.algodata[self.algo]['last_modify'] = timer.get_timestamp() def __len__(self): """仅返回当前算法的配置数量 """ return len(self.algodata[self.algo]) @staticmethod def placeholder(): """生成一个电子占位符 """ return Electron("电子对象样例内容", {})