Internal contributors have write permissins to the repo, you can create new branches, do your work and submit pull requests:
# move to the repo
cd path/to/repo
# when you start working on something new, create a new branch from master
git checkout -b new-feature
# work on new feature and remember to keep in sync with the master branch
# from time to time
git merge master
# remember to push you changes to the remote branch
git push
# when the new feature is done open a pull request to merge new-feature to master
# once the pull request is accepted and merged to master, don't forget to remove
# the branch if you no longer are going to use it
# remove from the remote repository
git push -d origin new-feature
# remove from your local repository
git branch -d new-feature
Every function should contain at least a brief description of what it does, as well as input and output description. However, complex functions might require more to be understood.
We use numpydoc style docstrings.
Function example:
def fibonacci(n):
"""Compute the nth fibonacci number
Parameters
----------
n: int
The index in the fibonacci sequence whose value will be calculated
Returns
-------
int
The nth fibonacci number
"""
# fibonacci needs seed values for 0 and 1
if n == 0:
return 0
elif n == 1:
return 1
# for n > 1, the nth fibonnacci number is defined as follows
else:
return fibonacci(n-1) + fibonacci(n-2)
Object example:
class Square(object):
def __init__(self, l):
"""Represent a square
Parameters
----------
l: float
Side length
"""
self.l = l
def area(self):
"""Compute the area of the square
Returns
-------
float
The area of the square
"""
return self.l**2
A note about comments: comments should explain why you are doing some operation not what operation. The what can be infered from the code itself but the why is harder to infer. You do not need to comment every line, but add them when it may be hard for others to understand what's going on
A note about objects: objects are meant to encapsulate mutable state. Mutable objectsa are hard to debug. When writing scientific software, we usually do not need mutable state, we only want to process input in a stateless manner, so only use objects when absolutely necessary.
Write Python 3 code. Python 2 is retiring...
In most cases, it's really easy to write Python 2 and 3 compliant code, here's the official porting guide.
Print is evil. It does not respect anyone or anything, it just throws stuff into stdout without control. The only case when print makes sense is when developing command line applications. So use logging, it's much better and easy to setup. More about logging here.
Setting up logger in a script:
import logging
logger = logging.getLogger(__name__)
def my awesome_function(a):
logger.info('This is an informative message')
if something_happens(a):
logger.debug('This is a debugging message: something happened,'
' it is not an error but we want you to know about it')
# do stuff...
If you want to log inside an object, you need to do something a bit different:
import logging
class MyObject(object):
def __init__():
self.logger = logging.getLogger(__name__)
def do_stuff():
self.logger.debug('Doing stuff...')
Beautiful is better than ugly. The Zen of Python
To make our code readable and maintanble, we need some standards, Python has a style guide called PEP8. We don't expect you to memorize it, so here's a nice guide with the basics.
If you still skipped the guide, here are the fundamental rules:
- Variables, functions, methods, packages and modules:
lower_case_with_underscores
- Classes and Exceptions:
CapWords
- Avoid one-letter variables, except for counters
- Use 4 spaces, never tabs
- Line length should be between 80-100 characters
However, there are tools to automatically check if your code complies
with the standard. flake8
is one of such tools, and can check for
PEP8 compliance as well as other common errors:
pip install flake8
To check a file:
flake8 my_script.py
Most text editors and IDE have plugins to automatically run tools such
as flake8
when you modify a file, here's one for Sublime
Text.
If you want to know more about flake8
and similar tools, this is a
nice
resource