import pathlib import toml import time import auxiliary as aux class Electron(): """电子: 记忆分析元数据及算法""" algorithm = "SM-2" # 暂时使用 SM-2 算法进行记忆拟合, 考虑 SM-15 替代 """ content = "" # 内容 efactor = 2.5 # 易度系数, 越大越简单, 最大为5 real_rept = 0 # (实际)重复次数 rept = 0 # (有效)重复次数 interval = 0 # 最佳间隔 last_date = 0 # 上一次复习的时间戳 next_date = 0 # 将要复习的时间戳 is_activated = 0 # 激活状态 # *NOTE: 此处"时间戳"是以天为单位的整数, 即 UNIX 时间戳除以一天的秒数取整 last_modify = 0 # 最后修改时间戳(此处是UNIX时间戳) """ def __init__(self, content: str, data: dict): self.content = content self.efactor = data.get('efactor', 2.5) self.real_rept = data.get('real_rept', 0) self.rept = data.get('rept', 0) self.interval = data.get('interval', 0) self.last_date = data.get('last_date', 0) self.next_date = data.get('next_date', 0) self.is_activated = data.get('is_activated', 0) self.last_modify = time.time() def activate(self): self.is_activated = 1 def modify(self, var: str, value): setattr(self, var, value) self.last_modify = time.time() def export_data(self): return { 'efactor': self.efactor, 'real_rept': self.real_rept, 'rept': self.rept, 'interval': self.interval, 'last_date': self.last_date, 'next_date': self.next_date, 'is_activated': self.is_activated } def revisor(self, quality): """SM-2 算法迭代决策机制实现 根据 quality(0 ~ 5) 进行参数迭代最佳间隔 quality 由主程序评估 Args: quality (int): 记忆保留率量化参数 """ 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 = aux.get_daystamp() + 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) @staticmethod def placeholder(): return Electron("电子对象样例内容", {}) @staticmethod def import_from_file(path: pathlib.Path): name = path.name.replace(path.suffix, "") with open(path, 'r') as f: all = toml.load(f) lst = list() for i in all.keys(): lst.append(Electron(i, all[i])) return (name, lst) @staticmethod def save_to_file(electron_dictized, path: pathlib.Path): with open(path, 'w') as f: toml.dump(electron_dictized, f) class Nucleon(): """核子: 材料元数据""" def __init__(self, content: str, data: dict): self.metadata = data self.content = content @staticmethod def import_from_file(path: pathlib.Path): name = path.name.replace(path.suffix, "") with open(path, 'r') as f: all = toml.load(f) lst = list() for i in all.keys(): lst.append(Nucleon(i, all[i])) return (name, lst) @staticmethod def save_to_file(nucleon_dictized, path: pathlib.Path): with open(path, 'w') as f: toml.dump(nucleon_dictized, f) @staticmethod def placeholder(): return Nucleon("核子对象样例内容", {}) 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): dictobj = {i.content: i.export_data() for i in self.datalist} print(dictobj) if self.type_ == "nucleon": Nucleon.save_to_file(dictobj, self.path) if self.type_ == "electron": Electron.save_to_file(dictobj, 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) class Atom(): @staticmethod def placeholder(): return (Electron.placeholder(), Nucleon.placeholder())