Re: Questions about InputField
- To: mathgroup at smc.vnet.net
- Subject: [mg80326] Re: Questions about InputField
- From: David Bailey <dave at Remove_Thisdbailey.co.uk>
- Date: Fri, 17 Aug 2007 01:57:57 -0400 (EDT)
- References: <fa1cen$7o7$1@smc.vnet.net>
Fred Simons wrote:
> The following contains a highly simplified version of a problem I ran
> into using Inputfields.
>
> Here is a construction for displaying the updated values of two numbers
> n and m, and to enter values for m:
>
> Column[{Dynamic[n], InputField[Dynamic[m]]}]
>
> I want to use this column for controlling the following (infinite) loop:
>
> n = 100; m = 0;
> While[n > 0,
> n = n - m; m = 0]
>
> Having started this loop, the column shows the numbers 100 and 0. Now
> enter 8 in the input field. Since the pre-emptive link will be used, the
> evaluation of the loop will be interrupted and the assignment m=8 is
> done. Then the loop is resumed, so n gets the value 92 and m is reset to 0.
>
> Having done this, the column indeed shows the value 92 for n, but for m
> the value 8 is displayed. Aborting the loop and inspecting the value of
> m gives 0, so here we have a Dynamic[m] that does NOT show the updated
> value for m.
>
> It is very strange that we can force the updating of m by explicitly
> entering the default value for the second argument of Dynamic:
>
> Column[{Dynamic[n], InputField[Dynamic[m, (m = #) &]]}]
>
> Restart the loop and repeatedly enter not too large positive values for
> m. Then, on my Windows Visa system, sometimes the number will be
> subtracted, sometimes not.
>
> Though this looks buggish, it probably is not. We have to take into
> consideration that we do not know at which point the execution of the
> loop is interrupted. That it does make a difference can be seen from
> the following two examples. In the next two loops it is practically sure
> that the interrupt will happen during the Pause statement. So the first
> loop can be perfectly controlled and in the second loop nothing seems to
> happen:
>
> n = 100; m = 0;
> While[n > 0,
> Pause[0.1]; n = n - m; m = 0]
> n = 100; m = 0;
>
> While[n > 0,
> n = n - m; Pause[0.1]; m = 0]
>
> So I suppose that in the situations that no subtraction happened, the
> execution of the loop was interrupted just before the assignment m=0.
>
> Can someone explain why it is necessary to use the default value for the
> second argument in Dynamic, and find a better and safer way of
> controlling the loop, not using a Pause statement?
>
> Fred Simons
> Eindhoven University of Technology
>
As you have already realised, there is a timing problem here, and it is
vital to arrange code such as this so that timing is not an issue. Your
example is perhaps a bit too cut down, but I assume that you want to
loop for one value of n and to jump to n-m whenever the user enters a
value of m. Therefore it makes sense to do the subtraction inside the
Dynamic function:
Column[{Dynamic[n], InputField[Dynamic[m, (n = n - #; m = #) &],Number]}]
Now the loop is much simpler - in fact it contains no body at all, so
let's put a line of code to display n in the notebook status field:
n = 100;
While[n > 0,
SetOptions[SelectedNotebook[], WindowStatusArea -> ToString[n]]
];
SetOptions[SelectedNotebook[], WindowStatusArea -> ""]
Note that I have reset the status field after the loop is over to avoid
confusion.
I have also added Number as a second argument to InputField - this makes
the code more robust because you can't enter a non-numeric value.
Of course, it might be simpler to make your InputField work on n directly.
David Bailey
http://www.dbaileyconsultancy.co.uk