¿Cómo hacer una tabla generada en bucle en función del resultado de un cálculo?

¿Cómo hacer una tabla generada en bucle en función del resultado de un cálculo?

Como profesora de holandés, mi escala de calificaciones va del 1,0 al 10,0. El cálculo de la nota depende de tres variables: el término N; la puntuación del estudiante; el número total de puntos del examen.

Me gustaría que mis exámenes generen automáticamente una tabla de calificaciones que consta de cuatro tablas separadas donde cada tabla contiene partes específicas de la escala de calificaciones: [1,0;3,2] y [3,3;5,4] y [5,5;7,7] y [7,8;10,0].

Con N-term=1,0 y una puntuación total (incluidos cero puntos) divisible por cuatro, se obtendrán cuatro tablas de la misma longitud. En muchos otros casos no. Vea el ejemplo a continuación.

Este es un ejemplo para un término N de 0,0 y un número total de 47 puntos:

ingrese la descripción de la imagen aquí

Hasta ahora, tengo un código que hace la mayor parte del truco. Sin embargo, el problema es que la longitud de cada tabla separada se determina manualmente en el código. Realmente me gustaría que esto también fuera automático.

Un ex compañero de clase escribió el código; en la mayoría de las partes no estoy seguro de cómo funciona.

La confección de la mesa se realiza con un bucle foreach. El \ique se utiliza se refiere a los puntos del candidato, donde el final de la tabla depende de la calificación correspondiente a una determinada cantidad de puntos.

Entonces tal vez \foreach \i in {0,...,\GetNumPoints} \while 1,0 =< \NormFormule =< 3.2algo así funcione mejor. Pero no tengo idea de cómo se puede hacer.

¿Alguna sugerencia?

\documentclass[addpoints]{exam}

\usepackage{tikz}

%-----------------------------------------
% The Nterm determines which grade correspends to which grade; this is normally a number between 0,0 and 2,0
%-----------------------------------------
\newcommand{\Nterm}{1.0}

%-----------------------------------------
% This is some prework that needs to be done
%-----------------------------------------
\makeatletter
   \providecommand{\exam@numpoints}{1}%
   \newcommand{\GetNumPoints}{\exam@numpoints}%
    \newcommand*{\@MyTempTableTokens}{}%
    \newtoks\@tabtoks
    %%% assignments to \@tabtoks must be global, because they are done in \foreach
    \newcommand\AddTableTokens[1]{\global\@tabtoks\expandafter{\the\@tabtoks#1}}
    \newcommand\eAddTableTokens[1]{% 
        \protected@edef\@MyTempTableTokens{#1}%
        \expandafter\AddTableTokens\expandafter{\@MyTempTableTokens}}
    %%% variable should always be operated on either always locally or always globally
    \newcommand*\ResetTableTokens{\global\@tabtoks{}}
    \newcommand*\PrintTableTokens{\the\@tabtoks}
\makeatother
\newcommand*{\NormFormule}[1]{%
    \pgfmathparse{
        \ifdim \Nterm pt < 1 pt
            max(
                9 * ( #1 / \GetNumPoints ) + \Nterm ,
                1 + ( #1 * ( 9 / \GetNumPoints ) * 0.5 ),
                10 - ( \GetNumPoints - #1 ) * ( 9 / \GetNumPoints ) * 2
            )
        \else
            min(
                9 * ( #1 / \GetNumPoints ) + \Nterm ,
                1 + ( #1 * ( 9 / \GetNumPoints ) * 2 ),
                10 - ( \GetNumPoints - #1 ) * ( 9 / \GetNumPoints ) * 0.5
            )       
        \fi
    }
    \pgfmathprintnumber[fixed, precision=1, fixed zerofill, use comma]{\pgfmathresult}}


%-----------------------------------------
% This is the command for making the table; which works fine. Except for needing to manually define the length of the specific tables
%-----------------------------------------
\newcommand{\maketable}{\bigskip
\Huge Grading Table\bigskip\\\normalsize
    \ResetTableTokens
    \foreach \i in {0,...,14}   %THIS IS WHERE I GOT STUCK!
    {\eAddTableTokens{\i & \noexpand\NormFormule{\i} \\}}{}                 
        \begin{minipage}[t]{.23\textwidth}\centering$(1{,}0-3{,}2)$\\       
            \begin{tabular}{|c|c|}
                \hline
                \textbf{score}&\textbf{grade}\\\hline\centering
                \PrintTableTokens
                \hline
            \end{tabular}
        \end{minipage}  
    \ResetTableTokens
    \foreach \i in {15,...,29} {\eAddTableTokens{\i & \noexpand\NormFormule{\i} \\}}
        \begin{minipage}[t]{.23\textwidth}\centering$(3{,}3-5{,}4)$\\
            \begin{tabular}{|c|c|}
                \hline
                \textbf{score}&\textbf{grade}\\\hline\centering
                \PrintTableTokens
                \hline
            \end{tabular}
        \end{minipage}          
    \ResetTableTokens
    \foreach \i in {30,...,44} {\eAddTableTokens{\i & \noexpand\NormFormule{\i} \\}}
        \begin{minipage}[t]{.23\textwidth}\centering$(5{,}5-7{,}7)$\\
            \begin{tabular}{|c|c|}
                \hline
                \textbf{score}&\textbf{grade}\\\hline\centering
                \PrintTableTokens
                \hline
            \end{tabular}
        \end{minipage}      
    \ResetTableTokens
    \foreach \i in {45,...,\GetNumPoints} {\eAddTableTokens{\i & \noexpand\NormFormule{\i} \\}}
        \begin{minipage}[t]{.23\textwidth}\centering$(7{,}8-10{,}0)$\\
            \begin{tabular}{|c|c|}
                \hline
                \textbf{score}&\textbf{grade}\\\hline\centering
                \PrintTableTokens
                \hline
            \end{tabular}
        \end{minipage}
}


%-----------------------------------------
% And here the actual exam begins
%-----------------------------------------

\begin{document}

\begin{questions}
    \question[60]
    The content of this question is irrelevant.
\end{questions}

\maketable

\end{document}

Respuesta1

Reescribí el código completo con sintaxis expl3, porque creo que es más fácil de mantener a largo plazo. Además, las cosas se volvieron un poco más fáciles de esta manera. Utilicé el siunitxpaquete para formatear los números.

Creo que este código es lo que desea: genera cuatro columnas con las escalas de calificación requeridas. La longitud de las columnas varía dependiendo de la cantidad de puntos que puedas obtener.

\documentclass[addpoints]{exam}
% use siunitx to format numbers
\usepackage{siunitx}
\sisetup{
    round-mode = places,
    round-precision = 1,
    output-decimal-marker = {,}
}

\ExplSyntaxOn

% variable that stores the amount of exam points
\fp_new:N \g_kenadams_exampoints_exampoints_fp
\fp_gset:Nn \g_kenadams_exampoints_exampoints_fp { 1.0 }

% variable that stores the nterm
\fp_new:N \g_kenadams_exampoints_nterm_fp
\fp_gset:Nn \g_kenadams_exampoints_nterm_fp { 1.0 }
% command to change the nterm
\NewDocumentCommand{\SetPointsNterm}{ m }{
    \fp_gset:Nn \g_kenadams_exampoints_nterm_fp { #1 }
}

\makeatletter
% internal command to retrieve the current amount of exam points
% set by the exam class
\cs_new:Npn \kenadams_exampoints_update: {
    \cs_if_exist:cT { exam@numpoints } {
        \fp_gset:Nn \g_kenadams_exampoints_exampoints_fp { \exam@numpoints }
    }
}
\makeatother

% internal command to calculate a score from a given point value
% the logic is taken over from the original code
\cs_new:Npn \kenadams_exampoints_calculatescore:n #1 {
    \fp_eval:n {
        round( \g_kenadams_exampoints_nterm_fp < 1 ? 
            max(
                9 * ( #1 / \g_kenadams_exampoints_exampoints_fp ) + \g_kenadams_exampoints_nterm_fp ,
                1 + ( #1 * ( 9 / \g_kenadams_exampoints_exampoints_fp ) * 0.5 ),
                10 - ( \g_kenadams_exampoints_exampoints_fp - #1 ) * ( 9 / \g_kenadams_exampoints_exampoints_fp ) * 2
            )
        : 
            min(
                9 * ( #1 / \g_kenadams_exampoints_exampoints_fp ) + \g_kenadams_exampoints_nterm_fp ,
                1 + ( #1 * ( 9 / \g_kenadams_exampoints_exampoints_fp ) * 2 ),
                10 - ( \g_kenadams_exampoints_exampoints_fp - #1 ) * ( 9 / \g_kenadams_exampoints_exampoints_fp ) * 0.5
            ) 
        , 1 , 1 )
    }
}

% internal variable (counter) that stores the current table row 
\int_new:N \g_kenadams_exampoints_tablerow_int
% internal command to create a part of the set of tables
\cs_new:Npn \kenadams_exampoints_tablepart:nnn #1 #2 {
    % clearing temporary sequence variable
    \seq_clear:N \l_tmpa_seq 
    % stepwise increase table row number as long as 
    % the calculated score from this value is less than #2
    \fp_do_until:nNnn { \kenadams_exampoints_calculatescore:n { \g_kenadams_exampoints_tablerow_int } } > { #2 } {
        % add formatted table row to sequence variable
        \seq_put_right:Nx \l_tmpa_seq { 
            \int_use:N \g_kenadams_exampoints_tablerow_int & 
            \num { \kenadams_exampoints_calculatescore:n { \g_kenadams_exampoints_tablerow_int } } 
        }
        \int_gincr:N \g_kenadams_exampoints_tablerow_int
    }
    
    \begin{minipage}[t]{.23\textwidth} \centering (\num{#1}--\num{#2}) \\       
        \begin{tabular}{ | c | c | }
            \hline
            \textbf{score} & \textbf{grade} \\ \hline
            % insert the values stored in the sequence variable
            % and add \\ after each item
            \seq_use:Nn \l_tmpa_seq { \\ } \\
            \hline
        \end{tabular}
    \end{minipage}
}

% command to print the grading table
\NewDocumentCommand{\MakePointsTable}{ }{
    % retrieve current amount of exam points
    \kenadams_exampoints_update:
    % reset table row counter
    \int_gzero:N \g_kenadams_exampoints_tablerow_int

    \bigskip
    \Huge Grading ~ Table 
    \bigskip \par
    \normalsize
    
    % typeset the four parts of the grading table
    \kenadams_exampoints_tablepart:nnn { 1.0 } { 3.2 }
    \kenadams_exampoints_tablepart:nnn { 3.3 } { 5.4 } 
    \kenadams_exampoints_tablepart:nnn { 5.5 } { 7.7 }
    \kenadams_exampoints_tablepart:nnn { 7.8 } { 10.0 }
}

\ExplSyntaxOff

%-----------------------------------------
% The Nterm determines which grade correspends to which grade; this is normally a number between 0,0 and 2,0
%-----------------------------------------
\SetPointsNterm{1.0}

\begin{document}

\begin{questions}
    \question[60]
    The content of this question is irrelevant.
\end{questions}

\MakePointsTable

\end{document}

ingrese la descripción de la imagen aquí


Para \question[47]usted obtendría:

ingrese la descripción de la imagen aquí


Para \question[47]y \SetPointsNterm{0.0}obtendrías:

ingrese la descripción de la imagen aquí

información relacionada