Contributing to Inhabit ======================= Thank you for your interest in contributing to the Inhabit project! We welcome contributions from developers of all skill levels. This guide outlines the standards and processes we use to maintain a high-quality codebase. Development Philosophy ---------------------- The Inhabit model is used for academic and policy research. Therefore, we prioritize: 1. **Correctness**: Ensuring simulation logic is mathematically sound and matches the intended housing market theory. 2. **Reproducibility**: Changes must not introduce non-deterministic behavior unless explicitly intended. 3. **Readability**: Code should be self-documenting where possible, supplemented by clear docstrings. Git Workflow ------------ We follow a standard feature-branch workflow: 1. **Fork/Branch**: Create a new branch for every feature or bug fix. * Feature branches: ``feature/description-of-change`` * Bug fixes: ``fix/description-of-bug`` 2. **Commits**: Write descriptive commit messages. Explain *why* a change was made, not just *what* was changed. 3. **Pull Requests**: Submit a PR to the ``main`` or ``development`` branch. Ensure all tests pass before requesting a review. Code Style and Standards ------------------------ To keep the codebase consistent, we adhere to the following standards: Python Style ~~~~~~~~~~~~ * **PEP 8**: Follow standard Python style guidelines. * **Type Hints**: All new functions should include PEP 484 type hints for parameters and return values. * **Linters**: We recommend using ``ruff`` or ``flake8`` for style checking. Docstrings ~~~~~~~~~~ We use the **Google Python Style** for docstrings. Every public function and class must include a docstring that specifies: * A brief summary of functionality. * **Args**: Parameters with their types and descriptions. * **Returns**: Return values with their types and descriptions. * **Notes/Examples**: Optional sections for complex logic or usage examples. Testing Requirements -------------------- We maintain a high level of test coverage using ``pytest``. * **Unit Tests**: Every new function in the ``scripts/`` directory must have corresponding unit tests in the ``tests/`` directory. * **Mocking**: Use the ``unittest.mock`` library to isolate tests from file I/O, network calls, and expensive external dependencies (like SOEP data loaders). * **Running Tests**: .. code-block:: console $ pytest tests/ * **Regression**: Ensure that your changes do not break existing tests. If you intentionally change functionality, update the corresponding tests. Documentation ------------- Documentation is managed using **Sphinx**. * **Docstring Integration**: We use ``autodoc`` to pull documentation directly from the code. Ensure your docstrings are correctly formatted to be picked up by the build process. * **Updating .rst Files**: If you add a new module to the ``scripts/`` folder, ensure you add a corresponding ``automodule`` entry in ``docs/code.rst`` and an entry in ``docs/api.rst``. * **Building Locally**: .. code-block:: console $ cd docs $ make html Performance Best Practices -------------------------- Since Inhabit processes large datasets over long time horizons, performance is critical. * **Avoid iterrows()**: Never use ``df.iterrows()`` for large DataFrames. Use vectorized operations, ``map()``, or ``apply()`` where vectorization is impossible. * **Minimize Copies**: Be mindful of ``df.copy()``. Only copy DataFrames when necessary to avoid unintended side effects. * **Memory Hygiene**: If processing multiple scenarios in a loop, ensure large temporary objects are cleared to prevent memory leaks. Questions and Support --------------------- If you are unsure about a specific implementation or architectural decision, please open an issue for discussion before starting significant work. We are happy to provide guidance!