Style guide

This document details the code style that is recommended for Mpacts

Python Style

We adhere to following:

https://www.python.org/dev/peps/pep-0008/

The summary:

Naming Conventions

There are a lot of different naming styles. It helps to be able to recognize what naming style is being used, independently from what they are used for.

The following naming styles are commonly distinguished:

b (single lowercase letter)

B (single uppercase letter)

lowercase

lower_case_with_underscores

UPPERCASE

UPPER_CASE_WITH_UNDERSCORES

CapitalizedWords (or CapWords, or CamelCase – so named because of the bumpy look of its letters [3] ). This is also sometimes known as StudlyCaps.

Note: When using abbreviations in CapWords, capitalize all the letters of the abbreviation. Thus HTTPServerError is better than HttpServerError.

mixedCase (differs from CapitalizedWords by initial lowercase character!)

Capitalized_Words_With_Underscores (ugly!)

There’s also the style of using a short unique prefix to group related names together. This is not used much in Python, but it is mentioned for completeness. For example, the os.stat() function returns a tuple whose items traditionally have names like st_mode , st_size , st_mtime and so on. (This is done to emphasize the correspondence with the fields of the POSIX system call struct, which helps programmers familiar with that.)

The X11 library uses a leading X for all its public functions. In Python, this style is generally deemed unnecessary because attribute and method names are prefixed with an object, and function names are prefixed with a module name.

In addition, the following special forms using leading or trailing underscores are recognized (these can generally be combined with any case convention):

_single_leading_underscore : weak “internal use” indicator. E.g. from M import * does not import objects whose name starts with an underscore.

single_trailing_underscore_ : used by convention to avoid conflicts with Python keyword, e.g.

Tkinter.Toplevel(master, class_=’ClassName’)

__double_leading_underscore : when naming a class attribute, invokes name mangling (inside class FooBar, __boo becomes _FooBar__boo ; see below).

__double_leading_and_trailing_underscore__ : “magic” objects or attributes that live in user-controlled namespaces. E.g. __init__ , __import__ or __file__ . Never invent such names; only use them as documented.

Prescriptive: Naming Conventions

Names to Avoid

Never use the characters ‘l’ (lowercase letter el), ‘O’ (uppercase letter oh), or ‘I’ (uppercase letter eye) as single character variable names.

In some fonts, these characters are indistinguishable from the numerals one and zero. When tempted to use ‘l’, use ‘L’ instead. Package and Module Names

Modules should have short, all-lowercase names. Underscores can be used in the module name if it improves readability. Python packages should also have short, all-lowercase names, although the use of underscores is discouraged.

When an extension module written in C or C++ has an accompanying Python module that provides a higher level (e.g. more object oriented) interface, the C/C++ module has a leading underscore (e.g. _socket ).

Class Names

Class names should normally use the CapWords convention.

The naming convention for functions may be used instead in cases where the interface is documented and used primarily as a callable.

Note that there is a separate convention for builtin names: most builtin names are single words (or two words run together), with the CapWords convention used only for exception names and builtin constants. Exception Names

Because exceptions should be classes, the class naming convention applies here. However, you should use the suffix “Error” on your exception names (if the exception actually is an error).

Global Variable Names

(Let’s hope that these variables are meant for use inside one module only.) The conventions are about the same as those for functions.

Modules that are designed for use via from M import * should use the __all__ mechanism to prevent exporting globals, or use the older convention of prefixing such globals with an underscore (which you might want to do to indicate these globals are “module non-public”). Function Names

Function names should be lowercase, with words separated by underscores as necessary to improve readability.

mixedCase is allowed only in contexts where that’s already the prevailing style (e.g. threading.py), to retain backwards compatibility. Function and method arguments

Always use self for the first argument to instance methods.

Always use cls for the first argument to class methods.

If a function argument’s name clashes with a reserved keyword, it is generally better to append a single trailing underscore rather than use an abbreviation or spelling corruption. Thus class_ is better than clss . (Perhaps better is to avoid such clashes by using a synonym.)

Method Names and Instance Variables

Use the function naming rules: lowercase with words separated by underscores as necessary to improve readability.

Use one leading underscore only for non-public methods and instance variables.

To avoid name clashes with subclasses, use two leading underscores to invoke Python’s name mangling rules.

Python mangles these names with the class name: if class Foo has an attribute named __a , it cannot be accessed by Foo.__a . (An insistent user could still gain access by calling Foo._Foo__a .) Generally, double leading underscores should be used only to avoid name conflicts with attributes in classes designed to be subclassed.

Note: there is some controversy about the use of __names (see below). Constants

Constants are usually defined on a module level and written in all capital letters with underscores separating words. Examples include MAX_OVERFLOW and TOTAL.

  • DO not use “import * from” !

C++ Style

  • Indentation 4 spaces
  • Brackets are always on a new line. Except for else clauses that can be on a single line (like }else{)

Documentation

Source code documentation

Code-documentation at every level (C++ and Python) is strongly encouraged to improve readability, to help in de-bugging and to improve readability and modularity of code snippets. Avoid adding documentation to ‘trivial’ lines of code that are self-explanatory. However, for long algorithms that contain complex ‘decision trees’, it is very important to document the rationale for each individual ‘case’ or code ‘branch’.

API documentation

Proper documentation of anything that gets exposed in the Python API is very important. For all C++ modules, write a clear and distinct docstring that explains in short what the module does, for what it can be used. If the module is relying on a complex or long-winded algorithm it makes sense to briefly explain the rationale behind it, or to link to a publication or on-line document that outlines the numerical approach. In the same vein, write a clear and concise docstring for each ‘property’. For documenting individual contact model chain elements, there is a special procedure which consists out of the following two steps:

  1. Add a docstring to the chain element itself using the CHAIN_DOC macro. Only explain what this specific chain element does.
  2. Add the module in mpacts.contact.models.chain_element_documenter.cpp to ensure that is actually compiled for on-line documentation. For this you must: * Add the name of the class you want to document as DEFINE_CHAIN_DOCSTRING( classname ); * Add an include statement for the file in which your class is defined.

In general, we rely on syntax of reStructuredText to decorate the Python documentation. A good introduction on the use of reStructuredText with Sphinx can be found here.

Very briefly, parameters should be documented in this style:

:param str name: The name of the command you want to add
:param obj: An object that should be given
:type obj: The type of the object that is passed

Attention

The documentation of a Python class should come after the class definition and not after the __init__ method.

Hyper links can be added using the syntax:

Link: `name_of_link <http://url_to>`_

or directly as:

Link: `http://url_to`_

For explaining equations used in algorithms, it’s very convenient to use LaTeX style notations, which can be done as:

:math:`E = m c^2`

which will produce E = m c^2.