3

If anyone can help me with this, it would be greatly appreciated. I'm using the following code with the intent of using controls to easily input values and units:

Slider[Dynamic[b]]
SetterBar[Dynamic[lengthUnit], {"feet", "inches", "centimeters", "meters"}]
Quantity[Dynamic[b], Dynamic[lengthUnit]]

The above code returns "Quantity[0.,feet]"

But if I leave Dynamic out of the second argument by substituting the following line, everything works as expected:

Quantity[Dynamic[b], lengthUnit]

I suspect that this has something to do with the HoldRest attribute of Quantity and the HoldFirst attribute of Dynamic, but I'm not sure. Does anyone have any suggestions of how to make this work?

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
Avery K
  • 31
  • 2

2 Answers2

5

Let's try to explain this: The Dynamic never goes away and just because you don't see it on screen, doesn't mean that it isn't still there. So let's assume you have a similar function which doesn't act in such a special way as Dynamic does and let's call it freakyFunc. This function has no definition and when you use it, it is not further evaluated.

The question is now, what do you expect as result when you call

Quantity[freakyFunc[1], freakyFunc["feet"]]
(* Quantity[freakyFunc[1], freakyFunc["feet"]] *)

or when you call something like

Plot[freakyFunc[a] x, {x, 0, 1}]

Mathematica graphics

Right, it just won't work because you cannot calculate or plot something, when you have this freakyFunc wrapped around an expression in the wrong place.

But let's assume that freakyFunc will evaluate everything that you give as argument, which is the usual behavior anyway:

a = 1;
freakyFunc[a]
(* freakyFunc[1] *)

Nothing spectacular so far. Now, we will give freakyFunc a very important meaning: It will only display its arguments when you call it, but it will stay there, invisible but alive. Furthermore, when you call something like freakyFunc[a], then it will display the value of a and track all chances of a from now on.

If you have followed me so far, it should become obvious that freakyFunc inside your Quantity won't work. Instead, you want the whole Quantity expression tracked and dynamically updated. So let's try this with Dynamic, because if you understood freakyFunc, then you understood how Dynamic works in general:

Slider[Dynamic[b]]
SetterBar[
 Dynamic[lengthUnit], {"feet", "inches", "centimeters", "meters"}]
Dynamic[Quantity[b, lengthUnit]]

Mathematica graphics

And of course you see now, that you have to dynamically update the whole Plot instead of the function only

Slider[Dynamic[a], {1, 5}]
Dynamic[Plot[a x, {x, 0, 1}, PlotRange -> {Automatic, {0, 1}}]]

There are limits and exceptions to my explanation, but it should help you to get on the right track. Btw, one of those exceptions is that options of functions can have (often, always, rarely, I don't know) dynamic content on their right side. Therefore, this works

Slider[Dynamic[a], {1, 5}]
Plot[x, {x, 0, 1}, PlotLabel -> Dynamic[a]]
halirutan
  • 112,764
  • 7
  • 263
  • 474
  • Dynamic[Quantity[Dynamic[b], lengthUnit]] works also and Dynamic[b] still in the background. – Basheer Algohi May 04 '15 at 16:56
  • @Algohi It depends on how you define works, because when you try to add two quantities, the result is not what one expects: Dynamic[Quantity[Dynamic[b], "feet"] + Quantity[1, "meters"]] Now try the same with a version where you remove the inner Dynamic. – halirutan May 04 '15 at 18:01
  • yes, it is now clear. Thanks :) – Basheer Algohi May 04 '15 at 22:34
2

A control such as slider is updating a variable and the front-end needs to know that the variable is dynamic, so the Dynamic wrapper goes on the variable. But Quantity is a display form and the front-end only needs to know that it should treat the whole form as dynamic.

On my system, V10.1 running on OS X Yosemite,

Quantity[Dynamic[b], lengthUnit]

does not work. Selecting a new unit from setter bar isnot* reflected in the Quantity display. However,

Quantity[Dynamic[b], Dynamic[lengthUnit]]

does work, but really all you need is one Dynamic:

Dynamic @ Quantity[b, lengthUnit]
m_goldberg
  • 107,779
  • 16
  • 103
  • 257