Best way to reuse some code in multiple notebooks?

I have some code I’d like to reuse in multiple notebooks. Simple definitions, like

ratioFromDb[db_] := 10^(db / 20)

I expect I should put these definitions in their own file, and then somehow include that file in various notebooks. What are the details for this process, please? I have researched this in the documentations, and I’ve probably already seen the correct answer there, but I’m still not sure about this.

My best guess is, put my library in a regular .nb file, and then invoke the library like this:

Once[Get["myLibrary.nb"]]

Do I have it right? If not, if someone could direct me to the specific page or section in the documentation that covers this, I’d appreciate it. Thank you.

Joe,

I would save it as a package and do:

Needs[mypackage`]

to use the package from other notebooks.

This is a great way to reuse code. The package can either be installed with Needs[] or you can even add it to your init file and have it automatically available every time you start Mathematica.

Look at the package documentation to get started.

Regards,

Neil

Thanks very much.

I am trying this, but unable to get it to work so far. When I evaluate

Needs["myLibrary`"]

I get an error message:

Get::noopen: Cannot open myLibrary`.
Needs::nocont: Context myLibrary` was not created when Needs was evaluated.

I suspect there’s a problem with how my search-paths are setup. All my notebooks, along with my newly created package, are in a directory, but I notice that directory doesn’t appear in (dollar-sign, capital p, lowercase a, lowercase t, lowercase h) when I evaluate (dollar-sign, capital p, lowercase a, lowercase t, lowercase h). I have to spell out that variable, because Wolfram’s website formats it strangely when I just try to type it in verbatim. So many surprises.

I’d rather not hardcode the full pathname into the Needs statement, because if my I did that, my code would break if I later moved my files to a different directory.

In C I would just do “include myLibray”, and this common task would be very easy.

So the Needs function doesn’t have an option for setting Path, so I’ve gone back to trying the Get function. When I try

Once[Get["myLibrary.nb", Path -> NotebookDirectory[]]]

it prints out the entire contents of myLibrary.nb, and when it’s done, the symbol ratioFromDb still is not defined. I could write a book on making this not work, but still having no idea how to perform this common task in Mathematica, so easy in numerous other languages.

Now I have found yet another way to make this not work:

AppendTo[$Path, NotebookDirectory[]];

Needs["myLibrary2`"]

?? ratioFromDb

Information::notfound: Symbol ratioFromDb not found.

Removing the double-quotes yields a new way to make this not work:

In[3]:= AppendTo[$Path, NotebookDirectory[]];

In[5]:= Needs[myLibrary2`]

During evaluation of In[5]:= Syntax::tsntxi: "Needs[myLibrary2`]" is incomplete; more input is needed.

In[4]:= ratioFromDb[4]

Out[4]= ratioFromDb[4]

Here are two additional ways to make this not work:

In[3]:= AppendTo[$Path, NotebookDirectory[]];

In[4]:= Needs[myLibrary2`]

In[4]:= << myLibrary2`

In[5]:= ratioFromDb[4]

Out[5]= ratioFromDb[4]

In[6]:= << myLibrary2.wl

In[7]:= ratioFromDb[4]

Out[7]= ratioFromDb[4]

Joe,

Create your package and use the install menu item. It will place the file in the proper directory. On the mac it is in Library/Mathematica/applications (from memory-- I am not in front of my computer).

I appreciate your advice, but for me, the proper directory is “C:\Users\MyFirstName\Documents\Wolfram Mathematica”, even though Mathematica has a different opinion about what’s proper. The directory I’ve named above is where I have version-control set up for Mathematica code.

I am grateful for your trying to help me get this working, but I really just want Mathematica to evaluate a file containing function-definitions, when I specifically request it. I don’t want Mathematica to automatically evaluate these function-definitions. I only want them to be evaluated when I specifically ask Mathematica to evaluate them. And I’d hope I could keep this file in the directory I’ve set up for Mathematica files, because that’s the location where my version-control is tracking files. That’s the location where my bash scripts operate when I tell them to operate on Mathematica files. That’s the location that my backup-software backs up when I run it.

There’s no “just read this file and evaluate everything in it” command in all of Mathematica?

Try Get["path_to_file"] or use the second argument to Needs[]. See documentation if needed.

“Try Get[“path_to_file”]”

Thank you, but that didn’t work for me:

In[14]:= Get[
  "C:\Users\MyFirstName\Documents\Wolfram Mathematica\myLibrary.nb"];

During evaluation of In[14]:= Syntax::stresc: Unknown string escape \U.

During evaluation of In[14]:= Syntax::stresc: Unknown string escape \M.

During evaluation of In[14]:= Syntax::stresc: Unknown string escape \D.

During evaluation of In[14]:= Syntax::stresc: Unknown string escape \W.

During evaluation of In[14]:= Syntax::stresc: Unknown string escape \m.

In[12]:= Get[
  "C:\\Users\\MyFirstName\\Documents\\Wolfram \
Mathematica\\myLibrary.nb"];

In[13]:= ratioFromDb[4]

Out[13]= ratioFromDb[4]

“or use the second argument to Needs[]. See documentation if needed.”

doesn’t work:

In[19]:= Needs["myLibrary2`", "myLibrary2.wl"]

In[20]:= ratioFromDb[4]

Out[20]= ratioFromDb[4]

In[21]:= Needs["myLibrary2`", \
"C:\\Users\\MyFirstName\\Documents\\Wolfram \
Mathematica\\myLibrary2.wl"]

In[22]:= ratioFromDb[4]

Out[22]= ratioFromDb[4]

“use the install menu item”

Now I’ve tried this too, and it too does not work.

A Mathematica Style (for application development).

I’m fairly certain you will object to this but it is the procedure that WRI has set up for development of significant projects and it works.

I’ve found a solution that survives preliminary testing. It is undocumented and it has not been mentioned before in this thread. It is the only solution that has survived preliminary testing here. myLibrary02.wl:

BeginPackage["myLibrary02`"]

ratioFromDb[db_] := 10^(db / 20)

dBFromRatio[ratio_] := 20 * Log10[Abs[ratio]]

EndPackage[]

Invocation:

In[1]:= Get[NotebookDirectory[] <> "myLibrary02.wl"]

In[2]:= ratioFromDb[4]

Out[2]= 10^(1/5)

In[3]:= dBFromRatio[6]

Out[3]= (20 Log[6])/Log[10]

An essential but undocumented step is to select all cells in the .wl file and set them to be “Initialization Cells”.

double-post deleted

Thanks for the link. If it works at all, I’ll object to it less than the proposed solutions that do not work at all. I can see how that might be good for significant projects, but for my projects it would be overkill incurring overhead. I got this working in a different computer algebra system in less time than it would take me to even read that document. “load(filename)”. Done.

By the way, I notice that your example is a decibel conversion. If you want to send me your email address I will send you a Dropbox link to an application I developed called UnitsHelper. It has a generalized decibel conversion facility as well as routines to install reduced unit systems, such as geometric units or atomic units, as well as other nifty features.

It also has style sheets, palettes and documentation and thus illustrates a rather complete example of setting up an application in Mathematica.

My email is on my profile page.

Joe,

I am back to my computer. If keeping the file in that directory is what you care about than just do the following:

NotebookEvaluate[NotebookDirectory[] <>"myfile.nb"]

This will execute the notebook contents and define all of its functions as if you opened it up manually and executed it in the kernel.

I still recommend packages. The way I do it is I develop the package in my “home” directory (so it is backed up and version controlled etc.). I install a COPY of the file into the $BaseDirectory/Applications. When I make improvements they are done on the home version of the file and then installed (usually manually by copying the file). If I have a really complicated package, I use eclipse with Wolfram Workbench installed because you can debug it and develop documentation for it. I hope this helps. If you need better instructions or an example, let me know.

Regards,

Neil

Thanks, that is very gracious of you. I will take you up on it.