Repository navigation
Code style notes
Code is for communication: to the computer and to other programmers. Should always be able to answer "yes" to the question: at any moment, could I hand this to someone else?
We will follow Python conventions in R as well.
Two categories of code:
-
Libraries: e.g. OpenSoundscape
- The legos; an engineering problem
- A bunch of function definitions
* Libraries are tested
- ("unit testing": testing normal & boundary cases on a single function)
-
Scripts:
- the towers; like writing a document
# Function imports at the top
import numpy as np
# Function defs
def function():
'''Docstring: one quick phrase
Longer description
Args:
list: description/requirements
Returns:
list:
'''
# Comment liberally
# --> use comments as section headers
# --> if it takes you more than 5 seconds to understand, comment it
# Not useful: set x to 0
# It's okay to do things the "stupid way" if it's easier to understand
x = 0
# Useful: initialize population at time zero
pop_zero = 0
# Make counters descriptive (not i, but instead, num_birds)
# Keep functions short--if the code takes more than one screen, consider breaking it up
R conventions: R allows dots in var/function names... Don't do that. Just use camelCase
If you find a bug, immediately write a test for it!
Avoids the "don't touch it" syndrome--you can change old code and run your tests to be sure it still works.
Python library for testing: pytest
Several dirs within repository/:
-
calcs/- orsrc/. Your code -
man/- your manuscript
Within calcs/src, numbered subdirectories give order of operations, contain Jupyter notebooks, results, & files, etc.
RE: Jupyter notebooks - use literate programming. Take advantage of text functionality and write notebook as a document. Could somebody follow along without you being there?
Make a very small example dataset where you know the output
Make a variable at the top for the path to the data file; switch that between test & actual output when needed
- The philosophy of testing
- Test the functionality of the code without caring how it is implemented
- A test: a function that asserts something
- Arguments to a test are called fixtures
- Fixtures can be kind of weird—can already have stuff in them (See below)
- Can run other code and then assert something at the end
- Tests that are short enough can just be “commented” in the name
- Why a test is here, instead of what the test does
- “This corrects issue <>”
- Arguments to a test are called fixtures
- Fixture: @pytest.fixture() generates input for tests
- Replaces a fixture name with code
- Finalizers: get rid of the thing you made, e.g. working with databases
- monkeypatch and request can be used but are not defined as fixtures
- Decorators
- Take a function that exists and add something to it
- e.g. timing a function