这是我的问题的最小例子:
我想将 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}