Feel free to skip past this explanation to the code below. My issue is trying to get \Q@Selection to work with edef.
I have a macro that uses a for loop to assign some dynamic macros that I am toying with to figure out how some things work. The goal was to take a bunch of macros that were generated using a for loop, then shuffle them, and then build a set of macros that have them shuffled.
I have a command \Knuth@Shuffle{Max#}{Name}{Pick#} Which generates (pick#) of counters, named NameI, NameII, ..., Name\Roman{Pick#}, each of which containing a random (non repeating) number 1 - Max#.
Using that, I then want to assign a new set of macros by selecting the pick# of macros from a pre-generated list of macros of the form Question@\Roman{(number)} for numbers 1 to Max#. But I want to pick the random ones, so I am using: Question@\Roman{Name\Roman{(number)}} to pull the random choice. Since I need to assign these values inside a loop, I need to use \edef to make sure that the values are assigned as the loop runs and not at the end (effectively giving me the same macro a bunch of times)
Code:
Function that fails:
\newcommand{\Q@Selection}{% The Command that Selects and stores Qs
\setcounter{Iteration@Select}{1}
%
\Knuth@Shuffle{\arabic{Problem@MasterCounter}}{Q@Pulled}{\arabic{Real@PullNumber}}% Start For Loop
\forloop{Iteration@Select}{1}{\arabic{Iteration@Select} < \arabic{Real@PullNumber}}% Iterate for each desired question
{% Start Iteration Step
\expandafter\edef\csname Q@\Roman{Iteration@Select}\endcsname{\csname Question@\Roman{Q@Pulled\Roman{Iteration@Select}}\endcsname}% Select the question that was the "Q@Pull" number from the start. Currently capable of pulling the same question twice.
}% End Iteration Step
% End for Loop
}
Supporting code if you want to see how the randomize function works:
\newcommand{\@genrand}[3] %\@genrand{NAME}{MIN}{MAX} generates a random number before MIN and MAX and stores it in the command \NAME.
{
\expandafter\pgfmathrandominteger\csname #1\endcsname{#2}{#3}
\setcounter{#1}{\csname #1\endcsname}
}
\newcommand{\Knuth@Shuffle}[3]% \Knuth@Shuffle{MAXCOUNT}{NAME}{USEDCOUNT} Generates and permutes a list MAXCOUNT number of counters, each with name NAMEI, NAMEII, NAMEIII, ..., NAME\Roman(MAXCOUNT). Then it stores up to USEDCOUNT of those counters in counters named
{
%Assign a maximum on how many numbers to pick. Set default to the max list size, and save in counter "RndQuant"
\ifthenelse{\isempty{#3}}% Check to see if Desired Maximum is given.
{
\setcounter{Rnd@Quant}{#1+1} %If not, use all of them.
}
{
\ifthenelse{#1 < #3}
{
\setcounter{Rnd@Quant}{#1+1} %Only select up to all problems.
}
{
\setcounter{Rnd@Quant}{#3+1}
}
}
\setcounter{Rnd@EndQuant}{#1+1}
%Generate a starting list of numbers 1 to maximum number given.
\forloop{Iteration@1}{1}{\arabic{Iteration@1} < \arabic{Rnd@EndQuant}}
{
\@ifundefined{c@#2\Roman{Iteration@1}} % Check to see if counter exists
{ %If not, make it.
\newcounter{#2\Roman{Iteration@1}}
}
{} %If so, do nothing.
\setcounter{#2\Roman{Iteration@1}}{\arabic{Iteration@1}} % Set Counter to next number.
}
%Permute using Knuth method
\forloop{Iteration@2}{1}{\arabic{Iteration@2} < \arabic{Rnd@Quant}}
{
\@genrand{Temp@RandMe}{\arabic{Iteration@2}}{#1}% Generate a random number from Current iterate number to maximum number.
\setcounter{Temp@Hold}{\arabic{#2\Roman{Temp@RandMe}}}% Set a temp variable so that we can swap values in position of the iterate and the random number selected.
\setcounter{#2\Roman{Temp@RandMe}}{\arabic{#2\Roman{Iteration@2}}}% Set the final counter to the value of the variable in the generated number's counter.
\setcounter{#2\Roman{Iteration@2}}{\arabic{Temp@Hold}}% Set current counter to the swapped counter.
}
}
As a footnote: I was writing this largely to learn how to do some things but if anyone has suggestions of a much cleaner and nicer way to do this I'd appreciate the advice as well. I like learning on my own but that doesn't mean I'll ignore good advice.





\edef, and only focus on that as the problem. Then, provide a simplified - yet comprehensive - version of it without nesting it inside a for loop. – Werner Dec 10 '16 at 06:30\edef-issue, your code should compile. Of course, in cutting down your code to a MWE you may well find what the real problem is yourself:) – Dec 10 '16 at 07:23\protected@edefinstead of\edef– egreg Dec 10 '16 at 10:26