21
$\begingroup$

I have a notebook containing some functions, for example:

f[x_] := 2*x
g[x_] := x^2

Now I would like to convert this notebook to a package, functions.m, which I can call with Get["functions.m"] inside other notebooks, making the functions f[x] and g[x] available.

How can I do this without writing the package from scratch?

In the File menu there is a sub-menu Save As -> Package, but if I save it, and load it withGet["functions.m"], nothing seems to happen in the new notebook; i.e., when I try to use the functions, I get:

f[x]
f[x] 

I guess there is something else that I need to do besides simply saving the notebook containing the function definitions as a package?

$\endgroup$

3 Answers 3

18
$\begingroup$

When you save a notebook as a package, the only cells that are setup to be evaluated when the package is loaded are Initialization cells. If you change the cell style to the code style, the initialization property is set automatically (this style has the shortcut alt+8) and the cells are distinguished by a darker background. You can also do this by marking the cell, right clicking and selecting "Initialization Cell".

$\endgroup$
2
  • $\begingroup$ btw, congrats on 10k! :) $\endgroup$
    – rm -rf
    Aug 28, 2013 at 22:53
  • $\begingroup$ @rm-rf Thank you. :) $\endgroup$
    – jVincent
    Aug 29, 2013 at 6:47
21
$\begingroup$

If you plan to keep developing the package, you can set up your notebook options so that this is all taken care of automatically.

To have your notebook saved as a package every time you save, open the option inspector and, for your notebook, set Notebook Options->File Options->AutoGeneratedPackage to True. Or, in the front-end, you can type

SetOptions[Notebooks["<notebook name>.nb"][[1]],AutoGeneratedPackage->Automatic]

There is also an option to make new cells initialization cells by default. In the option inspector it is Cell Options->Evaluation Options->InitializationCell (set it to True). The front-end command can be deduced from what is above.

I don't like making my initialization cells code-styled because it seems to disable Mathematica's automatic line-splitting. If you want that, however, change Cell Options->New Cell Defaults->DefaultNewCellStyle to "Code". Why some options have symbol values and some have string values is a mystery to me. You may also want to set DefaultDuplicateCellStyle, the function of which is also a mystery to me.

$\endgroup$
1
  • 1
    $\begingroup$ I am very happy with this method but there seems to be one downside. It does not preserve headings (nor text cells). On the other hand Save As Package does preserve these. Is it possible to get the same behavior in an automated method like the above? See also my question mathematica.stackexchange.com/q/249494/45020. $\endgroup$
    – Kvothe
    Jun 11, 2021 at 15:01
13
$\begingroup$

You can do this with the Save function.

First define some symbols in a notebook:

f[x_] := 2^x-1
g[x_] := 1/f[x]

Evaluate the definitions.

Now use Save to write them to a file:

Save["functions.m", {f, g}]

Now f, g, and all their dependencies have been written to the file.

Loading the file with Get["functions.m"] will load the definitions into the kernel.

$\endgroup$
4
  • $\begingroup$ What directory does this go into? It seems to go into a random one of the directories in $Path. Is there some way to change which directory this saves to by default? $\endgroup$ Oct 11, 2022 at 19:50
  • $\begingroup$ Directory[] returns the current working directory, change it with SetDirectory[]. Be aware this pushes onto a directory stack, go back to previous with ResetDirectory[]. You can change the default by putting a SetDirectory call in $UserBaseDirectory/Kernel/init.m $\endgroup$
    – Joel Klein
    Nov 1, 2022 at 18:52
  • $\begingroup$ You can also provide an absolute path to Save. But just like anywhere else, relative paths are relative to the current working directory, which is what Directory[] tells you and SetDirectory can change. $\endgroup$
    – Joel Klein
    May 25, 2023 at 18:19
  • $\begingroup$ NotebookDirectory[] returns the path the actual notebook is in. You can save the .m file in the same directory where its "mother notebook" resides by invoking Save[FileNameJoin[{NotebookDirectory[], "functions.m"}], {f,g}]. $\endgroup$ Feb 16 at 14:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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