0
$\begingroup$

Maybe I'm not using the best programming practices in Mathematica, but my notebooks usually contain a mixture of "definitions" and "computations" with these definitions. Say,

f[x_] := x^2 (* Definition *)
f[10] (* Computation *)
g[x_] := f[x] - 1/f[x] (* Definition *)
g[100] (* Computation *)

Then each time I open the notebook anew, to ensure that all definitions are in place the easiest way is to evaluate everything. But some computations can be costly, and I do not need their results.

So, is there a way to only evaluate "definitions" or assignments in the notebook, and omit the "computations"? In the code sample above only 1st and 3rd lines must be evaluated, while f[10] and g[100] must be ignored.

Or, if the question does not make much sense, what would be good solution to the described problem? Keeping assignments and computations separately does not make much sense to me, commenting out all the computations make notebook look weird and if I do need them some time later, I'll have to do a lot of typographic work removing them.

$\endgroup$
  • $\begingroup$ I'm not sure that doable in general: Which of the following are definitions? f[x_]:=..., f[10], SetAttributes[f, ...], Table[...], Table[f[i]=..., {i,...}], SetDirectory[...]. As you can see, it can be very hard to decide whether something will have meaningful side effects with respect to defining things (and the SetDirectory[...] one will most likely also need to be evaluated when reopening the notebook, but is not really a definition) $\endgroup$ – Lukas Lang Oct 27 at 15:46
  • 1
    $\begingroup$ One thing that could however work is if you manually mark the relevant cells as InitializationCell - if you reopen the notebook and start evaluating things, Mathematica will ask you whether the initialization cells of the notebook should be evaluated for you. $\endgroup$ – Lukas Lang Oct 27 at 15:48
  • $\begingroup$ @LukasLang Of course I understand my question may not be well defined or hard to solve precisely, but most of my code is pretty simple and I would be ok with evaluating all cells containing = or :=, I do not expect difficult side-effects in my case. As for the InitizlizationCell option -- it's of course better than commenting out some pieces of the code, but still highly non-optmal in my view, as it requires a lot of manual work. $\endgroup$ – Weather Report Oct 27 at 15:58
  • $\begingroup$ Rather than writing a notebook, you might consider writing a package with a context that can be imported in different notebooks. $\endgroup$ – evanb Oct 27 at 20:50
2
$\begingroup$

Update

(I added a gray background when in the "Initialization" screen style to remind the user to switch back after evaluating code)

Here's a stylesheet solution. The basic idea is to add an "Initialization" screen style environment (like "Working", "SlideShow" and "Presentation"). When the screen style environment is "Initialization" the style definition for "Input" cells looks at the the contents of the cell, and if doesn't match a Set or SetDelayed expression, the CellEvaluationFunction is neutered. Finally, key shortcuts are used to switch between the "Working" and "Initialization" screen style environments. Here is the stylesheet:

SetOptions[
    EvaluationNotebook[],
    StyleDefinitions -> Notebook[
        {
        Cell[StyleData[StyleDefinitions->"Default.nb"]],
        Cell[StyleData["Input","Initialization"],
            CellProlog :> If[
                !MatchQ[
                    NotebookRead[EvaluationCell[]],
                    Cell[BoxData[RowBox[{_,"="|":=",__}]],__]
                ],
                CurrentValue[EvaluationCell[],CellEvaluationFunction]=Null&
            ],
            CellEpilog :> (CurrentValue[EvaluationCell[], CellEvaluationFunction]=Inherited)
        ],
        Cell[StyleData[All, "Initialization"],
            MenuCommandKey -> "=",
            Background -> GrayLevel[.92]
        ],
        Cell[StyleData[All, "Working"],
            MenuCommandKey -> "-"
        ]
        },
        StyleDefinitions->"PrivateStylesheetFormatting.nb"
    ]
]

Use Cmd+= to switch to the "Initialization" screen style environment. Then, only "Input" cells that are Set or SetDelayed cells will evaluate. Use Cmd+- to switch back to the "Working" screen style environment, and all "Input" cells will evaluate normally.

$\endgroup$
  • 1
    $\begingroup$ A stupid follow-up: I need to apply cmd+=/- to the cell I want active/inactive or to the whole notebook? The hotkeys do not seem to work for me, how can this be done alternatively? $\endgroup$ – Weather Report Oct 28 at 10:13
  • $\begingroup$ I join the question. The hotkeys don't work for me too: after evaluation of the code I tried Control + "=" and Alt + "=" without getting the desired effect. $\endgroup$ – Alexey Popkov Oct 28 at 14:07
  • $\begingroup$ @WeatherReport I had an error in the style sheet, please try the updated code. If it still doesn't work, please mention your OS and M version. $\endgroup$ – Carl Woll Oct 28 at 14:28
  • $\begingroup$ @CarlWoll With the updated code the hotkeys also don't work for me. Windows 7 x64. How is it supposed to work under Windows? $\endgroup$ – Alexey Popkov Oct 28 at 16:25
  • $\begingroup$ @AlexeyPopkov I'm not using Windows, so I can't say for sure. Perhaps some other component has already taken the = and - short cuts. You can experiment with different keys, I believe that captialization matters, so that "u" is different from "U", and "!" is different from "1". $\endgroup$ – Carl Woll Oct 28 at 17:06
1
$\begingroup$

Then each time I open the notebook anew, to ensure that all definitions are in place the easiest way is to evaluate everything. But some computations can be costly, and I do not need their results.

One way is to wrap every evaluation by TimeConstrained using $Pre:

$Pre = Function[input, TimeConstrained[input, 0.001, Null], HoldAllComplete];

Now any time-consuming evaluations will be automatically aborted without generating any output, but simple and fast definitions will be evaluated as usual.

For clearing up the value of $Pre evaluate the following:

$Pre =.

most of my code is pretty simple and I would be ok with evaluating all cells containing = or :=

You can test whether the input expression is an assignment(s), and ignore inputs containing anything else:

$Pre = Function[input, 
   If[MatchQ[Unevaluated[input], 
     HoldPattern[(Set | SetDelayed)[_, _] | 
       CompoundExpression[(Set | SetDelayed)[_, _] .., Null ...]]], input], 
   HoldAllComplete];

For clearing up $Pre in this case one should evaluate the following two-lines input:

$Pre = Identity;
Clear[$Pre]

Of course there are other possible solutions, for example writing a function that will evaluate only the Set and SetDelayed statements using low-level Notebook programming. It even can be put as a Button in the Notebook or a Palette, or as a menu item with assigned keyboard shortkey.

$\endgroup$
  • $\begingroup$ Very interesting, I didn't know something like $Pre existed. $\endgroup$ – Weather Report Oct 28 at 10:13
  • $\begingroup$ @WeatherReport if I understand correctly, that might just be a user defined symbol that uses the $ context $\endgroup$ – CA Trevillian Nov 1 at 23:55
  • 1
    $\begingroup$ @CATrevillian No, $Pre is a built-in symbol with documented meaning: reference.wolfram.com/language/ref/$Pre.html $\endgroup$ – Alexey Popkov Nov 2 at 7:23
  • $\begingroup$ @AlexeyPopkov wow! That’s new to me, a built-in symbol meant to be redefined. Crazy!! I’ll have to play some good tricks with that one. Thanks for correcting me. So it is a built-in user defined symbol that uses the $ context? Maybe that’s still a bit broken of a definition, though. For clarity, does the symbol definition reset upon kernel restart? Or do you always have to remove downvalues? $\endgroup$ – CA Trevillian Nov 2 at 16:57
  • 1
    $\begingroup$ @CATrevillian $ is a part of symbol name, it isn't related to Context. The definition will exists only during the current kernel session. You will find may interesting examples of use of this symbol on this site and on SO with tag [wolfram-mathematica]. $\endgroup$ – Alexey Popkov Nov 2 at 17:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.