-
Notifications
You must be signed in to change notification settings - Fork 3
Development Setup
Complete guide to setting up a development environment for contributing to DVOACAP-Python.
- Prerequisites
- Getting Started
- Development Tools
- Project Structure
- Code Style
- Testing
- Documentation
- Git Workflow
Python 3.8 or higher:
# Check your Python version python3 --version # Should output: Python 3.8.0 or higher
Git:
# Install git (if not already installed) # Ubuntu/Debian sudo apt-get install git # macOS brew install git # Windows # Download from https://git-scm.com/download/win
pip and virtualenv:
# Install pip (usually included with Python) python3 -m ensurepip --upgrade # Install virtualenv pip install virtualenv
Fork the repository on GitHub:
- Visit https://github.com/skyelaird/dvoacap-python
- Click "Fork" button (top-right)
Clone your fork:
git clone https://github.com/YOUR_USERNAME/dvoacap-python.git
cd dvoacap-pythonAdd upstream remote:
git remote add upstream https://github.com/skyelaird/dvoacap-python.git git fetch upstream
Create and activate virtual environment:
# Create virtual environment python3 -m venv venv # Activate (Linux/macOS) source venv/bin/activate # Activate (Windows) venv\Scripts\activate # Your prompt should change to show (venv)
Install DVOACAP with all development dependencies:
# Install in editable mode with all extras pip install -e ".[all]" # This installs: # - dvoacap library (core) # - dashboard dependencies (flask, etc.) # - dev tools (pytest, black, flake8, mypy) # - documentation tools (sphinx, sphinx-rtd-theme)
Verify installation:
# Test import python3 -c "import dvoacap; print(dvoacap.__version__)" # Should output: 0.5.0 # Run a quick test pytest tests/test_path_geometry.py -v
Install pre-commit hooks (optional but recommended):
# Install pre-commit pip install pre-commit # Set up git hooks pre-commit install # Run against all files to test pre-commit run --all-files
DVOACAP-Python uses Black for consistent code formatting.
Configuration (from pyproject.toml):
[tool.black] line-length = 100 target-version = ['py38', 'py39', 'py310', 'py311', 'py312']
Usage:
# Format a single file black src/dvoacap/path_geometry.py # Format all Python files black src/ tests/ examples/ # Check without modifying black --check src/
Use Flake8 for code quality checks.
Usage:
# Lint a file flake8 src/dvoacap/path_geometry.py # Lint entire project flake8 src/ tests/ # Configuration in setup.cfg or pyproject.toml
Common issues:
- Line too long (E501) - Black should handle this
- Unused imports (F401) - Remove unused imports
- Undefined name (F821) - Check for typos
Use mypy for optional static type checking.
Configuration (from pyproject.toml):
[tool.mypy] python_version = "3.8" warn_return_any = true warn_unused_configs = true disallow_untyped_defs = false
Usage:
# Check a file mypy src/dvoacap/path_geometry.py # Check entire package mypy src/dvoacap/ # Ignore errors for now (many modules not fully typed) mypy --ignore-missing-imports src/
Run tests with pytest.
Usage:
# Run all tests pytest # Run with verbose output pytest -v # Run specific test file pytest tests/test_path_geometry.py # Run specific test function pytest tests/test_path_geometry.py::test_distance_calculation # Run with coverage pytest --cov=dvoacap tests/ # Generate HTML coverage report pytest --cov=dvoacap --cov-report=html tests/ # Open htmlcov/index.html in browser
Configuration (from pyproject.toml):
[tool.pytest.ini_options] testpaths = ["tests"] python_files = ["test_*.py"] python_classes = ["Test*"] python_functions = ["test_*"] addopts = "-v --tb=short"
dvoacap-python/
├── src/
│ └── dvoacap/ # Main Python package
│ ├── __init__.py # Package initialization
│ ├── path_geometry.py # Phase 1: Path geometry
│ ├── solar.py # Phase 2: Solar calculations
│ ├── geomagnetic.py # Phase 2: Geomagnetic field
│ ├── fourier_maps.py # Phase 3: CCIR/URSI maps
│ ├── ionospheric_profile.py # Phase 3: Ionosphere modeling
│ ├── layer_parameters.py # Phase 3: Layer parameters
│ ├── muf_calculator.py # Phase 4: MUF calculations
│ ├── reflectrix.py # Phase 4: Raytracing
│ ├── prediction_engine.py # Phase 5: Prediction engine
│ ├── noise_model.py # Phase 5: Noise modeling
│ └── antenna_gain.py # Phase 5: Antenna calculations
│
├── tests/ # Test suite
│ ├── test_path_geometry.py # Path geometry tests
│ ├── test_ionospheric.py # Ionospheric tests
│ └── test_voacap_parser.py # VOACAP reference tests
│
├── examples/ # Usage examples
│ ├── complete_prediction_example.py
│ ├── phase4_raytracing_example.py
│ └── integration_example.py
│
├── Dashboard/ # Web dashboard
│ ├── dashboard.html # Main UI
│ ├── server.py # Flask server
│ ├── generate_predictions.py # Prediction generator
│ └── README.md # Dashboard docs
│
├── DVoaData/ # CCIR/URSI coefficient data
│ ├── ccir*.asc # CCIR coefficients
│ └── ursi*.asc # URSI coefficients
│
├── SampleIO/ # Sample input/output files
│ └── voacap_reference/ # Reference VOACAP output
│
├── docs/ # Documentation
│ ├── source/ # Sphinx source
│ ├── build/ # Built documentation
│ └── *.md, *.pdf # Various docs
│
├── wiki/ # GitHub wiki (this documentation)
│ ├── Home.md
│ ├── Getting-Started.md
│ └── ...
│
├── pyproject.toml # Package configuration
├── README.md # Main README
├── LICENSE # MIT License
└── .gitignore # Git ignore rules
Follow PEP 8 with these specifics:
- Line length: 100 characters (Black default)
- Indentation: 4 spaces (no tabs)
- Imports: Grouped (standard library, third-party, local)
-
Naming:
- Functions/variables:
snake_case - Classes:
PascalCase - Constants:
UPPER_CASE
- Functions/variables:
Example:
"""Module docstring explaining purpose.""" import math from typing import List, Tuple import numpy as np from dvoacap.path_geometry import GeoPoint class PredictionEngine: """Class docstring explaining the class.""" MAX_FREQUENCY = 30.0 # Constant def __init__(self, location: GeoPoint): """Initialize prediction engine.""" self.location = location self._cache = {} # Private attribute def predict(self, frequencies: List[float]) -> np.ndarray: """ Run propagation prediction. Args: frequencies: List of frequencies in MHz Returns: Array of predictions """ # Implementation pass
Use NumPy/Google style docstrings:
def calculate_muf(foF2: float, hop_count: int, elevation: float) -> float: """ Calculate Maximum Usable Frequency. Args: foF2: F2 layer critical frequency in MHz hop_count: Number of hops (1-4) elevation: Elevation angle in radians Returns: MUF in MHz Raises: ValueError: If hop_count < 1 Example: >>> calculate_muf(foF2=8.5, hop_count=2, elevation=0.1) 15.2 """ if hop_count < 1: raise ValueError("hop_count must be >= 1") # Implementation return foF2 * 3.14 / math.sin(elevation)
Use type hints for function signatures:
from typing import List, Tuple, Optional import numpy as np def process_frequencies( frequencies: List[float], ssn: float, month: int ) -> Tuple[np.ndarray, Optional[str]]: """Process frequencies and return results.""" # Implementation pass
Test file structure:
# tests/test_my_module.py import pytest import numpy as np from dvoacap.my_module import MyClass class TestMyClass: """Tests for MyClass""" def test_basic_functionality(self): """Test basic usage""" obj = MyClass() result = obj.method(42) assert result == 84 def test_edge_case(self): """Test edge case""" obj = MyClass() with pytest.raises(ValueError): obj.method(-1) @pytest.mark.parametrize("input,expected", [ (1, 2), (2, 4), (3, 6), ]) def test_multiple_values(self, input, expected): """Test multiple input values""" obj = MyClass() assert obj.method(input) == expected
Run tests:
# All tests pytest # Specific module tests pytest tests/test_path_geometry.py # With coverage pytest --cov=dvoacap --cov-report=term-missing
Run VOACAP reference validation:
# Full validation suite python3 test_voacap_reference.py # Specific phase validation pytest tests/test_ionospheric.py -v
See Testing Guide for detailed testing instructions.
Install Sphinx dependencies:
pip install -e ".[docs]"Build HTML documentation:
Linux/macOS:
cd docs
make htmlWindows:
cd docs .\make.bat html # Or use PowerShell script .\make.ps1 html # Or direct sphinx-build sphinx-build -M html source build
View documentation:
# Open in browser open docs/build/html/index.html # macOS xdg-open docs/build/html/index.html # Linux start docs/build/html/index.html # Windows
Wiki pages are in the /wiki directory:
# Edit a wiki page vi wiki/Development-Setup.md # Add new page vi wiki/New-Page.md # Commit and push git add wiki/ git commit -m "Update wiki documentation" git push origin main
Main branches:
-
main- Stable releases - Feature branches - Development work
Create feature branch:
# Update main git checkout main git pull upstream main # Create feature branch git checkout -b feature/my-feature # Work on your changes # ... # Commit regularly git add . git commit -m "Add feature description"
1. Make changes:
# Edit files vi src/dvoacap/my_module.py # Format code black src/dvoacap/my_module.py # Run tests pytest tests/test_my_module.py
2. Commit changes:
# Stage changes git add src/dvoacap/my_module.py tests/test_my_module.py # Commit with clear message git commit -m "Add new feature: detailed description"
3. Push to your fork:
git push origin feature/my-feature
4. Create Pull Request:
- Visit your fork on GitHub
- Click "New Pull Request"
- Fill in description
- Submit for review
# Fetch upstream changes git fetch upstream # Update main git checkout main git merge upstream/main # Rebase feature branch (if needed) git checkout feature/my-feature git rebase main # Resolve any conflicts, then: git push --force-with-lease origin feature/my-feature
Complete workflow for adding a new feature:
# 1. Set up environment git clone https://github.com/YOUR_USERNAME/dvoacap-python.git cd dvoacap-python python3 -m venv venv source venv/bin/activate pip install -e ".[all]" # 2. Create feature branch git checkout -b feature/add-new-feature # 3. Make changes # Edit source files vi src/dvoacap/new_module.py # 4. Write tests vi tests/test_new_module.py # 5. Format and lint black src/ tests/ flake8 src/ tests/ # 6. Run tests pytest tests/test_new_module.py -v # 7. Update documentation vi docs/source/api/new_module.rst # 8. Commit changes git add src/dvoacap/new_module.py tests/test_new_module.py docs/ git commit -m "Add new module for feature X" # 9. Push and create PR git push origin feature/add-new-feature # Create pull request on GitHub
- Contributing Guide - Contribution guidelines
- Testing Guide - Detailed testing instructions
- API Reference - Code documentation
- Architecture - Project architecture overview
Solution:
# Ensure installed in editable mode pip install -e .
Solution:
# Install dev dependencies pip install -e ".[dev]"
Solution:
# Use Black's configuration
black --line-length=100 src/Solution:
# Ensure virtual environment is activated source venv/bin/activate # Reinstall package pip install -e .
Ready to contribute? Check out the Contributing Guide for detailed contribution guidelines!