动态数区间换算表

动态数区间换算表

我是一名教师,我需要在所有考试中使用一个表格,将所谓的“价值点”间隔转换为 0 至 20 之间的点数。我使用下表:

\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}
{\renewcommand{\arraystretch}{1}% for the vertical padding
\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} 

这些分值对于所有考试都是不同的(在这个例子中,最大分数是 83,但也可以是任何其他数字),而分数总是在 0 到 20 之间。因此,表格中的第二行应该是固定的,列数也应该是固定的。我想根据最大数字动态填充第一行,因此应该以某种方式在 for 循环中填充第一行中的每个单元格。我该如何实现呢?

答案1

在表格尺寸固定的情况下,您可以在每个单元格中设置多个公式来定义范围。下面我定义了\lrange{<num>}\urange{<num>}指定了lower 和upper 范围块(从 0 到 20)以及xfp用于计算相应的下限/上限值。测试的总分/m最高分s核心保存在里面\ms(但可以将其更改为自动获取测试的总分)。

在此处输入图片描述

\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}
  \renewcommand{\arraystretch}{1}% for the vertical padding
  \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} 

当然,我对格式进行了一些调整,您可以将其恢复为您自己的风格。

答案2

编辑(1): 第一次尝试时我错过了问点。

使用@Werner 答案中提出的想法来tabularray打包表代码可以是:

编辑(2): 在计算点范围时(现在)使用包colnum中定义的。tabularray

编辑(3): 任意范围\fpeval{ceil(83/21*(\thecolnum-2)}(因为第一个范围从 0 开始)并结束于,\fpeval{floor(83/21*(\thecolnum-1))-1}但最后一个范围除外,它以最大点数结束(\mr)。考虑到这一点,计算算法为:

    \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}

其中最大范围值。从算法可以看出,当等于或大于 42 时,\mr它是有意义的。\mr

完整的 MWE 是:

\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,
             cell{1,2}{2-11} = {font=\linespread{0.5}\relax},
             cell{1,2}{12-Z} = {font=\bfseries\linespread{0.5}\relax}
            }
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} 

在此处输入图片描述

相关内容