3
$\begingroup$

I have the following dynamic module. It works. The problem is that whenever I try to make the variable list or the variable s dynamic the code doesn't work.

My goal is to allow students to enter a list of points using familiar mathematical notation. That is, user inputs "(4, 5), (9, 0)" and this gets converted to

{{4, 5}, {9,0}}

Suggestions would be greatly appreciated. I can not for the life of me figure this out.

DynamicModule[{list = "((5, 6), (9, 0))", s},
   Panel[
    Column[
      {
       Labeled[InputField[Dynamic[list], String, FieldSize -> {50, 5}],StringForm["Data Points"], Left],
       s = ToExpression[StringReplace[list, {"(" -> "{", ")" -> "}"}] ],
       ListPlot[s]
      }
     ]
   ]
 ]
$\endgroup$
7
  • $\begingroup$ You don't need ToString[] and ToExpression (inside ListPlot). This works : DynamicModule[{list = "((5, 6), (9, 0))", s}, Panel[Column[{Labeled[ InputField[Dynamic[list], String, FieldSize -> {50, 5}], StringForm["Data Points"], Left], s = ToExpression[StringReplace[list, {"(" -> "{", ")" -> "}"}]], StringQ[s], s, ListPlot[s, PlotStyle -> PointSize[0.05]]}]]]/ $\endgroup$ Nov 1, 2012 at 8:17
  • $\begingroup$ You are correct. I had those in there because I started out using Dynamic[list] and Dynamic[s] and kept getting errors. For instance, StringReplace[Dynamic[list].....] gives and error. I'll clean the code. But the question remains, how can I make it dynamic? $\endgroup$
    – user246
    Nov 1, 2012 at 8:22
  • 1
    $\begingroup$ @YequalsX Dynamic is a wrapper that the front end handles, so you can't just act like it's the same as the variable. Doing anything like Dynamic[{1,2,3}][[1]] or Sin[Dynamic[x]] will not work. What you should do is to keep the wrapper on the outer level, and put your operations inside, e.g: Dynamic[{1,2,3}[[1]]] and Dynamic[Sin[x]]. $\endgroup$
    – jVincent
    Nov 1, 2012 at 8:27
  • $\begingroup$ I've put the Dynamic in every conceivable location and it won't work. I'm getting an error in the ListPlot. It says that s is not a list whenever I have Dynamic. No matter what level I put Dynamic at. $\endgroup$
    – user246
    Nov 1, 2012 at 8:32
  • $\begingroup$ @YequalsX see my answer, you need the dynamics to wrap the expressions that you want to be dynamicly updated. $\endgroup$
    – jVincent
    Nov 1, 2012 at 8:33

1 Answer 1

7
$\begingroup$

Here is a simple fix for your problem.

 DynamicModule[{list = "((5, 6), (9, 0))", s}, Panel[Column[{

  InputField[Dynamic[list], String, FieldSize -> {50, 5}], 
  Dynamic[s = ToExpression[StringReplace[list, {"(" -> "{", ")" -> "}"}]]], 
  Dynamic[ListPlot[s, PlotStyle -> PointSize[0.05]]]

  }]]]

When using Dynamic[expression] I would suggest thinking of it as a message to the front-end saying: "Hey, rather then just showing expression, could you keep it updated if something changes?". You can't just wrap Dynamic around every variable and expect expressions down the line to also be Dynamic. And as I stated in a comment, using operations on a Dynamic wrapped object won't give you the dynamic result of that operation on the variable.

This of course seems to clash with every built-in function that accepts dynamic arguments, for instance Slider[Dynamic[a]]. Since that returns a dynamic slider, you wold think that your function f[a_,b_]:=a+b would return a dynamicly updated value if you just ran: f[Dynamic[v1], Dynamic[v2]]. What instead happens is that the dynamic wrappers prevent evaluation of the sum. The imporant point to remember here is that functions like Slider work because they expect a dynamic input, and can rewrap the dynamic around their controlls so it still ends up in the right place. For this example, you would have needed to express how f should handle a dynamic, and could have used: f[Dynamic[a_], Dynamic[b_]] := Dynamic[a + b], which would then work in the way expected above.

$\endgroup$
5
  • $\begingroup$ Thank you. It works. I did not try to put Dynamic around the s = ToExpression.... I was not aware that I could do that. For some reason I had a mental block and thought that an assignment would mess up the Dynamic. Thank you for your explanation and solution. $\endgroup$
    – user246
    Nov 1, 2012 at 8:35
  • $\begingroup$ It gets even more dynamic if you add the otpion ContinuousAction -> True to InputField $\endgroup$ Nov 1, 2012 at 8:40
  • $\begingroup$ @YequalsX Dynamic will only reevaluate if something that it depends on changes, so it's not the case that Dynamic[s=a] will run continually, it only runs if a changes. I expect this was the root of your caution. $\endgroup$
    – jVincent
    Nov 1, 2012 at 8:40
  • $\begingroup$ @Rolf Thanks for letting me know this. In my case this would be bad since it would mess up ListPlot while typing in a new point. But I can see where this option would be useful in other cases. $\endgroup$
    – user246
    Nov 1, 2012 at 8:45
  • $\begingroup$ @jVincent What you say makes sense. My intuition said otherwise. I'm not experienced enough in Mathematica to have good intuition though. $\endgroup$
    – user246
    Nov 1, 2012 at 8:49

Your Answer

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