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.