# Dynamic number interval conversion table

I am a teacher and I need to use for all of my exams a table converting intervals of so called "value points" to points comprised between 0 and 20. I use the following table:

\documentclass[addpoints,12pt]{exam}

\newcolumntype{?}[1]{!{\vrule width #1}} % to have bold vertical line in tabular
\usepackage{makecell} % to be able to use \\  linebreaks in tabular

\begin{document}

\setlength\tabcolsep{0.25em}
\begin{tabular}{| p{1.3cm} |c | c | c | c | c |  c | c |  c | c |  c  ?{1mm} c |  c |  c | c |  c |  c | c | c | c | c | c  |}
\hline
Value points & \makecell{0\\-\\3}  & \makecell{4\\-\\7}  & \makecell{8\\-\\11}  & \makecell{12\\-\\15}  & \makecell{16\\-\\19}  & \makecell{20\\-\\23}  & \makecell{24\\-\\27}  & \makecell{28\\-\\31} & \makecell{32\\-\\35}  & \makecell{36\\-\\39} &
\makecell{40\\-\\43}  & \makecell{44\\-\\47}  & \makecell{48\\-\\51}  & \makecell{52\\-\\55}  & \makecell{56\\-\\59}  & \makecell{60\\-\\63}  & \makecell{64\\-\\67}  & \makecell{68\\-\\71}  & \makecell{72\\-\\75}  & \makecell{76\\-\\79}  & \makecell{80\\-\\83}  \\
\hline
Marks & 0&  1 & 2 & 3 & 4 & 5 & 6& 7& 8 & 9 & 10 & 11 & 12 & 13 & 14 &15 & 16 & 17 & 18 & 19 & 20  \\
\hline
\end{tabular}
}

\end{document}


These value points are different for all exams (in this example the maximum number is 83, but it may be any other number), whereas points are always between 0 and 20. So the the second line in the table should be fixed, and the number of columns also. I would like to fill the first line dynamically depending on the maximum number, so somehow every cell in the first row should be filled in a for loop. How could I achieve this?

• Welcome to TeX.SX! Please make your code compilable (if possible), or at least complete it with \documentclass{...}, the required \usepackage's, \begin{document}, and \end{document}. That may seem tedious to you, but think of the extra work it represents for TeX.SX users willing to give you a hand. Help them help you: remove that one hurdle between you and a solution to your problem. Jan 28, 2022 at 16:49
• What are the real rules for assessing a final mark? In the case of 83 it's easy: you just divide into 21 equal intervals. But what if the total number is 97? Jan 28, 2022 at 17:37
• I thought of a linear function like (value-point)*21/(maximum number)-1, where the result is always round up Jan 28, 2022 at 17:50
• Add \usepackage{array} before \newcolumntype... to make your example compilable. Jan 28, 2022 at 17:55

With the table dimensions being fixed, you can set a number of formulae in each cell that define the range. Below I define \lrange{<num>} and \urange{<num>} where you specify the lower and upper range block (from 0 to 20) and xfp is used to figure out the corresponding lower/upper range values. The total/maximum score for the test is held inside \ms (but this could be changed to automatically pick up the total score on the test).

\documentclass[addpoints,12pt]{exam}

\usepackage{booktabs,xfp,array}

\newcommand{\ms}{83}
\newcommand{\passfail}{10}
\newcommand{\lrange}[1]{%
\ifnum#1<\passfail
%\itshape% fail
\else
\bfseries% pass
\fi
\fpeval{#1 > 0 ? floor((\ms / 21) * #1 + 1, 0) : 0}
}%
\newcommand{\urange}[1]{%
\ifnum#1<\passfail
%\itshape% fail
\else
\bfseries% pass
\fi
\fpeval{floor((\ms / 21) * (#1 + 1), 0)}%
}

\begin{document}

\begingroup
\small
\setlength\tabcolsep{0.25em}
\begin{tabular}{ r *{21}{ w{c}{1em} } }
\toprule
& \multicolumn{21}{c}{Point range on this test (\textbf{pass} / fail)} \\
\cmidrule{2-22}
from & \lrange{0} & \lrange{1} & \lrange{2} & \lrange{3} & \lrange{4} & \lrange{5} & \lrange{6} & \lrange{7} & \lrange{8} & \lrange{9} & \lrange{10} &
\lrange{11} & \lrange{12} & \lrange{13} & \lrange{14} & \lrange{15} & \lrange{16} & \lrange{17} & \lrange{18} & \lrange{19} & \lrange{20} \\[\dimexpr-\normalbaselineskip+0.7em]
& -- & -- & -- & -- & -- & -- & -- & -- & -- & -- & -- & -- & -- & -- & -- & -- & -- & -- & -- & -- & -- \\[\dimexpr-\normalbaselineskip+0.8em]
to   & \urange{0} & \urange{1} & \urange{2} & \urange{3} & \urange{4} & \urange{5} & \urange{6} & \urange{7} & \urange{8} & \urange{9} & \urange{10} &
\urange{11} & \urange{12} & \urange{13} & \urange{14} & \urange{15} & \urange{16} & \urange{17} & \urange{18} & \urange{19} & \bfseries\ms \\
\midrule
Marks & 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 11 & 12 & 13 & 14 & 15 & 16 & 17 & 18 & 19 & 20  \\
\bottomrule
\end{tabular}
\endgroup

\end{document}


Of course, I played around with the formatting, which you can revert to your style.

Edit (1): In the first try I miss the question point.

Use of idea proposed in @Werner answer adapted to tabularray package the table code can be:

Edit (2): In calculation of points ranges is (now) used colnum defined in tabularray package.

Edit (3): Any range at \fpeval{ceil(83/21*(\thecolnum-2)} (because the first ranges start with 0) and end at \fpeval{floor(83/21*(\thecolnum-1))-1} with exception at the last range, which end with maximal number of points (\mr). Considering this, the calculation algorithm is:

    \newcommand{\mr}{42} % <--- maximum of ranges
\newcommand{\range}%
{\fpeval{ceil(\mr/21*(\thecolnum-2))}
\\---\\
\ifnum\thecolnum=22%
\vphantom{i}\mr
\else
\vphantom{i}\fpeval{ceil(\mr/21*(\thecolnum-1))-1}%
\fi}


where \mr maximum ranges value. From algorthm follows that it has sense, when \mr is equal or bigger than 42.

Complete MWE is:

\documentclass[12pt]{exam}
\usepackage{xfp}
\newcommand{\mr}{83}
\newcommand{\range}%
{\fpeval{ceil(\mr/21*(\thecolnum-2))}
\\---\\
\ifnum\thecolnum=22%
\vphantom{i}\mr
\else
\vphantom{i}\fpeval{ceil(\mr/21*(\thecolnum-1))-1}%
\fi}
\usepackage{tabularray}

\begin{document}
\begin{table}[ht]
%\small
\begin{tblr}{hlines,
vline{1-11}={solid}, vline{12}={1pt}, vline{13-Z}={solid},
colspec = {@{\,}Q[l,m, wd=1.3cm]
*{21}{ X[c,m] }
},
colsep=0pt,
}
Points ranges   & \range    & \range    & \range
& \range    & \range    & \range
& \range    & \range    & \range
& \range    & \range    & \range
& \range    & \range    & \range
& \range    & \range    & \range
& \range    & \range    & \range    \\
Marks           & 0  &  1 &  2  &  3 &  4 &  5  &  6 &  7 &  8
& 9  & 10 & 11  & 12 & 13  & 14 & 15 & 16 & 17
& 18 & 19 & 20  \\
\end{tblr}
\end{table}
\end{document}


• Why you need \relax in the font options? Jan 30, 2022 at 9:43
• @L.J.R., actually it is not needed. I sow somewhere a recommendation to use it, but I forgot when and where :-(. After then I use it. it may be a time to investigate this again and change my habits. Jan 30, 2022 at 9:53