# Best way to reuse some code in multiple notebooks?

GROUPS:
 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.
4 months ago
23 Replies
 Neil Singer 3 Votes 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
4 months ago
 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.
4 months ago
 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.
4 months ago
 Now I have found yet another way to make this not work: AppendTo[$Path, NotebookDirectory[]]; Needs["myLibrary2"] ?? ratioFromDb Information::notfound: Symbol ratioFromDb not found. Answer 4 months ago  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]
4 months ago
 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] Answer 4 months ago  Neil Singer 1 Vote 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). Answer 4 months ago  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? Answer 4 months ago  Michael Rogers 1 Vote Try Get["path_to_file"] or use the second argument to Needs[]. See documentation if needed. Answer 4 months ago  "Try Get["pathtofile"]"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] Answer 4 months ago  "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] Answer 4 months ago  "use the install menu item"Now I've tried this too, and it too does not work. Answer 4 months ago  David J M Park Jr 1 Vote 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. Answer 4 months ago  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. Answer 4 months ago  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". Answer 4 months ago  double-post deleted Answer 4 months ago  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. Answer 4 months ago  Thanks, that is very gracious of you. I will take you up on it. Answer 4 months ago  Neil Singer 1 Vote 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
4 months ago
 Thank you. I will try NotebookEvaluate.I will not forget your advice about packages when I advance to larger-scale projects. For the time-being, my projects and my library are small, and I don't think it's a good point yet for me to invest the time learning how to set up for large-scale applications.Do you have any insight about the relevance of the "Initialization Cells" for what I'm trying to do? As I reported earlier, I was only able to make this work (using Get and a .wl file) by setting all cells in my .wl file to "Initialization Cells". I happened upon that solution, but it is not documented in the Wolfram documentation I'm familiar with. I thought Get was supposed to evaluate all cells regardless of whether they're "Initialization Cells", but apparently the Wolfram documentation on that is misleading, or I misunderstood the documentation.