The grey 'x' and Debugging WL code

I am still unexperienced in WL, but I have come to a point that I can create some programs that are getting a tiny bit more complex (still quite modest though) :slight_smile:

But I often run into very basic things I just can’t figure out. So I hope someone can direct me a bit :

  1. Inside a Dynamic, I get the grey small ‘x’ if I do not 'close a line with the semicolon (;).
    That is annoying, because the script stops working as planned (as it interpretes the ‘x’ as a multiply sign) in an unintended way.

  2. In a Dynamic[ xxxxxx ], why does the last line have to be WITHOUT semicolon (:wink: ?

  3. How can I best view the values of the variables I use inside Dynamic? I did that by leaving out the semi-colon, as to output the result, but as I mentioned, that does not work inside a Dynamic script.
    Sometimes though this works and the annoying grey ‘x’ does not appear.
    can I switch off the automatic behavior of ‘filling in a x’ for me when the are spaces? I can myself put ‘*’ if I want a multiplication to occur.

  4. I am used to a debugger, where I can set Breakpoints and a Variable Watcher. How is serious debugging being done in WL?

For 1., 2., 3. can you provide a specific example? Is this what you are trying to do?

Row@{Dynamic[x], " ", Slider[Dynamic[x]]}

For 4. have you tried the built-in debugger?

As an example of my question 1 :

I attached an example. I dumbed it down to show what I mean
With the semicolon in place (See the annotement in the code (* Annotemen *) it is fine.
Deleting the semicolon (there or anywheren inside the Dynamic[ … ] gives similar results) :
a grey ‘x’ appears, and I get a red output + the following error in the Messages window :

Error message :
Set::write: Tag Times in {28,39,48,1,4,70,86,83,14,23} {36,76,41,56,39,6,83,7,59,33} is Protected.

Also at the end of the code I get following warnings :

Set::write: Tag First in First[numPoints] is Protected.

Set::write: Tag Last in Last[numPoints] is Protected.

This behavior does not occur ouside the Dynamic[ …]

What is the matter here.?

On question 2 :
here the last semicolon in Dynamic[ … ] is there and it works. If I delete the semicolon, I get the output for that line : (pts3 = ), which is not the case for earlier lines inside Dynamic. On eartlier lines, I get what I described under 1.

In other scripts, which I have to search, the last line in a Dynamic script cannot have the semicolon.

I find it sometimes very hard to pose a question coherently, because I experience part of WL behavior as errartic and hard to pinpoint where the trouble or unclearness is.

Thanks for your help.

x for Forum.nb (33.3 KB)

I attached a Notebook as example, but now I see my response, it looks very strange. The code is inline and the Nb is not as an attachment. Sorry, I have done it right I thought : I used the button “Add Notebook” and browsed to my Nb and clicked ‘Add’ whatever was asked.

I found the Debugger. Looks very unfamiliar to me, but I will study it first, before asking more :slight_smile:

I tried again to attach the Nb. Again the same strange effect. The code is inline in the message and at the end is a very long pink rectangle (error output), which is not in my Nb.

I don’t get it.
How do attach a Nb properly?

How to attach a Nb properly?

Agree that it is a bit confusing. “Add” versus “Attach”. My experience:

  • If you want the notebook contents to appear directly in the post, use the editors menu button “Add Notebook”. Which you obviously did.

Add.png

  • If you do not want the notebook to appear directly in the post, use the button “Add a file to this post” at the bottom. That will insert a reference to the notebook which can then be downloaded by the viewer. And opened in Mathematica.

Thanks, your explanation makes sense. As opposed to the directions on screen :slight_smile:
I will see if I can Edit my previous post as to ‘Attach’ the Nb

Yes, now it is ok.
I hope I remember for next time :slight_smile:

For 1.

If my memory serves, this was the way things behaved many versions ago if had adjacent expressions in a cell with no semicolon separating them. I believe that at some point a feature was added so that Mathematica was “smart” about interpreting what otherwise looks like a product to actually be a compound expression. I guess the intention was to be more user friendly, but it’s not really some sort of deep thing that requires careful consideration–probably best to just always add the semicolons. Maybe this feature just can’t be easily implemented within a Dynamic. That being said, I don’t understand why, if you’re using a compound expression semantically, you wouldn’t be happy with the actual syntax of CompoundExpression. How could just adding in the proper semicolon break anything?

For 2

I don’t believe there is any constraint about terminating the expression wrapped in Dynamic with semicolon. It might not be behaving the way you expect, but I suspect that you’re expectations are just not aligned with how Dynamic works.

For 3

I really think your understanding of Dynamic is far out of alignment with its actual design. There is no “Dynamic script”. There is simply a Dynamic expression. Dynamic is basically just a wrapper that tells the UI to automatically update at that location when relevant variables are changed elsewhere in the notebook without needing to re-evaluate the cell. It’s actually more of a presentation thing than a “script[ing]” thing (although it does have special uses in conjunction with other structures, like controls). You’ve used Dynamic to wrap a rather large expression with many separate variables, and I can’t quite figure out why you’d want to do that. I suspect that Manipulate may be more appropriate (although I didn’t didn’t take the time to reverse engineer your objective, so I could be wrong). There are scoping constructs if that’s what you need: Module, DynamicModule, With, etc.

Set::write: Tag First in First[numPoints] is Protected.

Set::write: Tag Last in Last[numPoints] is Protected.

As for these errors, they’re actually pretty self-explanator, although you do need to understand Mathematica’s computation model. You have this line:

First[numPoints] = 1

This is trying to set DownValues for First. But First has the Attribute Protected (as is typical for built-in functions/symbols). So, to avoid the error, you’d either need to Unset that Attribute (bad idea) or set UpValues for numPoints (won’t do what you actually want) or initialize numPoints as a List before you start setting its elements using syntax like this: numPoints[[1]] = 1 (but this also doesn’t seem to be what you want just based on what I can infer from your variable names).

I find it sometimes very hard to pose a question coherently, because I experience part of WL behavior as errartic and hard to pinpoint where the trouble or unclearness is.

Yes, I have a lot of sympathy for you. It takes quite a bit of practice with Mathematica to get familiar with these things, especially if your previous programming experience was with more imperative languages. Wolfam Language is more similar to Lisp than anything else (as far as my experience goes). You need to try to think more in terms of expressions and transformation rules and less in terms of sequential execution of instructions.

Also, a common pattern I see in this forum is notebooks with all of the code in one gigantic cell. This really does make it difficult to debug. My suggestion would be to build up larger expressions from smaller ones. Do some small things in their own cells until you get those working. Then compose them together into a larger expression in another cell. And so on. Maybe people think they’re making it easier to read their code if they have one gigantic cell, but the only practical way to start understanding where things go wrong is to start deconstructing that huge cell into smaller chunks. Then the error messages appear close to the offending expression (and maybe you could have figured out for yourself where the problem with Protected was happening).

Anyway, I think you’ve dug yourself in too far with your current situation. It would be easier to help if we knew what you were trying to do.

Thanks Eric for your answers, I appreciate.

  1. The reason I wanted to sometimes take out the semicolon, was to see what the value(s) at that point was. So to Debug. Now I have been shown that there is a built in debugger, I will study that and hopefully be able to use it, as it looks very different from the debuggers I know - at least at first sight. I will look into that.

  2. and 3. You are probably right about my conceptions of Dynamic and certainly about how I’ve expressed it. I know though that Dynamic is a wrapper. I started of with using Manipulate, but soon got stuck by my scripts becoming too long to make them understandable in a Manipulate wrapper. I could not subdivide my script and lost control in the woods of different kinds of brackets and functions. And I could not test my variables (= intermidiate steps) to see where it fell apart.
    The error messages are quite cryptic at times :slight_smile:
    So I read the docs about Manipulate and Dynamic and decided to go for Dynamic. If I remember correctly, the Manipulate is a wrapper around a Dynamic script part that is being created by Manipulate. But I’m not totally sure that I say this correctly.

Almost all my scripts are being done with Dynamic and I am sure not in the most effective way. But then again, I am still learning and already glad a script is working :slight_smile:

I use many separate variables so I can see (debug) where I go wrong. If I do much in 1 compound function, I have no idea where I mess up. When a script works, I try tyo compact it, but it has not top priority for me. And of course I want to learn better as well.

It might be self explonatory for seasoned users, but alas not for me.

I already am wondering what means : Set::write

I just read about “Down Values” this afternoon, otherwise I would not have understood.

With initiating : numPoints = {1, 6}; the error is gone.

Thanks, this was enlightning :slight_smile:

I only know very little about Lisp and the concept of symbolic langauges is quite different from where I lived :slight_smile:
It takes quite a rethinking. Thanks for the advice.
As many people come from a procedural programming experience, it might be usefull to add some more in the way of How to go from Procedural to Symbolic/Functional programmimng in the documentation.

I have spent almost a week figuring out how to get a result out of a For loop. I looed up the help and all the examples were with Print. I needed the result in a variable and none of the examples gave me that. Same with While loop.

Example :

bb  = Range[20];
endpoint = 9;
dd = {};
For[i = 1, i < 4, i = i + 2,
 dd = Join[dd, 
   List[bb[[i]], bb[[endPoint - i ]], bb[[endPoint - (i + 1)]]]]]   (*  Kind of  rhythmic figur ABB  *)

I did not get a result.
Only if I explicitly added the code ‘dd’ at the end, I get the result of what was inside dd.
That took me a week, as it is completely contrary to normal WL behavior, like :

Times[3,4] which gives me an output.
So all the time I was fiddling with the code inside the For loop, thinking there was something wrong there. And this is an example of that I often do not know what to search for. How can you know what you don’t know? :slight_smile:

Thanks a million for your help, Eric

As to the last part of your answer :

I agree. I often try things out in separate modules.
The putting it together, especially with the Dynamic wrappers, can still cause problems. And then it is hard to see to which line of code the error message refers, as WL does not show variable names.

It is always a choice as to ask an abstraction of the problem, or as you suggets, a wider view as to what actually should happen. In the latter case, the code I’d need to post would be quite some larger :slight_smile:

So, For is a special form. In its documentation you’ll find this:

Unless an explicit Return is used, the value returned by For is Null.

And for that specific example, I personally wouldn’t have gravitated toward a For loop but instead toward some List restructuring/combining strategy like Riffle.

Okay, here is a start on what you seem to be trying to do. I’ve shown the values of the Manipulate variables explicitly just to demonstrate a sort of validate as you go strategy. I built up each part of the Grid bit by bit, adding each new Manipulate variable only after getting the previous ones to work as I wanted. Once the graphic part of the display was to my liking, then I’d remove (or maybe just comment out) these pseudo-debugging elements.

With[
 {xCoords = {28, 39, 48, 1, 4, 70, 86, 83, 14, 23},
  yCoords = {36, 76, 41, 56, 39, 6, 83, 7, 59, 33}},
 With[
  {pts = Transpose[{xCoords, yCoords}]},
  Manipulate[
   Grid[
    {{"pointSubRange", pointSubRange},
     {"pointCount", Abs[Subtract @@ pointSubRange]},
     {"allPts", pts},
     {"selectedPts", Take[pts, pointSubRange]},
     {"splineDegree", splineDegree},
     {"groupedPoints", Partition[pts, UpTo[groupSize]]},
     {"lineThickness", lineThickness},
     {"aspectRatio", aspectRatio},
     {"curveType", curveType},
     {"splineClosedQ", splineClosedQ},
     {"showPointsQ", showPointsQ},
     {Graphics[{Thickness[lineThickness], 
        curveType[
         Partition[Take[pts, pointSubRange], UpTo[groupSize]], 
         SplineDegree -> splineDegree, SplineClosed -> splineClosedQ],
         Red, If[showPointsQ, Point[pts], Nothing]}], 
      SpanFromLeft}}],
   {pointSubRange, 1, Length@pts, 1, ControlType -> IntervalSlider},
   {splineDegree, 1, Length@pts, 1},
   {groupSize, 2, Length@pts, 1},
   {lineThickness, 0.005, 0.05},
   {aspectRatio, .1, 10, .1},
   {curveType, {BSplineCurve, BezierCurve}},
   {splineClosedQ, {True, False}},
   {showPointsQ, {True, False}}]]]

I understand that now, but something like that is Not to found in the Help. I have been breaking my head over it, as it is not consistent with WL behavior in other cases.

And for that specific example, I personally wouldn’t have gravitated
toward a For loop but instead toward some List restructuring/combining
strategy like Riffle.

I agree, but sometimes I do and sometimes I don’t manage to make the code in the “Mathematica-way”.
Here I just didn’t succeed and also wanted to at least master the For function.
You know, I am an artist and the programming is to get new ideas into my work. So for me it is more important to have some code running properly than that it will win a beauty- or efficiency price.
I like to learn and make better code, but in the meantime I produce some real ugly, but at least working code :slight_smile:

Thanks again for your help.

Wonderfull,Eric. I am studying your example at this moment. It might take a little while to answer. I first want to understand your code completely.
Also, I will again read again about Manipulate versus Dynamic :slight_smile:

Eric, thank you for your extended effort.

I like the way you have implemented a kind of Debugger (in the Grid form). I was missing that and the way I tried to do it, to erase the semicolon on lines I wanted to check the output, which in a Dynamic wrapper does not work well.

I had never used With, which is useful and clear to me. Great.

I played a bit with your example and I understood it.
I also made the showPoints working and beautified the thing a bit. Just playing around to see if I get it.

Still I have some questions :

The values I set with the sliders and buttons are not retained, the next time I run the script.
As I am working with RandomIntegers[100] instead of in the example fixed xCoords & yCoords, I need to run the script often, but would like to retain the settings. This I have working with the script using Dynamic.

Another thing is, how can I get the Graphics outside the Grid. I tried in several ways, but get either warnings in my script or when I run the script, like this :

Manipulate::vsform: Manipulate argument {} does not have the correct form for a variable specification.

I would like to have the Graphics outside the Grid, so I can comment out the Grid entirely when things are working.

I attached my ‘work’.

Thanks again :slight_smile:

Eric Rimbey manipulate 20-3-22 copy 3.nb (11.7 KB)

Another thing is, how can I get the Graphics outside the Grid.

The body of the Manipulate can be any Mathematica expression, so it could be a CompoundExpression. So, you could just do something like

Grid[<debug stuff>];Graphics[<graphics stuff>]

This will suppress the debug stuff. When you want the debug stuff, you’ll need to comment out the ;Graphics[...] bit (including the semi-colon). You could also add another Manipulate variable, like debug and then wrap the whole body in an If (showing whatever you want if debug is True and just the Graphics if debug is False). Or, you could wrap the debug stuff in Print. Or… <there’s no end to how you might want to handle this>.