[Date Index]
[Thread Index]
[Author Index]
Re: Re: How to find which variable caused the trigger in Manipulate[]
*To*: mathgroup at smc.vnet.net
*Subject*: [mg104160] Re: [mg104136] Re: How to find which variable caused the trigger in Manipulate[]
*From*: John Fultz <jfultz at wolfram.com>
*Date*: Wed, 21 Oct 2009 06:31:33 -0400 (EDT)
*Reply-to*: jfultz at wolfram.com
On Tue, 20 Oct 2009 22:13:15 -0500, Nasser M. Abbasi wrote:
>
>
> From: "John Fultz"
>
> "Now this code has the distinct advantage that it works, and it's not so
> complicated, but there's one fatal flaw in it. It relies on the same
> undocumented assumption I discussed earlier...that Dynamics are validated
> left-to-right. It would fall down if you flipped the order of the Row[],
> or in a hypothetical future implementation of Dynamic that violates this
> assumption. So that's not my final solution. But I wanted you to see
> this so you could understand better how I built my final solution. My
> final solution takes the same approach, but tracks the Dynamics as
> they're initialized, forcing the Text[] Dynamic to evaluate (possibly
> again) after the others. The solution doesn't seem very elegant, but it
> does work. I'm afraid that the educational value of this example will
> require some study of the code, but you seem willing to do that. I
> reversed the Row[] in this example to prove that it does, in fact, work
> as advertised.
>
> Manipulate[Row[{
>
> Dynamic[Refresh[
> Switch[dynamicsInitialized,
> {True, True, False}, dynamicsInitialized[[3]] = True;r = initialState,
> {True, True, True}, initialState = r];
> Text[r], TrackedSymbols -> {y, x, dynamicsInitialized}]],
>
> Dynamic[Refresh[dynamicsInitialized[[1]] = True; r = x;
> "",TrackedSymbols -> {x}]],
>
> Dynamic[Refresh[dynamicsInitialized[[2]] = True; r = y;
> "",TrackedSymbols -> {y}]]}
> ],
>
> {x, 0, 1, 0.01},
> {y, 0, 1, 0.01},
> {r, "", "", ControlType -> None},
> {{initialState, 0}, ControlType ->None},
> {{dynamicsInitialized, {False, False, False}}, ControlType -> None},
>
> Initialization :> (dynamicsInitialized = {False, False, False})
> ]
>
> "
>
> Brilliant John as always.
>
> Studying your code, I just learned something I never knew about
> Manipulate, which is probably why I could not come up with a solution.
>
> I was wondering, since in the code above, dynamicsInitialized variable is
> initialized to {False, False, False}, then, assuming does not "touch" the
> "y" slider at all the whole time, then how could the Switch statement,
> which checks only for {True, True, False} and {True, True, True}, ever
> gets executed?
>
> Since only when the "y" slider is moved, would you set the
> dynamicsInitialized[[2]] to true.
>
> Yet, when I look at the DynamicModule[] code generated by the hitting the
> "Paste snapshot" button in the corner of the Manipulate display, it says
> that dynamicsInitialized has the value {True, True, True} each time !
> But how could it be so, I have not even touched the "y" slider! even if I
> do not touch the "x" slider, this variable will have this value.
>
> But when I click the "initial settings" button, then look at the "Paste
> snaphot", then I see this variable having the value {False, False,=
False}.
>
> I came up with a theory on how this could be:
>
> Just by the act of displaying the Manipulate result on the screen, or
> scrolling over it, all the control variables will be "activated", or
> "triggered" initially, even when one has not physically moved the
> slides/the controls yet.
>
> This means there will be some initial evaluations of the Manipulate
> expression. 3 initial evaluations that occur behind the scene before I
> ever get to touch the sliders.
>
> The first evaluation detects that "x" is triggered (or maybe "y", since
> the order is not defined), so this will cause dynamicsInitialized to
> become {True, False, False}.
>
> The second evaluation will detect that "y" control variable is triggered,
> so now dynamicsInitialized becomes {True, True, False}.
>
> And now in the third evaluation, since dynamicsInitialized is being
> tracked also, and it has changed from the above evaluations, then now and
> only now, would one of the Switch statement conditions be used, the one
> which checks for {True, True, False}.and this will finally cause
> dynamicsInitialized becomes {True, True, True}. And now the rest will
> follow as the user moves the "x" or the "y" slides.
>
> Thanks again for your help John.
>
> --Nasser
Yes, you've largely got it. For purposes of full understanding, I'll just
correct a very forgivable oversight.
Not three evaluations, but six.
Evaluation 1: The code in Initialization comes first. That's a documented,
ironclad guarantee. My solution relies on that guarantee.
The remaining evaluations, as I've stressed, could hypothetically come in any
order, but in version 7, here's how they come...
Evaluation 2: The Switch[] code. But the Switch[] fails, as dynamicsInitialized
will be {False, False, False}, remains unevaluated, and r is left unchanged.
Evaluation 3: The x initialization, as you say.
Evaluation 4: The y initialization, as you say.
Evaluation 5: Evaluations 3 and 4 have now re-tickled the Switch[] code, by
virtue of changing dynamicsInitialized (you'll note that I added
dynamicsInitialized to that particular Refresh). So now the Switch[] code
evaluates again, but this time with dynamicsInitialized set to {True, True,
False}
Evaluation 6: Evaluation 5 now tickles *again* the Switch[] statement by virtue
of changing dynamicsInitialized to {True, True, True}. So one last
re-evaluation.
And now things are in a stable state and no further evaluations happen until you
start moving sliders.
Sincerely,
John Fultz
jfultz at wolfram.com
User Interface Group
Wolfram Research, Inc.
Prev by Date:
**Re: Question on Dynamic with "DockedCell"**
Next by Date:
**Re: Question on Dynamic with "DockedCell"**
Previous by thread:
**Re: Re: How to find which variable caused the trigger in Manipulate[]**
Next by thread:
**Re: How to find which variable caused the trigger in Manipulate[]**
| |