diff --git a/src/main.py b/src/main.py index 6416a16..38ba1d6 100644 --- a/src/main.py +++ b/src/main.py @@ -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() \ No newline at end of file diff --git a/src/question_generator.py b/src/question_generator.py index 10e7a86..64a42de 100644 --- a/src/question_generator.py +++ b/src/question_generator.py @@ -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 \ No newline at end of file +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("无效的账户类型") \ No newline at end of file