# Printing a Dynamic variable inside Dynamic

I'm trying to Print the variable a inside the Dynamic wrapper. Seems like such a simple question, but I haven't been able to get it to work. Here's what I tried.

Dynamic[
mQ[n_] :=
75.63510582933174 - 35.87130621205199 n + 86.18343750838301 n^2 -
55.324190072519976 n^3;
mV[t_] := -29.619999999999976 + 5.499999999999998 t +
18.333333333333325 t^2;
a = xVariable + 2 - yVariable;
{Slider[Dynamic[n, Automatic]],
Dynamic[{n, xVariable = mQ[n]},
ContinuousAction -> False]} {Slider[Dynamic[t, Automatic]],
Dynamic[{t, yVariable = mV[t]}, ContinuousAction -> False]}]


I need to print the results of "a"

I've updated the example code minus the plot to try and better explain the problem. I have tried the usual Print["a= ", Dynamic[a]] only to find it returns NULL or nothing at all. The variable is being calculated because it plots. So I believe the problem is more complex than I have explained above, and the issue now comes from the fact that the print statement must be closed with a ";" for the rest of the code in the Dynamic wrapper to run. That effectually keeps the print statement from writing to the nb. The code is long and complex but is many calculated variables that take input from dynamic sliders and then create a 3D plot. Debugging this has proved impossible when the variables that take input from the sliders are wrapped in Dynamic[]. Remove that and the variables do not get input from the sliders and their output can not be checked. I hope that helps to explain the problem better.

Thanks for your help!

-
I guess R Hall looks for a way to have feedback on the value of a if the above dynamic assignment is part of a larger gui. If that's the case (or even if not), CHM's answer is the correct one, especially I prefer the second one without the Print. –  István Zachar Apr 11 '12 at 9:27
add comment

## Short answer

For me a Print from within a Dynamic goes to the Messages notebook. Have you checked that with a very simple case? If I evaluate this:

Column[{Slider[Dynamic[x]],Dynamic[Print[x];x]}]

and play with the slider, the Messages notebook will be opened and the x-values are printed to it. If that is not also happening for you, you should provide more detailed information (version, operating system, any special settings?)

## Debugging and Organization of User Interface code

Honestly, I think there are some misunderstandings in your code fragment about how to use Dynamic, so I think your real problem is that you don't know how to efficiently organize and debug your user interface code. It doesn't become clear from neither your example nor your description what the complications with your code actually are, so I can just give some general advice.

First of all I would consider it essential to separate any programming logic from the user interface functionality. I would absolutely discourage to use code within a Dynamic to update variables (or even do parts of your calculation) as a side effect, as e.g. Dynamic[{n, xVariable = mQ[n]}] does. I don't think that Dynamic was ever meant to be used like that.

If you want to create a 3D-plot from the values of many sliders, then write a function which accepts all those values as arguments and calculates the 3D-plot. Keep this function completely free from any user interface code, that is any Dynamic whatsoever. This function can be debugged and tested in the usual way (using Print, Trace or the debugger). When it produces the plot you want, only in the end write a user interface that makes use of that function. From what you described even a simple Manipulate would do, e.g.:

complicatedPlot3D[a_, b_, c_] := Plot3D[x^a + y^b - x*y^c, {x, -1, 1}, {y, -1, 1}]

Manipulate[ complicatedPlot3D[a, b, c], {a, 1, 5}, {b, 2, 5}, {c, 5, 6}]

If you find a Manipulate will not provide enough flexibility, I think you should try to learn as much as possible from the tutorials on the topic before you try to build something more complicated on your own. I would consider Introduction to Dynamic a must read and Advanced Dynamic Functionality to also be helpful (reading them in the documenation center and actually executing the examples is to be recommended).

## Additional Remarks on Example Code

There are some details in the example code that -- at least without a larger picture -- do not seem to make much sense to me:

1. It seems useless to wrap a Dynamic around everything. Doing so will actually not do anything because all appearances of the values that are changed are in nested Dynamics. If there would be such expressions which were not nested, it would redefine the functions mQ and mV and recreate the sliders on every change of n or t, but neither of these does in any way depend on those variables. In that latter case the sliders would also start to behave strangely.

2. Neither the second argument Automatic nor the ContinuousAction->False option to the nested Dynamic do seem to achieve anything.

3. As it is written, it uses the product of lists to arrange it's various parts. The product is probably just a typo and the whole construct looks more like an accident altogether. There are special functions which allow to control the arrangement of the various parts of a gui, like Grid, Column or Row.

4. Your question about Print and the placement of ; make me believe that you are not fully aware of the difference between the return value that any expression will give on evaluation and the side effect of writing to a notebook that Print achieves and how all that is linked to the dynamic functionality.

Basically I think the answer of @CHM already gives you something that will work, but I think it might make sense to go one step further and remove all things that seem strange. Here is a version that would do what your example does:

mQ[n_] :=
75.63510582933174 - 35.87130621205199 n + 86.18343750838301 n^2 -
55.324190072519976 n^3;
mV[t_] := -29.619999999999976 + 5.499999999999998 t +
18.333333333333325 t^2;

Grid[{
{Slider[Dynamic[n, (n = #; xVariable = mQ[n]) &]],
Dynamic[{n, xVariable}]}, {Slider[
Dynamic[t, (t = #; yVariable = mV[t]) &]],
Dynamic[{t, yVariable}]},
{Dynamic[xVariable + 2 - yVariable], SpanFromLeft}
}]


These are the changes: function definitions are made outside of the user interface code, I removed any arguments and options that are not necessary and arranged all parts of the user interface in a Grid. Also I do now set xVariable and yVariable in the functions given as second argument to the Dynamic in the sliders. All other Dynamic are now only showing current values and have no side effects. The overall Dynamic did go away altogether, since it only will make a difference in the initialization of the code, which I will address in the following paragraph.

This code has now two drawbacks, one of that you probably tried (and partially did) solve with that overall Dynamic: 1) the function definitions will not automatically be defined when the resulting gui is shown with a new Kernel and 2) all variables are global. This both can be solved by making proper use of DynamicModule, which would look like this:

DynamicModule[{n = 0, t = 0, xVariable, yVariable},
xVariable = mQ[n];
yVariable = mV[t];
Grid[{{
Slider[Dynamic[n, (n = #; xVariable = mQ[n]) &]],
Dynamic[Row[{
"n=", NumberForm[n, {5, 3}],
", x=", NumberForm[xVariable, {5, 3}]
}]]
}, {
Slider[Dynamic[t, (t = #; yVariable = mV[t]) &]],
Dynamic[Row[{
"t=", NumberForm[t, {5, 3}],
", y=", NumberForm[yVariable, {5, 3}]
}]]
}, {
Panel[Dynamic[NumberForm[xVariable + 2 - yVariable, {5, 3}]]],
SpanFromLeft
}
}],
Initialization :> (
mQ[n_] :=
75.63510582933174 - 35.87130621205199 n + 86.18343750838301 n^2 -
55.324190072519976 n^3;
mV[t_] := -29.619999999999976 + 5.499999999999998 t +
18.333333333333325 t^2;
)
]


You will find more information about the details of these constructs in the mentioned tutorials. Note that I have also added some means to make the behaviour of the user interface somewhat more appealing.

-
Thank you for your kind advice @Albert Retey, but the nb variables must be controlled by sliders and also update a 3D plot Dynamically. This code was tested as static. I do very much appreciate your advice. Thanks also for your suggested tutorials. The main issue here is that each suggestion to Print is unterminated, and will cripple the code. If the Print[]; is terminated as in normal MMA print statements they are effectively silenced in a Dynamic Wrapper. Thanks again for your help! –  R Hall Apr 11 '12 at 19:36
Have you tried my simple example and verified whether it does print to the Message notebook or not? I don't think that it does matter very much whether or not you do terminate the Print with a ; or not, that will only effect what will be returned. If you remove the ; then the Print will work as before, but there will an additional Null be multiplied to the value shown. Print writes as a side effect which will happen when Print is evaluated, that's completely independent from what's happening with its return value... –  Albert Retey Apr 11 '12 at 19:52
@ Albert Retey yes thanks, the results did print to the message nb with a twist it worked in my code also. I used: Print[Dynamic[a]]; and the results went to the message nb. Thanks very much! –  R Hall Apr 11 '12 at 20:20
@RHall: When Print[Dynamic[a]]; will show something and Print[a]; does not I think you are facing a problem of evaluation order. It looks like a is only set to the value you expect to see after the Print. It's nice that you accepted my answer, but I still think your actual problem isn't solved and it's related to your "unconventional" usage of Dynamic. If you are still interested I can elaborate on some of the things that make me believe this... –  Albert Retey Apr 11 '12 at 20:34
@ Albert Retey please elaborate. I would certainly love to learn more. Thanks! –  R Hall Apr 12 '12 at 2:29
show 3 more comments

I've rewritten my answer after you edited yours.

Dynamic[
mQ[n_] :=
75.63510582933174 - 35.87130621205199 n + 86.18343750838301 n^2 -
55.324190072519976 n^3;

mV[t_] := -29.619999999999976 + 5.499999999999998 t +
18.333333333333325 t^2;

a = xVariable + 2 - yVariable;

{Slider[Dynamic[n, Automatic]],
Dynamic[{n, xVariable = mQ[n]}, ContinuousAction -> False],
Slider[Dynamic[t, Automatic]],
Dynamic[{t, yVariable = mV[t]}, ContinuousAction -> False],
Dynamic[a]}]


That's the code I used to generate this:

Modifications to your code

What I've done is wrap all the Slider[]s and Dynamic[] variables in {}'s, so that there's only one list, instead of two. This makes sure that the value of the slider is displayed next to it. The only thing that your code was really missing is the inclusion of a Dynamic[a] so the value of a gets printed, just like the values of mQ[] and mV[] are.

-
I have updated the problem statement since it appears the problem was more complex than I had initially thought. Thanks for your help! –  R Hall Apr 11 '12 at 10:58
I see this shows the new variable result also! Very nicely done! Thanks! –  R Hall Apr 12 '12 at 2:31
add comment

If the problem is about debugging, perhaps this will help:

Slider[Dynamic[t], {0, 20}]
nb = CreateDocument[];
Dynamic[NotebookWrite[nb, Cell[ToString@t]]]


It will give you the output in a separate Notebook. If you would like to write to the same notebook use nb=EvaluationNotebook[]; instead (but I don't recommend it:).

EDIT:

Adapting this answer also works nicely

insertBelowEvaluationCell[expr_, nb_] :=
(SelectionMove[nb, After, EvaluationCell];
NotebookWrite[nb, Cell[BoxData@ToBoxes[expr], "Print"]]);


and then:

Slider[Dynamic[t], {0, 20}]
nb = CreateDocument[];
Dynamic@insertBelowEvaluationCell[t, nb]


## EDIT 2

This code works for me:

{Slider[Dynamic[n, Automatic]],
Dynamic[{n, mQ[n]}, ContinuousAction -> False]} {Slider[
Dynamic[t, Automatic]],
Dynamic[{t, mV[t]}, ContinuousAction -> False]}

Dynamic[mQ[n_] :=
75.63510582933174 - 35.87130621205199 n + 86.18343750838301 n^2 -
55.324190072519976 n^3;
mV[t_] := -29.619999999999976 + 5.499999999999998 t +
18.333333333333325 t^2;
a = mQ[n] + 2 - mV[t]]


I'm still not sure if you need to display just the last value of a or all values...

-
Thanks, but the actual problem has nothing to do with a slider variable, but variables buried in the Dynamic portion of the nb that receives input from the slider. Using this method in the dynamic wrapper produces hundreds of nb files in a minute or so and none contain the variable. Thanks for your help! –  R Hall Apr 11 '12 at 14:54
You're welcome. But it seems like I still don't understand the problem... –  Ajasja Apr 11 '12 at 14:56
OK, I've updated the code example to hopefully make the issue more clear. Thanks! –  R Hall Apr 11 '12 at 15:16
add comment