![声明变量和编写循环](https://linux22.com/image/288958/%E5%A3%B0%E6%98%8E%E5%8F%98%E9%87%8F%E5%92%8C%E7%BC%96%E5%86%99%E5%BE%AA%E7%8E%AF.png)
我的考试模板包含一个表格,列出了考试中每道题的分值。有没有办法在 latex 中将每道题的分值声明为变量,然后编写代码来自动生成该表格?
\documentclass[letterpaper]{article}
\usepackage{amsthm}
\theoremstyle{definition}
\newtheorem{problem}{Problem}
\begin{document}
\begin{center}
\begin{tabular}{|c|c|c|}
\hline
Problem & Points & Score \\ \hline
1 & 12 & \\ \hline
2 & 17 & \\ \hline
Total & 29 & \\ \hline
\end{tabular}
\end{center}
\begin{problem}[12 Points]
Problem statement.
\end{problem}
\begin{problem}[17 Points]
Problem statement.
\end{problem}
\end{document}
答案1
面对与列表相关的任何内容,我都会使用etoolbox
。以下内容可能有些过度(主要是为了定制);实际列表处理材料的核心在\addqpoint
和中\printqlist
;其余部分的设计确实是为了使用户界面可行。
为了使事情保持一致,我对代码进行了相当广泛的注释。
\documentclass{article}
\usepackage{etoolbox}% for list handlig
\usepackage{booktabs}% for nice tables
% We define a list. Questions and points
% will be placed into the list as \qpoint{question}{points}
\newcommand{\qplist}{}
% A counter for question numbers
\newcounter{qnum}
% And a counter for total points
\newcounter{totalpoints}
% And one for the points of a particular question
\newcounter{thisqpoints}
% And (for ease of customization) the name for a question, points, score,
% so these could be changed to "marks" or whatever
\newcommand{\questionname}{Question}
\newcommand{\spoint}{point}% singular
\newcommand{\ppoint}{points}% plural
\newcommand{\Score}{Score}
\newcommand{\Points}{Points}
\newcommand{\Pointstotal}{Total}
% And a command that prints the points at the end of a qustion
\newcommand{\printpoints}{%
\ifnumcomp{\value{thisqpoints}}{=}{1}
{\arabic{thisqpoints}~\spoint}
{\arabic{thisqpoints}~\ppoint}}
% We define a command to allow resetting of the list
\newcommand{\resetqplist}{\renewcommand{\qplist}{}}
% ... and a command to add a something to the list
% \addqpoint{question}{list}
\newcommand{\addqpoint}[2]{%
\listxadd{\qplist}{{#1}{#2}}}
% To print the list we simply iterate over it expanding as we go
\newcommand{\printqplist}{%
\gdef\do##1{\qpoint ##1 \\}%
\setcounter{totalpoints}{0}%
\dolistloop{\qplist}}
% This is the main internal command: it is designed for use in a
% table, and updates the totalpoints counter
\newcommand{\qpoint}[2]{%
\addtocounter{totalpoints}{#2}%
& #1 & #2}
% So far all the commands are "internal". Now the user interface
\newenvironment{question}[1][]
{\refstepcounter{qnum}%
\ifblank{#1}% If no points are given, nothing is added to the list
{\setcounter{thisqpoints}{0}}
{\setcounter{thisqpoints}{#1}%
\addqpoint{\arabic{qnum}}{#1}}%
\subsection*{\questionname~\arabic{qnum}}}
{\ifnumcomp{\value{thisqpoints}}{>}{0}% print the points only if there are some!
{\marginpar{\printpoints}}
{}%
\par\bigskip}%
\newcommand{\printpointstable}{%
\subsection*{\Points}
\setcounter{totalpoints}{0}%
\par\noindent
\begin{tabular}{lcrl}
\toprule
& \questionname & \Points & \Score \\
\midrule
\printqplist
\midrule
& \bfseries\Pointstotal & \bfseries\arabic{totalpoints} \\
\bottomrule
\end{tabular}}
\begin{document}
\begin{question}[2]
Is this a question?\label{q:1}
\end{question}
\begin{question}[3]
How well do you consider you answered question \ref{q:1}?
\end{question}
\begin{question}
And how many points for this?
\end{question}
\printpointstable
\end{document}
(话虽如此,我宁愿使用其他人专门开发的类,也不愿自己开发。证据是:我发布的第一个版本有一个难以发现的扩展错误,我希望现在已经解决了!)
答案2
正如我在我的文章中提到的评论, 这exam
文档类开箱即可完成。此外,它还具有许多其他功能,您在考试时可能会发现它们很有用,如果您不喜欢默认布局/样式,还可以使用自定义选项。
代码
对于您的基本 MWE,等效代码如下:
\documentclass[addpoints]{exam}
\begin{document}
\begin{center}
\vqword{Problem} % change table heading text from the default ``Question''
\gradetable % print a grade table (much customization possible here)
\end{center}
\begin{questions}
\question[12] % optional argument gives point value
Problem statement.
\question[17]
Problem statement.
\end{questions}
\end{document}
输出
答案3
在 TeX(如 M4)中,数据结构表示为未求值处理,循环是通过将未求值处理绑定到适当的过程并求值数据结构来实现的。例如,我们定义一个列表,如下所示
\def\kinglist{\\{Louis IX}\\{Louis X, dit le hutin}\\{Louis XI}}
为了处理这三项,\kinglist
我们绑定\\
到适当的处理,例如
\def\paraking#1{#1\par}
\def\lineking#1{ #1}
\let\\=\paraking
\kinglist
\let\\=\lineking
\kinglist
\let\\=\undefined
如果我们要定义一个真的数据结构,我们肯定会添加记账宏,例如允许将项目添加到列表中的宏。
在你的情况下,你可以定义宏\problemtable
,\problempop
这样你就可以输入你的原始表格
\begin{center}
\begin{tabular}{|c|c|c|}
\hline
Problem & Points & Score \\ \hline
1 & 12 & \\ \hline
2 & 17 & \\ \hline
Total & 29 & \\ \hline
\end{tabular}
\end{center}
作为
\newcommand\problemlist{\\{{1}{12}}\\{{2}{17}}}
\problemtable
我们希望\problemtable
扩展到您编写的表格。应该\problempop
在您的环境中使用来problem
准备文本(带有问题编号和分数)和pop
的第一个元素\problemlist
。
如果您想避免自己做这件事的乐趣,您可以使用其他人建议的包。