如何汇总成绩表中的问题部分?

如何汇总成绩表中的问题部分?

再会,

我正在为考试班制作一个自定义评分表。具体来说,我想删除第一列并在末尾添加一个新列。看来,创建一个新的表格才是最佳选择。

在搜索 stackexchange 后我发现这个问题,它会修改\part环境并将每个问题部分及其分数写入辅助文件,然后将它们放入表中。除了分数的显示方式外,我可以根据自己的喜好进行更改。建议的解决方案默认使用问题部分,而我只想查看每个问题的总数。因此,问题是计算每个的总数\question

我当前的代码(主要是@Andrew 提出的代码)如下:

% redefine \question command to be \myquest
\appto\questions{\let\examquestion\question\let\question\myquestion}
% redefine \part command to be \mypart
\appto\parts{\let\exampart\part\let\part\mypart}

\makeatletter
\ExplSyntaxOn

% this will become a sequence of the part numbers and scores
% like: 1a,10,1b,8,1c,9,2a,6,2b,8,3,12,4,14, ...
\clist_new:N \g_grades_clist
\clist_new:N \g_grades_aux_clist

\int_new:N \g_questions_row_int
\int_new:N \g_scores_row_int
\int_new:N \g_spaces_row_int

\int_new:N \g_grade_total_int
\int_new:N \g_number_of_scores_int
\int_new:N \g_total_questions

% add a question/part number and score to \g_grades_clist
\cs_new:Nn \__add_to_grades_list:nn {
  \clist_gput_right:Nx \g_grades_clist { #1 }
  \clist_gput_right:Nx \g_grades_clist { #2 }
}

\NewDocumentCommand\myquestion{o}{
  \IfNoValueTF{#1}{\examquestion}{
    % don't do anything special inside solutions
    \if@insolution\examquestion[#1]
    \else\examquestion[#1]
      % store both the part number and score in \g_grades_clist
      \__add_to_grades_list:nn { Auf.~\arabic{question} } { #1 }
    \fi
  }
}

\NewDocumentCommand\mypart{o}{
  \IfNoValueTF{#1}{\exampart}{
    % don't do anything special inside solutions
    \if@insolution\exampnrt[#1]
    \else\exampart[#1]
      % store both the part number and score in \g_grades_clist
      \__add_to_grades_list:nn { Auf.~\arabic{question}\alph{partno} } { #1 }
    \fi
  }
}

\AtEndDocument{
  \iow_now:cx { @auxout } {
    \token_to_str:N \SetGradeList { \g_grades_clist  } ^^J
  }
}
% set grade list from the aux file
\NewDocumentCommand\SetGradeList{m}{\clist_gset:Nn \g_grades_aux_clist {#1}}
% Draw quesions
\cs_new:Nn \__add_questions_to_grade_table: {
    \int_gincr:N \g_questions_row_int
       \clist_item:Nn \g_grades_aux_clist {2*\g_questions_row_int-1} \int_compare:nT {\g_questions_row_int < (\g_number_of_scores_int)} { & \__add_questions_to_grade_table: }
}
% Draw scores
\cs_new:Nn \__add_scores_to_grade_table: {
     \int_gincr:N \g_scores_row_int
       \clist_item:Nn \g_grades_aux_clist {2*\g_scores_row_int} \int_compare:nT {\g_scores_row_int < \g_number_of_scores_int} { & \__add_scores_to_grade_table: }
}
% Draw empty spaces
\cs_new:Nn \__add_spaces_to_grade_table: {
     \int_gincr:N \g_spaces_row_int
         \int_compare:nT {\g_spaces_row_int < \g_number_of_scores_int} { & \__add_spaces_to_grade_table: }
}

\NewDocumentCommand\PrintGradeTable{}{% the new grade table
  \int_set:Nn \g_number_of_scores_int {(\clist_count:N \g_grades_aux_clist)/2}
  \int_gzero:N \g_questions_row_int % a counter to step through the rows
  \int_gzero:N \g_scores_row_int % a counter to step through the rows
  \int_gzero:N \g_spaces_row_int % a counter to step through the rows
  % create the grade table
  \renewcommand{\arraystretch}{2}
    \begin{tabular}{|c|*{\int_eval:n {(\clist_count:N \g_grades_aux_clist)/2-1}}{c|}c}
        \hline
        \int_compare:nT {\g_number_of_scores_int>0} { \__add_questions_to_grade_table: } & \multicolumn{1}{l|}{\hphantom{A}~\large\textbf{Note}~\hphantom{A}} \\
        \hline
        \int_compare:nT {\g_number_of_scores_int>0} { \__add_scores_to_grade_table: } & \\
        \hline
        \int_compare:nT {\g_number_of_scores_int>0} { \__add_spaces_to_grade_table: } & \multicolumn{1}{l|}{} \\
        \hline
    \end{tabular}
}
\ExplSyntaxOff

以下是代码生成结果的直观表示:当前评分表

考试中的每个练习都采用以下格式:

\question
\begin{parts}
    \part
\end{parts}

因此每个问题总是由多个部分组成的。

计算各部分总数的最简单的方法是什么?

答案1

我最终修改了内置的表函数。如果有人需要做同样的事情,我引入了一个较短版本的 emptycols 迭代器,它少创建一个单元格,并将所有循环更改为在主要部分后添加 & 符号,因此它们不会在它们之前留下一个空单元格,而是在它们之后留下一个。这样,它就不是包含所有名称或为空的第一列,而是最后一列。

全部改变的代码如下:

\def\do@lines@h{%
  % Called only by \@multirowtable.
  % It's either bonus or regular, but not combined:
  \addtocounter{current@row}{1}% Set to the number of the current row
  \setcounter{cols@done}{0}%
  \do@pq@indexloop@h
  % When we finish \do@pq@indexloop@h, either we've finished a
  % complete row of page numbers (or questions), or we've done all
  % the page numbers (or questions) through \last@pq@index, or both:
  \ifnum \value{cols@done} < \value{num@cols}\relax
    % We've inserted all the page or question numbers, and there's
    % room remaining on the current line for \@htword (or \@bhtword):
    \ifnum \value{current@row} = \value{num@rows}\relax
      % This is the last row; put in the total:
      \do@note
    \else
      % This isn't the last row.  We insert (\value{num@cols} -
      % \value{cols@done}) ampersands.
      \setcounter{@iterator}{\value{num@cols}}%
      \addtocounter{@iterator}{-\value{cols@done}}%
      \do@emptycols@h
    \fi
  \fi
  \\
  \hline
  % Point values go here!
  \setcounter{cols@done}{0}%
  \if@bonus
    \do@bptloop@h
  \else
    \do@ptloop@h
  \fi
  % When we finish \do@ptloop@h or \do@bptloop@h, either
  % we've finished a complete row of point values, or we've done all
  % the question (or page) numbers through \last@pq@index, or both:
  \ifnum \value{cols@done} < \value{num@cols}\relax
    % We've inserted all the point values, and there's room
    % remaining on the current line for Total Points:
    \ifnum \value{current@row} = \value{num@rows}\relax
      % This is the last row; put in the total:
      \if@bonus
        \do@totalbpts@h
      \else
        \do@totalpts@h
      \fi

    \else
      % This isn't the last row.  We insert (\value{num@cols} -
      % \value{cols@done}) ampersands.
      \setcounter{@iterator}{\value{num@cols}}%
      \addtocounter{@iterator}{-\value{cols@done}}%
      \do@emptycols@h
    \fi
  \fi
  % We hold off on putting in the "\\ \hline" because we may want to
  % immediately follow it with either an "\end{tabular}" or another
  % "\hline".
  % Scores?
  \if@scores
    \\
    \hline
    \if@bonus
      \hidden@ampersand
    \else
      \hidden@ampersand
    \fi
    \setcounter{cols@done}{0}%
    \do@sloop@h
  \fi
  \ifnum \value{current@row} = \value{num@rows}\relax
    % This is the last line!  End the tabular:
    \\
    \hline
    \end{tabular}%
  \else
    % Don't end the tabular:
    \\
    \hline\hline
  \fi
  % Check if we should repeat:
  \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@pq@indexloop@h{%
  % Called by both \do@lines@h and \do@comblines@h.
  % We insert at most one row of pq@index:
  \increment@index{pq@index}%
  \ifnum \value{pq@index} > \last@pq@index\relax
    % Do nothing!
  \else
    Aufg. \refto@index{pq@index}%
    \hidden@ampersand
    \addtocounter{cols@done}{1}%
  \fi
  \ifnum \value{pq@index} < \last@pq@index\relax
    \ifnum \value{cols@done} < \value{num@cols}\relax
      \let\nextdo@pq@indexloop@h=\do@pq@indexloop@h
    \else
      \let\nextdo@pq@indexloop@h=\relax
    \fi
  \else
    \let\nextdo@pq@indexloop@h=\relax
  \fi
  \nextdo@pq@indexloop@h
}% do@pq@indexloop@h

\def\do@ptloop@h{%
  % Called by both \do@lines@h and \do@comblines@h.
  % We insert at most one row of non-bonus point values:
  \increment@index{pq@index@pts}%
  \ifnum \value{pq@index@pts} > \last@pq@index\relax
    % Do nothing!
  \else
    \addtocounter{cols@done}{1}%
    \pointsof@index{pq@index@pts}%
    \hidden@ampersand
    \addto@hlfcntr{tbl@points}{\pointsof@index{pq@index@pts}}%
  \fi
  \ifnum \value{pq@index@pts} < \last@pq@index\relax
    \ifnum \value{cols@done} < \value{num@cols}\relax
      \let\nextdo@ptloop@h=\do@ptloop@h
    \else
      \let\nextdo@ptloop@h=\relax
    \fi
  \else
    \let\nextdo@ptloop@h=\relax
  \fi
  \nextdo@ptloop@h
}% do@ptloop@h

\def\do@note{%
  % Called by both \do@lines@h and \do@comblines@h.
  % We insert (\value{num@cols} - \value{cols@done}) ampersands,
  % and then either \@htword or \@bhtword or \@chtword:
  \setcounter{@iterator}{\value{num@cols}}%
  \addtocounter{@iterator}{-\value{cols@done}}%
  \do@shortemptycols@h
  \if@combined
      Gesamt \hidden@ampersand \textbf{Note}
  \else
    \if@bonus
      Gesamt \hidden@ampersand \textbf{Note}
    \else
      Gesamt \hidden@ampersand \textbf{Note}
    \fi
  \fi
}% do@note

\def\do@totalpts@h{%
  % Called by both \do@lines@h and \do@comblines@h.
  % We insert (\value{num@cols} - \value{cols@done}) ampersands
  % and then the total points:
  \setcounter{@iterator}{\value{num@cols}}%
  \addtocounter{@iterator}{-\value{cols@done}}%
  \do@shortemptycols@h
  \prt@tablepoints
}% do@totalpts@h

\def\do@shortemptycols@h{%
  % Called by \do@lines@h, \do@comblines@h, \do@note,
  % \do@totalpts@h, and \do@totalbpts@h.
  % We insert \value{@iterator} ampersands:
  \ifnum \value{@iterator} > 1\relax
    \hidden@ampersand
    \addtocounter{@iterator}{-1}%
    \let\nextdo@emptycols@h=\do@emptycols@h
  \else
    \let\nextdo@emptycols@h=\relax
  \fi
  \nextdo@emptycols@h
}% do@emptycols@h

产生以下结果: 在此处输入图片描述

所有文本部分都是硬编码的,因为在我的特定情况下不需要变化,但可以很容易地用变量替换。

相关内容