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$ Dec 1 '12 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
    Dec 2 '12 at 1:07
  • $\begingroup$ Strongly related: (1), (2) $\endgroup$
    – Mr.Wizard
    Jan 12 '13 at 13:46
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
    Dec 1 '12 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
    Dec 1 '12 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
    Dec 1 '12 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
    Dec 1 '12 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$

This site is temporarily in read only mode and not accepting new answers.

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