Re: Buttons to interactively restart/finish a program
- To: mathgroup at smc.vnet.net
- Subject: [mg99141] Re: [mg99120] Buttons to interactively restart/finish a program
- From: John Fultz <jfultz at wolfram.com>
- Date: Tue, 28 Apr 2009 04:45:42 -0400 (EDT)
- Reply-to: jfultz at wolfram.com
On Mon, 27 Apr 2009 05:25:45 -0400 (EDT), Alexei Boulbitch wrote: > Dear community, > > I am writing a simple interactive teaching program to teach my child > arithmetics. Here is a simplified example on addition from 1 to 4: > > Panel[DynamicModule[{a, b}, > Clear[a, b, f]; > a = RandomInteger[{1, 4}]; > b = RandomInteger[{1, 4 - a}]; > f = "?"; > g1 := (Clear[f]; f = a + b); > g2 := (Clear[f]; f = "?"); > > Column[{ > Row[{ > > Dynamic@Button[Style[1, 30], If[a + b == 1, g1, g2]], > Dynamic@Button[Style[2, 30], If[a + b == 2, g1, g2]], > Dynamic@Button[Style[3, 30], If[a + b == 3, g1, g2]], > Dynamic@Button[Style[4, 30], If[a + b == 4, > g1, g2]] > > }], > > Panel[Row[{Text[Style[a, 50]], > Text[Style["+", 50]], > Text[Style[b, 50]], > Text[Style["=", 50]], > Text[Style[Dynamic[f], 50]]}]] > > }] > > ] > ] > > > In this program however, one needs to manually re-execute the program > (e.g. via Shift+Enter) each time one wants to have a new execise. In > order to avoid the manual restarting in addition to the above code I > would like to include two buttons. First should restart the program, so > that the task is renewed. The second button should close the panel when > the game is finished. Thus, the program may be executed only once before > the game starts. My idea to add a restart button the way shown below did > not work: > > Label["aa"]; > Panel[DynamicModule[{a, b}, > Clear[a, b, f]; > a = RandomInteger[{1, 4}]; > b = RandomInteger[{1, 4 - a}]; > f = "?"; > g1 := (Clear[f]; f = a + b); > g2 := (Clear[f]; f = "?"); > > > Column[{ > Row[{ > > Dynamic@Button[Style[1, 30], If[a + b == 1, g1, g2]], > Dynamic@Button[Style[2, 30], If[a + b == 2, g1, g2]], > Dynamic@Button[Style[3, 30], If[a + b == 3, g1, g2]], > Dynamic@Button[Style[4, 30], If[a + b == 4, > g1, g2]] > > }], > > Panel[Row[{Text[Style[a, 50]], > Text[Style["+", 50]], > Text[Style[b, 50]], > Text[Style["=", 50]], > Text[Style[Dynamic[f], 50]]}]], > Button["Restart", Goto["aa"]] > > }] > > ] > ] > > > Could anybody give me an idea? > > Best, Alexei There are at least two really good reasons Goto[] can never work here. It's a dead end. Copy the initialization code into the Button[]. E.g., Button["Restart", a = RandomInteger[{1, 4}]; b = RandomInteger[{1, 4 - a}]; f = "?"; g1 := (Clear[f]; f = a + b); g2 := (Clear[f]; f = "?")] But this isn't enough because the Panel doesn't have a Dynamic representation of a and b. You can either wrap the entire Panel in Dynamic (in which case you can remove the Dynamic around 'f', which would now be redundant), or you can wrap Dynamic individually around the references to 'a' and 'b' in the Panel. The important principle to understand here is that after you press Shift+Enter, the only code in this example which will ever evaluate again is... * Code inside of Dynamic[] * Code in the second argument of a Button[] The rest of the code is history. It evaluated once, but never again until the next Shift+Enter. So, if you want code to evaluate again, you really have to put it in one of those two places. Sincerely, John Fultz jfultz at wolfram.com User Interface Group Wolfram Research, Inc.