我们希望根据学习成果对考试中的问题进行分类。每个问题将有一个或多个类别编号。这些数字应该出现在成绩表中。例如,我可以通过像这样修改奖励点环境来创建自定义组合成绩表组(参考:类似问题但不相同):
\begingroup
\chbpword{Category}
\settabletotalbonuspoints{}
\renewcommand{\bonuspointsofquestion}[1]{}
\combinedgradetable[h]
\endgroup
但是我不知道如何为问题分配类别并将其显示在成绩表中。或者如果有任何其他方法可以实现这一点,我将不胜感激。
提前致谢。
答案1
我在这里定义了一些命令,这些命令允许根据exam
课程本身的代码为考试课程文档中的问题分配类别。我认为将大部分代码放在一个文件中会更清楚category.sty
,该文件位于答案的末尾。我进行了一些测试,我认为它在大多数情况下应该可以工作。但我注意到它可能无法与该包一起使用hyperref
。
定义的新命令如下。
\newcategory{<name>}{<label>}
。此命令允许在考试中定义新类别。<name>
是类别的名称,它将以文本显示,<label>
是代码中访问类别的标签。此命令应放在序言中。\category{<label>}
. 返回与标签关联的类别的名称<label>
,全部为小写字符。\Category{<label>}
。与 相同\category
,但将类别名称的首字母大写。\categorynumber{<label>}
。返回与标签关联的类别的编号<label>
。类别按\newcategory
命令中定义的顺序进行编号。\categorize{<label>}
。用于项目中\question
。将相应问题与标记为的类别关联<label>
。该\categorize
命令只能将单个标签作为参数,但\categorize
可以对同一问题使用多个命令,以将问题与多个类别关联。\categorytable
。创建一个显示类别名称和相应编号的表格。无需调用类别表即可对类别进行编号。
如果已定义类别并对问题进行分类,则类别将显示在水平完整评分表(成绩、分数、奖励或组合)中(如果它们是按问题索引的)。在部分或垂直评分表中,或在按页面索引的表中,类别将被忽略。
这里有一个小例子来展示大多数命令的用法。
\documentclass[addpoints]{exam}
\usepackage{wrapfig}
\usepackage{category}
\newcategory{Analysis}{cat:an}
\newcategory{Topology}{cat:topo}
\newcategory{Algebra}{cat:alg}
\begin{document}
\begin{wraptable}{r}{0.2\textwidth}
\centering
\categorytable
\caption{Example of \textbackslash\texttt{categorytable}.}
\end{wraptable}
The categories used in this exam are \category{cat:an} (\categorynumber{cat:an}), \category{cat:topo} (\categorynumber{cat:topo}) and \category{cat:alg} (\categorynumber{cat:alg}).
\medskip\combinedgradetable[h]
\begin{questions}
\question[15] \categorize{cat:an} First question.
\question[25] \categorize{cat:an}\categorize{cat:topo} Second question.
\question[30] \categorize{cat:topo} Third question.
\question[30] \categorize{cat:alg} Fourth question.
\bonusquestion[5] \categorize{cat:topo}\categorize{cat:alg} Bonus question.
\bonusquestion[5] Bonus question, not categorized.
\end{questions}
\end{document}
默认情况下,单词“Category:”将显示在成绩表中相应行的开头,但可以使用命令\hcword{newname}
、\bhcword{newname}
和\chcword{newname}
将关联表(分别为成绩、奖金和组合)中的“Category:”替换为“newname”。similar 命令\cwordctbl
允许更改 中显示的名称\categorytable
,默认情况下为“Categories”。如果问题未分类,则此问题的类别行中显示的内容由命令定义\nocword
。默认值为\nocword{--}
,但类似调用将替换--
为参数。
以下是category.sty
文件。如果您希望将该代码放在序言中,只需加载包refcount
,并将以下代码的前三行以外的所有内容放在\makeatletter
和之间\makeatother
。
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{category}
\RequirePackage{refcount}
\def\hcword#1{\def\@hcword{#1}}
\def\bhcword#1{\def\@bhcword{#1}}
\def\chcword#1{\def\@chcword{#1}}
\def\cwordctbl#1{\def\@cwordctbl{#1}}
\def\nocword#1{\def\@nocword{#1}}
\hcword{Category:}
\bhcword{Category:}
\chcword{Category:}
\cwordctbl{Categories}
\nocword{--}
\newcounter{num@cats}
\newcounter{current@category}
\newcounter{current@catofq}
\newcounter{qfor@lastc}
\def\relaxwitharg#1{\relax}
\def\newcategory#1#2{%
\stepcounter{num@cats}
\expandafter\gdef\csname category\romannumeral\thenum@cats \endcsname{#1}%
\expandafter\edef\csname numberof#2 \endcsname{\thenum@cats}%
\protected@write\@auxout{}%
{\string\newlabel{#2}{{\thenum@cats}{\thepage}}}%
}% newcategory
\def\categorynumber#1{%
\csname numberof#1 \endcsname%
}% categorynumber
\def\category#1{%
\expandafter\MakeLowercase \csname category\romannumeral\categorynumber{#1} \endcsname%
}% category
\def\Category#1{%
\edef\temp{\csname category\romannumeral\categorynumber{#1}\endcsname}%
\expandafter\MakeUppercase{\expandafter\@car\temp\@nil}%
\expandafter\@cdr\temp\@nil%
}% Category
\def\categorize#1{%
\@ifundefined{c@num@catsofq@\romannumeral\thequestion}{%
\newcounter{num@catsofq@\romannumeral\thequestion}%
}{}%
\stepcounter{num@catsofq@\romannumeral\thequestion}%
\immediate\write\@mainaux%
{\string\gdef\string\category\romannumeral\the\value{num@catsofq@\romannumeral\thequestion}ofq@\romannumeral\thequestion{\string\ref{#1}}}%
}% categorize
\def\do@catloop@ctbl{%
\stepcounter{current@category}%
\thecurrent@category%
\hidden@ampersand%
\csname category\romannumeral\thecurrent@category \endcsname%
\ifnum \value{current@category} = \value{num@cats}\relax%
\\
\hline
\end{tabular}
\let\nextdo@catloop@ctbl\relax
\else
\\
\let\nextdo@catloop@ctbl\do@catloop@ctbl
\fi
\nextdo@catloop@ctbl
}% do@catloop@ctbl
\def\categorytable{%
\begin{tabular}{ll}
\multicolumn{2}{c}{\@cwordctbl} \\
\hline
\do@catloop@ctbl
}% categorytable
\def\do@lastcloop{%
\stepcounter{qfor@lastc}%
\@ifundefined{exam@numquestions}{%
\let\nextdo@lastcloop=\relax
}{%
\ifnum \value{qfor@lastc} > \exam@numquestions\relax
\let\nextdo@lastcloop=\relax%
\else
\@ifundefined{thenum@catsofq@\romannumeral\theqfor@lastc}%
{%
\immediate\write\@mainaux%
{\string\xdef\string\exam@catsofquestion\romannumeral\theqfor@lastc{0}}%
\let\nextdo@lastcloop=\do@lastcloop%
}{%
\immediate\write\@mainaux%
{\string\xdef\string\exam@catsofquestion\romannumeral\theqfor@lastc{\csname thenum@catsofq@\romannumeral\theqfor@lastc \endcsname}}%
\let\nextdo@lastcloop=\do@lastcloop%
}%
\fi
}%
\nextdo@lastcloop
}% do@lastcloop
\AtEndDocument{%
\do@lastcloop%
}
\def\do@catsofqloop#1{%
\stepcounter{current@catofq}%
\@ifundefined{exam@catsofquestion\romannumeral #1}{%
\let\nextdo@catsofqloop=\relaxwitharg
}{%
\ifnum \value{current@catofq} = \csname exam@catsofquestion\romannumeral #1 \endcsname\relax
\csname category\romannumeral\thecurrent@catofq ofq@\romannumeral #1 \endcsname%
\let\nextdo@catsofqloop=\relaxwitharg
\else
\csname category\romannumeral\thecurrent@catofq ofq@\romannumeral #1 \endcsname,\,%
\let\nextdo@catsofqloop=\do@catsofqloop
\fi
}%
\nextdo@catsofqloop{#1}%
}% do@catsofqloop
\def\categoriesofquestion#1{\@ifundefined{categoryiofq@\romannumeral #1}%
{\mbox{\@nocword}}%
{%
\setcounter{current@catofq}{0}%
\do@catsofqloop{#1}
}%
}% categoriesofquestion
\def\categoriesof@index#1{%
\categoriesofquestion{\arabic{#1}}%
}% categoryof@index
\def\do@catloop@h{%
\increment@index{pq@index}%
\ifnum \value{pq@index} > \last@pq@index\relax
% Do nothing!
\else
\hidden@ampersand
\addtocounter{cols@done}{1}%
\categoriesof@index{pq@index}%
\fi
\ifnum \value{pq@index} < \last@pq@index\relax
\ifnum \value{cols@done} < \value{num@cols}\relax
\let\nextdo@catloop@h=\do@catloop@h
\else
\let\nextdo@catloop@h=\relax
\fi
\else
\let\nextdo@catloop@h=\relax
\fi
\nextdo@catloop@h
}% do@catloop@h
\def\do@lines@h{%
\addtocounter{current@row}{1}%
\iftbl@pgs
\if@bonus
\@bhpgword
\else
\@hpgword
\fi
\else
\if@bonus
\@bhqword
\else
\@hqword
\fi
\fi
\setcounter{cols@done}{0}%
\do@pq@indexloop@h
\ifnum \value{cols@done} < \value{num@cols}\relax
\ifnum \value{current@row} = \value{num@rows}\relax
\do@htword@h
\else
\setcounter{@iterator}{\value{num@cols}}%
\addtocounter{@iterator}{-\value{cols@done}}%
\do@emptycols@h
\fi
\fi
\\
\hline
\iftbl@pgs
%Do nothing
\else
\if@partial
%Do nothing
\else
\setcounter{pq@index}{0}%
\setcounter{cols@done}{0}%
\@hcword
\do@catloop@h
\hidden@ampersand
\\
\hline
\fi
\fi
% Point values go here!
\setcounter{cols@done}{0}%
\if@bonus
\@bhpword
\do@bptloop@h
\else
\@hpword
\do@ptloop@h
\fi
\ifnum \value{cols@done} < \value{num@cols}\relax
\ifnum \value{current@row} = \value{num@rows}\relax
\if@bonus
\do@totalbpts@h
\else
\do@totalpts@h
\fi
\else
\setcounter{@iterator}{\value{num@cols}}%
\addtocounter{@iterator}{-\value{cols@done}}%
\do@emptycols@h
\fi
\fi
% Scores?
\if@scores
\\
\hline
\if@bonus
\@bhsword \hidden@ampersand
\else
\@hsword \hidden@ampersand
\fi
\setcounter{cols@done}{0}%
\do@sloop@h
\fi
\ifnum \value{current@row} = \value{num@rows}\relax
\\
\hline
\end{tabular}%
\else
\\
\hline\hline
\fi
\ifnum \value{current@row} < \value{num@rows}\relax
\let\nextdo@lines@h=\do@lines@h
\else
\let\nextdo@lines@h=\relax
\fi
\nextdo@lines@h
} %do@lines@h
\def\do@comblines@h{%
\addtocounter{current@row}{1}%
\iftbl@pgs
\@chpgword
\else
\@chqword
\fi
\setcounter{cols@done}{0}%
\do@pq@indexloop@h
\ifnum \value{cols@done} < \value{num@cols}\relax
\ifnum \value{current@row} = \value{num@rows}\relax
\do@htword@h
\else
\setcounter{@iterator}{\value{num@cols}}%
\addtocounter{@iterator}{-\value{cols@done}}%
\do@emptycols@h
\fi
\fi
\\
\hline
\iftbl@pgs
%Do nothing
\else
\if@partial
%Do nothing
\else
\setcounter{pq@index}{0}%
\setcounter{cols@done}{0}%
\@chcword
\do@catloop@h
\hidden@ampersand
\\
\hline
\fi
\fi
% Point values go here!
\@chpword
\setcounter{cols@done}{0}%
\do@ptloop@h
\ifnum \value{cols@done} < \value{num@cols}\relax
\ifnum \value{current@row} = \value{num@rows}\relax
\do@totalpts@h
\else
\setcounter{@iterator}{\value{num@cols}}%
\addtocounter{@iterator}{-\value{cols@done}}%
\do@emptycols@h
\fi
\fi
\\
\hline
% Bonus point values go here!
\@chbpword
\setcounter{cols@done}{0}%
\do@bptloop@h
\ifnum \value{cols@done} < \value{num@cols}\relax
\ifnum \value{current@row} = \value{num@rows}\relax
\do@totalbpts@h
\else
\setcounter{@iterator}{\value{num@cols}}%
\addtocounter{@iterator}{-\value{cols@done}}%
\do@emptycols@h
\fi
\fi
% Scores?
\if@scores
\\
\hline
\@chsword \hidden@ampersand
\setcounter{cols@done}{0}%
\do@sloop@h
\fi
\ifnum \value{current@row} = \value{num@rows}\relax
\\
\hline
\end{tabular}%
\else
\\
\hline\hline
\fi
\ifnum \value{current@row} < \value{num@rows}\relax
\let\nextdo@comblines@h=\do@comblines@h
\else
\let\nextdo@comblines@h=\relax
\fi
\nextdo@comblines@h
}% do@comblines@h