n sqrt or ^2, generate again
return self.generate((1, 5))
return result
class ExamGenerator3(ExamGenerator):
"""Exam generator for senior high school."""
def __init__(self) -> None:
super().__init__()
self.operators.extend(["^2", "sqrt", "sin", "cos", "tan"])
def generate(self, nums_range=(1, 5)) -> str:
op_num = random.randint(nums_range[0], nums_range[1])
op = random.choice(self.operators)
op1 = random.choice(self.operators[:4])
if op_num == 1:
if op in self.operators[4:] and random.random() < 0.66:
result = self.unary_op(op, str(random.randint(1, 100)))
else:
result = str(random.randint(1, 100))
elif op_num == 2:
left_op = self.generate((1, 1))
right_op = self.generate((1, 1))
if op in self.operators[4:]:
result = self.unary_op(op, f"{left_op}{op1}{right_op}")
else:
result = f"{left_op}{op}{right_op}"
else:
left_op = self.generate((1, op_num // 2))
right_op = self.generate((1, op_num - op_num // 2))
if op in self.operators[4:]:
result = self.unary_op(op, f"{left_op}{op1}{right_op}")
else:
result = f"{left_op}{op}{right_op}"
if (nums_range[1] == 5 and result.find("sin") == -1 and
result.find("cos") == -1 and result.find("tan") == -1): # If the result don't contain sin, cos or tan, generate again
return self.generate((1, 5))
return result
优点
1 抽象类和多态: ExamGenerator ? 是一个抽象基类,定义了一个抽象方法 generate ?,并且在子类中进行了实现。这利用了Python的多态性,允许不同子类提供不同的实现
缺点
-
部分魔法数值: 代码中出现了一些魔法数值,如 0.45、0.66 等,这些值没有明确的解释和注释,可能会导致代码的可读性和可维护性降低。最好将这些数值提取为常量,并提供相关注释。
-
文件操作错误处理不足: 代码中的文件操作没有足够的错误处理机制,如果文件无法创建或写入,代码会引发异常而无法处理。
-
生成题目的方法命名不一致: 不同级别的生成器子类中的 generate ? 方法签名不一致,这可能会导致混淆和错误。最好统一方法名。
-
未考虑边界情况: 代码中未考虑一些边界情况,如生成的数值范围、一元运算符的频率等,这可能导致生成的题目不够多样化或有问题。
main.py
#!/usr/bin/env python3.10.9
# -*- coding: utf-8 -*-
from account import Accounts
from examgenerator import ExamGenerator
from examgenerator import ExamGenerator1
from examgenerator import ExamGenerator2
from examgenerator import ExamGenerator3
def Exam_generator(grade: str) -> ExamGenerator:
"""Return the corresponding ExamGenerator according to the grade.
Arguments:
grade: The grade of the account.
Returns:
The corresponding ExamGenerator.
"""
if grade == "小学":
return ExamGenerator1()
elif grade == "初中":
return ExamGenerator2()
elif grade == "高中":
return ExamGenerator3()
else:
return ExamGenerator()
def main():
"""Main function of the program."""
accounts = Accounts()
account, grade = accounts.login()
exam_generator = Exam_generator(grade)
prob_num = 0
while True:
try:
prob_num = input(
f"准备生成{grade}数学题目,请输入生成题目数量(输入-1将退出当前用户重新登录,输入切换为XX可以切换身份): ")
if prob_num.startswith("切换为"):
if prob_num[3:] in ["小学", "初中", "高中"]:
grade = prob_num[3:]
exam_generator = Exam_generator(grade)
else:
print("请输入小学、初中和高中三个选项中的一个!")
elif int(prob_num) >= 10 and int(prob_num) <= 30:
exam_generator.save_probs(account, int(prob_num))
print(f"{grade}数学题目生成完毕,已保存到exams/{account}目录下!")
elif int(prob_num) == -1:
account, grade = accounts.lo
|