# How to track dynamically generated manipulators?

In the code below the manipulators that are generated from the stakes buttons are not tracked by the Manipulate expression that contains them.

How can I make the plot update with these sliders? If I add 'stakeWeights' and 'roi' (the values of the manipulators) to the tracked symbols, the manipulators won't move.

My apologies for posting the complete code but I couldn't find an easy way to isolate this from the rest of the code.

RandomWalk[n_, roi_, bi_, rake_] :=
(*If errors return list with zero so ListPlot does not complain *)
Quiet@Check[(pwin = bi (1 + roi)/(2 (bi - rake));
NestWhileList[# + RandomChoice[{pwin, 1 - pwin} -> {1 - 2 rake/bi, -1}] &,
0, True &, 0, n]),
{0}]

trial = 0;
allStakes = {1.5, 3.5, 7, 15, 30, 60, 100, 200, 300, 500, 1000};
rakes = {0.06, 0.1, 0.15, 0.31, 0.63, 1.26, 1.88, 3.34, 4.49, 6.65, 11.2}
MapIndexed[(rakebyStake[#1] = rakes[[#2]]) &, allStakes]

Manipulate[trial;
data = RandomWalk[nrTournaments, avgROI/100, avgBI, avgRake];
(stakeWeights[#] = 100) & /@ allStakes;
(roi[#] = 1) & /@ allStakes;
avgBI =
Quiet@Check[
Total[(# stakeWeights[#]/Total[stakeWeights /@ stakes]) & /@
stakes // N], 0];
avgRake =
Quiet@Check[
Total[(rakebyStake[#][[1]] stakeWeights[#]/
Total[stakeWeights /@ stakes]) & /@ stakes // N], 0];
avgROI =
Quiet@Check[
Total[(roi[#] stakeWeights[#]/Total[stakeWeights /@ stakes]) & /@
stakes // N], 0];
biWon = Quiet@Check[Last[data], 0]; dollarWon = biWon avgBI;
pwin = Quiet@Check[avgBI (1 + avgROI/100)/(2 (avgBI - avgRake)), 0];
expectedBiWon =
Quiet@Check[((1 - 2 avgRake/avgBI) pwin - (1 - pwin)) nrTournaments, 0];
expectedDollarWon = expectedBiWon avgBI;
sampleROI = Quiet@Check[dollarWon/(nrTournaments avgBI), 0];
Dynamic@ListPlot[data, Joined -> True, PlotStyle -> {RGBColor[0, 0.2, 0.6]}],
{{nrTournaments, 3000, "tournaments"}, 0, 100000, 100, Appearance -> "Open"},
{{stakes, {60}, "stakes"}, allStakes, ControlType -> TogglerBar},
Dynamic[Column@{Grid[({#,
Manipulator[Dynamic[stakeWeights[#]], {0, 100, 1}],
Dynamic[Quiet@
Check[100 stakeWeights[#]/
Total[stakeWeights /@ stakes // N], 0]],
"ROI",
Manipulator[Dynamic[roi[#]], {0, 75},
Appearance -> "Labeled"]}) & /@ Sort[stakes]]}],
{{avgROI, 1.5, "avg ROI (%)"}, 0, 75, 0.01, Appearance -> "Open"},
{{avgBI, 60, "avg BI ($)"}, 0, 10000, 1, Appearance -> "Open"}, {{avgRake, 1.26, "avg rake ($)"}, 0, avgBI/10, 0.01, Appearance -> "Open"},
{{rakeback, 37, "rakeback (%)"}, 0, 100, 0.01, Appearance -> "Open"},
Delimiter,
Panel[Grid[{{Dynamic[
Row[{"sample ROI: ",
Style[ToString[sampleROI 100] <> "%",
If[sampleROI >= 0, Darker[Green], Red]]}]]}, {Dynamic[
Row[{"# BI won: ", ToString[biWon], " (",
Style["$" <> ToString[dollarWon], If[dollarWon >= 0, Darker[Green], Red]], ")"}]]}, {Dynamic[ Row[{"rakeback: ", Style["$" <> ToString[avgRake rakeback/100 nrTournaments],
Darker[Green]]}]]}, {Dynamic[
Row[{"$won after rakeback: ", Style["$" <>
ToString[dollarWon + avgRake rakeback/100 nrTournaments],
If[dollarWon + avgRake rakeback /100 nrTournaments >= 0,
Darker[Green], Red]]}]]},
{Dynamic[
Row[{"expected # BI won: ", ToString[expectedBiWon], " (",
Style["\$" <> ToString[expectedDollarWon],
If[expectedDollarWon >= 0, Darker[Green], Red]], ")"}]]}},
Alignment -> Left]],
Button["Run again", trial++, ImageSize -> Medium],
SaveDefinitions -> True,
TrackedSymbols :> {nrTournaments, avgROI, avgBI, avgRake, trial,
stakes, rakeback}]

-
You really should make an attempt to reduce your problem to an example that reproduces it in far fewer lines of code. – m_goldberg May 3 '13 at 4:52

Your manipulators don't move because of the lines

(stakeWeights[#] = 100) & /@ allStakes;
(roi[#] = 1) & /@ allStakes;


inside the Manipulate. Just pull those lines outside.

On a related note, I was playing around and found this kind of control that you might benefit/get ideas from:

adaptoControl[Dynamic[settings_]] := Dynamic[
Column[MapIndexed[Function[{val, position},
Manipulator[Dynamic[settings[[Sequence @@ position]]]]],
settings, {3}]]];


Usage:

stakes = {1.5, 3.5, 7, 15, 30};
settings = # -> {0, 1} & /@ stakes;


Also you can construct your Manipulate piecemeal using various methods:

controls = Sequence[{u, 0, 1}, {v, 0, 1}];
Manipulate[
{u, v},
Evaluate[controls]]

With[{controls = Sequence[{u, 0, 1}, {v, 0, 1}]},
Manipulate[
{u, v},
controls]]

-
Thanks for the suggestions. – dabd May 3 '13 at 11:57
Sequence is not needed when there is only one control. A better example is With[{controls = Sequence[{u, 0, 1}, {v, 0, 1}]}, Manipulate[{u, v}, controls]] – m_goldberg May 3 '13 at 13:15
@m_goldberg That's good, I'll add it. I was tryng to keep the examples "minimally general". Funnily, it wouldn't have occured to me to apply Sequence that way. – amr May 3 '13 at 17:06