| name | developing-experiment-code |
| description | Developing Python experiment code with incremental validation, proper error handling, and project structure. Use when writing Python modules, creating experiment infrastructure, or setting up project scaffolding. Triggers on "create module", "write Python", "setup project", "implement feature". |
Developing Experiment Code
Best practices for Python experiment development.
When to Use
- Creating new Python modules or scripts
- Setting up project structure
- Writing experiment infrastructure
Progress Checklist (Per File)
[ ] 1. Create file with imports
[ ] 2. Add core data structures/classes
[ ] 3. Run validation: uv run python -c "from module import X"
[ ] 4. Add functions
[ ] 5. Run validation again
[ ] 6. Add main/script logic if needed
[ ] 7. Full test run
Core Rules
YOU MUST:
- Validate imports after creating EVERY file
- Write <100 lines before testing
- Use pathlib for all file operations
- Create directories before writing files
YOU MUST NOT:
- Write entire modules without testing
- Use string paths instead of Path objects
- Assume directories exist
File Creation Order
1. pyproject.toml → uv sync
2. core/config.py → test imports
3. core/models.py → test imports
4. core/factory.py → test imports
5. runners/main.py → test imports
6. scripts/run.py → test full execution
Validation Commands
After each file:
uv run python -c "from package.module import Thing; print('OK')"
uv run python -c "from package.module import Thing; t = Thing(); print(t)"
Patterns
Safe File I/O
from pathlib import Path
def save_json(data, path: Path):
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(data, indent=2, default=str))
Error Handling
def process_items(items):
results, errors = [], []
for item in items:
try:
results.append(process(item))
except Exception as e:
errors.append({"item": item, "error": str(e)})
return results, errors
Factory Pattern
def create_processor(name: str, **kwargs):
processors = {"fast": FastProc, "accurate": AccurateProc}
if name not in processors:
raise ValueError(f"Unknown: {name}. Available: {list(processors)}")
return processors[name](**kwargs)
References
- See
references/project_structure.md for directory layout
- See
references/common_patterns.md for more code patterns