You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Curriculum_Design/src/typing_logic.py

175 lines
6.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

class TypingLogic:
def __init__(self, learning_content: str):
"""
初始化打字逻辑状态。。。。
- 存储学习材料
- 初始化当前索引为0
- 初始化错误计数为0
"""
self.learning_content = learning_content
self.current_index = 0
self.error_count = 0
self.total_chars = len(learning_content)
self.typed_chars = 0
def check_input(self, user_text: str) -> dict:
"""
检查用户输入与学习材料的匹配情况
- 逐字符比较逻辑
- 进度跟踪
- 准确率计算
- 返回字典包含:
* correct: 布尔值,当前输入是否正确
* expected: 字符串,当前期望的字符
* position: 整数,当前位置
* completed: 布尔值,是否完成
* accuracy: 浮点数,准确率
"""
# 保存当前索引用于返回
current_position = len(user_text)
# 临时保存原始的typed_chars值用于准确率计算
original_typed_chars = self.typed_chars
# 更新已输入字符数
self.typed_chars = len(user_text)
# 如果用户输入的字符数超过了学习材料的长度,截取到相同长度
if len(user_text) > self.total_chars:
user_text = user_text[:self.total_chars]
current_position = len(user_text)
# 检查当前输入是否正确
correct = True
expected_char = ''
if self.current_index < self.total_chars:
expected_char = self.learning_content[self.current_index]
if len(user_text) > self.current_index and user_text[self.current_index] != expected_char:
correct = False
else:
# 已经完成所有输入
# 恢复原始的typed_chars值用于准确率计算
accuracy = self._calculate_accuracy()
self.typed_chars = original_typed_chars
return {
"correct": True,
"expected": "",
"position": self.current_index,
"completed": True,
"accuracy": accuracy
}
# 检查是否完成
completed = current_position >= self.total_chars
# 计算准确率
accuracy = self._calculate_accuracy()
# 恢复原始的typed_chars值
self.typed_chars = original_typed_chars
return {
"correct": correct,
"expected": expected_char,
"position": current_position,
"completed": completed,
"accuracy": accuracy
}
def update_position(self, user_text: str):
"""
更新当前索引和错误计数
- 根据用户输入更新当前位置
- 计算并更新错误计数
"""
new_position = len(user_text)
# 计算新增的错误数
for i in range(self.current_index, min(new_position, self.total_chars)):
if user_text[i] != self.learning_content[i]:
self.error_count += 1
# 更新当前索引
self.current_index = new_position
def get_expected_text(self, length: int = 10) -> str:
"""
获取用户接下来应该输入的内容
- 返回从当前位置开始的一定长度文本如10个字符
- 处理文本结束情况
"""
start_pos = self.current_index
end_pos = min(start_pos + length, self.total_chars)
return self.learning_content[start_pos:end_pos]
def get_progress(self) -> dict:
"""
获取当前学习进度统计
- current: 整数,当前位置
- total: 整数,总长度
- percentage: 浮点数,完成百分比
- remaining: 整数,剩余字符数
"""
current = self.current_index
total = self.total_chars
percentage = (current / total * 100) if total > 0 else 0
remaining = max(0, total - current)
return {
"current": current,
"total": total,
"percentage": percentage,
"remaining": remaining
}
def reset(self, new_content: str = None):
"""
重置打字状态
- 重置当前索引为0
- 重置错误计数
- 如果提供了新内容,更新学习材料
"""
if new_content is not None:
self.learning_content = new_content
self.total_chars = len(new_content)
self.current_index = 0
self.error_count = 0
self.typed_chars = 0
def get_statistics(self) -> dict:
"""
获取打字统计信息
- total_chars: 整数,总字符数
- typed_chars: 整数,已输入字符数
- error_count: 整数,错误次数
- accuracy_rate: 浮点数,准确率
"""
return {
"total_chars": self.total_chars,
"typed_chars": self.typed_chars,
"error_count": self.error_count,
"accuracy_rate": self._calculate_accuracy()
}
def _calculate_accuracy(self) -> float:
"""
计算准确率
"""
# 防止递归的保护措施
if hasattr(self, '_calculating_accuracy') and self._calculating_accuracy:
return 0.0
if self.typed_chars == 0:
return 0.0
# 设置递归保护标志
self._calculating_accuracy = True
try:
# 准确率 = (已输入字符数 - 错误次数) / 已输入字符数
accuracy = (self.typed_chars - self.error_count) / self.typed_chars
return max(0.0, min(1.0, accuracy)) # 确保准确率在0.0到1.0之间
except (ZeroDivisionError, RecursionError):
return 0.0
finally:
# 清除递归保护标志
self._calculating_accuracy = False