Message Boards Message Boards

Building Packages: A basic tutorial

Posted 11 years ago
In a response to an earlier thread I posted a notebook containing a basic tutorial on creating packages in Mathematica. Since the link to the notebook was embedded down in the responses to that post I thought it might be useful to some folks to have access to it at the top level here since they might have missed it.

I have updated that notebook a bit since the last time.  I hope it is useful to some people.  It was originally written as a tutorial for a consulting client of mine and he agreed to allow me to share with others.  

Enjoy. It is attached to this posting
Attachments:
POSTED BY: David Reiss
13 Replies

Of course there is a bit of an ambiguity as to which David you are responding to ;-) !

But the approach of using the 2-argument form of BeginPackage is tried and true -- it has worked for us for about 25 years since version 1 of Mathematica. And, indeed, it just worked for me now.

I am attaching two packages, TestPackage1 and TestPackage2. They each have one function, TestPackage1 and TestPackage2 respectively. The function TestPackage1 depends on TestPackage2.

If both are placed in a directory called dir and one then appends dir to $Path using

$Path=AppendTo[$Path,dir] 

or, more simply, if you simply put both packages in this directory

FileNameJoin[{$UserAddOnsDirectory, "Applications"}]

which you can open using

SystemOpen[FileNameJoin[{$UserAddOnsDirectory, "Applications"}]]

Then execute

Needs["TestPackage1`"]

and all works fine. One gets

In[4]:= TestPackage1[x]

Out[4]= Sin[x]

and life (an Mathematica) is problem-free from then on (at least in this small universe.

Attachments:
POSTED BY: David Reiss

David,

I have tested the general approach you have explained above but it does not work. I think that it is a problem with Mathematica.

Sincerely, I thank you for your help.

The general approach to having one package make use of another package is to start your first package's Begin function in the following way (using your example):

BeginPackage["RKG`", {DoublePendulum`"}];     

Then you only execute a Needs on the "RKG`" package context.

see the documentation for BeginPackage for a discussion:

http://reference.wolfram.com/language/ref/BeginPackage.html

Of course then the second package cannot depend on the first one's functions--package dependency can only can go one way down a tree.

POSTED BY: David Reiss

David, Sorry because It is true that I have not explained very well and there are some errors in my example. I have develop routines within a Mathematica(10.2.0.0 version) notebook and now, I need to put them in two packages. In one package, I put a numerical integration method and in the second package, I write an ordinary differential equations of the problem.
I have put the packages your $UserBaseDirectory/Applications folder. RKG function (method) call DoublePendulumODE but I think Mathematica do not find it.

(Method)

BeginPackage["RKG`"];        
RKG::usage="Implicit Runge-Kutta integration of odefun.";
Begin["`Private`"];
RKG[ s_,u0_,e0_,t0_,tf_,n_,odefun_,parms_,opts___]:=
....]
End[ ];
EndPackage[];

(Problem)

BeginPackage["DoublePendulum`"];    
DoublePendulumODE::usage=" ";  
Begin["`Private`"];
DoublePendulumODE[t_,u_,parameters_List]:=
...]
 End[ ];
EndPackage[];

(* Notebook*)

Needs ["RKG`"];
Needs ["DoublePendulum`"];
....
RKG[s, u0, e00, T0, Tfinal, n, DoublePendulumODE, parameters)

Mikel, If you will read my tutorial you will see how to name your packages and have access to them. I don't feel like reproducing all of it right here. But also you will have to include the second argument in the BeginPackage statement that declares subsidiary packages that are needed in a tree structure - as David Reiss advises.

There is a way to divide an application into subpackages that all have the same Context and that call routines from each other, criss-cross. You don't have to use a tree structure. Essentially you break each subpackage into two files - a Public file that declares the exported names and a dummy Private section, and a second Private file with no public exported names. Then in the init.m file that launches the application all the Public files are read first and then afterwards all the Private files are read. Various other initiations can also be done in the init.m file. The Private routines then know all the names and can use them in the private code. I've used this in the GrassmannCalculus application without any problem.

Mikel, the question is too vague. And there are some errors. The BeginPackage statements should include backquotes:

BeginPackage["Package1`"]

BeginPackage["Package2`"]

Also the fun1 routine is not actually defined.

I think you are just trying to learn about packages, but before you start writing a package you have to have something to put into it. A better approach is to develop routines within a Mathematica notebook. Make sure they work there first. Write actual usage messages, SyntaxInformation statements, and other statements that may go with a routine. Then put them into a package.

Why are you writing two packages? Why can't both routines be in the same package? It may be worthwhile to have two packages, but make certain you know how to do the simpler thing first.

Also, Wolfram Research has provided a good place to put packages. That is in your $UserBaseDirectory/Applications folder. Create a folder there for your particular subject matter. Then the BeginPackage statement would look like the following with a binary name:

BeginPackage["MySubject`Package1`"]

The advantage of that is that now anyone could install your package in their private Applications folder and simply use it. Mathematica will automatically find it and all other resources, such as style sheets or palettes or documentation that might go with it. They would not have to set directories or anything else.

I have a tutorial on organizing packages within applications that explains all this at Tutorial on Writing Mathematica Applications.

I have one doubt about packages. I have implement two packages where package1 call a function which is defined in package2. Is correct the next implementation?


BeginPackage[["Package1"] myfunction::usage=""; Begin["Private"]; myfunction[x_]:= Module[{temp}, temp=fun1(x) End[]; EndPackage[]; ********************************************************* BeginPackage[["Package2"] fun1::usage=""; Begin["Private"]; fun1 Module[{temp}, temp=2*x: End[]; EndPackage[];

Yes indeed Gustavo. Or one could extend the way I create the package notebook in my tutorial to include a Docked Cell with a button that does this (and which clears out the package context first before re-executing the package's initialization cells). In addition to that one could add additional buttons to take care of other package programming tasks in the notebook. In this old thing of mine (which I wrote back in Mathematica Version 5, but which I still use daily) there are a bunch of buttons (in a palette) which take care of such tasks: http://scientificarts.com/worklife/

POSTED BY: David Reiss
Posted 11 years ago

Thank you for this nice tutorial. I would only add that when programming packages in notebooks, you don't get the nice reload button, but you can reload the package using the "Evaluation->Evaluate Initialization Cells" menu command.

POSTED BY: Gustavo Delfino
Posted 11 years ago

Hi,nice tutorial,I was wondering is there a place where we can share packages among us?

POSTED BY: milos cipo
Posted 11 years ago

One option: you can always create a self-answered question on Mathematica.SE and publish there a description of the package and the link to your GitHub code repository.

POSTED BY: Alexey Popkov
Another item that may be instructive for some folks is this discussion of creating material for the Documentation Center that I wrote some while ago.  Some may be out of date, but some may be of use....

http://scientificarts.com/worklife/notebooks/DocumentationCenterNotes.nb
POSTED BY: David Reiss
Very kind of you to share this, thank you. To keep things in one place I add a few related links:
POSTED BY: Sam Carrettie
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract