|
|
# Tech Stack
|
|
|
|
|
|
## Runtime & Language
|
|
|
- **Python ≥3.13** (type: runtime)
|
|
|
- Streamlit (type: web framework) - multi-page app: Home, Stemwijzer, Explorer (4 tabs)
|
|
|
|
|
|
## Data Layer
|
|
|
- **DuckDB** (type: database) - 9 tables: motions, mp_votes, svd_vectors, mp_party_history, etc.
|
|
|
- **ibis** (type: ORM) - DuckDB backend for Pythonic SQL
|
|
|
- Query mode: duckdb:// path or :memory: (see database.py:50-51)
|
|
|
|
|
|
## ML / Analytics
|
|
|
- **scikit-learn** (type: ML) - clustering, Procrustes alignment
|
|
|
- **UMAP** (type: dimensionality reduction) - 2D political compass projection
|
|
|
- **scipy** (type: scientific computing) - spatial/alignment algorithms
|
|
|
- **numpy** (type: numerical computing) - array operations
|
|
|
|
|
|
## Visualization
|
|
|
- **Plotly** (type: charting) - dual-layer interactive charts (scatter + annotations)
|
|
|
|
|
|
## Key Source Files
|
|
|
| File | Purpose |
|
|
|
|------|---------|
|
|
|
| `database.py` | MotionDatabase singleton, DuckDB connection, 9-table schema |
|
|
|
| `explorer.py` | Explorer page with 4 tabs (Motion, MP, Party, Evolution) |
|
|
|
| `explorer_helpers.py` | Pure helper functions, Plotly chart builders, coordinate computation |
|
|
|
| `analysis/` | SVD pipeline, UMAP projection, clustering algorithms |
|
|
|
| `pipeline/` | Data fetch → transform → store pipeline |
|
|
|
| `pages/1_🗳️_Stemwijzer.py` | Quiz page (thin wrapper) |
|
|
|
| `pages/2_🔍_Explorer.py` | Explorer page (thin wrapper) |
|
|
|
| `config.py` | Dataclass Config pattern |
|
|
|
|
|
|
## Database Tables
|
|
|
- `motions` - parliamentary motions with id, title, date, category
|
|
|
- `mp_votes` - individual MP votes on motions (1/0/-1)
|
|
|
- `svd_vectors` - SVD-computed political positions (entity_id, window, vector_2d)
|
|
|
- `mp_party_history` - MP-to-party mappings over time
|
|
|
- `party_centroids` - aggregated party positions
|
|
|
- `windows` - time period definitions
|
|
|
- `mp_trajectories` - MP position changes across windows
|
|
|
- Plus 2 additional tables (exact names vary)
|
|
|
|