添加问题类别并使其出现在考试类别的成绩表中

添加问题类别并使其出现在考试类别的成绩表中

我们希望根据学习成果对考试中的问题进行分类。每个问题将有一个或多个类别编号。这些数字应该出现在成绩表中。例如,我可以通过像这样修改奖励点环境来创建自定义组合成绩表组(参考:类似问题但不相同):

\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

相关内容