#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 数学题目生成器 生成小学、初中、高中的数学选择题 """ import random import math class QuestionGenerator: """数学题目生成器""" def __init__(self): self.generated_questions = set() # 用于避免重复题目 def generate_questions(self, level, count): """生成指定数量和难度的题目""" questions = [] self.generated_questions.clear() for _ in range(count): question = self._generate_single_question(level) # 确保题目不重复 while str(question) in self.generated_questions: question = self._generate_single_question(level) self.generated_questions.add(str(question)) questions.append(question) return questions def _generate_single_question(self, level): """生成单个题目""" if level == "小学": return self._generate_primary_question() elif level == "初中": return self._generate_middle_question() elif level == "高中": return self._generate_high_question() else: raise ValueError("不支持的学段") def _generate_primary_question(self): """生成小学题目""" question_types = [ self._basic_arithmetic, self._fraction_question, self._decimal_question, self._geometry_question, self._word_problem ] return random.choice(question_types)() def _generate_middle_question(self): """生成初中题目""" question_types = [ self._algebra_question, self._geometry_advanced, self._function_question, self._equation_question, self._statistics_question ] return random.choice(question_types)() def _generate_high_question(self): """生成高中题目""" question_types = [ self._trigonometry_question, self._calculus_question, self._complex_number_question, self._sequence_question, self._probability_question ] return random.choice(question_types)() def _basic_arithmetic(self): """基础四则运算""" operations = ['+', '-', '*', '/'] op = random.choice(operations) if op == '+': a, b = random.randint(1, 100), random.randint(1, 100) answer = a + b question = f"{a} + {b} = ?" elif op == '-': a, b = random.randint(50, 100), random.randint(1, 50) answer = a - b question = f"{a} - {b} = ?" elif op == '*': a, b = random.randint(1, 12), random.randint(1, 12) answer = a * b question = f"{a} × {b} = ?" else: # division b = random.randint(2, 12) answer = random.randint(1, 12) a = b * answer question = f"{a} ÷ {b} = ?" # 生成错误选项 options = [answer] while len(options) < 4: wrong = answer + random.randint(-10, 10) if wrong != answer and wrong > 0 and wrong not in options: options.append(wrong) random.shuffle(options) correct_index = options.index(answer) return { 'question': question, 'options': options, 'correct_answer': correct_index, 'level': '小学' } def _fraction_question(self): """分数题目""" # 简单的分数加法 a1, b1 = random.randint(1, 5), random.randint(2, 8) a2, b2 = random.randint(1, 5), random.randint(2, 8) # 确保分母相同 b1 = b2 = random.randint(2, 8) question = f"{a1}/{b1} + {a2}/{b2} = ?" # 计算答案 numerator = a1 + a2 denominator = b1 # 简化分数 gcd_val = math.gcd(numerator, denominator) answer_num = numerator // gcd_val answer_den = denominator // gcd_val if answer_den == 1: answer = answer_num else: answer = f"{answer_num}/{answer_den}" # 生成选项 options = [answer] while len(options) < 4: if isinstance(answer, int): wrong = answer + random.randint(-2, 2) if wrong != answer and wrong > 0: options.append(wrong) else: wrong_num = answer_num + random.randint(-2, 2) wrong_den = answer_den + random.randint(-1, 1) if wrong_den <= 0: wrong_den = answer_den if wrong_num > 0: options.append(f"{wrong_num}/{wrong_den}") random.shuffle(options) correct_index = options.index(answer) return { 'question': question, 'options': options, 'correct_answer': correct_index, 'level': '小学' } def _decimal_question(self): """小数题目""" a = round(random.uniform(1, 10), 1) b = round(random.uniform(1, 10), 1) question = f"{a} + {b} = ?" answer = round(a + b, 1) options = [answer] while len(options) < 4: wrong = round(answer + random.uniform(-2, 2), 1) if wrong != answer and wrong > 0 and wrong not in options: options.append(wrong) random.shuffle(options) correct_index = options.index(answer) return { 'question': question, 'options': options, 'correct_answer': correct_index, 'level': '小学' } def _geometry_question(self): """几何题目""" shapes = ['正方形', '长方形', '圆形', '三角形'] shape = random.choice(shapes) if shape == '正方形': side = random.randint(2, 10) question = f"边长为{side}的正方形的面积是?" answer = side * side elif shape == '长方形': length = random.randint(3, 10) width = random.randint(2, 8) question = f"长为{length},宽为{width}的长方形的面积是?" answer = length * width elif shape == '圆形': radius = random.randint(2, 8) question = f"半径为{radius}的圆的面积是?(π取3.14)" answer = round(3.14 * radius * radius, 2) else: # 三角形 base = random.randint(3, 10) height = random.randint(2, 8) question = f"底为{base},高为{height}的三角形的面积是?" answer = base * height // 2 options = [answer] while len(options) < 4: wrong = answer + random.randint(-5, 5) if wrong != answer and wrong > 0 and wrong not in options: options.append(wrong) random.shuffle(options) correct_index = options.index(answer) return { 'question': question, 'options': options, 'correct_answer': correct_index, 'level': '小学' } def _word_problem(self): """应用题""" problems = [ ("小明有{}个苹果,吃了{}个,还剩多少个?", lambda x, y: x - y), ("小红有{}元钱,买书花了{}元,还剩多少元?", lambda x, y: x - y), ("班级有{}个学生,又来了{}个新同学,现在有多少个学生?", lambda x, y: x + y), ("一盒铅笔有{}支,{}盒铅笔一共有多少支?", lambda x, y: x * y) ] problem, func = random.choice(problems) a = random.randint(1, 20) b = random.randint(1, 10) question = problem.format(a, b) answer = func(a, b) options = [answer] while len(options) < 4: wrong = answer + random.randint(-3, 3) if wrong != answer and wrong > 0 and wrong not in options: options.append(wrong) random.shuffle(options) correct_index = options.index(answer) return { 'question': question, 'options': options, 'correct_answer': correct_index, 'level': '小学' } def _algebra_question(self): """代数题目""" x = random.randint(1, 10) a = random.randint(2, 10) b = random.randint(1, 20) question = f"解方程:{a}x + {b} = {a*x + b}" answer = x options = [answer] while len(options) < 4: wrong = answer + random.randint(-3, 3) if wrong != answer and wrong > 0 and wrong not in options: options.append(wrong) random.shuffle(options) correct_index = options.index(answer) return { 'question': question, 'options': options, 'correct_answer': correct_index, 'level': '初中' } def _geometry_advanced(self): """高级几何题目""" # 勾股定理 a = random.randint(3, 8) b = random.randint(3, 8) c = round(math.sqrt(a*a + b*b), 2) question = f"直角三角形的两条直角边分别为{a}和{b},斜边长为?" answer = c options = [answer] while len(options) < 4: wrong = round(c + random.uniform(-2, 2), 2) if wrong != answer and wrong > 0 and wrong not in options: options.append(wrong) random.shuffle(options) correct_index = options.index(answer) return { 'question': question, 'options': options, 'correct_answer': correct_index, 'level': '初中' } def _function_question(self): """函数题目""" a = random.randint(1, 5) b = random.randint(1, 10) x = random.randint(1, 10) question = f"函数f(x) = {a}x + {b},求f({x})的值" answer = a * x + b options = [answer] while len(options) < 4: wrong = answer + random.randint(-5, 5) if wrong != answer and wrong not in options: options.append(wrong) random.shuffle(options) correct_index = options.index(answer) return { 'question': question, 'options': options, 'correct_answer': correct_index, 'level': '初中' } def _equation_question(self): """方程题目""" x = random.randint(1, 10) a = random.randint(2, 5) b = random.randint(1, 10) question = f"解方程:{a}x - {b} = {a*x - b}" answer = x options = [answer] while len(options) < 4: wrong = answer + random.randint(-3, 3) if wrong != answer and wrong not in options: options.append(wrong) random.shuffle(options) correct_index = options.index(answer) return { 'question': question, 'options': options, 'correct_answer': correct_index, 'level': '初中' } def _statistics_question(self): """统计题目""" numbers = [random.randint(1, 20) for _ in range(5)] question = f"数据{numbers}的中位数是?" sorted_nums = sorted(numbers) answer = sorted_nums[2] # 中位数 options = [answer] while len(options) < 4: wrong = answer + random.randint(-3, 3) if wrong != answer and wrong > 0 and wrong not in options: options.append(wrong) random.shuffle(options) correct_index = options.index(answer) return { 'question': question, 'options': options, 'correct_answer': correct_index, 'level': '初中' } def _trigonometry_question(self): """三角函数题目""" angle = random.choice([30, 45, 60]) question = f"sin({angle}°) = ?" if angle == 30: answer = "1/2" elif angle == 45: answer = "√2/2" else: # 60 answer = "√3/2" options = [answer, "1/2", "√2/2", "√3/2"] options = list(set(options)) # 去重 while len(options) < 4: options.append(f"{random.randint(1,3)}/{random.randint(2,4)}") random.shuffle(options) correct_index = options.index(answer) return { 'question': question, 'options': options, 'correct_answer': correct_index, 'level': '高中' } def _calculus_question(self): """微积分题目""" # 简单的导数 a = random.randint(1, 5) b = random.randint(1, 10) question = f"函数f(x) = {a}x² + {b}x的导数是?" answer = f"{2*a}x + {b}" options = [answer] while len(options) < 4: wrong_a = random.randint(1, 5) wrong_b = random.randint(1, 10) if f"{wrong_a}x + {wrong_b}" != answer: options.append(f"{wrong_a}x + {wrong_b}") random.shuffle(options) correct_index = options.index(answer) return { 'question': question, 'options': options, 'correct_answer': correct_index, 'level': '高中' } def _complex_number_question(self): """复数题目""" a = random.randint(1, 5) b = random.randint(1, 5) question = f"复数{a} + {b}i的模长是?" answer = round(math.sqrt(a*a + b*b), 2) options = [answer] while len(options) < 4: wrong = round(answer + random.uniform(-2, 2), 2) if wrong != answer and wrong > 0 and wrong not in options: options.append(wrong) random.shuffle(options) correct_index = options.index(answer) return { 'question': question, 'options': options, 'correct_answer': correct_index, 'level': '高中' } def _sequence_question(self): """数列题目""" a1 = random.randint(1, 10) d = random.randint(1, 5) n = random.randint(3, 8) question = f"等差数列首项为{a1},公差为{d},第{n}项是?" answer = a1 + (n-1) * d options = [answer] while len(options) < 4: wrong = answer + random.randint(-5, 5) if wrong != answer and wrong not in options: options.append(wrong) random.shuffle(options) correct_index = options.index(answer) return { 'question': question, 'options': options, 'correct_answer': correct_index, 'level': '高中' } def _probability_question(self): """概率题目""" # 简单的概率计算 total = random.randint(10, 20) favorable = random.randint(1, total-1) question = f"袋子里有{total}个球,其中{favorable}个是红球,随机取出一个球是红球的概率是?" answer = f"{favorable}/{total}" options = [answer] while len(options) < 4: wrong_total = random.randint(5, 25) wrong_favorable = random.randint(1, wrong_total-1) wrong_answer = f"{wrong_favorable}/{wrong_total}" if wrong_answer != answer and wrong_answer not in options: options.append(wrong_answer) random.shuffle(options) correct_index = options.index(answer) return { 'question': question, 'options': options, 'correct_answer': correct_index, 'level': '高中' }