.. _contributing: 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. .. contents:: On this page :local: :depth: 2 ---- 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 -------------------------------------- .. code-block:: bash # 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 ----------------- .. code-block:: text 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: .. code-block:: bash 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``: .. code-block:: bash git checkout -b fix/description-of-fix 2. Make your changes. Commit with clear messages: .. code-block:: bash 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: .. code-block:: text 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 μ₁: Expected μ₁: Getting Help ------------ * **GitHub Issues** — bug reports and feature requests * **GitHub Discussions** — questions and general discussion See also -------- * :doc:`/api-reference/core` — backend API reference * :doc:`/api-reference/toful-parser` — parser API reference * :doc:`/theory/convergence` — understanding the computation methods