3
$\begingroup$

I have a notebook that calculates some data in a relatively large time so I want to keep these data saved inside the notebook without recalculate them every time I open the notebook.

I know I can save them to an external file but this is not what I want.

Imagine that the first time I run the notebook after some time I get an array data. Now I close the notebook, I reopened it and I want to use the data stored in data without having to evaluate the notebook again.

$\endgroup$
1
  • $\begingroup$ You might take a look at the option SaveDefinitions->True with Manipulate or at DynamicModule as these should address your problem. $\endgroup$ Commented Dec 19, 2013 at 10:29

2 Answers 2

1
$\begingroup$

How about using

notebookHasData[] := Length[Cells[CellTags -> "data"]] > 0; myData[] := RandomReal[1, 1000]; 

and

If[ notebookHasData[], NotebookEvaluate[EvaluationNotebook[], EvaluationElements -> {"Tags" -> {"data"}}, InsertResults -> True]; , data = myData[]; NotebookDelete[Cells[CellTags -> "data"]]; CellPrint@ Cell[BoxData@ ReleaseHold@ Hold[MakeBoxes][Hold[Set][Hold[data], Hold@Evaluate@data]], "Input", CellTags -> "data"] ] 

evaluating the big piece of code generates a cell that looks like

what the printed cell looks like

It checks if such a cell already exists. If it does, it evaluates that cell, rather than generating the data and the cell again.

This still requires you to evaluate one cell, whether it is the generated cell or a cell containing/refering to the "big piece of code" I show above. You could further automate this process by using an InitializationCell (which will prompt you), or by using some more advanced stuff using Dynamics or CellEvaluationFunction (this is hacky), which allow for solutions that will not prompt you.

This stores the data in quite an ineffecient way, with a lot of RowBoxes. We could make a text cell to store all the numbers and maybe make it invisible. Then we could probably make a function to extract the data from this cell by some other means than evaluation.

Do you want to share your notebooks with others and is that the reason you don't want to work with files? If there is no special reason, my advice would be not to get too perfectionistic about this, as I think solutions using files are usually better.

$\endgroup$
1
$\begingroup$

You can use DynamicModule:-

From documentation: "Symbols specified in a DynamicModule will by default have their values maintained even across Mathematica sessions."

In the example below the data in x is saved in list when 'save' is clicked. The 'save' button has to remain in the notebook, and in fact it needs to be visible before list is ready for use, (so a docked cell could be handy). When the notebook is reopened list is ready for use.

DynamicModule[{savelist = Null}, Dynamic[Button["save", savelist = list = x], Initialization :> (list = savelist)]] 

enter image description here

x = {1, 2, 3, 4}; 

Click 'save'.

list 

{1, 2, 3, 4}

Save, close, quit and reopen. list is ready for use :-

list * 2 

{2, 4, 6, 8}

$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.