Contributing to pulse2percept

Note

If you found a bug or want to request a feature, please open an issue in our Issue Tracker on GitHub. Make sure to label your issue appropriately.

We are excited that you are here and want to contribute! If you have any questions that aren’t discussed below, please let us know by opening an issue in our Issue Tracker on GitHub.

Already know what you’re looking for in this guide? Jump to the following sections:

Understanding issue labels

Make sure to check out the current list of issue labels:

  • Bug

    These issues point to problems in the project.

    If you find new a bug, please provide as much information as possible to recreate the error. The issue template will automatically populate any new issue you open, and contains information we’ve found to be helpful in addressing bug reports. Please fill it out to the best of your ability!

    Note

    If you experience the same bug as one already listed in an open issue, please add any additional information that you have as a comment.

  • Enhancement

    These issues are asking for new features to be added to the project.

    Please try to make sure that your requested enhancement is distinct from any others that have already been requested or implemented.

    Note

    If you find one that’s similar but there are subtle differences, please reference the other request in your issue.

  • Help wanted

    These issues contain a task that a member of the team has determined we need additional help with.

    If you feel that you can contribute to one of these issues, we especially encourage you to do so!

    Note

    Issues that are also labelled as good first issue are a great place to start if you’re looking to make your first contribution.

Contributing code

Perform all your work on a new branch of the repository. For example, say you want to add “feature1” to the latest version of pulse2percept:

  1. Make sure you have the latest code:

    git checkout master
    git pull upstream master
    

    Note

    If you get an error saying “upstream does not appear to be a git repository”, you need to run the following command first: git remote add upstream https://github.com/pulse2percept/pulse2percept.git

  2. Create a new branch (aptly named “feature1” or similar):

    git checkout -b feature1
    
  3. Add and commit your changes to this branch. Then push it to your remote repository on GitHub:

    git push origin feature1
    

    Important

    All code additions must be documented and tested.

  4. Go to GitHub and submit a pull request:

    1. Click on “compare across forks” at the top of the page.

    2. Choose “pulse2percept/pulse2percept” as the base repository and “master” as the base branch.

    3. Choose “<username>/pulse2percept” as the head repository and “feature1” as the compare branch, where “<username>” is your GitHub user name.

    4. Click on “Create pull request” and describe the work you have done. Make sure to mention the issue number you are addressing (use # as prefix).

      An easy way to list all the things you changed is to use a list of checkboxes (type - [X]; or - [ ] for an item that has yet to be implemented).

Documenting your code

You are expected to document your code using NumPy docstrings. Make sure to:

  • supply short and long descriptions,
  • describe all input arguments to a function/method,
  • describe the output of a function/method,
  • provide examples of how to use your code.

For example, consider an appropriate docstring for a hypothetical function rad2deg:

def rad2deg(angle_rad):
    """Converts radians to degrees

    This function converts an angle in radians to degrees.

    Parameters
    ----------
    angle_rad : int, float
        The input angle in radians

    Returns
    -------
    angle_deg : float
        The corresponding angle in degrees

    Examples
    --------
    Converting pi to degrees:
    >>> import numpy as np
    >>> rad2deg(np.pi)
    180.0

    .. seealso:: `deg2rad`
    """
    ...

You can generate the documentation yourself using Sphinx. From the root directory of your git clone, type:

cd doc
pip3 install -r requirements.txt
make html
google-chrome _build/html/index.html

This will build the documentation in “doc/_build/html”. To see the documentation, use the above command or open “doc/_build/html/index.html” in your browser of choice.

Testing your code

You are expected to test your code using pytest:

  • Bug fixes should include an example that exposes the issue.
  • New features should have tests that show at least a minimal example.

Running the test suite

pulse2percept uses pytest and numpy-testing for testing.

Every subpackage of pulse2percept (e.g., stimuli) has a subdirectory called “tests”. Within the test directory, there is a “test_<subsubpackage>.py” file for every subsubpackage of pulse2percept (e.g., “pulse2percept/stimuli/tests/test_pulse_trains.py” for pulse_trains).

When you contribute new code, you are expected to test your code in the corresponding test file.

You can run the test suite with:

pip3 install -r requirements-dev.txt
pytest --doctest-modules --showlocals -v pulse2percept

Successful tasks will be marked with “PASSED”, unsuccessful ones with “FAILED”. We will usually not accept pull requests that don’t pass all tests.

Writing your own tests

If you work on code from an existing subpackage (e.g., pulse2percept.stimuli.pulse_trains), open the corresponding test file (e.g., “pulse2percept/stimuli/tests/test_pulse_trains.py”).

You can add a new test by adding a function whose name starts with “test_”, followed by the name of the class or function you want to test. For example:

  • def test_TimeSeries for testing the TimeSeries object (note that this function already exists).
  • def test_TimeSeries_resample for testing the resample method of the TimeSeries object.
  • def test_newfunc for a new function called newfunc.

Within this function, you want to make sure your code works as expected. Useful numpy-testing routines for achieving this include:

  • assert_equal(actual, desired) returns an AssertionError if two objects are not equal.
  • assert_almost_equal(actual, desired, decimal=7) returns an AssertionError if two items are not equal up to desired precision (good for testing doubles).
  • assert_raises(exception_class) fails unless an Exception of class exception_class is thrown.

In addition, we provide assert_warns_msg to ensure that a specific warning message is thrown.

Thank you

You are awesome!

This guide is based on contributing guidelines from the `Nipype`_ project.