Wolfram Computation Meets Knowledge

48 Debugging Your Code

48Debugging Your Code
Even the most experienced programmers have to spend time debugging their code. It’s an inevitable part of programming. But in the Wolfram Language it’s particularly easy, especially if you follow a few principles.
The first and most important principle is to try out any piece of code you write. Because the Wolfram Language is interactiveand symbolicyou can always instantly do this. So even if you just make a tiny change, run your code again, and see if your test examples still work. If they don’t, fix the code before you go on.
The Wolfram Language can sometimes tell as soon as you type something in that it’s likely to be wrongand then it’ll color it red.
A piece of code with various problems, indicated with red:
WordCloud[ Nest[Join[#, Length[] + Reverse[#, 1, 2]] &, {0}, m], Spacings -> 0]
Once you run a piece of code, the Wolfram Language can also often tell if things have gone obviously wrongin which case it’ll display a message. The code here ends up, for example, asking for the first element of a length-0 list.
Something is obviously wrong when First is applied to the {} that’s produced by Cases:
First[Cases[{1, 2, 3, 4}, 777]]
 
Sometimes the Wolfram Language may not know what to do with something, but it may not be sure there’s a problem. In such cases, it’ll just leave the input unchanged and return it in a symbolic form that can later get a definite value.
Without values for a, b and c, the Wolfram Language just returns this unchanged:
Graph[{a, b, c}]
 
If you generate graphics with symbolic pieces that can’t be rendered, you’ll get a pink box:
Graphics[{Circle[{0, 0}], Disk[{a, b}]}]
 
Use With to temporarily set m=4 to test a fragment of code:
With[{m = 4}, Nest[Join[#, Length[#] + Reverse[#]] &, {0}, m]]
 
When debugging takes a long time it’s usually because one’s made the wrong assumption about what one’s code is doing. And in my experience, the best way to overcome this is just to systematically analyze how the code behaves, making tables of results, generating visualizations, testing out assertions and so on.
Make plots to see what the code is doing:
ListLinePlot /@ Table[Nest[Join[#, Length[#] + Reverse[#]] &, {0}, m], {m, 6}]
 
If this code is working correctly, the result should contain every number from 0 to 2^m-1:
Sort[With[{m = 4}, Nest[Join[#, Length[#] + Reverse[#]] &, {0}, m]]]
 
Systematically check this up to m=10:
Table[Sort[Nest[Join[#, Length[#] + Reverse[#]] &, {0}, m]] == Range[0, 2^m - 1], {m, 10}]
 
Sometimes it’s not sufficient just to see the final result of a piece of code; you need to see what’s going on inside as well. You can insert the function Echo anywhere to print intermediate results or values from your code.
Echo prints values, but does not interfere with the result:
Table[Echo[n]^2, {n, 3}]
1
2
3
 
Continuously show (with a frame) the value of n reached so far:
Monitor[Table[PrimeQ[2^2^n + 1], {n, 15}], Framed[n]]
 
Echo and Monitor just display things. If you want to actually capture intermediate results, you can do it using Sow and Reap.
Reap gives the final result together with a list of everything that was sown by Sow:
Reap[Total[Table[Sow[n], {n, 5}]]]
 
This sows successive values of Length[#], and reaps the results:
Last[Reap[Nest[Join[#, Sow[Length[#]] + Reverse[#]] &, {0}, 10]]]
 
With[{x=value},expr] compute expr with x replaced by value
Echo[expr] display and return the value of expr
Monitor[expr,obj] continually display obj during a computation
Sow[expr] sow the value of expr for subsequent reaping
Reap[expr] collect values sowed while expr is being computed
48.1Correct the program Counts[StringTake[#, 2]&/@WordList[]] for counting possible first two letters in words. »
Sample expected output:
Out[]=
48.2Use Sow and Reap to find intermediate values of #1 in Fold[10#1+#2&, {1, 2, 3, 4, 5}]»
Expected output:
Out[]=
48.3Use Sow and Reap to get a list of all cases where #/2 is used in Nest[If[EvenQ[#], #/2, 3#+1]&, 1000, 20]»
Expected output:
Out[]=
Can I cause a problem by just trying to run a piece of code?
Is there a most common type of bug in Wolfram Language code?
Not really. The design of the language makes all sorts of bugs that are common in other programming languages rare. For example, “off by one” errors are common in languages where you’re always explicitly manipulating loop variables, but are rare when you’re using Wolfram Language “whole-list” functions like Table.
If I can’t figure out what’s going on, is it worth just trying random things?
If you think you’re close, it’s often not crazy to try making small random changes to code to see what happens. Since in the Wolfram Language simpler code is usually more likely to be correct, it’s not uncommon to hit the code you want by a small amount of random searching.
Is there a way to do interactive step-by-step debugging in the Wolfram Language?
Yes (at least with a native desktop interface)though it’s rarely used. Given the structure of the Wolfram Language, systematically capturing and analyzing intermediate results is almost always a better approach.
When there’s a message, how can I tell where it was generated?
Click the
\!\(\* GraphicsBox[ TagBox[RasterBox[CompressedData[" 1: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 Qd72aKKM3iv+k/H/DybC7Q4= "], {{0., 86.94737205227011}, {110., 9.947372052270111}}, {0, 255}, ColorFunction->RGBColor, ImageResolution->{72., 72.}, SmoothingQuality->"High"], BoxForm`ImageTag["Byte", ColorSpace -> "RGB", Interleaving -> True], Selectable->False], DefaultBaseStyle->"ImageGraphics", ImageSize->{22.116394042968622`, Automatic}, ImageSizeRaw->{110., 77.}, PlotRange->{{0, 110.}, {0, 77.}}]\)
next to the message, then press Show Stack Trace. This will show you the stack of functions in which the message was generated.
How can I tell what’s wrong when a piece of graphics is “pinked”?
Hover over it and you’ll see the underlying symbolic expression. Or press the + to print messages.
What is the code that makes the fractal-like graphics doing?
It’s making a Gray codean ordering of integers so that only one binary digit changes at each step.
  • If Dynamic[x] appears in a notebook, it’ll display as the dynamically updated current value of x, giving you a way to produce a real-time display of what’s going on inside a program.
  • EchoFunction, EchoTiming and EchoEvaluation are useful variants of Echo.
  • The Wolfram Language has various mechanisms for bulletproofing code. An example is Enclose and Confirm, which allows you to confirm that your program didn’t fail, and if it did, fall through to the enclosing Enclose.
  • For large-scale software development, the Wolfram Language has a built-in framework for creating and running systematic tests, with functions like VerificationTest and TestReport.
  • A major goal of good language design is to encourage people to write correct code.
Next Section