diff --git a/README.md b/README.md index 417f5a0..f6a4898 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ A comprehensive Python project template designed specifically for research devel - **Comprehensive Linting & Type Checking**: Pre-configured with mypy, isort, pylint, black, pydocstyle, and flake8 - **Pre-commit Hooks**: Automated code quality checks before each commit - **CI/CD Integration**: GitHub Actions workflow for continuous integration on PRs -- **Experiment Tracking**: Ready-to-use configuration for Hydra and Weights & Biases (W&B) +- **Experiment Tracking**: Ready-to-use configuration for Hydra and Weights & Biases (W&B) (optional dependencies) ## Directory Structure @@ -79,6 +79,8 @@ powershell -c "irm https://astral.sh/uv/install.ps1 | iex" This template is designed to support reproducible research experiments using [Hydra](https://hydra.cc/) for configuration management and [Weights & Biases (W&B)](https://wandb.ai/) for experiment tracking. +> **Note**: Hydra and W&B are included as dependencies in this template for convenience, but they are **optional**. You can remove them from `pyproject.toml` if you don't need experiment tracking or configuration management features. + #### Basic Experiment Execution Place your experiment scripts in the `experiments/` directory: @@ -276,18 +278,24 @@ The GitHub Actions workflow (`.github/workflows/pr-monitor.yml`) automatically r ## Adding New Dependencies -Use uv to add new dependencies: +Use uv to add new dependencies to your project. The `uv add` command automatically installs the package and updates `pyproject.toml`: ```bash # Add a runtime dependency -uv pip install package-name -# Then add it to pyproject.toml under [project.dependencies] +uv add package-name # Add a development dependency -uv pip install package-name -# Then add it to pyproject.toml under [project.optional-dependencies.dev] +uv add --dev package-name + +# Add a specific version +uv add "package-name>=1.0.0" + +# Add multiple packages at once +uv add package1 package2 package3 ``` +After adding dependencies, make sure to commit the updated `pyproject.toml` to keep your project configuration in sync. + ## Configuration Files All linter and type-checker configurations are located in the `.dev-config/` directory: diff --git a/src/utils.py b/src/utils.py new file mode 100644 index 0000000..4c01bf8 --- /dev/null +++ b/src/utils.py @@ -0,0 +1,45 @@ +"""Utility functions for the research project. + +This module contains common utility functions used across experiments. +""" + +from typing import Any, Dict, List + + +def compute_mean(values: List[float]) -> float: + """Compute the mean of a list of values. + + Args: + values: List of numerical values. + + Returns: + The arithmetic mean of the input values. + + Raises: + ValueError: If the input list is empty. + + Example: + >>> compute_mean([1.0, 2.0, 3.0, 4.0]) + 2.5 + """ + if not values: + raise ValueError("Cannot compute mean of empty list") + return sum(values) / len(values) + + +def validate_config(config: Dict[str, Any]) -> bool: + """Validate experiment configuration. + + Args: + config: Configuration dictionary to validate. + + Returns: + True if configuration is valid, False otherwise. + + Example: + >>> config = {"learning_rate": 0.001, "batch_size": 32} + >>> validate_config(config) + True + """ + required_keys = ["learning_rate", "batch_size"] + return all(key in config for key in required_keys) diff --git a/tests/test_example.py b/tests/test_example.py index 6660df2..56d9635 100644 --- a/tests/test_example.py +++ b/tests/test_example.py @@ -34,7 +34,9 @@ def test_compute_mean_single_value(self) -> None: def test_compute_mean_empty_list(self) -> None: """Test that empty list raises ValueError.""" - with pytest.raises(ValueError, match="Cannot compute mean of empty list"): + with pytest.raises( + ValueError, match="Cannot compute mean of empty list" + ): compute_mean([])