Coding Style Guide¶
The main principles behind pulse2percept development are:
- Robustness: The results of a piece of code must be verified systematically, enhancing stability and reducing redundancies.
- Readability: The code is read much more frequently than it is written, and should be easy to understand by other developers. Documentation is essential.
- Consistency: Following these guidelines will ease reading the code and will make it less error-prone.
pulse2percept uses the standard Python PEP8 style guide to ensure readibility and consistency of the code base.
For example, if you work with Sublime, you can use the PEP8 Autoformat
package. For convenience, make sure the setting
A few general guidelines:
- Use 4 spaces instead of tab.
- Limit all lines to a maximum of 79 characters.
- Write code for Python 3.5+.
pulse2percept recommends using the following package shorthands to increase consistency and readibility across the library:
import numpy as np import numpy.testing as npt import scipy as sp import pandas as pd import pulse2percept as p2p
Whitespace and blank lines¶
Don’t use spaces around the
= sign to indicate a keyword argument:
# Good: def complex(real, image=0.0): return magic(r=real, i=imag) # Bad: def complex(real, image = 0.0): return magic(r = real, i = imag)
Surround top-level function and class definitions with two blank lines. Use blank lines in functions, sparingly, to indicate logical sections.
Breaking long lines (W503 vs W504)¶
The recommended style is to break a line after binary operators:
# Good: income = (gross_wages + taxable_interest - student_loan_interest) # Bad: income = (gross_wages + taxable_interest - student_loan_interest)
Yes, we are aware of the ongoing W503 vs W504 discussion. W504 would improve readibility. However, for now, we want to ensure consistency with the existing code.
Class layout (slots, properties)¶
Classes can have
__slots__ that list all class attributes.
This can have several advantages:
- Users cannot add new class attributes on-the-fly. This is desirable for
AxonMapModel), which has a predefined number of attributes.
- Slots reduce memory usage. This is desirable for stimuli (e.g.,
TimeSeries), for which a large number of instances are created.
Subclasses that inherit from classes with
__slots__ must themselves
implement slots. The top-level class must inherit from
attributes cannot be listed more than once:
class Vehicle(object): __slots__ = ('owner') def __init__(self, owner): self.owner = owner class Car(Vehicle): __slots__ = ('n_doors') def __init__(self, owner, n_doors): self.owner = owner self.n_doors = n_doors
If you did it right, then neither
Car should have a
car = Car('myself', 4) assert hasattr(car, '__slots__') assert not hasattr(car, '__dict__')
This guide was inspired by the `DIPY style guide <https://dipy.org/documentation/1.1.1./devel/coding_style_guideline>`_.