从题库生成考试吗?

从题库生成考试吗?

我正在寻找一个 LaTeX 软件包,它允许我使用从特定题库中抽取的问题生成考试。题库中的每个问题都是一个独立的 LaTeX 代码块。

例如,本着该exam方案的精神,我可能会有以下问题:

\question
$2+2=$
\begin{choices}
\choice 3
\choice 0
\choice 4
\choice $\sqrt{2}$
\choice $-\pi$
\end{choices}

\question
$\int_0^1 x^2\,dx=$
\begin{choices}
\choice $-1$
\choice $1/3$
\choice $\infty$
\choice $1/2$
\choice None of the above.
\end{choices}

这将是一个包含两个问题的库。每个问题都是一个 LaTeX 代码块,如果将其从库中“取出”并插入“父”可编译 LaTeX 文件,则会生成一份考试(大概是此类软件包的作用)。

出于贪心,我真的很想指定从问题库 $B_1$ 中抽取的问题数量 $q_1$,从 $B_2$ 中抽取的问题数量 $q_2$,等等,其中每个库 $B_i$ 都涉及一个特定的主题。

如果这个已经存在,我还没能找到。保留 documentclass exam(或类似的东西)的功能将使分配分数和/或生成答案键与(随机)考试创建同时进行。

答案1

假设你有A其中的问题库bankA.tex具有以下格式:

\begin{questionblock}
Question 1
\end{questionblock}
\begin{questionblock}
Question 2
\end{questionblock}
\begin{questionblock}
Question 3
\end{questionblock}
\begin{questionblock}
Question 4
\end{questionblock}
\begin{questionblock}
Question 5
\end{questionblock}
\begin{questionblock}
Question 6
\end{questionblock}
\begin{questionblock}
Question 7
\end{questionblock}
\begin{questionblock}
Question 8
\end{questionblock}
\begin{questionblock}
Question 9
\end{questionblock}
\begin{questionblock}
Question 10
\end{questionblock}

用某种形式的块/环境 (在本例中) 来表示每个问题很重要questionblock。最终,您会将每个银行保存在单独的文件中,例如bankA.tex,,bankB.tex... 对于环境中可以包含的内容不应有任何限制questionblock

我们从该库中生成一组随机问题的算法如下:

  1. 读取文件并存储在宏中(感谢catchfile

  2. 计算银行里有多少个问题(使用environ将整个questionblock环境作为一个\stepcounter机制来处理)。拨打此号码totalquestions

  3. 创建一个从 1 到totalquestions(作为参考,请参阅生成无重复的随机数));

  4. 重复以下步骤:

    • 从随机列表中选择一个数字;

    • 处理整个银行,直到找到与所选数字相匹配的问题并将其打印出来;

    • 通过删除选定的数字来修剪随机列表。

上述过程可能会进行大量额外处理,但我相信它不会过于繁琐。以下是一家银行的完整最小示例:

在此处输入图片描述

\documentclass{article}
\usepackage{multicol}% Just for this example
\usepackage{filecontents}
\begin{filecontents*}{bankA.tex}
\begin{questionblock}
Question 1
\end{questionblock}
\begin{questionblock}
Question 2
\end{questionblock}
\begin{questionblock}
Question 3
\end{questionblock}
\begin{questionblock}
Question 4
\end{questionblock}
\begin{questionblock}
Question 5
\end{questionblock}
\begin{questionblock}
Question 6
\end{questionblock}
\begin{questionblock}
Question 7
\end{questionblock}
\begin{questionblock}
Question 8
\end{questionblock}
\begin{questionblock}
Question 9
\end{questionblock}
\begin{questionblock}
Question 10
\end{questionblock}
\end{filecontents*}

\usepackage{catchfile,environ,tikz}

\makeatletter% Taken from https://tex.stackexchange.com/q/109619/5764
\def\declarenumlist#1#2#3{%
  \expandafter\edef\csname pgfmath@randomlist@#1\endcsname{#3}%
  \count@\@ne
  \loop
    \expandafter\edef
    \csname pgfmath@randomlist@#1@\the\count@\endcsname
      {\the\count@}
    \ifnum\count@<#3\relax
    \advance\count@\@ne
  \repeat}
\def\prunelist#1{%
  \expandafter\xdef\csname pgfmath@randomlist@#1\endcsname
          {\the\numexpr\csname pgfmath@randomlist@#1\endcsname-1\relax}
  \count@\pgfmath@randomtemp 
  \loop
    \expandafter\global\expandafter\let
    \csname pgfmath@randomlist@#1@\the\count@\expandafter\endcsname
    \csname pgfmath@randomlist@#1@\the\numexpr\count@+1\relax\endcsname
    \ifnum\count@<\csname pgfmath@randomlist@#1\endcsname\relax
      \advance\count@\@ne
  \repeat}
\makeatother

% Define how each questionblock should be handled
\newcounter{questionblock}
\newcounter{totalquestions}
\NewEnviron{questionblock}{}%

\newcommand{\randomquestionsfrombank}[2]{%
  \CatchFileDef{\bank}{#1}{}% Read the entire bank of questions into \bank
  \setcounter{totalquestions}{0}% Reset total questions counters  ***
  \RenewEnviron{questionblock}{\stepcounter{totalquestions}}% Count every question  ***
  \bank% Process file  ***
  \declarenumlist{uniquequestionlist}{1}{\thetotalquestions}% list from 1 to totalquestions inclusive.
  \setcounter{totalquestions}{#2}% Start the count-down
  \RenewEnviron{questionblock}{%
    \stepcounter{questionblock}% Next question
    \ifnum\value{questionblock}=\randomquestion 
      \par% Start new paragraph
      \BODY% Print question
    \fi
  }%
  \foreach \uNiQueQ in {1,...,#2} {% Extract #2 random questions
    \setcounter{questionblock}{0}% Start fresh with question block counter
    \pgfmathrandomitem\randomquestion{uniquequestionlist}% Grab random question from list
    \xdef\randomquestion{\randomquestion}% Make random question available globally
    \prunelist{uniquequestionlist}% Remove picked item from list
    \bank% Process file
  }}

\begin{document}

\begin{multicols}{3}
  \foreach \x in {1,...,6} {
    \bigskip
    \randomquestionsfrombank{bankA.tex}{6}
  }
\end{multicols}

\end{document}

调用 会从 中随机\randomquestionsfrombank{<file>}{<num>}挑选问题。如果您不想第一次处理 以获取问题数量,您可以删除用 突出显示的行。<num><file><file>***

答案2

也许我来晚了。我在寻找一种自动创建随机考试的方法时发现了这个旧帖子。正如@vonbrand所建议的,Python脚本可以解决问题。这是我想到的解决方案:

import sys
import os
import random

exam = sys.argv[1]
folder = sys.argv[2]

questions = []
for bank, number in zip(sys.argv[3::2], map(int, sys.argv[4::2])):
    qfiles = [
        os.path.join(dirpath, fname) 
        for dirpath, dirnames, filenames in os.walk(os.path.join(folder, bank)) 
        for fname in filenames 
        if os.path.splitext(fname)[-1].lower() == '.tex'
        ]
    for qfile in random.sample(qfiles, number):
        with open(qfile, 'r') as qfh:
            questions.append(qfh.read())

with open(exam, 'w') as efh:
    for question in questions:
        print(question, file=efh)

演示

假设我们有3个题库,分别是ch1ch2ch3,分别有5,10和100道模拟题,按照以下文件树:

C:
├── exams
└── banks
    ├── ch1
    │   ├── ch1q1.tex 
    │   ├── ...
    │   └── ch1q5.tex 
    ├── ch2
    │   ├── ch2q1.tex 
    │   ├── ...
    │   └── ch2q10.tex 
    └── ch3
        ├── ch3q1.tex 
        ├── ...
        └── ch3q100.tex 

如果我们希望通过从中随机挑选一道题ch1、从中随机挑选一道题ch2和从中随机挑选两道题来创建考试ch3,我们可以在命令行中输入以下指令来完成这项工作:

C:\>python exam.py C:\exams\sample_exam.tex C:\banks ch1 1 ch2 1 ch3 2

sample_exam.tex最终文件看起来如下:

\question Chapter 1 -- Question 4
\begin{choices}
\choice Choice a
\CorrectChoice Choice b
\choice Choice c
\choice Choice d
\end{choices}

\question Chapter 2 -- Question 8
\begin{choices}
\choice Choice a
\choice Choice b
\CorrectChoice Choice c
\end{choices}

\question Chapter 3 -- Question 75
\begin{choices}
\CorrectChoice Choice a
\choice Choice b
\choice Choice c
\choice Choice d
\choice Choice e
\end{choices}

\question Chapter 3 -- Question 23
\begin{choices}
\choice Choice a
\choice Choice b
\CorrectChoice Choice c
\end{choices}

需要指出的是,您可以<bank_i> <number_i>在命令行参数列表中放入与问题库数量相同的对。还值得注意的是,没有什么可以阻止您将问题库组织成部分(子目录):

C:
├── exams
└── banks
    ├── ch1
    │   ├── ch1q1.tex 
    │   ├── ...
    └── ch2
        ├── sec1
        │    ├── ch2sec1q1.tex 
        │    ├── ch2sec1q2.tex
        │    ├── ...
        ├── sec2
        │    ├── ch2sec2q1.tex 
        │    ├── ch2sec2q2.tex
        │    ├── ...
        ├── ...

因为问题搜索是递归进行的。

答案3

我不确定您是否仍在寻找这样的包,但如果是的话,请查看 probsoln 包:https://ctan.org/pkg/probsoln?lang=en。过去几年我一直在使用它,我认为它完全满足你的要求。

答案4

我曾经编写过一个代码,用于从“库”中随机选择方程式,并将试卷中的几乎所有细节随机化。该代码可在以下网址免费下载: https://github.com/LiuGangKingston/Personalized-Test-Creator.git

具体来说,它可以随机化

  1. 从“问题库”中选择问题;
  2. 从多项选择题的“选择库”中选择选项;
  3. 给定问题或分组问题的顺序;
  4. 多项选择题的选择顺序;
  5. 计算问题中的任何整数、实数或其他数字;等等。

当然,老师可以完全控制随机化的方式和程度。因此,老师可以得到他/她想要的任意数量的试卷。同时,任何生成的试卷中任何问题的答案和/或解决方案也将在单独的文件中生成。为了使用它,老师应该在 Latex 中提供一份原始试卷和一些特殊命令。例如,特殊命令“PTC-RRR(2.00, 5.51, .25)”将被随机替换为 (2.00, 2.25, 2.50, 2.75, 3.00, 3.25, 3.50, 3.75, 4.00, 4.25, 4.50, 4.75, 5.00, 5.25, 5.50) 中的一个数字。请注意,根据命令的用法,它们都在小数点后有两位数字。缺点是它是用 FORTRAN 语言编写的,因此为了生成答案,老师也应该编写一点 FORTRAN 代码。因为为了得到答案,只需要非常有限的 FORTRAN 语言的简单编程子集。例如,Variable_A = Variable_B + Variable_C * sin(Variable_D) / Variable_E + Variable_F ** Variable_G 计算结果并将其与其他变量一起保存到 Variable_A。然后,所有这些都可以直接用于在 Latex 文件中编写答案。

最后一点,它是通用的Latex编码,目前试卷的格式完全由老师设计,可以任意选择,后续版本可能会全面支持试卷文档类,更加方便。

相关内容