我正在使用考试类来排版考试。作为 MWE,我的考试有一个 MCQ 部分和简答题部分。
在成绩表中,我希望 MCQ 部分显示为一行总分(而不是 20-30 个 1 分框),而 Short 部分按问题显示。由于没有预定义命令,我想编写自己的表格生成器:
\documentclass[addpoints]{exam}
\begin{document}
\newcounter{qnitr}
\setcounter{qnitr}{\firstqinrange{short}}
\begin{tabular}{|c|c|c|}
\hline
Qns & Points & Score \\\hline
MCQ & \pointsinrange{mcq} & \\\hline
\whiledo{ \not \( \theqnitr > \lastqinrange{short} \) }{%
\ifthenelse{ \not \( \theqnitr > \lastqinrange{short} \) }{%
\theqnitr & \pointsofquestion{\theqnitr} & \\ \hline
}{blah}
\stepcounter{qnitr}
}
Total: & \numpoints & \\\hline
\end{tabular}
\begin{questions}
\section{MCQ Section}
\begingradingrange{mcq}
\question[2]
MCQ Question 1
\question[2]
MCQ Question 2
\question[2]
MCQ Question 3
\endgradingrange{mcq}
\section{Short Answer Section}
\begingradingrange{short}
\question
This question has 3 parts.
\begin{parts}
\part[2]
Part 1.
\part[2]
Part 2.
\part[3]
Part 3
\end{parts}
\question
This question has 2 parts.
\begin{parts}
\part[5]
Part 1.
\part[4]
Part 2.
\end{parts}
\endgradingrange{short}
\end{questions}
\end{document}
我想要实现的是这样的表格:
但是,\setcounter{qnitr}{\firstqinrange{short}}
出现了一个错误。
我花了几个小时尝试查找要使用的扩展宏\setcounter
,但似乎找不到解决方案。我了解到它\setcounter
很脆弱,需要扩展为数字。但我尝试了 、 、 的各种组合,\noexpand
由于我缺乏对 LaTeX 评估的了解和理解,我只是随机尝试。\protect
\value
我查看了exam.cls
表格生成方式的线索,找到了如下代码
\edef\tbl@firstq{\csname range@\tbl@range @firstq\endcsname}%
\edef\tbl@lastq{\csname range@\tbl@range @lastq\endcsname}%
\let\first@pq@index=\tbl@firstq
\let\last@pq@index=\tbl@lastq
...
\setcounter{num@cols}{\tbl@lastq}%
\addtocounter{num@cols}{-\tbl@firstq}%
为什么考试班能够为命令设置计数器,但当我尝试这样做时,它总是失败?
答案1
通过检查文件。使用和exam.cls
生成的实际问题范围数量可以通过这两个宏调用,\firstqinrange
\lastqinrange
\range@short@firstq
\range@short@lastq
因此代码应编辑如下:
\documentclass[addpoints]{exam}
\begin{document}
\newcounter{fqr}
\newcounter{lqr}
\makeatletter
\setcounter{fqr}{\range@short@firstq}
\setcounter{lqr}{\range@short@lastq}
\makeatother
\begin{tabular}{|c|c|c|}
\hline
Qns & Points & Score \\\hline
MCQ & \pointsinrange{mcq} & \\\hline
\whiledo{ \not \( \thefqr > \thelqr \) }{%
\ifthenelse{
\not \( \thefqr > \thelqr \) }{%
\thefqr & \pointsofquestion{\thefqr} & \\ \hline%
}{blah}%
\stepcounter{fqr}%
}
Total: & \numpoints & \\\hline
\end{tabular}
\begin{questions}
\section{MCQ Section}
\begingradingrange{mcq}
\question[2]
MCQ Question 1
\question[2]
MCQ Question 2
\question[2]
MCQ Question 3
\endgradingrange{mcq}
\section{Short Answer Section}
\begingradingrange{short}
\question
This question has 3 parts.
\begin{parts}
\part[2]
Part 1.
\part[2]
Part 2.
\part[3]
Part 3
\end{parts}
\question
This question has 2 parts.
\begin{parts}
\part[5]
Part 1.
\part[4]
Part 2.
\end{parts}
\endgradingrange{short}
\end{questions}
\end{document}
编辑:我会尽力回答你的问题。如果这里提到的任何内容不正确。请纠正我。问题来自命令
\def
和\firstqinrange
定义\lastqinrange
。如果你看一下文件中这两个命令的定义exam.cls
。例如,对于\firstqinrange
:
\newcommand{\firstqinrange}[1]{%
\def\tbl@range{#1}% define a macro using #1, e.g. If this is the short range, #1=short.
\@ifundefined{range@\tbl@range @firstq}% use previous macro in here to judge if command \range@short@firstq has not been defined.
{\bad@range}% If true, return a error.
{\csname range@#1@firstq\endcsname}% If false, return \range@short@firstq.
}% firstqinrange
在这个定义中,命令\def
不可扩展。为什么?你可以看看这个邮政。因此,为了更好地说明这一点,我们可以修补该命令\firstqinrange
并\lastqinrange
消除\def
使用包的命令etoolbox
。
\documentclass[addpoints]{exam}
\usepackage{etoolbox}
\makeatletter
\patchcmd{\firstqinrange}{\def\tbl@range{#1}\@ifundefined{range@\tbl@range @firstq}}{\@ifundefined{range@#1@firstq}}{}{}
%% get rid of `\def\tbl@range{#1}` and using `range@#1@firstq` as value testing the define state.
\patchcmd{\lastqinrange}{\def\tbl@range{#1}\@ifundefined{range@\tbl@range @lastq}}{\@ifundefined{range@#1@lastq}}{}{}
%% get rid of `\def\tbl@range{#1}` and using `range@#1@lastq` as value testing the define state.
\makeatother
\begin{document}
\newcounter{fqr}
\newcounter{lqr}
\setcounter{fqr}{\firstqinrange{short}}%%use `\firstqinrange{short}` to set the counter
\setcounter{lqr}{\lastqinrange{short}}%%use `\firstqinrange{short}` to set the counter
\begin{tabular}{|c|c|c|}
\hline
Qns & Points & Score \\\hline
MCQ & \pointsinrange{mcq} & \\\hline
\whiledo{ \not \( \thefqr > \thelqr \) }{%
\ifthenelse{
\not \( \thefqr > \thelqr \) }{%
\thefqr & \pointsofquestion{\thefqr} & \\ \hline%
}{blah}%
\stepcounter{fqr}%
}
Total: & \numpoints & \\\hline
\end{tabular}
\begin{questions}
\section{MCQ Section}
\begingradingrange{mcq}
\question[2]
MCQ Question 1
\question[2]
MCQ Question 2
\question[2]
MCQ Question 3
\endgradingrange{mcq}
\section{Short Answer Section}
\begingradingrange{short}
\question
This question has 3 parts.
\begin{parts}
\part[2]
Part 1.
\part[2]
Part 2.
\part[3]
Part 3
\end{parts}
\question
This question has 2 parts.
\begin{parts}
\part[5]
Part 1.
\part[4]
Part 2.
\end{parts}
\endgradingrange{short}
\end{questions}
\end{document}
现在代码正在用于\setcounter{fqr}{\firstqinrange{short}}
设置计数器,并且成功编译而没有错误。