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!