Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a set of variables which are used in various places in my calculations (solving a system, initial conditions, etc.). In order to make this easier to deal with, I want to make a control-like thing which makes them easier to manipulate, rather than just using long lists of unlabeled values such as

calculateValues[{0, 0, π, 0.5, 3}]

So far I have something like this:

This clearly doesn't work, and I expect in order to get it working properly I'll need to use Interpretation or more Dynamic incantations, but I can't figure out exactly what needs to happen. Any advice would be appreciated. Thanks in advance!

share|improve this question

3 Answers 3

up vote 3 down vote accepted

You could do

myControl[varNames_List, start_: 0] := 
 myControl[varNames, ConstantArray[start, Length@varNames]]

myControl[varNames_List, start_List] := 
 Interpretation[{vars = start}, 
  Panel[Grid[{varNames, 
     Array[InputField[Dynamic@vars[[#]], 
        FieldSize -> {{0, Infinity}, 1}] &, Length@vars]}]], vars]

Now you can run that function to create a control myControl["a"~CharacterRange~"g"]. Each instance will have its own values and they all evaluate to their values when supplied as input

share|improve this answer
    
This works great, thanks! But what is the purpose of the DynamicSetting and Evaluate? It seems that if I remove them, it works just the same way. Also, I would expect to need Dynamic[vars] instead of vars at the end... –  jtbandes Nov 23 '12 at 20:10
    
@jtbandes, without the DynamicSetting it shouldn't work as I thought you wanted. Try running myControl["a"~CharacterRange~"g"] and then adding +3 to the output in the output cell with and without the DynamicSetting –  Rojo Nov 23 '12 at 21:14
    
The Evaluate is probably useless, but since Interpretation has attribute HoldAll and I don't know why it's not simply HoldRest, I wanted to make sure it evaluated the first argument. However, it seems to evaluate it anyway –  Rojo Nov 23 '12 at 21:21
    
The second argument of Interpretation needs to be what you want the kernel to receive when you use that control as input. You want the values of vars, and not a visual GUI that shows the dynamically updated value of vars. Always remember that Dynamic is only for SHOWING updated output (or in a control such as Slider[Dynamic@..] "as a notation" for input in controls). –  Rojo Nov 23 '12 at 21:25
1  
@jtbandes, I just passed through the docs of Interpretation and saw that it can take an extra argument, specifying the local variables, and using it expands to the same code that I had used before: DynamicSetting@DynamicModule[..., but is way neater. Edited –  Rojo Nov 25 '12 at 5:17

You could use interpretation.

Here's the idea.

SetAttributes[makeDynamicPanel, HoldFirst]
makeDynamicPanel[x_, defaultValue_] :=
 Module[{y},
    y = 
       Interpretation[
          Panel@InputField[Dynamic[x]]
          ,
          x
       ];
    x = defaultValue;
    y
 ]

Then you do for example

makeDynamicPanel[z, {0, 0, π, 0.5, 3}]

and you get a panel that allows to edit the value of z and can be used as argument to your function, you can even do for example panel + 2 and get a valid value, it's quite practical.

share|improve this answer

I would suggest using another list (vals) to store values for the variables vars. To set up a list of controllers (InputFields here) programmatically, some clever construct is required. Here I used an explicit Function call to save the changed value of the $i^{th}$ element of vals inside the Dynamic (as the # stands for the index of the list element, not the actual controller value, which is denoted as $x), but this can also be achieved using With.

calculateValues[v_List] := Plus @@ (v^Range@Length@v);

vars = {a, b, c, d, e};
vals = {1, 2, 3, 4, 5};

Panel[
 Grid[{
   Text /@ vars,
   InputField[Dynamic[vals[[#]], Function[{$x}, vals[[#]] = $x]], 
      FieldSize -> {{0, Infinity}, 1}] & /@ Range@Length@vals
   }]]

Mathematica graphics

Dynamic@vals
{1, 2, 3, 4, 5}
calculateValues@vars
a + b^2 + c^3 + d^4 + e^5
Dynamic[calculateValues@vars /. Thread[vars -> vals]]
3413
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.