Contributing
The Minitorch codebase is structured to mimic the experience of contributing to a real open-source project. It is not sufficient to implement functions correctly; the code itself needs to meet the specific contributor requirements. These are checked by the system automatically before acceptance.
Style
It is required to keep your code organized and clean to make it easier to debug, optimize, and document. To help with this process, we utilize required formatting on all assignments.
Fixing style bugs can be an annoying process. However, there are now tools
to fix most formatting issues automatically. We use ruff
to automatically
reformat all of your code to fit most of the requirements (see
the ruff website for
more details).
Ruff will fix many of your issues, but cannot check for aspects like using unknown variables.
We recommend setting up your editor or IDE to highlight other style issues. Many developers utilize VSCode with plugins to check for these issues as they code.
Testing
Each assignment has a series of tests that require your code to pass.
These tests are in the tests/
directory and are in the pytest
format (https://docs.pytest.org/en/stable/). Any function in that
directory starting with test
is run as part of the test
suite.
>>> pytest
Each assignment has 4 task groups that you will need to pass. To run
individual task groups you can use the -m
option.
>>> pytest -m task0_0
In addition to running a full task which runs all of the tests, you can run tests in a single file with:
>>> pytest tests/test_operators.py
Or even a particular test with:
>>> pytest tests/test_operators.py -k test_sum
Note: PyTest will hide all print statements unless a test fails. If you want to see output for a given tests you may need to cause an assertion failure.
Type Checking
Modern versions of Python allow for static type checking to ensure that functions take and returns objects of the correct type. The Minitorch code base is fully annoted with typed on each function. Users will not have to provide types, but they provide documentation as to what functions expect as arguments and as for their return values. For example, if we are writing a function that does multiplication it would have the following signature.
def mul(x: float, y: float) -> float:
...
As we get to more complex topics the type signatures will get more
complex as well. For example, Iterable
is use to represent a type
that can be iterated over.
def negList(ls: Iterable[float]) -> Iterable[float]:
...
In order to check that the code matches the types, the project requires
that you use the pyright
library. This is run as part of the style check.
Documentation
Throughout the codebase, we require you to document all functions in a standardized style. Documentation is critical for our Python codebase, and we use it to convey requirements on many functions. Functions should have docstrings in the following form (known as Google docstyle):
def index(ls: List[Any], i: int) -> Any:
"""
List indexing.
Args:
ls: A list of any type.
i: An index into the list
Returns:
Value at ls[i].
"""
...
For short function you can also just include a single line docstring. A full description of this docstyle is listed as the Google format.
The project also requires that you keep documentation up-to-standard throughout. Lint errors will be thrown if your documentation is in the incorrect format.
Pre-Commit
These elements can be checked automatically through a tool known as pre-commit. Using the precommit tool is optional but will likely save you time in your coding process and ensure that you are not making too many unnecessary failed pull requests. You can install the tool by running,
pip install pre-commit
You can run all the checks (black, flake8, mypy, etc) and corrections on your code with the following command:
pre-commit run --all
You can also 'install' pre-commits which will run on every commit automatically, and prevent you from committing bad code.
pre-commit install
Continuous Integration (CI)
In addition to local testing, the project is set up such that on each code push, tests are automatically run and checked on the server. You are able to see how well you are doing on the assignment by committing your code, pushing to the server, and then logging in to GitHub. This process takes several minutes, but it is an easy way to keep track of your progress as you go.
Specifically, you can run:
>>> git commit -am "First commit"
>>> git push origin master
Then go to your GitHub and click on "Pull requests". Clicking on the request itself gives a link to show the current progress of your work.