7
$\begingroup$

I wish I didn't feel like a newbie after several months, but...

If I enter the following:

Table[ Button[ "Number: " <> ToString @ i, Print @ i], {i, 1, 5}]

this creates a list of buttons, labelled Number: 1, Number: 2, etc. but pressing each button only prints i, not the number corresponding to the button. I assume this is standard newbie-doesn't-understand Mathematica stuff, but would appreciate any explanation of how to change the behaviour so that each button prints the value of i.

$\endgroup$
3
  • 1
    $\begingroup$ Very closely related question $\endgroup$ Commented Dec 1, 2012 at 18:44
  • $\begingroup$ Don't feel bad -- it took me a rather embarrassing long time to realize Button's HoldRest attribute required I use With to get the kind of behavior you are looking for. $\endgroup$
    – m_goldberg
    Commented Dec 2, 2012 at 1:07
  • $\begingroup$ Strongly related: (1), (2) $\endgroup$
    – Mr.Wizard
    Commented Jan 12, 2013 at 13:46

4 Answers 4

8
$\begingroup$

You could do

Table[
 With[{i = i}, Button["Number: " <> ToString@i, Print@i]],
 {i, 1, 5}]

The reason is that

Attributes@Button

(*{HoldRest, Protected, ReadProtected}*)

so that the code you produce ends up containing things like Button["Number: 2", Print[i]] (try looking at Table[Button["Number: " <> ToString@i, Print@i],{i, 1, 5}] // FullForm to see this). With literally replaces i with the value at each iteration, even if the expression is held (as it is here).

$\endgroup$
1
  • $\begingroup$ Many thanks, that's a great link too. $\endgroup$
    – Cuboid
    Commented Dec 1, 2012 at 18:37
5
$\begingroup$

Since your parameter i in Button is outside Table (because of the HoldRest attribute of Button), it is not a number anymore. However you could do e.g. this :

Button["Number: " <> ToString @ #, Print @ #] & /@ Range[5]

If there is a need for i parameter one can do this :

Button["Number: " <> ToString @ #, Print @ # ] & /@ Table[i, {i, 5}]
$\endgroup$
3
  • $\begingroup$ I guess the question really is "how does i end up outside the Table" (answer, because Button is HoldRest) $\endgroup$
    – acl
    Commented Dec 1, 2012 at 18:42
  • $\begingroup$ The question was : How to change the behaviour so that each button prints the value of i ? I didn't need the reasoning concerning the attributes of Button, my answer explains how to do what the OP wanted. $\endgroup$
    – Artes
    Commented Dec 1, 2012 at 19:07
  • $\begingroup$ OK, my apologies then. Note that your code works precisely because it circumvents the attributes (i gets evaluated to a number outside the Button, so HoldRest can't prevent it), so I don't see how you don't need the HoldRest bit. $\endgroup$
    – acl
    Commented Dec 1, 2012 at 19:27
4
$\begingroup$

You can do :

Table[With[{i = i}, Button["Number: " <> ToString@i, Print[i]]], {i, 1, 5}]
$\endgroup$
3
$\begingroup$

I favor Array here:

Array[Button[Row @ {"Number: ", #}, Print @ #] &, 5]

Also see:

Function in Table

How do you properly create Buttons to change dynamic variables using Table

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.