Upload New File
This commit is contained in:
parent
8466665e17
commit
51372ae6a5
175
PYGUIDE.md
Normal file
175
PYGUIDE.md
Normal file
@ -0,0 +1,175 @@
|
||||
# Cerc Python Style Guide
|
||||
## What's coding style and why it matters.
|
||||
|
||||
Coding style is just how the code looks, it's incredibly personal, and everyone has their style.
|
||||
|
||||
Your preferred architectures, variable and function naming style all of then impacts in your code style and how the others read and understand it, so it could become a significant burden if everyone is coding on his or her own.
|
||||
|
||||
At CERC, we are following the [PEP8](https://www.python.org/dev/peps/pep-0008/) with two spaces indentation instead of four.
|
||||
|
||||
## Tools.
|
||||
|
||||
We use [PyCharm](https://www.jetbrains.com/pycharm/) as an integrated development environment and follow the tool's overall advice but the space indentation, which we set to two spaces instead of default four spaces.
|
||||
|
||||
For code analysis, we enforce the usage of [pylint](https://www.pylint.org/) with our own [custom style definition](pylintrc). This file will be downloaded with the project the first time you clone it.
|
||||
|
||||
## Naming convention.
|
||||
|
||||
* Name your folders and files in lowercase and use _ (underscore) to separate words.
|
||||
* Your class names must start in capital letters and follow the python CapWords pattern.
|
||||
* Methods and properties that return lists must end in "s". Therefore, those that return single values, must be singular.
|
||||
* Methods and variables should be lowercase and use _ (underscore) as a word separator.
|
||||
* Constant names must be all capitals.
|
||||
* Avoid the usage of "get_" and "set_" methods whenever it is possible, use @property and @variable.setter decorators instead.
|
||||
* "Private" methods, variables and properties start with _ (underscore).
|
||||
|
||||
## Imports.
|
||||
Place your imports at the top of the file, after the license and contact information
|
||||
comment.
|
||||
|
||||
```python
|
||||
"""
|
||||
MyClass module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder name name@concordia.ca
|
||||
"""
|
||||
|
||||
import sys
|
||||
```
|
||||
|
||||
Ensure that your imports are used and remove any unused.
|
||||
|
||||
|
||||
## Object attributes and methods.
|
||||
|
||||
Use properties whenever it is possible. Encapsulate the access to all the calculated object attributes to avoid recalculating each time the property is called.
|
||||
|
||||
```python
|
||||
|
||||
@property
|
||||
def object_attribute(self):
|
||||
if self._object_attribute is None:
|
||||
self._object_attribute = ...
|
||||
...
|
||||
return self._object_attribute
|
||||
|
||||
```
|
||||
|
||||
And like in the following example for read and write properties:
|
||||
|
||||
```python
|
||||
|
||||
@property
|
||||
def object_changeable_attribute(self):
|
||||
return self._object_changeable_attribute
|
||||
|
||||
@object_changeable_attribute.setter
|
||||
def object_changeable_attribute(self, value):
|
||||
self._object_changeable_attribute = value
|
||||
|
||||
```
|
||||
|
||||
If your method or attribute returns a complex object, use type hints as in this example:
|
||||
|
||||
```python
|
||||
|
||||
@property
|
||||
def complex_object(self) -> ComplexObject:
|
||||
return self._object_changeable_attribute
|
||||
|
||||
def new_complex_object(self, first_param, second_param) -> ComplexObject:
|
||||
other_needed_property = self.other_needed_property
|
||||
return ComplexObject(first_param, second_param, other_needed_property)
|
||||
|
||||
```
|
||||
|
||||
Always access your variable through the method and avoid to access directly.
|
||||
|
||||
```python
|
||||
|
||||
@property
|
||||
def object_attribute(self):
|
||||
return self._object_attribute
|
||||
|
||||
def operation(self, first_param, second_param):
|
||||
return self.object_attribute * 2
|
||||
|
||||
```
|
||||
|
||||
### Comments.
|
||||
|
||||
#### Code documentation.
|
||||
|
||||
All public classes, properties, and methods must have code comments. Code comments start with capital letters and end without period:
|
||||
|
||||
```python
|
||||
|
||||
class MyClass
|
||||
"""
|
||||
MyClass class perform models class operations
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
|
||||
|
||||
@property
|
||||
def object_attribute(self):
|
||||
"""
|
||||
Get my class object attribute
|
||||
:return: int
|
||||
"""
|
||||
return self._object_attribute
|
||||
|
||||
def operation(self, first_param, second_param):
|
||||
"""
|
||||
Multiplies object_attribute by two
|
||||
:return: int
|
||||
"""
|
||||
return self.object_attribute * 2
|
||||
|
||||
```
|
||||
|
||||
Comments at getters and setters always start with Get and Set, and identity the type of variable at return (at getter) or the value (at setter):
|
||||
|
||||
```python
|
||||
|
||||
@property
|
||||
def object_attribute(self):
|
||||
"""
|
||||
Get object attribute
|
||||
:return: int
|
||||
"""
|
||||
return self._object_attribute
|
||||
|
||||
@object_attribute.setter
|
||||
def object_attribute(self, value):
|
||||
"""
|
||||
Set object attribute
|
||||
:param value: int
|
||||
"""
|
||||
self._object_attribute = value
|
||||
|
||||
```
|
||||
|
||||
Attributes with known units should be explicit in method's comment.
|
||||
|
||||
```python
|
||||
|
||||
@property
|
||||
def distance(self):
|
||||
"""
|
||||
My class distance in meters
|
||||
:return: float
|
||||
"""
|
||||
return self._distance
|
||||
```
|
||||
|
||||
#### To do's.
|
||||
|
||||
Pending to implement operations should be indicated with todo comments to highlight the missing functionality.
|
||||
|
||||
```python
|
||||
# todo: right now extracted at the city level, in the future should be extracted also at building level if exist
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user