> ## Documentation Index
> Fetch the complete documentation index at: https://systematica.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Development Tips

> Code format & principles

## SOLID Principles

The SOLID principles are a set of five foundational guidelines in object-oriented design, aimed at creating software that is maintainable, scalable, and robust. Adhering to these principles promotes cleaner architecture, reduces technical debt, and enhances testability.

<Steps>
  <Step title="Single Responsibility Principle (SRP).">
    *A class should have one, and only one, reason to change.*

    Each class or module should encapsulate a single responsibility or function. This separation of concerns reduces complexity and improves maintainability.

    > **Best Practice:** Decompose complex classes into smaller, purpose-driven components. Avoid mixing unrelated functionality within a single class.
  </Step>

  <Step title="Open/Closed Principle (OCP).">
    *Software entities (classes, modules, functions) should be open for extension but closed for modification.*

    Design systems so that behavior can be extended without altering existing source code. This is typically achieved via abstraction and polymorphism.

    > **Best Practice:** Leverage inheritance, interfaces, or composition to enable new features without modifying existing implementations.
  </Step>

  <Step title="Liskov Substitution Principle (LSP).">
    *Subtypes must be substitutable for their base types without altering the correctness of the program.*

    Derived classes should honor the contract established by their base class. Substitution should not introduce unexpected behavior or side effects.

    > **Best Practice:** Avoid overriding methods in ways that violate assumptions made by the base type. Ensure consistent behavior across all derived types.
  </Step>

  <Step title="Interface Segregation Principle (ISP).">
    *Clients should not be forced to depend on interfaces they do not use.*

    Design narrow, role-specific interfaces rather than monolithic ones. This minimizes the impact of changes and aligns interfaces with specific client needs.

    > **Best Practice:** Split large interfaces into smaller, more focused abstractions tailored to specific contexts or use cases.
  </Step>

  <Step title="Dependency Inversion Principle (DIP).">
    *High-level modules should not depend on low-level modules. Both should depend on abstractions.*

    System components should rely on abstractions rather than concrete implementations. This decouples the system and facilitates easier testing and flexibility.

    > **Best Practice:** Apply dependency injection techniques to supply dependencies, and define stable interfaces for critical components.
  </Step>
</Steps>

## DRY Principle

**DRY** stands for **Don't Repeat Yourself**, a fundamental software engineering principle aimed at reducing duplication within a codebase. It encourages reusability and abstraction to minimize redundancy and improve maintainability.

### Definition

*Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.*

In practice, this means that logic, behavior, or configuration should not be duplicated. Repetition often leads to inconsistencies, increases the surface area for bugs, and makes future changes more error-prone.

### Benefits

* **Improved Maintainability:** Changes need to be made in only one place.
* **Reduced Errors:** Less duplication means fewer opportunities for introducing bugs.
* **Increased Clarity:** Consolidated logic improves readability and understanding of the system.
* **Better Scalability:** Reusable components are easier to extend and adapt.

### Common Violations

* Duplicated business logic scattered across multiple classes or modules.
* Copy-pasted code blocks instead of shared functions.
* Repeating the same configuration or constants in multiple files.

### Best Practices

* **Abstract Repetitive Logic:** Extract common functionality into functions, classes, or modules.
* **Centralize Constants and Configurations:** Use configuration files or environment variables.
* **Use Templates:** In web or UI development, utilize templating systems to avoid markup duplication.
* **Leverage Inheritance and Composition:** In object-oriented design, avoid rewriting similar behaviors across classes.

> **Note:** Avoid over-abstracting early. Premature abstraction can lead to unnecessary complexity. Let repetition emerge before generalizing.

## Working with Jupyter Notebooks

When running example notebooks, you might want to prevent git from tracking your notebook output changes to avoid accidentally committing over the examples.

<Steps>
  <Step title="Ignore notebook changes">
    Run once after cloning:

    ```sh theme={null}
    git ls-files "examples/notebooks/**/*.ipynb" | xargs git update-index --assume-unchanged
    ```

    This tells git to ignore any changes to notebooks in the examples directory.
  </Step>

  <Step title="Resume tracking specific notebooks">
    When you need to make intentional changes:

    ```sh theme={null}
    git update-index --no-assume-unchanged "examples/notebooks/specific_notebook.ipynb"
    ```
  </Step>

  <Step title="Resume tracking all notebooks">
    If you need to revert the ignore setting

    ```sh theme={null}
    git ls-files "examples/notebooks/**/*.ipynb" | xargs git update-index --no-assume-unchanged
    ```
  </Step>
</Steps>

## Auto-Generate documentation

To auto-generate your documentation, you can follow these steps:

<Steps>
  <Step title="Generate documentation from docstrings">
    Run `pdoc3` to save `.md` files to the `./docs/reference` folder with the following command:

    ```sh theme={null}
    pdoc3 systematica --output-dir docs/pdoc_md  --config='docformat="numpy"' --template-dir docs/pdoc_templates --force
    ```
  </Step>

  <Step title="Generate mdx files">
    Run `gen_api_docs.py` to save `.mdx` files to the `./docs/api` folder with the following command:

    ```sh theme={null}
    uv run docs/scripts/gen_api_docs.py
    ```
  </Step>

  <Step title="Update reference docs">
    Run `gen_api_ref.py` to update `docs.json` with the following command:

    ```sh theme={null}
    uv run docs/scripts/gen_api_ref.py     
    ```
  </Step>

  <Step title="Visualize the API Reference locally">
    To visualize the API Reference locally, `cd` into the `docs` directory

    ```sh theme={null}
    cd docs
    ```

    and run the following command:

    ```sh theme={null}
    mint dev 
    ```

    This will start a local development server, allowing you to view the API Reference in your browser at `http://localhost:3000/api-reference/systematica/`.
  </Step>
</Steps>
