Skip to content

Commit 5bb9885

Browse files
authored
Merge pull request #32 from bernalde/cleanup-and-docs
Update Python version requirements and enhance local CI testing
2 parents b0139dd + 5faa76d commit 5bb9885

36 files changed

Lines changed: 5572 additions & 1575 deletions
Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
# Naming Convention Refactor for v2.0
2+
3+
## Overview
4+
5+
The current codebase uses non-standard naming conventions that violate PEP 8 guidelines. This document outlines a plan to refactor the naming conventions in a future major version (v2.0) to align with Python best practices.
6+
7+
## Current State
8+
9+
### PEP 8 Violations
10+
11+
The codebase currently uses **PascalCase for method names** instead of the recommended **snake_case**:
12+
13+
**Examples:**
14+
- `initAll()` → should be `init_all()`
15+
- `run_Bootstrap()` → should be `run_bootstrap()`
16+
- `run_Interpolate()` → should be `run_interpolate()`
17+
- `run_Stats()` → should be `run_stats()`
18+
- `StatsSingle()` → should be `stats_single()` (function, not class)
19+
- `get_TrainingResults_recipe()` → should be `get_training_results_recipe()`
20+
- `get_TrainingStats_recipe()` → should be `get_training_stats_recipe()`
21+
22+
### Why This Exists
23+
24+
This appears to be a deliberate design choice made early in the project. The naming convention is:
25+
- Consistent throughout the codebase
26+
- Used in all examples and documentation
27+
- Part of the public API
28+
- Not a bug, just a stylistic deviation from PEP 8
29+
30+
## Why Change It?
31+
32+
### Benefits
33+
34+
1. **PEP 8 Compliance**: Aligns with Python community standards
35+
2. **Better Tooling**: Many linters/formatters expect snake_case for methods
36+
3. **Consistency**: Matches Python standard library conventions
37+
4. **Readability**: snake_case is more readable for longer method names
38+
5. **Professional**: Shows adherence to Python best practices
39+
40+
### Costs
41+
42+
1. **Breaking Change**: Existing code using the library will break
43+
2. **Documentation Update**: All examples, tutorials, and docs need updating
44+
3. **Migration Effort**: Users need to update their code
45+
4. **Testing**: Extensive testing needed to ensure nothing breaks
46+
47+
## Refactor Plan
48+
49+
### Phase 1: Inventory (v1.x)
50+
51+
- [ ] Create comprehensive list of all public API methods with non-standard naming
52+
- [ ] Categorize by module (stochastic_benchmark, bootstrap, stats, etc.)
53+
- [ ] Identify which methods are most commonly used (check examples)
54+
- [ ] Document current usage patterns
55+
56+
### Phase 2: Deprecation Period (v1.x → v2.0)
57+
58+
**Option A: Dual API (Recommended)**
59+
```python
60+
# Add new snake_case methods alongside old PascalCase ones
61+
def init_all(self, ...):
62+
"""New naming convention."""
63+
# implementation
64+
65+
def initAll(self, ...):
66+
"""Deprecated: Use init_all() instead."""
67+
warnings.warn(
68+
"initAll() is deprecated and will be removed in v2.0. "
69+
"Use init_all() instead.",
70+
DeprecationWarning,
71+
stacklevel=2
72+
)
73+
return self.init_all(...)
74+
```
75+
76+
**Timeline:**
77+
- v1.x: Add new methods, deprecate old ones with warnings
78+
- v1.x+1: Update all examples to use new naming
79+
- v1.x+2: Update documentation to recommend new naming
80+
- v2.0: Remove deprecated methods (breaking change)
81+
82+
**Option B: Direct Migration (Faster but riskier)**
83+
- v2.0: Rename all methods, publish migration guide
84+
- Provide automated migration script
85+
86+
### Phase 3: Implementation (v2.0)
87+
88+
#### Core Methods to Rename
89+
90+
**stochastic_benchmark.py:**
91+
```python
92+
# Current → New
93+
initAll() → init_all()
94+
run_Bootstrap() → run_bootstrap()
95+
run_Interpolate() → run_interpolate()
96+
run_Stats() → run_stats()
97+
get_TrainingResults_recipe() → get_training_results_recipe()
98+
get_TrainingStats_recipe() → get_training_stats_recipe()
99+
```
100+
101+
**Other modules:**
102+
```python
103+
# bootstrap.py
104+
Bootstrap() → bootstrap()
105+
BootstrapSingle() → bootstrap_single()
106+
Bootstrap_reduce_mem() → bootstrap_reduce_mem()
107+
108+
# stats.py
109+
Stats() → stats()
110+
StatsSingle() → stats_single()
111+
112+
# interpolate.py
113+
Interpolate() → interpolate()
114+
Interpolate_reduce_mem() → interpolate_reduce_mem()
115+
```
116+
117+
#### Files to Update
118+
119+
1. **Source Code:**
120+
- [ ] `src/stochastic_benchmark.py`
121+
- [ ] `src/bootstrap.py`
122+
- [ ] `src/stats.py`
123+
- [ ] `src/interpolate.py`
124+
- [ ] `src/training.py`
125+
- [ ] `src/random_exploration.py`
126+
- [ ] `src/sequential_exploration.py`
127+
- [ ] Other modules as needed
128+
129+
2. **Tests:**
130+
- [ ] `tests/test_bootstrap.py`
131+
- [ ] `tests/test_stats.py`
132+
- [ ] `tests/test_stochastic_benchmark.py` (if exists)
133+
- [ ] All integration tests
134+
- [ ] All other test files
135+
136+
3. **Examples:**
137+
- [ ] `examples/QAOA_iterative/`
138+
- [ ] `examples/QAOA_multipleSplits/`
139+
- [ ] `examples/wishart_n_50_alpha_0.5/`
140+
- [ ] Any other example directories
141+
142+
4. **Documentation:**
143+
- [ ] `README.md`
144+
- [ ] `TESTING.md`
145+
- [ ] API documentation
146+
- [ ] Tutorial notebooks
147+
- [ ] Inline code comments
148+
149+
### Phase 4: Migration Support
150+
151+
#### Provide Migration Tools
152+
153+
**Option 1: Automated Script**
154+
```python
155+
# migrate_naming.py
156+
"""
157+
Script to automatically update code from v1.x to v2.0 naming conventions.
158+
159+
Usage:
160+
python migrate_naming.py path/to/your/code
161+
"""
162+
163+
import re
164+
import sys
165+
from pathlib import Path
166+
167+
REPLACEMENTS = {
168+
r'\.initAll\(': '.init_all(',
169+
r'\.run_Bootstrap\(': '.run_bootstrap(',
170+
r'\.run_Interpolate\(': '.run_interpolate(',
171+
r'\.run_Stats\(': '.run_stats(',
172+
# Add all other replacements
173+
}
174+
175+
def migrate_file(filepath):
176+
"""Update a single file to v2.0 naming."""
177+
with open(filepath, 'r') as f:
178+
content = f.read()
179+
180+
original = content
181+
for old, new in REPLACEMENTS.items():
182+
content = re.sub(old, new, content)
183+
184+
if content != original:
185+
with open(filepath, 'w') as f:
186+
f.write(content)
187+
return True
188+
return False
189+
190+
# Implementation continues...
191+
```
192+
193+
**Option 2: Migration Guide**
194+
Create a comprehensive guide in `MIGRATION_v1_to_v2.md`:
195+
```markdown
196+
# Migration Guide: v1.x to v2.0
197+
198+
## Breaking Changes
199+
200+
### Method Naming
201+
202+
All public API methods now use snake_case instead of PascalCase.
203+
204+
| Old (v1.x) | New (v2.0) |
205+
|------------|------------|
206+
| `sb.initAll()` | `sb.init_all()` |
207+
| `sb.run_Bootstrap()` | `sb.run_bootstrap()` |
208+
| ... | ... |
209+
210+
## Quick Migration Steps
211+
212+
1. Find and replace in your codebase
213+
2. Run tests
214+
3. Update any custom extensions
215+
```
216+
217+
### Phase 5: Release Strategy
218+
219+
**v1.x (Current):**
220+
- Continue bug fixes and critical updates
221+
- No new features with old naming
222+
- Document deprecation plan
223+
224+
**v1.x+1 (Deprecation Start):**
225+
- Add all new snake_case methods
226+
- Old methods remain but emit DeprecationWarning
227+
- Update all examples to use new naming
228+
- Release migration guide
229+
230+
**v1.x+2 (Final Warning):**
231+
- Increase warning visibility
232+
- Update all documentation
233+
- Provide automated migration script
234+
- Set firm v2.0 release date
235+
236+
**v2.0 (Breaking Release):**
237+
- Remove all deprecated methods
238+
- Only snake_case API available
239+
- Clean, PEP 8 compliant codebase
240+
241+
## Success Criteria
242+
243+
- [ ] All public methods use snake_case
244+
- [ ] All tests pass with new naming
245+
- [ ] All examples updated and working
246+
- [ ] Documentation completely updated
247+
- [ ] Migration guide published
248+
- [ ] Migration script tested on example codebases
249+
- [ ] No reduction in test coverage
250+
- [ ] User feedback incorporated
251+
252+
## Timeline Estimate
253+
254+
- **Phase 1 (Inventory)**: 1-2 weeks
255+
- **Phase 2 (Deprecation)**: 3-6 months across multiple releases
256+
- **Phase 3 (Implementation)**: 2-3 weeks
257+
- **Phase 4 (Migration Support)**: 2 weeks
258+
- **Phase 5 (Release)**: Following standard release cycle
259+
260+
**Total**: ~6-9 months from start to v2.0 release
261+
262+
## Risks and Mitigations
263+
264+
### Risk: Breaking User Code
265+
**Mitigation**: Long deprecation period with clear warnings
266+
267+
### Risk: Incomplete Migration
268+
**Mitigation**: Automated testing, comprehensive checklists
269+
270+
### Risk: Documentation Drift
271+
**Mitigation**: Update docs simultaneously with code
272+
273+
### Risk: User Confusion
274+
**Mitigation**: Clear communication, migration tools
275+
276+
## Alternative Approaches
277+
278+
### Keep Current Naming
279+
**Pros**: No breaking changes, existing code continues to work
280+
**Cons**: Continues to violate PEP 8, may confuse Python developers
281+
282+
### Gradual Module-by-Module
283+
**Pros**: Smaller, more manageable changes
284+
**Cons**: Inconsistent API during transition, longer timeline
285+
286+
### Aliases Forever
287+
**Pros**: Backward compatible
288+
**Cons**: Maintains technical debt, larger codebase
289+
290+
## Decision
291+
292+
**Recommended Approach**: Option A (Dual API with Deprecation Period)
293+
294+
This provides the best balance of:
295+
- User experience (time to adapt)
296+
- Code quality (eventual PEP 8 compliance)
297+
- Project maintainability (clean v2.0 codebase)
298+
299+
## Next Steps
300+
301+
1. Get stakeholder buy-in on this plan
302+
2. Create GitHub issue to track this work
303+
3. Begin Phase 1 (Inventory) when ready to start v2.0 planning
304+
4. Communicate plan to users via:
305+
- GitHub issue/discussion
306+
- Release notes
307+
- Documentation
308+
- Email/blog if applicable
309+
310+
## References
311+
312+
- [PEP 8 - Style Guide for Python Code](https://peps.python.org/pep-0008/)
313+
- [PEP 8 - Naming Conventions](https://peps.python.org/pep-0008/#naming-conventions)
314+
- [Semantic Versioning](https://semver.org/)
315+
316+
---
317+
318+
**Status**: Proposed
319+
**Created**: 2025-10-21
320+
**Author**: GitHub Copilot
321+
**Version**: Draft 1.0

.github/copilot-instructions.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ stochastic-benchmark/
4949
## Code Standards and Guidelines
5050

5151
### Python Version Compatibility
52-
- **Minimum Python version**: 3.9
53-
- **Tested versions**: 3.9, 3.10, 3.11, 3.12
54-
- **Type hints**: Use `from typing import List, Dict, DefaultDict, ...` for compatibility
55-
- **Avoid**: Modern syntax like `list[str]` or `dict[str, int]` (use `List[str]`, `Dict[str, int]`)
52+
- **Minimum Python version**: 3.10
53+
- **Tested versions**: 3.10, 3.11, 3.12
54+
- **Type hints**: Use `from typing import List, Dict, DefaultDict, ...` for compatibility with older versions
55+
- **Note**: You can use modern syntax like `list[str]` or `dict[str, int]` as Python 3.10+ supports it, but `List[str]`, `Dict[str, int]` is also acceptable
5656

5757
### Code Quality Standards
5858
- **Linting**: Code is linted with flake8 (max line length: 120 characters)
@@ -181,7 +181,7 @@ def test_bootstrap_with_metrics(self, mock_evaluate):
181181
5. **Handle edge cases** and error conditions
182182
6. **Maintain backward compatibility** with existing APIs
183183
7. **Document complex algorithms** with clear comments
184-
8. **Test on multiple Python versions** (3.9-3.12)
184+
8. **Test on multiple Python versions** (3.10-3.12)
185185
9. **Keep functions focused** with single responsibilities
186186
10. **Use descriptive variable names** and function signatures
187187

.github/copilot-setup-steps.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Automated setup steps for GitHub Copilot development in stochastic-
55

66
setup_steps:
77
environment:
8-
python_version: "3.9+"
8+
python_version: "3.10+"
99
required_packages:
1010
core:
1111
- pandas
@@ -49,7 +49,7 @@ setup_steps:
4949
- "pytest tests/ -v --cov=src" # Run with coverage
5050

5151
3_development:
52-
- "Follow type annotation standards (Python 3.9+)"
52+
- "Follow type annotation standards (Python 3.10+)"
5353
- "Write tests before implementing features"
5454
- "Use proper mocking for multiprocessing and external dependencies"
5555
- "Maintain docstring standards (NumPy style)"
@@ -165,8 +165,8 @@ setup_steps:
165165

166166
type_annotation_errors:
167167
- "Import required types from typing module"
168-
- "Use Python 3.9+ compatible syntax"
169-
- "Avoid using built-in generics (list[str] -> List[str])"
168+
- "Use Python 3.10+ compatible syntax"
169+
- "Can use built-in generics (list[str]) or typing module (List[str])"
170170

171171
multiprocessing_issues:
172172
- "Mock Pool at correct module level"
@@ -180,7 +180,7 @@ setup_steps:
180180
- "pull requests to main/develop"
181181

182182
test_matrix:
183-
python_versions: ["3.9", "3.10", "3.11", "3.12"]
183+
python_versions: ["3.10", "3.11", "3.12"]
184184
operating_systems: ["ubuntu-latest"]
185185

186186
required_checks:

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,9 @@ notebooks/example_data/wishart*
155155
notebooks/example_data/max_clique*
156156
notebooks/example_data/sk_pleiades_n=200/*
157157
notebooks/example_data/sk_pleiades_n=100/checkpoints/*.DS_Store
158+
159+
# Example checkpoints and large generated files
160+
examples/**/checkpoints/*.pkl
161+
examples/**/checkpoints/**/*.pkl
162+
examples/**/*.pkl
163+
!examples/**/*demo*.pkl

0 commit comments

Comments
 (0)