expl3 - 序列 - 弹出一个项目,然后堆叠相同的项目

expl3 - 序列 - 弹出一个项目,然后堆叠相同的项目

这个帖子,我需要实现颜色循环。我的想法是有一个颜色列表,从左侧弹出一种颜色,然后将这种颜色推到右侧。以下是使用列表的类似 Python 语法的一些步骤。

list     = [red,blue,orange,gray]
# Pop left
colpoped = red # To be used
list     = [blue,orange,gray]
# The color has to be pushed at the right.
list     = [blue,orange,gray,red]
...etc

这是我尝试使用但是不起作用的一段代码。

\seq_pop_left:NN \l__tnscalc_colors_seq \l__tnscalc_actual_color_temp_tl
...
\seq_push:Nn \l__tnscalc_colors_seq {\l__tnscalc_actual_color_temp_tl}

有什么建议吗?

以下是在 Marcel K. 的评论的帮助下构建的完整工作代码。

\documentclass{article}

\usepackage{nicematrix}
\usepackage{tikz}
\usetikzlibrary{fit}

\usepackage{tcolorbox}
\tcbuselibrary{theorems}

% Sources
%   * https://tex.stackexchange.com/a/475291/6880
%   * https://tex.stackexchange.com/a/558343/6880
%   * https://tex.stackexchange.com/a/558185/6880

\newcommand\decoframe[3]{
    \begin{tikzpicture}[remember picture, overlay]
    \node[draw = #1,
          rounded corners,
          thick,
          fit = (#2.north west) (#2.north east) 
                (#3.south west) (#3.south east)] {};
    \end{tikzpicture}
}

\newcommand\decobox[1]{
    \tcboxmath[colframe = red,
               left = 0mm, right = 0mm, top = 0mm, bottom = 0mm,
               boxsep = 1mm, ,boxrule = 1pt]{#1}
}


\ExplSyntaxOn
% Global variables used.
    \seq_new:N \l__tnscalc_colors_seq
    \tl_new:N \l__tnscalc_actual_color_temp_tl

    \seq_new:N \l__tnscalc_calcexpval_seq
    \seq_new:N \l__tnscalc_subseq_seq
    \tl_new:N \l__tnscalc_xline_temp_tl
    \tl_new:N \l__tnscalc_pline_temp_tl

    \int_new:N \l__tnscalc_nbline_int
    \int_new:N \l__tnscalc_numcol_int
    \int_new:N \l__tnscalc_numcol_deco_int
    \int_new:N \l__tnscalc_numcol_decotwo_int

% #1 : line separator
% #2 : cell separator
% #3 : content
    \NewDocumentCommand{\calcexpval}{O{red,blue,orange,gray} m m +m} {
        \tnscalc_calcexpval:nnnn{#1}{#2}{#3}{#4}
    }

% The internal version of the general purpose macro
    \cs_new_protected:Nn \tnscalc_calcexpval:nnnn {
% #1 (option) : colors
% #2 : line separator
% #3 : cell separator
% #4 : content
  
% Colors.
        \seq_set_split:Nnn \l__tnscalc_colors_seq { , } { #1 }
        
% Split into lines
        \seq_set_split:Nnn \l__tnscalc_calcexpval_seq { #2 } { #4 }
        
        \int_set:Nn \l__tnscalc_nbline_int { \seq_count:N \l__tnscalc_calcexpval_seq }

% Split each line into cells.
        \seq_pop_left:NN \l__tnscalc_calcexpval_seq \l__tnscalc_xline_temp_tl
        \seq_set_split:NnV \l__tnscalc_x_seq { #3 } \l__tnscalc_xline_temp_tl
        
        \seq_pop_left:NN \l__tnscalc_calcexpval_seq \l__tnscalc_pline_temp_tl
        \seq_set_split:NnV \l__tnscalc_p_seq { #3 } \l__tnscalc_pline_temp_tl

% Number of columns (offensive programming)
        \int_set:Nn \l__tnscalc_numcol_int { \seq_count:N \l__tnscalc_x_seq }

        \int_set:Nn \l__tnscalc_numcol_deco_int { 2 }

% The table of values                 
        \[%|*{\int_use:N \l_mbc_N_int}{c}
            \begin{NiceArray}{r*{\int_use:N \l__tnscalc_numcol_int}{|c}}
                x\sb{k} & \l__tnscalc_xline_temp_tl \\
                \hline
                p\sb{k} & \l__tnscalc_pline_temp_tl
                \CodeAfter  
                \int_add:Nn \l__tnscalc_numcol_int {2}
                \bool_while_do:nn { \int_compare_p:nNn \l__tnscalc_numcol_deco_int < \l__tnscalc_numcol_int }{
                    \seq_pop_left:NN \l__tnscalc_colors_seq \l__tnscalc_actual_color_temp_tl
                    \seq_put_right:Nn \l__tnscalc_colors_seq {\l__tnscalc_actual_color_temp_tl}
                    \decoframe{\l__tnscalc_actual_color_temp_tl}{1-\int_use:N \l__tnscalc_numcol_deco_int}{2-\int_use:N \l__tnscalc_numcol_deco_int}
    
                    \int_add:Nn \l__tnscalc_numcol_deco_int {2}
                }
            \end{NiceArray}
        \]
        
% Explain the calculus of the expected value.
        \int_set:Nn \l__tnscalc_numcol_deco_int { 1 }
              
        $E(X) = \sum\limits\sb{k=1}^{\int_use:N \l__tnscalc_numcol_int} p\sb{k} \cdot x\sb{k}$
        
        \par
        
        $E(X) = 
        
        \bool_while_do:nn { \int_compare_p:nNn \l__tnscalc_numcol_int > 0 }{
            \seq_pop_left:NN \l__tnscalc_x_seq \l__tnscalc_xval_tl
            \seq_pop_left:NN \l__tnscalc_p_seq \l__tnscalc_pval_tl
        
            \bool_if:NTF { \int_compare_p:nNn { \int_eval:n{ \int_mod:nn \l__tnscalc_numcol_deco_int 2} } = 1 }  { \decobox{\l__tnscalc_xval_tl \cdot \l__tnscalc_pval_tl} } { \l__tnscalc_xval_tl \cdot \l__tnscalc_pval_tl }
    
            \bool_if:NTF { \int_compare_p:nNn \l__tnscalc_numcol_int = 1 }  { } { + }

            \int_add:Nn \l__tnscalc_numcol_deco_int {1}
            \int_add:Nn \l__tnscalc_numcol_int {-1}
        }
        $
    } 
\ExplSyntaxOff

\setlength\parindent{0pt}

\begin{document}

Let's try...

\calcexpval{\\}{&}{
    0      & 1   & 2   & 3    & 4    \\
    0.2000 & 0.2 & 0.4 & 0.05 & 0.15
}

With the default cycle of colors.

\calcexpval{\\}{&}{
    0      & 1   \\
    0.2000 & 0.2
}

With an odd number of columns and the cycle of colors \verb#blue,gray#.

\calcexpval[blue,gray]{\\}{&}{
    0      & 1   & 2   \\
    0.2000 & 0.2 & 0.4
}

With a single( ? ) column and the cycle of colors \verb#black#..

\calcexpval[black]{\\}{&}{
    0      \\
    0.2000
}

%With the short cycle of colors \verb#blue,red#..

\calcexpval[blue,red]{\\}{&}{
    0      & 1   & 2   & 3    & 4    & 1   & 2   & 3    & 4    \\
    0.2000 & 0.2 & 0.4 & 0.05 & 0.15 & 0.2 & 0.4 & 0.05 & 0.15
}

\end{document}

答案1

错误在于使用\seq_put_right:Nn在序列末尾重新插入颜色。您需要\seq_put_right:NV添加内容标记列表变量。

然而,还有很多其他的改进工作要做。

例如,你滥用了\int_use:N在需要整数的地方永远不需要的。此外,\int_compare_p:nNn想要一个支撑参数,一个无支撑参数和另一个有支撑参数;但\int_compare_p:n更容易(并且更强大,尽管速度稍慢;没什么可担心的)。

通过使用 可以简化条件并避免多次弹出\seq_map_indexed_inline:Nn

\documentclass{article}

\usepackage{nicematrix}
\usepackage{tikz}
\usetikzlibrary{fit}

\usepackage{tcolorbox}
\tcbuselibrary{theorems}

% Sources
%   * https://tex.stackexchange.com/a/475291/6880
%   * https://tex.stackexchange.com/a/558343/6880
%   * https://tex.stackexchange.com/a/558185/6880

\newcommand\decoframe[3]{%
    \begin{tikzpicture}[remember picture, overlay]
    \node[draw = #1,
          rounded corners,
          thick,
          fit = (#2.north west) (#2.north east) 
                (#3.south west) (#3.south east)] {};
    \end{tikzpicture}%
}

\newcommand\decobox[1]{%
    \tcboxmath[colframe = red,
               left = 0mm, right = 0mm, top = 0mm, bottom = 0mm,
               boxsep = 1mm, ,boxrule = 1pt]{#1}%
}


\ExplSyntaxOn
% Global variables used.
\seq_new:N \l__tnscalc_colors_seq
\tl_new:N \l__tnscalc_actual_color_temp_tl

\seq_new:N \l__tnscalc_calcexpval_seq
\seq_new:N \l__tnscalc_subseq_seq
\tl_new:N \l__tnscalc_xline_temp_tl
\tl_new:N \l__tnscalc_pline_temp_tl

\int_new:N \l__tnscalc_nbline_int
\int_new:N \l__tnscalc_numcol_int
\int_new:N \l__tnscalc_numcol_deco_int
\int_new:N \l__tnscalc_numcol_decotwo_int

% #1 : line separator
% #2 : cell separator
% #3 : content
\NewDocumentCommand{\calcexpval}{O{red,blue,orange,gray} m m +m}
  {
   \tnscalc_calcexpval:nnnn{#1}{#2}{#3}{#4}
  }

% The internal version of the general purpose macro
\cs_new_protected:Nn \tnscalc_calcexpval:nnnn
 {
  % #1 (option) : colors
  % #2 : line separator
  % #3 : cell separator
  % #4 : content

  % Colors.
  \seq_set_split:Nnn \l__tnscalc_colors_seq { , } { #1 }

  % Split into lines
  \seq_set_split:Nnn \l__tnscalc_calcexpval_seq { #2 } { #4 }
  \int_set:Nn \l__tnscalc_nbline_int { \seq_count:N \l__tnscalc_calcexpval_seq }

  % Split each line into cells.
  \seq_pop_left:NN \l__tnscalc_calcexpval_seq \l__tnscalc_xline_temp_tl
  \seq_set_split:NnV \l__tnscalc_x_seq { #3 } \l__tnscalc_xline_temp_tl

  \seq_pop_left:NN \l__tnscalc_calcexpval_seq \l__tnscalc_pline_temp_tl
  \seq_set_split:NnV \l__tnscalc_p_seq { #3 } \l__tnscalc_pline_temp_tl

  % Number of columns (offensive programming)
  \int_set:Nn \l__tnscalc_numcol_int { \seq_count:N \l__tnscalc_x_seq }
  \int_set:Nn \l__tnscalc_numcol_deco_int { 2 }

  % The table of values                 
  \[
  \begin{NiceArray}{r*{\l__tnscalc_numcol_int}{|c}}
    x\sb{k} & \l__tnscalc_xline_temp_tl \\
    \hline
    p\sb{k} & \l__tnscalc_pline_temp_tl
    \CodeAfter  
    \int_add:Nn \l__tnscalc_numcol_int {2}
    \bool_while_do:nn
     { \int_compare_p:n { \l__tnscalc_numcol_deco_int < \l__tnscalc_numcol_int } }
     {
      \seq_pop_left:NN \l__tnscalc_colors_seq \l__tnscalc_actual_color_temp_tl
      \seq_put_right:NV \l__tnscalc_colors_seq \l__tnscalc_actual_color_temp_tl
      \decoframe{\l__tnscalc_actual_color_temp_tl}
                {1-\int_use:N \l__tnscalc_numcol_deco_int}
                {2-\int_use:N \l__tnscalc_numcol_deco_int}
      \int_add:Nn \l__tnscalc_numcol_deco_int {2}
     }
  \end{NiceArray}
  \]

  % Explain the calculus of the expected value.
  \int_set:Nn \l__tnscalc_numcol_deco_int { 1 }

  $E(X) = \sum\limits\sb{k=1}^{\int_use:N \l__tnscalc_numcol_int} p\sb{k} \cdot x\sb{k}$
  \par
  $E(X) = 
  \seq_map_indexed_inline:Nn \l__tnscalc_x_seq
   {
    \seq_pop_left:NN \l__tnscalc_p_seq \l__tnscalc_pval_tl
    \int_if_odd:nTF { \l__tnscalc_numcol_deco_int }
     { \decobox{ ##2 \cdot \l__tnscalc_pval_tl} }
     { ##2 \cdot \l__tnscalc_pval_tl }
    
    \int_compare:nT { ##1 < \seq_count:N \l__tnscalc_x_seq } { + }
    \int_add:Nn \l__tnscalc_numcol_deco_int {1}
   }
  $
 } 
\ExplSyntaxOff

\setlength\parindent{0pt}

\begin{document}

Let's try...

\calcexpval{\\}{&}{
    0      & 1   & 2   & 3    & 4    \\
    0.2000 & 0.2 & 0.4 & 0.05 & 0.15
}

With the default cycle of colors.

\calcexpval{\\}{&}{
    0      & 1   \\
    0.2000 & 0.2
}

With an odd number of columns and the cycle of colors \verb#blue,gray#.

\calcexpval[blue,gray]{\\}{&}{
    0      & 1   & 2   \\
    0.2000 & 0.2 & 0.4
}

With a single( ? ) column and the cycle of colors \verb#black#..

\calcexpval[black]{\\}{&}{
    0      \\
    0.2000
}

%With the short cycle of colors \verb#blue,red#..

\calcexpval[blue,red]{\\}{&}{
    0      & 1   & 2   & 3    & 4    & 1   & 2   & 3    & 4    \\
    0.2000 & 0.2 & 0.4 & 0.05 & 0.15 & 0.2 & 0.4 & 0.05 & 0.15
}

\end{document}

抱歉,我重新格式化了,但我看不到具有缩进样式的括号。

相关内容