用python做一个试卷生成器,直接生成word文档

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

业务需求做一个企业内部的技能考核,那么就要做一个试卷来进行考试,题目录入进去之后,怎么把题目生成试卷呢?

因为这个是嵌入到erp系统中,题目也都是在原有系统的知识库中进行录入,所以只做为试卷生成的工具使用,用到了python-docx来进行word的操作,用fastapi作为接口处理,代码如下:

import uuid
import os
from fastapi import FastAPI
from fastapi.responses import FileResponse
from pydantic import BaseModel
from typing import List, Optional
from docx import Document
from docx.shared import Pt
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT

app = FastAPI()

TEMP_DIR = "temp_files"
os.makedirs(TEMP_DIR, exist_ok=True)

# 定义题目模型
class Question(BaseModel):
    question: str
    options: Optional[List[str]] = None
    answer: Optional[str] = None

# 定义题型配置模型
class QuestionSection(BaseModel):
    questions: List[Question]
    score_per_question: float
    total_score: float

# 定义请求模型
class ExamRequest(BaseModel):
    exam_title: str
    class_name: Optional[str] = "________"
    student_name: Optional[str] = "________"
    student_id: Optional[str] = "________"
    exam_duration: Optional[str] = "90分钟"
    total_score: Optional[str] = "100分"
    single_choice: Optional[QuestionSection] = None
    multiple_choice: Optional[QuestionSection] = None
    fill_blank: Optional[QuestionSection] = None
    essay_questions: Optional[QuestionSection] = None

@app.post("/generate_exam")
def generate_exam(exam: ExamRequest):
    doc = Document()

    # 标题
    title = doc.add_heading(exam.exam_title, 0)
    title.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

    # 考生信息
    info_text = f"部门:{exam.class_name}  姓名:{exam.student_name}  学号:{exam.student_id}  考试时间:{exam.exam_duration}  总分:{exam.total_score}"
    info = doc.add_paragraph(info_text)
    info.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
    info.paragraph_format.space_after = Pt(15)

    doc.add_paragraph()

    question_number = 1
    section_titles = ["一、单选题", "二、多选题", "三、填空题", "四、解答题"]
    sections = [
        exam.single_choice, exam.multiple_choice, exam.fill_blank, exam.essay_questions
    ]

    for idx, section in enumerate(sections):
        if section and section.questions:
            doc.add_heading(f"{section_titles[idx]}(每题{section.score_per_question}分,共{section.total_score}分)", level=1)
            for q in section.questions:
                para = doc.add_paragraph(f"{question_number}. {q.question}")
                para.paragraph_format.space_after = Pt(5)
                if q.options:
                    for opt in q.options:
                        opt_para = doc.add_paragraph(opt, style='List Bullet')
                        opt_para.paragraph_format.left_indent = Pt(20)
                else:
                    if section_titles[idx] == "四、解答题":
                        # 解答题较大空白预留空间
                        para.paragraph_format.space_after = Pt(100)
                    else:

                    # 解答题空白预留空间
                        para.paragraph_format.space_after = Pt(5)
                question_number += 1
            doc.add_paragraph()

    # 保存文件
    file_name = f"{TEMP_DIR}/exam_{uuid.uuid4().hex}.docx"
    doc.save(file_name)

    return FileResponse(path=file_name, filename="exam.docx",
                        media_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document")

运行之后fastapi自动会给出接口实例
在这里插入图片描述
接下来试一试。
接口发送以下json:

{
  "exam_title": "string",
  "class_name": "部门名称",
  "student_name": "________",
  "student_id": "________",
  "exam_duration": "90分钟",
  "total_score": "100分",
  "single_choice": {
    "questions": [
      {
        "question": "问题",
        "options": [
          "答案一"
        ],
        "answer": "string"
      }
    ],
    "score_per_question": 5,
    "total_score": 10
  },
  "multiple_choice": {
    "questions": [
      {
        "question": "string",
        "options": [
          "答案1","答案2","答案3","答案4"
        ],
        "answer": "string"
      }
    ],
    "score_per_question": 5,
    "total_score": 20
  },
  "fill_blank": {
    "questions": [
      {
        "question": "填空问题______哈哈哈",
       
        "answer": "string"
      }
    ],
    "score_per_question": 0,
    "total_score": 0
  },
  "essay_questions": {
    "questions": [
      {
        "question": "解答题问题1",
    
        "answer": "string"
      }
    ],
    "score_per_question": 10,
    "total_score": 20
  }
}

生成的word文档就是如下样子了:其他的内容
在这里插入图片描述

接入到系统中调用就是发送这样的数据:

{
  "exam_title": "制药企业生产工艺知识考核试卷",
  "class_name": "生产技术部",
  "student_name": "________",
  "student_id": "________",
  "exam_duration": "60分钟",
  "total_score": "100分",
  "single_choice": {
    "score_per_question": 5,
    "total_score": 10,
    "questions": [
      {
        "question": "制药企业生产必须遵循的质量管理规范简称为?",
        "options": ["A. GMP", "B. GDP", "C. SOP", "D. ISO"]
      },
      {
        "question": "洁净区的洁净等级划分依据标准是?",
        "options": ["A. ISO14644", "B. ISO9001", "C. ISO13485", "D. ISO17025"]
      }
    ]
  },
  "multiple_choice": {
    "score_per_question": 10,
    "total_score": 20,
    "questions": [
      {
        "question": "下列属于无菌制剂生产工艺控制措施的是?",
        "options": ["A. 洁净室空气净化", "B. 环境微生物监测", "C. 人员净化", "D. 设备灭菌"]
      },
      {
        "question": "制药过程中涉及的危险废弃物包括?",
        "options": ["A. 废有机溶剂", "B. 抗生素废物", "C. 废酸碱液", "D. 药渣"]
      }
    ]
  },
  "fill_blank": {
    "score_per_question": 5,
    "total_score": 10,
    "questions": [
      {
        "question": "药品生产批记录至少应保存______年。"
      },
      {
        "question": "GMP文件管理中SOP是指______。"
      }
    ]
  },
  "essay_questions": {
    "score_per_question": 30,
    "total_score": 60,
    "questions": [
      {
        "question": "结合实际生产过程,详细描述无菌制剂的灭菌与无菌保证措施。"
      },
      {
        "question": "制药企业如何实现全面的质量管理,请结合GMP的要求进行阐述。"
      }
    ]
  }
}

然后生成的文件就是这样子:
在这里插入图片描述
下课!

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小袁同学.

赏个早餐吃?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值