Skip to content

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.