\chapter{Documentation}

The NekPy package certainly had to be documented in order to provide an easily accessible 
information about the wrapped classes to both users and developers. Ideally, the documentation should be:
\begin{itemize}
    \item easily readable by humans,
    \item accessible using Python's inbuilt \texttt{help} method,
    \item compatible with the existing Nektar++ doxygen-based documentation.
\end{itemize}

Traditionally, Python classes and functions are documented using a docstring -- a string occurring 
as the very first statement after the function or class is defined. This string is then accessible 
as the \texttt{\_\_doc\_\_} attribute of the function or class. The conventions associated with 
Python docstrings are described in PEP 257 document \cite{PEP257}.

Boost.Python provides an easy way to include docstrings in the wrapped methods and classes as 
shown in Listing \ref{lst:doc_example}. The included docstrings will appear when Python 
\texttt{help} method is used.

\begin{lstlisting}[caption={Example of class and method documentation in Boost.Python}, label={lst:doc_example}, language=C++]
void export_Points()
{
	py::class_<PointsKey>("PointsKey", 
        "Create a PointsKey which uniquely defines quadrature points.\n"
        "\n"
        "Args:\n"
        "\tnQuadPoints (integer): The number of quadrature points.\n"
        "\tpointsType (PointsType object): The type of quadrature points.",
        py::init<const int, const PointsType&>())
        	
            .def("GetNumPoints", &PointsKey::GetNumPoints,
            "Get the number of quadrature points in PointsKey.\n"
            "\n"
            "Args:\n"
            "\tNone\n"
            "Returns:\n"
            "\tInteger defining the number of quadrature points in PointsKey.")
}
\end{lstlisting}

In order to fully document the existing bindings a number of enumeration type classes such 
as \texttt{PointsType} had to have docstrings included which proved to be a challenge 
since Boost.Python does not provide a way to do this. Instead a direct call to Python C API 
has to be made and the method adapted from \cite{PythonEnumDocstring} was used, as shown in 
Listing \ref{lst:enum_doc}. A downside of this solution is that it does requires the developer 
to manually update the Python documentation if the enumeration type is ever changed (e.g. 
adding a new type of point) as the code does not automatically gather information from the 
C++ class. In theory it could be possible to create a Python script which would generate Python 
docstrings based on the existing C++ documentation using regular expressions; however it would 
be difficult to integrate this solution into the existing framework.

\begin{lstlisting}[caption={Code used to include dosctings in enumetation type classes - part of \texttt{NekPyConfig.hpp}}, label={lst:enum_doc}, language=C++]
#define NEKPY_WRAP_ENUM_STRING_DOCS(ENUMNAME,MAPNAME,DOCSTRING)    \
    {                                                              \
        py::enum_<ENUMNAME> tmp(#ENUMNAME);                        \
        for (int a = 0; a < (int)SIZENAME(ENUMNAME); ++a)          \
        {                                                          \
            tmp.value(MAPNAME[a].c_str(), (ENUMNAME)a);            \
        }                                                          \
        tmp.export_values();                                       \
        PyTypeObject * pto =                                       \
            reinterpret_cast<PyTypeObject*>(tmp.ptr());            \
        PyDict_SetItemString(pto->tp_dict, "__doc__",              \
            PyString_FromString(DOCSTRING));                       \
    }
\end{lstlisting}

There are many docstrings conventions that are popular in Python such as Epytext, reST and 
Google therefore a choice had to be made as to which docstring style to use. After considering 
the criteria which the documentation had to fulfill it was decided to use Google Python Style 
\cite{PythonGoogle} as it is highly readable by humans (and hence an excellent choice for 
documentation which will be primarily accessible by Python \texttt{help} method) and can be 
used to generate automated documentation pages with Sphinx (a tool for creating Python documentation). 

Unfortunately, it proved to be difficult to include the documentation of NumPy package in the 
existing doxygen-based documentation due to the fact that the docstrings are generated by Boost.Python. 
It was decided that if the time constraints of the project permit this problem could be resolved 
at a later date and the possibility of accessing the documentation though inbuilt \texttt{help} 
method was deemed sufficient.
