如何将 clist 的一个元素作为另一个函数的 int 参数传递?

如何将 clist 的一个元素作为另一个函数的 int 参数传递?

这是我的问题的最小例子:

我想将 a 的一个元素转换为 ,clist以便int能够将它们传递给另一个函数。这与 不符undefined control sequence。我做错了什么?

\documentclass{scrlttr2}

\ExplSyntaxOn

\NewDocumentCommand{\hours}{m}
{
    \fp_eval:n { #1 / 60 } h
}

\NewDocumentCommand{\strtime}{mm}
{
    \clist_clear_new:N \l__timelist_testing_clist
    \clist_put_right:Nn \l__timelist_testing_clist { #1 * 60 }
    
    \l__timelist_testing_clist \\
    \fp_eval:n {  \clist_item:nn { \l__timelist_testing_clist } {1} } \\
    \fp_eval:n { round( \fp_eval:n {  \clist_item:nn { \l__timelist_testing_clist } {1} }) } \\
    
    \int_set:Nn \l__timecalc_time_minutes_testing_int
        { \fp_eval:n { round( \fp_eval:n {  \clist_item:nn { \l__timelist_testing_clist } {1} }) } }
    
    \hours{ \l__timecalc_time_minutes_testing_int }
}
\ExplSyntaxOff

\begin{document}
    new:
    
    \strtime{2}{h}
    
\end{document}

=============================================================================== 要了解为什么我现在要这样做,请看完整的示例:

在这些宝贵帮助下,我能够创建一些函数来汇总不同单位(h,d,min)的时间值,然后以有用的方式显示该总和。

另外,我能够根据clist不同单位的时间值计算中值(如上所述)并将其返回。

我无法使用的相同功能然后以与总和一样有用的方式显示结果中值(以分钟为单位)。

不知何故,我无法将clist中值函数的输出变量转换为整数,以使其能够作为以有用的方式显示该分钟值的函数的有效输入......

\documentclass{scrlttr2}

\ExplSyntaxOn

\NewDocumentCommand{\newtime}{m}
{
    \fp_new:c { g__timecalc_time_#1_fp }
    \fp_new:c { g__timecalc_factor_#1_fp} % factor to divide the result by after the table
}
\newtime{default} % initialize one

% \addtime* will also show the added time
\NewDocumentCommand{\addtime}{sO{default}mm}
{
    \timecalc_time_add:nnn { #2 } { #3 } { #4 }
    
    % with \addtime* also show what's been added    
    \IfBooleanT{#1}{#3\,\textup{#4}}
}

% show the result of the sum in g__timecalc_time_#1_fp with biggest unit being #2
\NewDocumentCommand{\strtime}{O{default}m}
{
    \timecalc_time_str:nn { #1 } { #2 }
}

\int_new:N \l__timecalc_time_days_int
\int_new:N \l__timecalc_time_hours_int
\int_new:N \l__timecalc_time_minutes_int

% add the given time #2 with given unit #3 to __timecalc_time_#1_fp
\cs_new_protected:Nn \timecalc_time_add:nnn
{
    \str_case:nnF { #3 }
    {
        {h}{ \fp_gadd:cn { g__timecalc_time_#1_fp } { #2 * 60 } }
        {d}{ \fp_gadd:cn { g__timecalc_time_#1_fp } { #2 * 60 * 24 } }
        {min}{ \fp_gadd:cn { g__timecalc_time_#1_fp } { #2 } }
    }
    {\ERROR}
}

% calculate #1 = #1 / #2 and return the modulo in #3
\cs_new_protected:Nn \timecalc_int_div_mod:nnn {
    \int_set:Nn #3 
    { \int_div_truncate:nn { #1 } { #2 } }
    
    \int_set:Nn #1
    { \int_mod:nn { #1 } { #2 } }
}

% round the sum in g__timecalc_time_#1_fp and show value with biggest unit being #2
\cs_new_protected:Nn \timecalc_time_str:nn
{
    % round to full minutes
    \int_set:Nn \l__timecalc_time_minutes_int
    { \fp_eval:n { round( \fp_use:c { g__timecalc_time_#1_fp }, 0 ) } }
    
    \timecalc_time_strshow:nn \l__timecalc_time_minutes_int { #2 }
}

% show the value of \l__timecalc_time_minutes_int with biggest unit being #2
\cs_new_protected:Nn \timecalc_time_strshow:nn
{
    \bool_if:nTF
    {
        \str_if_eq_p:nn{#2}{d}
    }
    {%yes
        % compute and remove the number of days
        \timecalc_int_div_mod:nnn{\l__timecalc_time_minutes_int}{1440}{\l__timecalc_time_days_int}
        
        % now print the days
        \int_compare:nTF { \l__timecalc_time_days_int > 0 }
        { \int_eval:n { \l__timecalc_time_days_int }\,\textup{d}\; }
        {
            \unkern
        }
    }{} % no
    
    \bool_if:nTF
    {
        \str_if_eq_p:nn{#2}{h} ||
        \str_if_eq_p:nn{#2}{d} 
    }
    {% yes
        % compute and remove the number of hours
        \timecalc_int_div_mod:nnn{\l__timecalc_time_minutes_int}{60}{\l__timecalc_time_hours_int}
        
        % now print the hours
        \int_compare:nTF { \l__timecalc_time_hours_int > 0 }
        {
            \int_eval:n { \l__timecalc_time_hours_int }\,\textup{h}\;
        }
        {% no hours
            \unkern
        }       
    }{} % no
    
    
    % now print the minutes
    \int_compare:nTF { \l__timecalc_time_minutes_int > 0 }
    {
        \int_eval:n { \l__timecalc_time_minutes_int }\,\textup{min}
    }
    {% no minutes
        \unkern
    }
}

% =====================
%  time list and median calculations

% show the median of the clist in #1
\NewDocumentCommand{\listmedian}{m}
{
    \timelist_median:x { #1 }
}

\clist_new:N \l__timelist_median_clist
\int_new:N \l__timelist_median_int

\cs_new_protected:Nn \timelist_median:n
{
    % set a comma separated list
    \clist_set:Nn \l__timelist_median_clist { #1 }
    % sort it numerically
    \clist_sort:Nn \l__timelist_median_clist
    {
        \fp_compare:nTF { ##1 > ##2 }
        { \sort_return_swapped: }
        { \sort_return_same: }
    }
    % compute the number of items
    \int_set:Nn \l__timelist_median_int { \clist_count:N \l__timelist_median_clist }
    \int_if_odd:nTF {\l__timelist_median_int }
    {% if the number is odd, return the middle item
        \clist_item:Nn \l__timelist_median_clist { (\l__timelist_median_int + 1)/2 }
    }
    {% otherwise the average of the middle two elements
        \fp_eval:n
        {
            ( 
            \clist_item:Nn \l__timelist_median_clist { \l__timelist_median_int/2 }
            +
            \clist_item:Nn \l__timelist_median_clist { \l__timelist_median_int/2 + 1 }
            )/2
        }
    }
}
\cs_generate_variant:Nn \timelist_median:n { x }

\clist_clear_new:N \g__timelist_median_clist

\NewDocumentCommand{\addtimelist}{sO{default}mm}
{
    \str_case:nnF { #4 }
    {
        {h}{ \clist_gput_right:Nn { \g__timelist_median_clist } { #3 * 60 } }
        {d}{ \clist_gput_right:Nn { \g__timelist_median_clist } { #3 * 60 * 24 } }
        {min}{ \clist_gput_right:Nn { \g__timelist_median_clist } { #3 } }
    }
    {
        %\ERROR
    }
    
    \IfBooleanT{#1}{#3\,\textup{#4}}    
}

\NewDocumentCommand{\timelistmedian}{O{default}}
{
    \listmedian{ \g__timelist_median_clist }
}

% should show the 
\NewDocumentCommand{\strtimelist}{O{default}m}
{
    \listmedian{ \g__timelist_median_clist }

% ========================================================
% the code from here breaks

% round to full minutes
%   \int_set:Nn \l__timecalc_time_minutes_int
%   { \fp_eval:n { round( \fp_use:x { \listmedian{ \g__timelist_median_clist } }, 0 ) } } % cannot use clist as input for median?
%
%   \int_eval:N \l__timecalc_time_minutes_int
%\timecalc_time_strshow:nn \l__timecalc_time_minutes_int { #2 }
}



\ExplSyntaxOff

\begin{document}
    addtime:
    
    \addtime*{4}{min}
    
    \addtime*{5}{h}
    
    sum = 
    
    \strtime{h}
    
    \strtime{min}
    
    \bigskip
    addtimelist:
    
    \addtimelist*{4}{min}
    
    \addtimelist*{5}{h}
    
    \timelistmedian
    
    median = \strtimelist{h}
    
\end{document}

我希望的结果\strtimelist{h}2 h 32 min(152 分钟(4 分钟和 5 小时的中位数)转换为 h 和 min),就像\strtime

答案1

! Undefined control sequence.
<argument> \l__timecalc_time_minutes_testing_int 
                                                 
l.27     \strtime{2}{h}
                       
?

所以声明变量

\int_new:N \l__timecalc_time_minutes_testing_int

然后没有报告错误,但是

\clist_put_right:Nn { \l__timelist_testing_clist } { #1 * 60 }

应该

\clist_put_right:Nn  \l__timelist_testing_clist  { #1 * 60 }

然后

    \fp_eval:n { \l__timelist_testing_clist } 

正在将整个列表传递给fpeval它,由于只有一个项目,所以它意外地起作用了,但如果没有多个项目,为什么要使用列表呢?

或许改为

    \clist_put_right:Nx  \l__timelist_testing_clist  {\fp_eval:n{ #1 * 60} }

然后你得到

! Missing number, treated as zero.

正如你

\clist_item:nn { \l__timelist_testing_clist }

从列表中选择一个项目,但缺少一个参数来说明哪个项目

也许

\clist_item:nn { \l__timelist_testing_clist } {1}

运行无错误

在此处输入图片描述

但我不知道这是否是预期的输出

\documentclass{scrlttr2}

\ExplSyntaxOn

\int_new:N \l__timecalc_time_minutes_testing_int

\NewDocumentCommand{\strtime}{mm}
{
    \clist_clear_new:N \l__timelist_testing_clist
    \clist_put_right:Nx  \l__timelist_testing_clist  {\fp_eval:n{ #1 * 60} }

    
    % round to full minutes
    \int_set:Nn \l__timecalc_time_minutes_testing_int
        { \fp_eval:n { round( \clist_item:nn { \l__timelist_testing_clist } {1} ) } }
    
    \int_eval:n{\l__timecalc_time_minutes_testing_int}
    
    %\strtimegen [ \l__timecalc_time_minutes_testing_int ] {#2}
    
}
\ExplSyntaxOff

\begin{document}
    new:
    
    \strtime{2}{h}
    
\end{document}

相关内容