Group Code Style Guide

If you are looking for an example of what your code should look like, refer to the group  template repo . For details regarding software package design, refer to  🚧Software Development .

Formatting and Linting

Ruff

Motivation

For internal consistency in the group, all open-source Python code (and codes we work on collaboratively) should be formatted and lint checked with  ruff . There are few things more frustrating in scientific computing than dealing with formatting inconsistencies when you're just trying to get things done. Ruff is fast, uncompromising, and "just works."

Usage

First, install ruff via pip install ruff. If you use VS Code, it can automatically format on-save if you have the  Ruff  extension installed (highly recommended!).
To format code from the command line, run ruff format in the directory of files you want to format. Use ruff check --fix to apply common lint fixes.

Type Annotations

All code that you develop should make use of  type annotations  for the class and function arguments. This is incredibly helpful for understanding what code should be doing. To the degree possible, you should address type annotation inconsistencies highlighted in VS Code; however, this may not always be trivial and we do not need to be perfect there. We do not generally require static type-checking with a tool like mypy.

Docstrings

All class and function definitions must have docstrings. We adopt numpy-style  docstrings . If you use type annotations, you do not need to include the type in the docstring itself.

Naming

All functions should be written in lower-case (e.g. my_function), and all classes should be written in CamelCase (e.g. MyClass). Variables and arguments should have clear yet concise names.

Handling Paths

Where possible, you should strive for your code to be platform-agnostic. One of the main things to keep in mind is that different operating systems handle paths different. As a general rule, you should never define paths in your code with string concatenation (i.e. do not do "/path/to/my/" + "folder"). Instead, you should use the pathlib library. For instance:
from pathlib import Path

p = Path("path/to/my/folder")
# or...
p = Path("path/to/my") / "folder"