2 #3

Merged
hnu202326010322 merged 5 commits from develop into main 5 months ago

@ -1,112 +1,113 @@
# main.py
from user_manager import UserManager, AccountType
from file_handler import FileHandler
from question_generator import QuestionGenerator, MathQuestion
def split_username_password(input_str: str) -> tuple[str, str]:
"""分割用户名和密码(支持用户名含空格)"""
parts = input_str.strip().split()
if len(parts) < 2:
return ("", "")
password = parts[-1]
username = " ".join(parts[:-1])
return (username, password)
def login_process(user_manager: UserManager) -> tuple[str, AccountType]:
"""登录流程,循环直到输入正确的用户名密码"""
while True:
input_str = input("请输入用户名和密码(空格分隔):")
username, password = split_username_password(input_str)
account_type = user_manager.verify_user(username, password)
if account_type != AccountType.INVALID:
print(f"登录成功!欢迎{username}")
print(f"当前选择为{user_manager.type_to_str(account_type)}出题")
return (username, account_type)
else:
print("请输入正确的用户名、密码")
def main():
user_manager = UserManager()
question_generator = QuestionGenerator()
while True:
# 登录流程
username, current_type = login_process(user_manager)
file_handler = FileHandler(username)
current_type_str = user_manager.type_to_str(current_type)
# 登录后操作循环
while True:
print(f"\n当前用户: {username}|当前难度: {current_type_str}")
print("1. 生成题目")
print("2. 切换难度级别")
print("3. 退出当前用户")
print("4. 退出程序")
choice = input("请选择操作(1-4): ").strip()
if choice == "1":
while True:
count_str = input("请输入生成题目数量(10-30): ").strip()
if count_str.isdigit():
question_count = int(count_str)
if 10 <= question_count <= 30:
# 生成题目(确保无重复)
print(f"正在生成{current_type_str}数学题目...")
generated_questions = []
while len(generated_questions) < question_count:
if current_type == AccountType.PRIMARY_SCHOOL:
content = question_generator._generate_primary_question()
elif current_type == AccountType.MIDDLE_SCHOOL:
content = question_generator._generate_middle_question()
else:
content = question_generator._generate_high_question()
new_question = MathQuestion(content, current_type)
if not file_handler.is_duplicate(new_question):
generated_questions.append(new_question)
# 保存题目到文件
save_success = file_handler.save_questions(generated_questions)
if save_success:
print(f"题目生成成功!共{question_count}题,已保存至{file_handler.user_dir}文件夹")
else:
print("题目保存失败,请重试")
break
else:
print("题目数量无效请输入10-30之间的整数")
else:
print("请输入有效的整数")
elif choice == "2":
while True:
print("1. 小学(+,-,*,/,括号)")
print("2. 初中(包含平方、开根号)")
print("3. 高中(包含三角函数)")
print("0. 返回主菜单")
level_choice = input("请选择难度级别: ").strip()
if level_choice.isdigit():
level = int(level_choice)
if level == 0:
break
new_type = user_manager.parse_type_choice(level)
if new_type != AccountType.INVALID:
current_type = new_type
current_type_str = user_manager.type_to_str(current_type)
print(f"已成功切换为{current_type_str}难度")
break
else:
print("请输入有效的选项")
else:
print("请输入有效的整数")
elif choice == "3":
print("退出当前用户")
break
elif choice == "4":
print("退出程序")
return
else:
print("请输入有效的选项(1-4)")
if __name__ == "__main__":
# main.py
from user_manager import UserManager, AccountType
from file_handler import FileHandler
from question_generator import QuestionGenerator, MathQuestion
def split_username_password(input_str: str) -> tuple[str, str]:
"""分割用户名和密码(支持用户名含空格)"""
parts = input_str.strip().split()
if len(parts) < 2:
return "", ""
password = parts[-1]
username = " ".join(parts[:-1])
return username, password
def log_in_process(user_manager: UserManager) -> tuple[str, AccountType]:
"""登录流程,循环直到输入正确的用户名密码"""
while True:
input_str = input("请输入用户名和密码(空格分隔):")
username, password = split_username_password(input_str)
account_type = user_manager.verify_user(username, password)
if account_type != AccountType.INVALID:
print(f"登录成功!欢迎{username}")
print(f"当前选择为{user_manager.type_to_str(account_type)}出题")
return username, account_type
else:
print("请输入正确的用户名、密码")
def handle_question_generation(question_generator, current_type, file_handler, user_manager):
"""处理题目生成逻辑新增user_manager参数"""
while True:
count_str = input(
f"准备生成{user_manager.type_to_str(current_type)}数学题目,请输入数量(10-30-1退出): "
).strip()
if count_str == "-1":
print("退出当前用户")
return True
if count_str.isdigit():
question_count = int(count_str)
if 10 <= question_count <= 30:
generated_questions = []
while len(generated_questions) < question_count:
content = question_generator.generate_question(current_type)
new_question = MathQuestion(content, current_type)
if not file_handler.is_duplicate(new_question):
generated_questions.append(new_question)
if file_handler.save_questions(generated_questions):
print(f"题目生成成功!共{question_count}题,已保存至{file_handler.user_dir}")
else:
print("题目保存失败,请重试")
return False
print("题目数量无效请输入10-30之间的整数")
else:
print("请输入有效的整数")
def handle_difficulty_switch(user_manager):
"""处理难度切换逻辑"""
while True:
print("1. 小学(+,-,*,/,括号)")
print("2. 初中(包含平方、开根号)")
print("3. 高中(包含三角函数)")
print("0. 返回主菜单")
level_choice = input("请选择难度级别: ").strip()
if level_choice.isdigit():
level = int(level_choice)
if level == 0:
return None
new_type = user_manager.parse_type_choice(level)
if new_type != AccountType.INVALID:
print(f"已成功切换为{user_manager.type_to_str(new_type)}难度")
return new_type
print("请输入有效的选项")
def main():
user_manager = UserManager()
question_generator = QuestionGenerator()
while True:
username, current_type = log_in_process(user_manager)
file_handler = FileHandler(username)
while True:
print(f"\n当前用户: {username}|当前难度: {user_manager.type_to_str(current_type)}")
print("1. 生成题目")
print("2. 切换难度级别")
print("3. 退出当前用户")
print("4. 退出程序")
choice = input("请选择操作(1-4): ").strip()
if choice == "1":
# 调用时传入user_manager参数
if handle_question_generation(question_generator, current_type, file_handler, user_manager):
break
elif choice == "2":
new_type = handle_difficulty_switch(user_manager)
if new_type:
current_type = new_type
elif choice == "3":
print("退出当前用户")
break
elif choice == "4":
print("退出程序")
return
else:
print("请输入有效的选项(1-4)")
if __name__ == "__main__":
main()

@ -1,107 +1,105 @@
import random
from user_manager import AccountType
class MathQuestion:
"""题目类,包含题目内容和对应的难度类型"""
def __init__(self, content: str, question_type: AccountType):
self.content = content
self.type = question_type
def __eq__(self, other) -> bool:
"""重载==运算符,用于题目查重"""
if not isinstance(other, MathQuestion):
return False
return self.content == other.content and self.type == other.type
class QuestionGenerator:
def __init__(self):
random.seed() # 初始化随机种子
def generate_questions(self, count: int, question_type: AccountType) -> list[MathQuestion]:
"""
生成指定数量和难度的题目列表
:param count: 题目数量
:param question_type: 题目难度类型
:return: 题目对象列表
"""
questions = []
while len(questions) < count:
if question_type == AccountType.PRIMARY_SCHOOL:
content = self._generate_primary_question()
elif question_type == AccountType.MIDDLE_SCHOOL:
content = self._generate_middle_question()
elif question_type == AccountType.HIGH_SCHOOL:
content = self._generate_high_question()
else:
continue # 无效类型跳过
# 去重(避免生成完全相同的题目)
new_question = MathQuestion(content, question_type)
if new_question not in questions:
questions.append(new_question)
return questions
def _generate_random_num(self) -> int:
"""生成1-100之间的随机整数"""
return random.randint(1, 100)
def _generate_expression(self, op_count: int, ops: list[str]) -> str:
"""
生成包含指定数量操作数和运算符的表达式
:param op_count: 操作数数量1-5
:param ops: 可用运算符列表
:return: 表达式字符串
"""
if op_count < 1:
return ""
# 初始化第一个操作数
expr_parts = [str(self._generate_random_num())]
for _ in range(op_count - 1):
op = random.choice(ops)
# 除法确保除数不为0且能整除避免小数
if op == "/":
divisor = self._generate_random_num()
dividend = self._generate_random_num() * divisor
expr_parts.append(op)
expr_parts.append(str(divisor))
else:
expr_parts.append(op)
expr_parts.append(str(self._generate_random_num()))
return " ".join(expr_parts)
def _add_parentheses(self, expr: str) -> str:
"""30%概率为表达式添加括号"""
if random.random() < 0.3 and len(expr.split()) >= 3: # 至少包含一个运算符才加括号
return f"({expr})"
return expr
def _generate_primary_question(self) -> str:
"""生成小学题目(仅+、-、*、/和()"""
op_count = random.randint(1, 5) # 1-5个操作数
ops = ["+", "-", "*", "/"]
expr = self._generate_expression(op_count, ops)
return self._add_parentheses(expr)
def _generate_middle_question(self) -> str:
"""生成初中题目(包含平方或开根号,可含+、-、*、/和()"""
op_count = random.randint(1, 5)
ops = ["+", "-", "*", "/"]
expr = self._generate_expression(op_count, ops)
# 确保包含平方或开根号
func_choice = random.choice(["square", "sqrt"])
if func_choice == "square":
expr = self._add_parentheses(expr) + " ^ 2"
else:
expr = f"sqrt({self._add_parentheses(expr)})"
return expr
def _generate_high_question(self) -> str:
"""生成高中题目包含sin、cos、tan可含+、-、*、/和()"""
op_count = random.randint(1, 5)
ops = ["+", "-", "*", "/"]
expr = self._generate_expression(op_count, ops)
# 确保包含三角函数
trig_func = random.choice(["sin", "cos", "tan"])
expr = f"{trig_func}({self._add_parentheses(expr)})"
return expr
import random
from user_manager import AccountType
from typing import List
class MathQuestion:
"""题目类,包含题目内容和对应的难度类型"""
def __init__(self, content: str, question_type: AccountType):
self.content = content
self.type = question_type
def __eq__(self, other) -> bool:
"""重载==运算符,用于题目查重"""
if not isinstance(other, MathQuestion):
return False
return self.content == other.content and self.type == other.type
class QuestionGenerator:
def __init__(self):
random.seed() # 初始化随机种子
def generate_questions(self, count: int, question_type: AccountType) -> List[MathQuestion]:
"""生成指定数量和难度的题目列表(去重)"""
questions = []
seen = set()
while len(questions) < count:
content = self.generate_question(question_type)
new_question = MathQuestion(content, question_type)
if new_question not in questions:
questions.append(new_question)
return questions
def _generate_random_num(self) -> int:
"""生成1-100之间的随机整数"""
return random.randint(1, 100)
def _generate_expression(self, op_count: int, ops: list[str]) -> str:
"""
生成包含指定数量操作数和运算符的表达式
:param op_count: 操作数数量1-5
:param ops: 可用运算符列表
:return: 表达式字符串
"""
if op_count < 1:
return ""
# 初始化第一个操作数
expr_parts = [str(self._generate_random_num())]
for _ in range(op_count - 1):
op = random.choice(ops)
# 除法确保除数不为0且能整除避免小数
if op == "/":
divisor = self._generate_random_num()
dividend = self._generate_random_num() * divisor
expr_parts.append(op)
expr_parts.append(str(divisor))
else:
expr_parts.append(op)
expr_parts.append(str(self._generate_random_num()))
return " ".join(expr_parts)
def _add_parentheses(self, expr: str) -> str:
"""30%概率为表达式添加括号"""
if random.random() < 0.3 and len(expr.split()) >= 3: # 至少包含一个运算符才加括号
return f"({expr})"
return expr
def _generate_primary_question(self) -> str:
"""生成小学题目(仅+、-、*、/和()"""
op_count = random.randint(1, 5) # 1-5个操作数
ops = ["+", "-", "*", "/"]
expr = self._generate_expression(op_count, ops)
return self._add_parentheses(expr)
def _generate_middle_question(self) -> str:
"""生成初中题目(包含平方或开根号,可含+、-、*、/和()"""
op_count = random.randint(1, 5)
ops = ["+", "-", "*", "/"]
expr = self._generate_expression(op_count, ops)
# 确保包含平方或开根号
func_choice = random.choice(["square", "sqrt"])
if func_choice == "square":
expr = self._add_parentheses(expr) + " ^ 2"
else:
expr = f"sqrt({self._add_parentheses(expr)})"
return expr
def _generate_high_question(self) -> str:
"""生成高中题目包含sin、cos、tan可含+、-、*、/和()"""
op_count = random.randint(1, 5)
ops = ["+", "-", "*", "/"]
expr = self._generate_expression(op_count, ops)
# 确保包含三角函数
trig_func = random.choice(["sin", "cos", "tan"])
expr = f"{trig_func}({self._add_parentheses(expr)})"
return expr
# 新增公共接口方法,根据难度生成题目
def generate_question(self, account_type: AccountType) -> str:
if account_type == AccountType.PRIMARY_SCHOOL:
return self._generate_primary_question()
elif account_type == AccountType.MIDDLE_SCHOOL:
return self._generate_middle_question()
elif account_type == AccountType.HIGH_SCHOOL:
return self._generate_high_question()
else:
raise ValueError("无效的账户类型")
Loading…
Cancel
Save