开发者

使用Python实现小学生算术自动出题工具

开发者 https://www.devze.com 2025-05-14 09:20 出处:网络 作者: 花小姐的春天
目录效果图实现思路1. 题目生成器2. 把题目生成Word3. GUI界面(假装专业的操作面板)昨天加完班刚躺下,手机突然"叮咚"一声。我眯着眼划开屏幕,嫂子发来条59秒的语音:"花花啊,你侄子数学最近不好
目录
  • 效果图
  • 实现思路
    • 1. 题目生成器
    • 2. 把题目生成Word
    • 3. GUI界面(假装专业的操作面板)

昨天加完班刚躺下,手机突然"叮咚"一声。我眯着眼划开屏幕,嫂子发来条59秒的语音:"花花啊,你侄子数学最近不好,计算题总出错,想多练练,但每天手写出题太费时间!从网上找的题目好多都要收费,我手抄了三天实在扛不住了,你们程序员不是会搞什么自动化吗?帮帮忙啊!"

为了挽救嫂子的家庭幸福,也出于对小侄子的关心,我回复了一个ok,抄起电脑就开始噼里啪啦敲代码...

代码比想象中简单的多

效果图

先给大伙看最终效果:

使用Python实现小学生算术自动出题工具

使用Python实现小学生算术自动出题工具

使用Python实现小学生算术自动出题工具

支持四种题型自由组合,自动去重,还能导出带答案的Word文档,直接打印就能用。

实现思路

核心代码其实就三大块:

1. 题目生成器

def generate_question(selected_operations):
    operators = selected_operations
    num1 = random.randint(1, 100)
    num2 = random.randint(1, 100)
    operator = random.choice(operators)
    
    # 确保生成的题目符合条件
    if operator == '+':
        return num1, operator, num2, num1 + num2
    elif operator == '-':
        while num2 > num1:  # 保证减法不为负数
            num1 ,num2 = num2 ,num1
        return num1, operator, num2, num1 - num2
    elif operator == '*':
        return num1, '', num2, num1 * num2
    elif operator == '/':
        num1 = random.randintpython(1, 100) * random.randint(1, 10)  # 确保能整除
        num2 = random.randint(1, 10)
        return num1, '', num2, num1 // num2

# 生成题目的函数
def generate_questions(quantity, selected_operations):
    questions = []
    answers = []
    
    for i in range(quantity):
        num1, operator, num2, answer = generate_question(selected_operations)
        question = f"{num1} {operator} {num2} = "
        questions.append(question)
        answers.append(f"{question} {answer}")
    print(len(questions),len(answers))
    return questions, answers

重点细节:

  • 减法自动交换数字避免负数(小学生还没学负数呢!)
  • 除法确保能整除

2. 把题目生成Word

from docx import Document
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.section import WD_SECTION_START

def save_to_word(questions, answers, filename="小学生计算题.docx"):
    doc = Document()
    
    # 添加数学题目标题
    title = doc.add_heading('数学题目', 0)
    title.alignment = WD_ALIGN_PARAGRAPH.CENTER

    # 插入"连续分节",设置4栏,题目区域都属于这一节
    section = doc.add_section(start_type=WD_SECTION_START.CONTINUOUS)
    sectPr = section._sectPr
    cols = sectPr.xpath('./w:cols')[0]
    cols.set('num', '4')

    # 添加题目内容
    for q in questions:
        p = doc.add_paragraph(q)
        p.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.LEFT  # 左对齐

    # 插入一个新的页面,用新节保持正确格式
    doc.add_page_break()

    # 添加答案标题
    answer_title = doc.add_heading('答案', 0)
    answer_title.alignment = WD_ALIGN_PARAGRAPH.CENTER

    # 插入新的"连续分节",设置4栏,答案区域也属于这一节
    section = doc.add_section(start_type=WD_SECTION_START.CONTINUOUS)
    sectPr = section._sectPr
    cols = sectPr.xpath('./w:cols')[0]
    cols.set('num', '4')

    # 添加答案内容
    for a in answers:
        p = doc.add_paragraph(a)
        p.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.LEFT

    doc.save(filen编程ame)

为了给嫂子节省打印前,这里用了Word的分栏功能,一行四道题目。

3. GUI界面(假装专业的操作面板)

import tkinter as tk
from tkinter import messagebox

# GUI界面
def on_generate():
    try:
        quantity = int(entry_quantity.get())
        selected_operations = []
        
        if var_add.get():
            selected_operations.append('+')
        if var_sub.get():
            selected_operations.append('-')
        if var_mul.get():
            selected_operations.append('*')
        if var_div.get():
            selected_operations.append('/')
        
        if not selected_operations:
            selected_operations = 'All'
  编程客栈      
        questions, answers = generate_questions(quantity, selected_operations)
        save_to_word(questions, answers)
        
    except ValueError:
        messagebox.showerror("编程输入错误", "请输入有效的题目数量")

# 创建主窗口
root = tk.Tk()
root.title("小学生出题工具")
root.geometry("400x350")  
root.config(bg="#f5f5f5")  

label_quantity = tk.Label(root, text="请输入题目数量:", font=("微软雅黑", 12), bg="#f5f5f5")
label_quantity.grid(row=0, column=0, padx=20, pady=10, sticky="w")

entry_quantity = tk.Entry(root, font=("微软雅黑", 12), width=15)
entry_quantity.insert(0, "100")
entry_quantity.grid(row=0, column=1, padx=20, pady=10)

label_operations = tk.Label(root, text="请选择题目类型:", font=("微软雅黑", 12), bg="#f5f5f5")
label_operations.grid(row=1, column=0, padx=20, pady=10, sticky="w")

var_add = tk.BooleanVar()
var_sub = tk.BooleanVar()
var_mul = tk.BooleanVar()
var_div = tk.BooleanVar()

check_add = tk.Checkbutton(root, text="加法", variable=var_add, font=("微软雅黑", 12))
check_add.grid(row=2, column=0, padx=20, sticky="w")

check_sub = tk.Checkbutton(root, text="减法", variable=var_sub, font=("微软雅黑", 12))
check_sub.grid(row=3, column=0, padx=20, sticky="w")

check_mul = tk.Checkbutton(root, text="乘法", variable=var_mul, font=("微软雅黑", 12))
check_mul.grid(row=4, column=0, padx=20, sticky="w")

check_div = tk.Checkbutton(root, text="除法", variable=var_div, font=("微软雅黑", 12))
check_div.grid(row=5, column=0, padx=20, sticky="w")

button_generate = tk.Button(root, text="生成题目", command=on_generate, font=("微软雅黑", 14), bg="#4CAF50", fg="white")
button_generate.grid(row=6, column=0, columnspan=2, pady=40)

root.mainloop()

设计心得:

  • grid布局比pack更适合这种规整的界面
  • 默认生成100道题目,小侄子看了更开心

没想到栽在这些小细节上

  • 侄子说除不尽的计算题看不懂
  • 减法为什么有负数,我们还没学负数
  • 乘号写成*,除号写成/结果被侄子吐槽"和作业本长得不一样

最绝的是加了个一键导出答案,嫂子现在每天把题目和答案分开打印,侄子做完自己核对,彻底js解放家长!

到此这篇关于使用python实现小学生算术自动出题工具的文章就介绍到这了,更多相关Python自动出题工具内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号