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:
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 Dynamic
s. 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.
Neither the second argument Automatic
nor the ContinuousAction->False
option to the nested Dynamic
do seem to achieve anything.
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
.
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.
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 thePrint
. $\endgroup$