Contributing to ToFUL

Contributions are welcome and appreciated. This guide covers everything needed to get started — from setting up a development environment to submitting a pull request.


Code of Conduct

Be respectful and constructive. Review others’ work with the same care you would want for your own. Report issues factually and without blame.


Ways to Contribute

Bug reports

If you find incorrect moment values, unexpected behaviour, or a crash, open an issue on GitHub with the exact input that caused the problem, the observed output, and the expected output.

Documentation

Correct typos, improve explanations, add examples. Documentation contributions are as valuable as code contributions.

New distribution examples

Add entries to the examples pages. Each entry should include the range input, PMF/PDF expression, known analytical values, and any tips specific to that distribution.

Performance improvements

Profile before submitting. Improvements should be demonstrated with a timing comparison on a representative input.

New features

Open an issue to discuss the feature before implementing it. This avoids duplicated work and ensures alignment with the project’s goals.


Setting Up a Development Environment

# 1. Fork the repository on GitHub, then clone your fork
git clone https://github.com/YOUR_USERNAME/ToFUL.git
cd ToFUL

# 2. Create a virtual environment
python -m venv .venv
source .venv/bin/activate        # macOS / Linux
.venv\Scripts\activate           # Windows

# 3. Install runtime dependencies
pip install -r requirements.txt

# 4. Install development dependencies
pip install pytest black flake8 sphinx sphinx-rtd-theme

# 5. Verify the installation
python -c "import core, toful_parser; print('OK')"
streamlit run app.py             # should open the UI

Project Structure

ToFUL/
├── app.py              Streamlit frontend
├── core.py             Computation engine
├── toful_parser.py     Input normalisation pipeline
├── requirements.txt    Runtime dependencies
├── docs/               Sphinx documentation source
│   ├── conf.py
│   ├── index.rst
│   ├── getting-started/
│   ├── user-guide/
│   ├── examples/
│   ├── theory/
│   ├── api-reference/
│   ├── troubleshooting/
│   └── contributing/
└── tests/              (planned) Unit and integration tests

Code Style

  • Formatting: black with default settings (line length 88). Run black app.py core.py toful_parser.py before committing.

  • Linting: flake8 with a maximum line length of 100. Run flake8 core.py toful_parser.py.

  • Type hints: Use Python type hints for all new public functions. Follow the pattern established in core.py.

  • Docstrings: NumPy-style docstrings for all public functions, as in the existing code. Include Parameters, Returns, and Examples sections.

  • Imports: Standard library first, then third-party, then local. No wildcard imports.


Working on core.py

The backend is the most sensitive part of the codebase. Before making changes:

  1. Understand the convergence cascade in _sum_series_with_acceleration. Each strategy has specific conditions under which it fires; changing the order affects correctness.

  2. Test against the known analytical values in the examples pages. Every distribution listed in the examples should produce the correct mean, variance, skewness, and kurtosis.

  3. The legacy shim classes at the bottom of core.py must remain backward-compatible until app.py is fully updated.


Working on toful_parser.py

The parser is safety-critical — a wrong normalisation produces silently incorrect computation. Rules:

  • Each transformation step must have at least one positive test (input that should change) and one negative test (input that must not change).

  • The order of transformations in normalise_for_eval() is fixed by dependency: do not reorder without checking all interactions.

  • Never add a rule that changes semantics ambiguously. When in doubt, leave the expression unchanged and let eval() produce a SyntaxError.


Working on Documentation

Documentation lives in the docs/ directory as reStructuredText files. To build locally:

cd docs
pip install sphinx sphinx-rtd-theme
make html                      # macOS / Linux
.\make.bat html                # Windows

The built HTML appears in docs/_build/html/. Open docs/_build/html/index.html in a browser to preview.

Style guide for RST:

  • Use ---- (four dashes) as a visual section separator before each h2-level heading.

  • Use .. code-block:: python for Python code and .. code-block:: text for plain-text inputs and outputs.

  • Use .. note::, .. tip::, and .. warning:: for callout boxes.

  • Reference other pages with :doc: cross-references rather than raw URLs.

  • Keep lines under 80 characters in RST source.


Submitting a Pull Request

  1. Create a branch from main:

    git checkout -b fix/description-of-fix
    
  2. Make your changes. Commit with clear messages:

    git commit -m "core: fix Wynn epsilon instability for monotone series"
    
  3. Push and open a pull request on GitHub.

  4. In the pull request description:

    • Explain what problem is solved or feature is added.

    • Include before/after output for any numerical change.

    • Reference the related issue if one exists.

  5. A maintainer will review the PR. Expect at least one round of review comments.


Reporting a Numerical Bug

If ToFUL produces an incorrect moment value, the most helpful bug report includes:

Variable type:  Discrete / Continuous
Range:          exact string entered
PMF / PDF:      exact string entered
Moment ref:     Origin / Mean / Custom (value)
Max order:      integer
Calc precision: integer

Observed μ₁:   <value from ToFUL>
Expected μ₁:   <known analytical value and its source>

Getting Help

  • GitHub Issues — bug reports and feature requests

  • GitHub Discussions — questions and general discussion

See also