﻿ function - function - Organizing Notebooks & Saving Results in Mathematica - oipapio - oipapio.com oipapio

# function - Organizing Notebooks & Saving Results in Mathematica

As of now I use 3 Notebook :

• Functions

Where I have all the functions I created and call in the other Notebooks.

• Transformation

Based on the original data, I compute transformations and add columns/List

When data is my raw data, I then call :

t1data : the result of the first transformation

t2data : the result of the second transformation

and so on, I am yet at t20.

• Display & Analysis

Using both the above I create Manipulate object that enable me to analyze the data.

## Questions

• Is there away to save the results of the Transformation Notebook such that t13data for example can be used in the Display & Analysis Notebooks without running all the previous computations (t1,t2,t3...t12) it is based on ?

• Is there a way to use my Functions or transformed data without opening the corresponding Notebook ?

• Does my separation strategy make sense at all ?

As of now I systematically open the 3 and have to run them all before being able to do anything, and it takes a while given my poor computing power and yet inefficient codes.

1. 2019-11-13

## Saving intermediate results

The native file format for Mathematica expressions is the .m file. This is human readable text format, and you can view the file in a text editor if you ever doubt what is, or is not being saved. You can load these files using `Get`. The shorthand form for `Get` is:

``````<< "filename.m"
``````

Using `Get` will replace or refresh any existing assignments that are explicitly made in the .m file.

Saving intermediate results that are simple assignments (`dat = ...`) may be done with `Put`. The shorthand form for `Put` is:

``````dat >> "dat.m"
``````

This saves only the assigned expression itself; to restore the definition you must use:

``````dat = << "dat.m"
``````

See also `PutAppend` for appending data to a .m file as new results are created.

Saving results and function definitions that are complex assignments is done with `Save`. Examples of such assignments include:

• ``````f[x_] := subfunc[x, 2]
``````
• ``````g[1] = "cat"
g[2] = "dog"
``````
• ``````nCr = #!/(#2! (# - #2)!) &;
nPr = nCr[##] #2! &;
``````

For the last example, the complexity is that `nPr` depends on `nCr`. Using `Save` it is sufficient to save only `nPr` to get a fully working definition of `nPr`: the definition of `nCr` will automatically be saved as well. The syntax is:

``````Save["nPr.m", nPr]
``````

Using `Save` the assignments themselves are saved; to restore the definitions use:

``````<< "nPr.m" ;
``````

## Moving functions to a Package

In addition to `Put` and `Save`, or manual creation in a text editor, .m files may be generated automatically. This is done by creating a Notebook and setting `Cell > Cell Properties > Initialization Cell` on the cells that contain your function definitions. When you save the Notebook for the first time, Mathematica will ask if you want to create an Auto Save Package. Do so, and Mathematica will generate a .m file in parallel to the .nb file, containing the contents of all Initialization Cells in the Notebook. Further, it will update this .m file every time you save the Notebook, so you never need to manually update it.

Sine all Initialization Cells will be saved to the parallel .m file, I recommend using the Notebook only for the generation of this Package, and not also for the rest of your computations.

When managing functions, one must consider context. Not all functions should be global at all times. A series of related functions should often be kept in its own context which can then be easily exposed to or removed from `\$ContextPath`. Further, a series of functions often rely on subfunctions that do not need to be called outside of the primary functions, therefore these subfunctions should not be global. All of this relates to Package creation. Incidentally, it also relates to the formatting of code, because knowing that not all subfunctions must be exposed as global gives one the freedom to move many subfunctions to the "top level" of the code, that is, outside of `Module` or other scoping constructs, without conflicting with global symbols.

Package creation is a complex topic. You should familiarize yourself with `Begin`, `BeginPackage`, `End` and `EndPackage` to better understand it, but here is a simple framework to get you started. You can follow it as a template for the time being.

This is an old definition I used before `DeleteDuplicates` existed:

``````BeginPackage["UU`"]

UnsortedUnion::usage = "UnsortedUnion works like Union, but doesn't \
return a sorted list.  \nThis function is considerably slower than \
Union though."

Begin["`Private`"]

UnsortedUnion =
Module[{f}, f[y_] := (f[y] = Sequence[]; y); f /@ Join@##] &

End[]

EndPackage[]
``````

Everything above goes in Initialization Cells. You can insert Text cells, Sections, or even other input cells without harming the generated Package: only the contents of the Initialization Cells will be exported.

`BeginPackage` defines the Context that your functions will belong to, and disables all non-`System`` definitions, preventing collisions. (There are ways to call other functions from your package, but that is better for another question).

By convention, a `::usage` message is defined for each function that it to be accessible outside the package itself. This is not superfluous! While there are other methods, without this, you will not expose your function in the visible Context.

Next, you `Begin` a context that is for the package alone, conventionally `"`Private`"`. After this point any symbols you define (that are not used outside of this `Begin`/`End` block) will not be exposed globally after the Package is loaded, and will therefore not collide with `Global`` symbols.

After your function definition(s), you close the block with `End[]`. You may use as many `Begin`/`End` blocks as you like, and I typically use a separate one for each function, though it is not required.

Finally, close with `EndPackage[]` to restore the environment to what it was before using `BeginPackage`.

After you save the Notebook and generate the .m package (let's say "mypackage.m"), you can load it with `Get`:

``````<< "mypackage.m"
``````

Now, there will be a function `UnsortedUnion` in the Context `UU`` and it will be accessible globally.

You should also look into the functionality of `Needs`, but that is a little more advanced in my opinion, so I shall stop here.

2. 2019-11-13

• Saving variable states: can be done using `DumpSave`, `Save` or `Put`. Read back using Get or <<
• You could make a package from your functions and read those back using `Needs` or <<
• It's not something I usually do. I opt for a monolithic notebook containing everything (nicely layered with sections and subsections so that you can fold open or close) or for a package + slightly leaner analysis notebook depending on the weather and some other hidden variables.