You've already forked HeurAMS-Legacy
138 lines
5.1 KiB
Python
138 lines
5.1 KiB
Python
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("电子对象样例内容", {})
|