Skip to content

RAVEN Code Standards

Paul Talbot edited this page Mar 29, 2017 · 5 revisions

Code standards are important to maintain code readability and a reasonable similarity in branding throughout the code architecture. Here we outline the coding practices for the RAVEN project.

Python

Tabs, Spacing, and Line Lengths

Use 2 spaces for each indent level. Use spaces, not tabs.

Function definitions should have at least one line of whitespace afterwards.

Multiple statements on one line are not allowed. For example the following is forbidden:

if makeAnimal: self.raiseAMessage("we just increased the MOOSE herd population")

and should be changed to:

if makeAnimal: 
  self.raiseAMessage("we just increased the MOOSE herd population")

Tuple unpacking and packing should only be used when needed. For example:

a, b = 0, 1

should be rewritten to be:

a = 0
b = 1

However, using it for function returns and swapping is allowed, since it saves temporary variables:

a, b = b, a

or:

a, b = funct()

are allowed.

Lines longer than 120 characters should be split if possible.

Naming Conventions

Class names should start with a Capital letter. Other variables should be camelBack case. Underscores should not be used in variable names, except in the case of private and protected variable prefixes.

Private variables start with two __underscores. Protected variables should start with one _underscore.

Exceptions

except: with no exception should only be used in extraordinary circumstances; instead something like except KeyError: or except Exception as e: print(repr(e)) would be better so only the provided exception is ignored or something is done with the exception.

Python 3 compatability

For python 2 code, it should have:

from __future__ import division, print_function, unicode_literals, absolute_import
import warnings
warnings.simplefilter('default',DeprecationWarning)

before any code to simplify porting to python 3. (Importing unicode_literals can be skipped if it causes problems and this is discussed with other developers.)

Function and Class Documentation Strings

Functions should have a ​docstring, which is right after the line defining the function and are between triple quotes """. The triple quotes should be on their own line, and an additional level of indentation should be provided for the documentation comments. Each input should be listed in the fashion below, starting with @ In, then the name of the input, the type of the input, (optional) and a brief description. For output variables, the line starts with @ Out, the name of the output variable, followed by the type of the output, and a brief description of it. In the event the return object is not a named variable [and it is not possible to do so (e.g. the method is very short and an addition of a named variable does not represent an added value for the readability of the code)], the name of the method should be listed instead. Other comments not at the start of a function, method or class should use the # character to start them. Lines beginning with a # should be indented to match the line(s) of code they refer to.

def sqr(x):
  """
    Returns the square of the argument.
    @ In, x, float, number to be squared
    @ Out, result, float, square of x
  """
  result = x*x #square by multiplying
  return result

def sqrWithOptionalArg(x=2.0):
  """
    Returns the square of the argument.
    @ In, x, float, optional, number to be squared
    @ Out, result, float, square of x
  """
  result = x*x #square by multiplying
  return result

def printWolf():
  """
    Print the message 'Wolf'
    @ In, None
    @ Out, None
  """
  #prints "Wolf" to stdout
  print("Wolf")

def returnSize(x):
  """
    Return the size of an array
    @ In, x, numpy.array, the array whose size needs to be determined
    @ Out, returnSize, int, the size of the array 'x'
  """
  return x.size

Module Importing

The so-called "wild importing" approach is FORBIDDEN, i.e. :

from aModule import *

Rather than editing the system python path to load modules, a hierarchal structure should be used. For example, instead of

  sys.path.append('/path/to/moduleGroup')
  import myModule

an effort should be made to make moduleGroup a true module by including a __init__.py file, then import by

  import moduleGroup.myModule