Coding Guidelines - madscatt/sasmol GitHub Wiki

For the most part one should follow the PEP 0008 Style Guide with some additional caveats to point out. All code is checked via autopep8 and pylint.

Indentation

Here is an example snippet from a .vimrc file that defines indentation rules. Developers that use other IDEs should provide their settings for others to benefit.

filetype plugin on
set smartindent
set ts=4
set shiftwidth=4
set expandtab

Here is the indentation rules for Wingware Python IDE (which has also been followed in Emacs24):

Default Tab Size: 4
Default Indent Size: 4
Default Indent Style: Spaces Only

Imports

Import each module using the full pathname location of the module. All imports should be done at the top of the file. This will reduce namespace conflict and increase the readability of the code. The following is preferred.

import sasmol.sasmol as sasmol
import numpy

mol_1 = sasmol.SasMol()
numpy.array(some_list)

while this is not allowed

import sasmol.sasmol as s
import numpy as np

mol_1 = s.SasMol()
np.array(some_list)

For this simple example one can see this will prevent in unexpected conflicts with objects/variables named "s" and "np" in the code base.

Classes:

Are written using camel case. For example

class SasMol():

where the first letter in each word is capitalized. Classes are the only objects that use camel case. Do not use camel case for any other object (method name, variable name, file name, module name etc.).

Variable names:

Long descriptive names are required. Short variable names should only be used while iterating over a list or array.

Method names:

Long descriptive names are required. Short method names can be defined in addition.

def calculate_radius_of_gyration()

is correct.

def crg() 

or

def calc_rg() 

are examples of what not to use. The recommended practice is to have the method with the longer descriptive name and if used elsewhere in the code you may redefine the name. For example, in the class method

def calculate_radius_of_gyration()

is defined. If you wish to use this method, perhaps more than once, in some other method in the library and you wish to save some typing then, redefine the name locally. As the example method above is in a class called Calculate in a module file called calcuate.py the usage is defined below.

import sasmol.calculate 

def some_other_method():

   calc_rg = calculate.Calculate.calculate_radius_of_gyration

   ...

   my_rg = calc_rg(mol_1, frame_1)
   other_rg = calc_rg(mol_2, frame_2)

Getters and Setters:

In the SasMol class contained in sasmol.py, all instance variables are managed using pairs of methods to assign or retrieve variables.

For example, to obtain a value of a variable from a SasMol object, one uses a getter method:

def resid(self):
    return self._resid

and to assign a new value to a variable from a SasMol object, one uses a setter method:

def setResid(self,newValue):
    self._resid = newValue

Notice that this is one different naming scheme for methods in the library. Setters use mixed case as a definition on how to change the value of an attribute in an instance of a SasMol class. This is to highlight the uniqueness of these methods as they hold SasMol variables.

Paths

Do not use forward or backward slash to denote paths in any disk based operations. Use os.path.join() and os.path.sep only. This is to guarantee that file operations work on all operating systems.

 path = os.path.join('test', 'path')

 path = os.path.join(os.path.sep, 'usr', 'local', 'bin')

 path = os.path.join('test', 'path') + os.path.sep

 path = os.path.join('data','some_pdb_file.pdb') 

would give for Linux, Unix, and OS X

 test/path

 /usr/local/bin

 test/path/

 data/some_pdb_file.pdb

respectively.