- Think about what your program will do and how that fits into the
structure of SAGE. In particular, much of SAGE is implemented in
the object-oriented language Python, and there is a hierachy of classes
that organize code and functionality. It is surprisingly
painful and difficult to create some Python classes, then realize
that much functionality should be factored out into base classes,
and to do it. So try to get the structure right the first time.
For example, if you implement elements of a ring yoru class should
derive from sage.structure.element.RingElement.
- Code it up, following the conventions in
Chapter 3. Make the basic structure and
interface for what you're doing in Python. You can use any of the
following languages to implement the hard parts: Python, C/C++,
Pyrex, GAP, Singular, and GP/PARI. You can also use the mwrank,
NTL, and PARI C libraries. (And if you are OK with your code
depending on optional SAGE packages, you can use Maxima, Octave, or
even Magma, Mathematica, or Maple.) For readability and usability
it is best to use SAGE when possible, but for efficiency reasons it
is often crucial to use a compiled language or an existing library
or program--do not reinvent the wheel or write code that is so slow
as to be only a toy.
- Document every Python function that you've defined, and
liberally include examples in your source code. See
Chapter 4 for more on automated testing of examples.
- (Optional) Write a file that randomly tries to test (and break!)
your code.
- (Optional) Send your package to me (wstein@gmail.com) for
inclusion in SAGE, or make a standalone spkg (see
Chapter 9).
Use LaTeX formatting in the documentation string. If you wish to use
backslashes in the documentation string, place an r right before
the first triple opening quote, or use double backslashes. For example,
def sin(x):
r"""
Return $\sin(x)$.
"""
def cos(x):
"""
Return $\\cos(x)$.
"""
The non-standard macros that are used when typesetting the
documentation are defined in
$SAGE_ROOT/doc/commontex/macros.tex
.
If you need to add more, add them there and send me (William Stein)
an email so I can include them in the next version of SAGE.
The first line two or three lines of the docstring should briefly summarize
what the function does, e.g., ``Returns X'' or ``Computes X'',
or ``Creates a new X''. Next describe the input and output of
the function using the following notation:
INPUT:
var1 -- <type> (default: ...) description
var2 -- <type> (default: ...) description
etc.
OUTPUT:
<type> -- description of return value 1
<type> -- description of return value 2
etc.
For consistency you should use the above format, which is used
throughout the system. Do not just describe the input and output
in long sentences. For methods of a class, whether or not
to describe self is up to you; this can be useful if self must
have some special properties. Also, you do not have to
specify the types of the input and output arguments
precisely; e.g., use ``integer'' for an int or long or
SAGE Integer
.
Every function should have at least one, and preferably many, examples
that illustrates its usage. These examples must exactly match the
output of an actual running copy of Python. To test whether this is
the case, run the program sage -t
with your Python or Pyrex
file as unique argument (see Chapter 4 for more details).
For more details, see Section 3.3.
You might also write additional documentation in LaTeX, which is not
be part of any source code file. The examples in this documentation
should be contained in verbatim environments. The examples should be
tested using sage-testtex, which you run on the LaTeX file. Put
%skip on the line proceeding the environment to skip testing of an
example.
Note that sage-testtex is completely different than sage-doctest. It extracts the documentation and feeds it to a
running instance of SAGE.
In addition to all the examples, which serve as both demonstrations
and tests of your code, you should also create a test suite. Think of
this as a program that will run for a while and ``tries'' to randomly
crash your code. Your test code should define a class Test
with a random() method that runs random tests. These are all
assembled together later, and each test is run for a certain amount of
time on a regular basis.
Release 2006.05.25, documentation updated on May 25, 2006.
See About this document... for information on suggesting changes.