Thank you for your interest in contributing to the Course Constraint Scheduler! This document provides guidelines and instructions for developers who want to contribute to the project.
- Getting Started
- Development Setup
- Project Structure
- Development Workflow
- Code Standards
- Testing
- Documentation
- Submitting Changes
- Release Process
- Python 3.12+: The project requires Python 3.12 or higher
- Git: For version control
- uv: Modern Python package manager (recommended)
We strongly recommend using uv for dependency management and virtual environments. It's faster and more reliable than traditional tools.
macOS and Linux:
curl -LsSf https://astral.sh/uv/install.sh | shWindows:
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"Alternative (pip):
pip install uvgit clone https://github.com/mucsci/scheduler.git
cd schedulerRecommended approach using uv:
# Create and activate virtual environment
uv venv
source .venv/bin/activate # On macOS/Linux
# OR
.venv\Scripts\activate # On Windows
# Install dependencies
uv sync
# Install package in editable mode
uv pip install -e .Alternative (if uv is not available):
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # On macOS/Linux
# OR
.venv\Scripts\activate # On Windows
# Install dependencies
pip install -r requirements.txt
pip install -e .# Using uv (recommended)
uv sync --group dev
# Using pip
pip install -e ".[dev]"# Test the scheduler
python -m scheduler.main --help
# Test the server
python -m scheduler.server --help
# Run tests
pytestsrc/scheduler/
├── __init__.py # Main package exports
├── config.py # Configuration models and validation
├── json_types.py # TypedDict definitions for JSON structures
├── main.py # Command-line interface
├── scheduler.py # Core scheduling logic and Z3 integration
├── server.py # FastAPI REST server
├── logging.py # Logging configuration
├── models/ # Data models
│ ├── __init__.py # Model exports
│ ├── course.py # Course and CourseInstance models
│ ├── day.py # Day enumeration
│ └── time_slot.py # Time-related models (TimeSlot, TimeInstance, etc.)
├── writers/ # Output formatters
│ ├── __init__.py # Writer exports
│ ├── json_writer.py # JSON output writer
│ └── csv_writer.py # CSV output writer
└── time_slot_generator.py # Time slot generation utilities
docs/ # Documentation
├── configuration.md # Configuration file format
├── python_api.md # Python API
└── rest_api.md # REST API
# Ensure you're on main and up to date
git checkout main
git pull origin main
# Create and checkout a feature branch
git checkout -b feature/your-feature-name- Write your code following the Code Standards
- Update documentation as needed
- Ensure all tests pass
# Run linting
ruff check
# Run type checking
ty check# Stage your changes
git add .
# Commit with a descriptive message
git commit -m "feat: add new optimization algorithm for room packing
- Implemented improved room packing algorithm
- Added configuration option for packing strategy
- Updated tests and documentation
- Performance improvement of 15% for large schedules"git push origin feature/your-feature-nameThen create a Pull Request on GitHub with:
- Clear description of changes
- Reference to any related issues
- Screenshots for UI changes
- Performance impact analysis if applicable
We follow PEP 8 with some modifications enforced by our linting tools.
Key Standards:
- Use 4 spaces for indentation (no tabs)
- Maximum line length: 88 characters (enforced by Black)
- Use descriptive variable and function names
- Add type hints for all function parameters and return values
- Use f-strings for string formatting (Python 3.6+)
# Standard library imports
import json
import logging
from typing import List, Optional
# Third-party imports
import z3
from pydantic import BaseModel
# Local imports
from .models import Course, CourseInstance
from .config import SchedulerConfigDocstrings:
def generate_schedule(config: SchedulerConfig) -> List[CourseInstance]:
"""Generate a course schedule based on configuration.
**Args:**
- config: The scheduler configuration containing courses, faculty, and constraints.
**Returns:**
A list of course instances representing the generated schedule.
**Raises:**
- ValueError: If the configuration is invalid.
- RuntimeError: If no valid schedule can be generated.
**Example:**
>>> config = load_config_from_file("config.json")
>>> schedule = generate_schedule(config, limit=5)
>>> print(f"Generated {len(schedule)} courses")
"""
passInline Comments:
# Use comments to explain WHY, not WHAT
# Avoid obvious comments like "increment counter"
# Good: "Skip Fridays for labs as they're not available for scheduling"
if day == Day.FRI:
continue# Use specific exception types
try:
result = z3_solver.check()
except z3.Z3Exception as e:
logger.error(f"Z3 solver failed: {e}")
raise RuntimeError(f"Schedule generation failed: {e}") from e
# Provide meaningful error messages
if not faculty_available:
raise ValueError(
f"Faculty member '{faculty_name}' has no available time slots "
f"that match the course requirements"
)- All public functions and classes must have docstrings
- Use Google-style docstrings for consistency
- Include examples for complex functions
- Document exceptions and error conditions
- Update REST API documentation for new endpoints
- Include request/response examples
- Document error codes and messages
- Update OpenAPI schema if applicable
- Update README.md for new features
- Add configuration examples
- Update troubleshooting guides
- Include performance considerations
Before submitting a pull request, ensure:
- Code passes linting (
ruff check) - Type checking passes (
ty check) - Documentation is updated
- Breaking changes are documented
- Commit messages follow conventional format
We use Conventional Commits format:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringtest: Adding or updating testschore: Maintenance tasks
Examples:
feat: add new optimization algorithm for room packing
fix(scheduler): resolve memory leak in large schedule generation
docs: update configuration guide with new options
test: add performance benchmarks for optimization algorithms
- Automated Checks: CI/CD pipeline runs tests and linting
- Code Review: At least one maintainer must approve
- Testing: Changes are tested in staging environment
- Merge: Changes are merged to main branch
We use Semantic Versioning:
- MAJOR: Breaking changes
- MINOR: New features (backward compatible)
- PATCH: Bug fixes (backward compatible)
- Update Version: Update version in
pyproject.toml - Changelog: Update
CHANGELOG.mdwith new changes - Tag Release: Create git tag for the version
- Build Package: Build and test the package
- Publish: Publish to PyPI
- Documentation: Update documentation for new version
# Build package
uv run build
# Test package
uv run twine check dist/*
# Publish to PyPI
uv run twine upload dist/*- GitHub Issues: Bug reports and feature requests
- GitHub Discussions: General questions and discussions
- Pull Requests: Code review and collaboration
New contributors are welcome! We're happy to:
- Help you get started
- Review your first pull request
- Pair program on complex features
- Provide guidance on best practices
We are committed to providing a welcoming and inclusive environment for all contributors. Please read our Code of Conduct for details.
By contributing to this project, you agree that your contributions will be licensed under the MIT License. See LICENSE for details.
Thank you for contributing to the Course Constraint Scheduler! Your contributions help make academic scheduling more efficient and accessible for everyone.