Error Resulting from Placing a Dynamic Variable inside of Table

I want to create a list of values, True or False, and to update those values with a Checkbox. But the number of elements needs to be arbitrary.

It should look something like the following code which works perfectly fine:

dyn={False,False,False};
A={{1,dyn[[1]]},{2,dyn[[2]]},{3,dyn[[3]]}}
Row@{Checkbox@Dynamic@dyn[[1]],Checkbox@Dynamic@dyn[[2]],Checkbox@Dynamic@dyn[[3]]}

But, of course, it is not practical to write out every iteration of these things. This is the reason that Table exists. However, when I put everything into tables, it does not work.

n=3;
dyn=Table[False,{i,n}];
A=Dynamic@Table[{i,dyn[[i]]},{i,n}]
Row@Table[Checkbox@Dynamic@dyn[[i]],{i,n}]

The code above results in this error message:

Part::pspec: Part specification i is neither an integer nor a list of integers. >>

I do not understand why Table and Dynamic are in conflict with one another. It is as if Dynamic reaches the i before Table and replace it with an iterative value and then Dynamic has no idea what to do with it. But why is this? Or is the problem something else altogether?

=================

  

 

Sounds like a job for Module or With; using these will allow you to limit the context of your counting variable.
– IPoiler
Jul 29 ’15 at 15:19

=================

2 Answers
2

=================

Compare the output of this:

Table[ Dynamic[i], {i,3}] (* gives {i,i,i} *)

with this:

Table[ With[{i=i},Dynamic[i]], {i,3}] (* gives {1,2,3} *)

Now you can use that:

a = Range[3];
Table[ With[{i=i}, Dynamic[ a[[i]] ] ], {i,3}] (* gives {1,2,3} *)

Then:

a+=1; (* changes output above to {2,3,4} *)

Addendum to address question in the comments below: You can look at the Attributes of a function (in this case Dynamic). If you see that it has a HoldFirst (or HoldRest, or HoldAll) attribute, then that tells you some of its arguments will not be evaluated. For example, consider:

Attributes[foo] = {HoldFirst};
Table[ foo[i], {i,3} ] (* gives {foo[i], foo[i], foo[i] *)
Table[ With[{i=i},foo[i]], {i,3}] (* gives {foo[1], foo[2], foo[3] *)

  

 

Thank you so much. That answers the question. Out of curiosity, precisely what was the problem? How can I avoid this in the future? Thanks again!
– cbward
Jul 29 ’15 at 15:51

  

 

I added some info in the answer. Also this post is useful; if you read it you will likely avoid many common programming conundrums: mathematica.stackexchange.com/questions/18393/…
– Arnoud Buzing
Jul 29 ’15 at 16:26

One possibility is to use MapIndexed:

n = 3; dyn = Table[False, {i, n}];
A = Dynamic@Transpose[{Range[n], dyn}]
MapIndexed[Checkbox[Dynamic[dyn[[#2[[1]]]]]] &, Range[n]]

  

 

similarly Table[ Checkbox[Dynamic[dyn[[#]]]] &@i , {i, 3}]
– george2079
Jul 29 ’15 at 19:21

  

 

@george2079 Yes. Or, of course, just Map[Checkbox[Dynamic[dyn[[#]]]] &, Range[n]]
– Rolf Mertig
Jul 29 ’15 at 20:51