170 lines
5.5 KiB
Python
170 lines
5.5 KiB
Python
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()) |