0

I'm trying to do a for loop so that each iteration takes into account the result of the previous iteration. Specifically, I start with a definition (let's say \newcommand\start{(0)}) and then I enter the loop. I check a condition (via \ifnum) and if positive I redefine \start so that it gives (0)--(ok). Then a new iteration and if the \ifnum is still positive, I redefine \start adding the new text --(ok) to the previous one (0)--(ok), so that overall it gets (0)--(ok)--(ok). And so on. This is my code.

\newcommand\start{(0)}
\newcommand\step{ }

\foreach \i in {1,...,5} {
\pgfmathparse{random(1,3)}

\ifnum\pgfmathresult=1
\renewcommand\step{\start --(ok)}
\else
    \ifnum\pgfmathresult=2
    \renewcommand\step{\start --(yes)}
    \else
        \ifnum\pgfmathresult=3
        \renewcommand\step{\start --(no)}
        \fi
    \fi
\fi

\renewcommand\start\step
}

\start

Of course it doesn't work. I tried to use \def, \let, etc. instead of \newcommand and \renewcommand, but the result does not change, even if I admit that I am not an expert on these commands. I would like to avoid using packages like etoolbox, ifthen

Thanks in advance.

1
  • It's not clear to me what you are trying to do but I wonder whether you want to use the remember key in the \foreach statement: \foreach \i [remember=\i as \step (initially 0)] in ...
    – user30471
    Jun 16, 2020 at 12:14

2 Answers 2

3

The problem is caused by \renewcommand\start\step.

  • Firstly, since the loop body of \foreach is executed inside a TeX group, here you need to use global assignment to save the change to \start after every execution of loop body.
  • Then, you also need to define \start as the (fully) expansion of \step, otherwise there would be infinite loop between \start and \step.

To sum up, change

\renewcommand\start\step

to

\xdef\start{\step}

Here \xdef can be seen as a shortcut of \global\edef.


In the following full example, I also change the nested \ifnum ... \else ... \fi to a \ifcase ... \or ... \or ... \fi.

\documentclass{article}
\usepackage{pgffor}

\begin{document}
\newcommand\start{(0)}
\newcommand\step{ }

\foreach \i in {1,...,5} {%
  \pgfmathparse{random(1,3)}%
  %
  \ifcase\pgfmathresult
  \or
    \renewcommand\step{\start -- (ok)}%
  \or
    \renewcommand\step{\start -- (yes)}%
  \or
    \renewcommand\step{\start -- (no)}%
  \else\fi
  %
  \xdef\start{\step}%
}

\start
\end{document}
1

You do not give a complete code. I guess you use the \foreach inside a path, if so, you need to put the extra code such inside \pgfextra. Here is an example code. As @muzimuzhi Z says, you need to use \xdef.

\documentclass[tikz, border=1cm]{standalone}
\usetikzlibrary{decorations}
\pgfdeclaredecoration{arrows}{draw}{
\state{draw}[width=\pgfdecoratedinputsegmentlength]{%
  \path [every arrow subpath/.try] \pgfextra{%
    \pgfpathmoveto{\pgfpointdecoratedinputsegmentfirst}%
    \pgfpathlineto{\pgfpointdecoratedinputsegmentlast}%
   };
}}
\tikzset{
  c/.style={every coordinate/.try},
  every arrow subpath/.style={->, draw, thick}
}
\def\temp{(o)}
\def\addtotemp#1{\xdef\temp{\temp#1}}

\begin{document}
\begin{tikzpicture}
  \coordinate (o) at (0, 0);
  \coordinate (yes) at (-1, 1);
  \coordinate (no) at (0, 2);
  \coordinate (ok) at (1, 1);
  \foreach \r in {0, 4, 8} {
    \def\temp{(o)}
    \draw[every coordinate/.style={yshift=\r cm},
      decoration=arrows, decorate,
    ] ([c]o) node[below] {o}
      \foreach \i [
        evaluate = \i as \random using {random(1, 3)},
      ] in {1, ..., 5} {
        \pgfextra{\typeout{xyz \temp}}
        \ifnum\random=1
          \pgfextra{\addtotemp{ -- (yes)}}
          to[->] ([c]yes) node[left] {yes}
        \else\ifnum\random=2
          \pgfextra{\addtotemp{ -- (no)}}
          -- ([c]no) node[above] {no}
        \else
          \pgfextra{\addtotemp{ -- (ok)}}
          -- ([c]ok) node[right] {ok}
        \fi\fi
      };
    \node[yshift=\r cm] at (0, -0.5) {\temp};
  }
\end{tikzpicture}
\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .