-
Notifications
You must be signed in to change notification settings - Fork 0
Code guidelines
All Python code should where possible follow the PEP 8 - Style Guide for Python Code.
A quick reference is provided below for some of the most commonly used examples:
Names that are visible to the user as public parts of the API should follow conventions that reflect usage rather than implementation.
Python packages should have short, all-lowercase names. The use of underscores is discouraged as per PEP 8, however they can be included only if required to improve readability.
Examples:
mypackage
my_complex_package_name
Module names should be short, all-lowercase, and ideally semantic in nature. Underscores can be used in the module name if it improves readability as per PEP 8.
Examples:
mymodule
my_module
my_more_complex_module
Class names should be short, ideally semantic in nature, and normally use the CapWords convention as per PEP 8.
Example:
MyNewClass
Function names should be lowercase and ideally semantic in nature with words separated by underscores as necessary to improve readability as per PEP 8.
Examples:
my_function
my_more_complex_function
Variable names should be lowercase and ideally semantic in nature, with words separated by underscores as necessary to improve readability as per PEP 8.
Example:
my_variable
my_more_complex_variable
Note: 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.
Documenting software is very important! Documentation helps both users and developers to understand everything about a given piece of software or code. From more high-level aspects such as what is the purpose of the code, how it is put together and how it is deployed, to more low-level information including installation, troubleshooting and how the code can be implemented and/or extended.
If a line of code does something, describe it with a comment! Comments should be complete sentences and be placed on the line above the line of code they are describing. The first word should be capitalized, unless it is an identifier that begins with a lower case letter (never alter the case of identifiers!). Comments that contradict the code are worse than no comments. Always make a priority of keeping the comments up-to-date when the code changes!
Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a # and a single space (unless it is indented text inside the comment). Paragraphs inside a block comment are separated by a line containing a single #.
Use inline comments sparingly.
An inline comment is a comment on the same line as a statement. Inline comments should be separated by at least two spaces from the statement. They should start with a # and a single space.
See PEP 8 - Comments for a full description of good commenting practices.
A docstring (or documentation string) is a string literal that occurs as the first statement in a module, function, class, or method definition. This docstring becomes the __doc__
special attribute of that object. All modules should normally have docstrings, and all functions and classes exported by a module should also have docstrings. A full description of general docstring best practices can be found in the PEP 257 - Docstring Conventions.
Beyond providing code-level information to the user via the __doc__
special attribute, docstrings can (and should) also be used to auto-generate package/API reference documentation. For this task, it is recommended to use Sphinx.
To auto-generate documentation using Sphinx, specific docstring formatting is required (i.e. you cannot use PEP 257 - Docstring Conventions formatting). For this, please use the numpydoc syntax. Documentation should use the sphinx-rtd-theme
found here.
Example Sphinx-compatible numpydoc formatting for a multiline docstring describing a function containing multiple explicit arguments:
def my_function(arg1, arg2, arg3=True):
"""
Clear and concise function description.
Parameters
----------
arg1 : string
Argument 1 description
arg2 : float
Argument 2 description
arg3 : bool, default True
Argument 3 description
Returns
----------
string
Description of returned object
"""
if type(arg1) == str and type(arg2) == float and type(arg3) == bool:
result = 'winning'
else:
result = 'not winning'
return result
Robust and transparent software testing is a very important phase of the complete development cycle. Routinely testing classes, functions and scripts not only ensures that code is working correctly, it also informs code optimisation.
To do this efficiently, unit testing is considered an industry-standard approach to evaluate Python code stability and performance.
For testing Python code at ACESS-NRI, it is recommended that unit testing be completed using the pytest framework. A library of pytest examples can be found here.