For a detailed description of the
numpydoc standard, see numpy’s actual description of the style. This should be read by each developer to make sure we understand exactly what is required and what other options we have while documenting. Here is a summary of the key components of that document:
numpydoc style docstrings are written in restructured text. They are composed of a short description of the object followed by a few required and optional sections. For functions and methods, these sections are:
The sections for a class are the same, except instead of a
Returns section there is an
Attribute section that defines all attributes of the class.
A docstring is a string that starts on the first new line immediately after the declaration of a function or a class. Like the body of the function or class, the docstring must be indented 4 spaces. Typically, a docstring is contained within a block string, set off by tripe quotes “”” as shown below:
def func(a, b): """ This is a docstring for a function """" class MyNewClass(object): """ This is a docstring for this class. """
Docstrings provide a way for developers to document their code inline. This is very useful for many reasons, among which are:
helpon a particular object.
numpydoc style docstrings are written using restructured text (aka rst: the markup used in sphinx documents), using a special structure. While any restructured text is valid in a numpydoc style docstring, the only required restructured text element is knowing how to define a section. In our docstrings, we will denote sections using the following syntax:
Section name ------------
The key elements are a line containing only the name of the section followed be another line containing only minus signs (
-) underneath each character of the section name.
Using this syntax, a
numpydoc style docstring for a function or method is made up of the following elements:
Parametersthat explains the object’s input parameters
Returnsthat explains that function’s output
Examples: This section is optional, but strongly recommended and encouraged within QuantEcon (it may be required at some time in the future). Within the section we would include one or more examples for how to use the obejct.
Notes: This section provides additional details that help the user or fellow developer understand the function, but were not included in the short description at the beginning. This might include a description of the algorithm or mathematics underlying the function.
References: If any journal articles, books, or other publications or 3rd party code were consulted when writing the function, this should be documented in this section.
Raises: if the function/class might raise an exception when called, the exception along with cases under which the exception is raised should be documented.
See Also: if the function/class is related to another object, we should specify this relation in a
Below is an example of such a docstring
def func(a, b, c=3): """ Short description of what the function accomplishes Parameters ---------- a : scalar(float) Explanation of what a is used for within the function b : array_like(float) Explanation of what a is used for within the function c : scalar(int), optional(default=3) Explanation of what c is used for within the function Returns ------- ret1 : type of ret1 Explanation of the first object returned ret2 : type of ret2 Explanation of the second object returned Notes ----- Any implementation notes that help understand how/why the function was written the way it was. This section is optional. References ---------- In this section we include any references to papers/articles/other reading material or other code that we referenced when writing the function Examples -------- >>> a = 130; b = [10, 20, 30] >>> func(a, b) <function output copied and pasted> Raises ------ ValueError If any parameters are equal to `None.` """
There are a few additional points to mention here:
selfin the list of parameters.
numpydoc standard for documenting classes is very similar. The key components are (this all goes the first line of the docstring that is below the line containing the
Parameterssection that describes the parameters for the class’s
Attributessection that describes all the attributes of the class. This replaces the
Returnssection we saw above for functions and methods.
Methodsthat are implemented specifically for this class.
Remark There is often overlap between the parameter list and the attribute list. To avoid repetition attributes already discussed in the parameter list can be entered in the attributes list in the form
a, b, c : seeParameters. An example is given below.
Below I will provide some examples. These are copied and pasted from the source of some code we are already using, or will soon be using from within QuantEcon. For additional examples, see these two references:
def poly_inds(d, mu, inds=None): """ Build indices specifying all the Cartesian products of Chebychev polynomials needed to build Smolyak polynomial Parameters ---------- d : scalar(int) The number of dimensions in grid / polynomial mu : scalar(int) The parameter mu defining the density of the grid inds : list(list(int)), optional(default=None) The Smolyak indices for parameters d and mu. Should be computed by calling `smol_inds(d, mu)`. If None is given, the indices are computed using this function call Returns ------- phi_inds : array_like(int, ndim=2) A two dimensional array of integers where each row specifies a new set of indices needed to define a Smolyak basis polynomial Notes ----- This function uses smol_inds and phi_chain. The output of this function is used by build_B to construct the B matrix """
class SmolyakGrid(object): """ This class currently takes a dimension and a degree of polynomial and builds the Smolyak Sparse grid. We base this on the work by Judd, Maliar, Maliar, and Valero (2013). Parameters ---------- d : scalar(int) The number of dimensions in the grid mu : scalar(int) or array_like(int, ndim=1, length=d) The "density" parameter for the grid Attributes ---------- d, mu : see Parameters lb : array_like(float, ndim=2) This is an array of the lower bounds for each dimension ub : array_like(float, ndim=2) This is an array of the upper bounds for each dimension cube_grid : array_like(float, ndim=2) The Smolyak sparse grid on the domain :math:`[-1, 1]^d` grid: : array_like(float, ndim=2) The sparse grid, transformed to the user-specified bounds for the domain inds : list(list(int)) This is a lists of lists that contains all of the indices B : array_like(float, ndim=2) This is the B matrix that is used to do lagrange interpolation B_L : array_like(float, ndim=2) Lower triangle matrix of the decomposition of B B_U : array_like(float, ndim=2) Upper triangle matrix of the decomposition of B Examples -------- >>> s = SmolyakGrid(3, 2) >>> s Smolyak Grid: d: 3 mu: 2 npoints: 25 B: 0.65% non-zero >>> ag = SmolyakGrid(3, [1, 2, 3]) >>> ag Anisotropic Smolyak Grid: d: 3 mu: 1 x 2 x 3 npoints: 51 B: 0.68% non-zero """ Method example -------------- def interpolate(self, pts, interp=True, deriv=False): """ Basic Lagrange interpolation, with optional first derivatives (gradient) Parameters ---------- pts : array_like(float, ndim=2) A 2d array of points on which to evaluate the function. Each row is assumed to be a new d-dimensional point. Therefore, pts must have the same number of columns as ``si.SGrid.d`` interp : bool, optional(default=false) Whether or not to compute the actual interpolation values at pts deriv : bool, optional(default=false) Whether or not to compute the gradient of the function at each of the points. This will have the same dimensions as pts, where each column represents the partial derivative with respect to a new dimension. Returns ------- rets : list(array(float)) A list of arrays containing the objects asked for. There are 2 possible objects that can be computed in this function. They will, if they are called for, always be in the following order: 1. Interpolation values at pts 2. Gradient at pts If the user only asks for one of these objects, it is returned directly as an array and not in a list. References ---------- This is a stripped down port of ``dolo.SmolyakBasic.interpolate`` """