1

I asked a question a couple of months ago about tweaking the gradetable setup using the exam document class, and I have based a considerable amount of work off of an answer provided there. Today I updated my distribution (MiKTeX) to install the latest exam.cls file (I am running MiKTeX version 2.9 with exam.cls version 2.6), and now my documents encounter the following problem:

Error: ! Class exam Error: The number of columns in a table must be positive. (exam)

Below is the code from the linked to answer that will reproduce the error. My question is simply how I can create a workaround so that I can still compile the numerous documents I have created that now encounter this problem.


\documentclass[addpoints]{exam}
\usepackage{twoopt}

\makeatletter

\newcommandtwoopt{\emptygradetable}[2][v][questions]{{%
  \renewcommand{\pointsofquestion}[1]{}
  \renewcommand{\prt@tablepoints}{}
  \@scorestrue
  \@bonusfalse
  \@partialfalse
  \@combinedfalse
  \ii@gtable{#1}[#2]%
}}

\newcommandtwoopt{\emptybonusgradetable}[2][v][questions]{{%
  \renewcommand{\bonuspointsofquestion}[1]{}
  \renewcommand{\prt@tablebonuspoints}{}
  \@scorestrue
  \@bonustrue
  \@partialfalse
  \@combinedfalse
  \ii@gtable{#1}[#2]%
}}

\newcommandtwoopt{\emptypartialgradetable}[3][v][questions]{{%
  \renewcommand{\pointsofquestion}[1]{}
  \renewcommand{\prt@tablepoints}{}
  \@scorestrue
  \@bonusfalse
  \@partialtrue
  \@combinedfalse
  \def\tbl@range{#3}%
  \ii@gtable{#1}[#2]%
}}%

\newcommandtwoopt{\emptypartialbonusgradetable}[3][v][questions]{{%
  \renewcommand{\bonuspointsofquestion}[1]{}
  \renewcommand{\prt@tablebonuspoints}{}
  \@scorestrue
  \@bonustrue      
  \@partialtrue
  \@combinedfalse
  \def\tbl@range{#3}%
  \ii@gtable{#1}[#2]%
}}%

\makeatother

\begin{document}
\emptygradetable[h]

\bigskip

\emptybonusgradetable[v]

\bigskip

\emptypartialgradetable[h][questions]{myrange}

\bigskip

\emptypartialbonusgradetable[v][questions]{myrange}   

\bigskip

\begin{questions}
\question[10] Question 1
\question[20] Question 2

\begingradingrange{myrange}
\bonusquestion[15] Question 3
\question[10] Question 4
\question[15] Question 5
\endgradingrange{myrange}
\end{questions}

\end{document}

Added: I found version 2.5 of exam.cls, and there are at least two pieces of code missing that are now present in the most recent version (2.603) of exam.cls, but I don't see this documented anywhere in the "changelog since version 2.4":

Rows (lines 6218-6236 for version 2.6):

%--------------------------------------------------------------------
% Check that the number of rows is OK, and compute the number of
% columns:

\def\check@num@rows@h{%
  % We get here from \tbl@v@or@h.
  % We make sure the number of rows is a positive integer.  If it
  % is, we go on to \@computenumcols@h
  \ifnum \value{num@rows} < 1\relax
    \ClassError{exam}{%
      The number of rows in a table must be positive.\MessageBreak
    }{%
      The number of rows must be a positive integer.\MessageBreak
    }%
    \fbox{\textbf{Error:} Multirow table with no rows!}%
  \else
    \@computenumcols@h
  \fi
}% check@num@rows@h

Columns (lines 6728-6754 for version 2.6):

% Check that the number of cols is OK, and compute the number of rows:

\def\check@num@cols@v{%
  % We get here from \tbl@v@or@h.
  % We make sure the number of cols is between 1 and 10 (since we
  % can't handle more than 10 cols in a multicolumn table).
  % If it is, we go on to \@computenumrows@v
  \ifnum \value{num@cols} < 1\relax
    \ClassError{exam}{%
      The number of columns in a table must be positive.\MessageBreak
    }{%
      The number of columns must be a positive integer.\MessageBreak
    }%
    \fbox{\textbf{Error:} Multicolumn table with no columns!}%
  \else
    \ifnum \value{num@cols} > 10\relax
      \ClassError{exam}{%
        Multicolumn tables can have at most 10 columns.\MessageBreak
      }{%
        Multicolumn tables can have at most 10 columns.\MessageBreak
      }%
      \fbox{\textbf{Error:} Multicolumn table with more than 10 columns!}%
    \else
      \@computenumrows@v
    \fi
  \fi
}% check@num@cols@v

Added: I ran the code above using version 2.5 of exam.cls and everything works just fine, but there's clearly an issue with the code and using version 2.6. I hope a LaTeX sleuth may be able to figure out what's going on, but I'll be reverting back to the older version of exam.cls until I can either figure this out myself (unlikely) or someone else can show me the light.

3

Starting in version 2.6 of exam.cls, you can create multicolumn or multirow grade tables or point tables, and the older code that created single column (or single row) tables was removed in favor of using the code for multicolumn tables with 1 column and multirow tables with 1 row. Your code tries to skip over the \gradetable etc. commands by setting the internal parameters used by exam.cls in the hope that exam.cls won't notice, but since version 2.6 there are extra parameters to be set.

I don't recommend that anyone do what you're doing, but: if you add the commands

\setcounter{num@cols}{1}
\setcounter{num@rows}{1}

to all of your commands that bypass \gradetable etc., your code works. Take a look at the definitions of \gradetable, \pointtable, etc. to see that these are what you're missing.

Edit, added later: Here's a better solution. It does the exact same thing that your code does, but it's more "futureproof" in that it uses less knowledge of the internals of exam.cls. It also works well with both version 2.5 and version 2.603 of exam class.

The new definition of \emptygradetable is

\newcommandtwoopt{\emptygradetable}[2][v][questions]{{%
  \renewcommand{\pointsofquestion}[1]{}%
  \settabletotalpoints{}%
  \gradetable[#1][#2]%
}}

If you check the definition of \settabletotalpoints, you'll see that this does exactly what your earlier command does. These new versions of the commands also don't require \makeatletter and \makeatother.

The whole latex file is then

\documentclass[addpoints]{exam}
\usepackage{twoopt}


\newcommandtwoopt{\emptygradetable}[2][v][questions]{{%
  \renewcommand{\pointsofquestion}[1]{}%
  \settabletotalpoints{}%
  \gradetable[#1][#2]%
}}

\newcommandtwoopt{\emptybonusgradetable}[2][v][questions]{{%
  \renewcommand{\bonuspointsofquestion}[1]{}%
  \settabletotalbonuspoints{}%
  \bonusgradetable[#1][#2]%
}}

\newcommandtwoopt{\emptypartialgradetable}[3][v][questions]{{%
  \renewcommand{\pointsofquestion}[1]{}%
  \settabletotalpoints{}%
  \partialgradetable{#3}[#1][#2]%
}}

\newcommandtwoopt{\emptypartialbonusgradetable}[3][v][questions]{{%
  \renewcommand{\bonuspointsofquestion}[1]{}%
  \settabletotalbonuspoints{}%
  \partialbonusgradetable{#3}[#1][#2]%
}}


\begin{document}
\emptygradetable[h]



\bigskip

\emptybonusgradetable[v]

\bigskip

\emptypartialgradetable[h][questions]{myrange}

\bigskip

\emptypartialbonusgradetable[v][questions]{myrange}   

\bigskip

\begin{questions}
\question[10] Question 1
\question[20] Question 2

\begingradingrange{myrange}
\bonusquestion[15] Question 3
\question[10] Question 4
\question[15] Question 5
\endgradingrange{myrange}
\end{questions}

\end{document}
  • Thanks for your answer, Phil. I actually want to use exam.cls to motivate my more serious study of TeX and LaTeX in general. It's such an incredibly useful and robust document class. Can I ask why you don't recommend what I'm doing? I'm sure it comes across as incredibly hacky and not elegant at all, but I was hoping you might expand on that comment a bit so I can maybe benefit from your explanation. Thanks! – Daniel W. Farlow Dec 18 '17 at 5:39
  • I don't think your code is at all unelegant, it's just that you're using internal, undocumented things about exam.cls which, being undocumented, are not promised to remain unchanged. This is why you didn't find an explanation in the changelog of exam.cls. I'm certainly not planning on changing anything that you're using, and I hope not to have to mess with this code again anytime soon, but you never know... I am pleased to learn that people are finding exam.cls useful, even if they're using it in ways I hadn't expected, and I hope this continues to work for you. – Phil Hirschhorn Dec 18 '17 at 5:48
  • Thanks for the clarification. That makes complete sense. I have found it to be extremely useful. At the risk of possibly embarrassing myself, this is a document I created for my (high school) calculus students using exam.cls. There's another version where I've written out full solutions to all of the problems, and I think that would have been an enormous headache without the nifty way the solution environment works. Also, the "grade tables" in this case my students found very useful for tracking progress. – Daniel W. Farlow Dec 18 '17 at 5:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.