Contributing¶
Contributions are welcome and greatly appreciated! Every little bit helps, and credit will always be given.
Environment Setup¶
amos uses uv to manage its environment. After
cloning the repository, install every dependency (including the optional
packages that the tests use) and the pre-commit hooks:
Then run the tests, the linter, and the type checker:
Development¶
Follow this basic process:
- Fork and clone the repository.
- Create a new branch:
git checkout -b feature-or-bugfix-name. - Edit the code.
- If you added functionality or features, update the documentation accordingly.
If you are unsure about how to fix or ignore a warning, just let the continuous integration fail, and we will help you during review.
Don't bother updating the changelog, we will take care of this.
Adding a technique¶
Most contributions to amos are new techniques. To add one:
- Find the module of its genre (
loaders,cleaners,mungers,mergers,shapers,describers,splitters,transformers,samplers,models,validators,metrics,evaluators,inferers, orplots) and copy a similar technique. Every class is adataclasses.dataclass. - Wrap tools from other packages by their import paths (in
contentsortools), not by importing them at the top of a module. They are imported only when the technique is used, soamosstays light and its optional packages stay optional. If the tool comes from a new package, add the package to an extra inpyproject.tomland tooptions._EXTRAS. - Give the class a docstring whose first line describes the technique. The
tables of the technique catalog in
docs/catalog.mdare made from these lines: write them again withuv run python docs/scripts/technique_catalog.py. A unit test checks that the catalog is up to date. If the technique (or a function) uses a tool from another package, end the description with a "Wraps:" section that names the tool by its import path, links to its documentation, and names its package:
Wraps:
[`sklearn.preprocessing.StandardScaler`](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html)
from scikit-learn.
List several tools as a list, each with what it is used for (such as "to
classify"). A unit test checks that each tool in contents or tools is
linked this way.
4. Make sure the technique learns only from the training rows, records what
it did in the dataset's history, and uses the dataset's seed for
anything random.
5. Add tests. Tests that use an optional package call requires (in
tests/conftest.py) so that they are skipped where the package cannot be
imported.
Examples in the README and the documentation are run by tests/test_docs.py.
The comment lines after a print statement are its expected output.
The figures in the README are drawn by the breast cancer study in the README
itself. If that study changes, draw them again (they are saved in docs/img):
Pull requests guidelines¶
Link to any related issue in the Pull Request message.
During the review, we recommend using fixups:
Once all the changes are approved, you can squash your commits:
And force-push:
If this seems all too complicated, you can push or force-push each new commit, and we will squash them ourselves if needed, before merging.
Style Guidelines¶
This package follows the Google Python Style Guide with two notable exceptions:
- It always adds spaces around "=". This not only violates the Google guide, it violates PEP8, the foundational Python style guide from which all other resources are derived. I defy this strong, long-standing norm because I find it more readable. My brain and eyes have trouble seeing two separate objects when an equal sign is in the middle. I imagine that I am not alone in this accessibility issue. Further, as PEP8 itself notes, required spaces around equal signs are becoming increasing common with type annotations becoming part of best practices (and, as a result, signatures to classes, functions, and methods regularly include spaces around the equal signs). I realize that this will seem alien to many coders, but it is far easier on my eyes.
- I use some so-called "power features", primarily dunder methods, to make my interfaces easier to access and use. This is disfavored in the Google Python Style Guide because such code is often more difficult for others to read. To address that concern, I try to document and comment as to what the code is doing whenever I used any of the "power features" of Python.
Because of the first exception, the project does not use a code formatter (such
as ruff format), which would remove those spaces.