Как создать циклически генерируемую таблицу в зависимости от результата вычисления?

Как создать циклически генерируемую таблицу в зависимости от результата вычисления?

Как преподаватель голландского языка, я использую шкалу оценок от 1,0 до 10,0. Расчет оценки зависит от трех переменных: N-термин; балл студента; общее количество баллов за экзамен.

Я хотел бы, чтобы мои экзамены автоматически генерировали таблицу оценок, состоящую из четырех отдельных таблиц, каждая из которых содержит определенные части шкалы оценок: [1,0;3,2] и [3,3;5,4] и [5,5;7,7] и [7,8;10,0].

При N-term=1,0 и общем счете (включая ноль баллов), делящемся на четыре, это приведет к четырем таблицам одинаковой длины. Во многих других случаях — нет. Смотрите пример ниже.

Это пример для N-члена 0,0 и общего количества точек 47:

введите описание изображения здесь

Пока что у меня есть код, который делает большую часть трюка. Проблема, однако, в том, что длина каждой отдельной таблицы определяется вручную в коде. Мне бы очень хотелось, чтобы это также происходило автоматически.

Код написал мой бывший одноклассник; в большинстве моментов я не совсем понимаю, как он работает.

Создание таблицы работает с циклом foreach. Используемый \iотносится к баллам кандидата, где окончание таблицы зависит от оценки, соответствующей определенному количеству баллов.

Так что, возможно, \foreach \i in {0,...,\GetNumPoints} \while 1,0 =< \NormFormule =< 3.2что-то вроде этого работает лучше. Но я понятия не имею, как это можно сделать.

Какие-либо предложения?

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

решение1

Я переписал весь код с синтаксисом expl3, потому что я думаю, что это проще поддерживать в долгосрочной перспективе. Кроме того, так все стало немного проще. Я использовал пакет siunitxдля форматирования чисел.

Я думаю, что этот код то, что вам нужно: он выводит четыре столбца с требуемыми шкалами оценок. Длина столбцов различается в зависимости от количества баллов, которые вы можете получить.

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

введите описание изображения здесь


Ибо \question[47]вы получите:

введите описание изображения здесь


Для \question[47]и \SetPointsNterm{0.0}вы получите:

введите описание изображения здесь

Связанный контент