You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
motief/.mindmodel/anti-patterns/anti-patterns.md

127 lines
3.2 KiB

---
title: Anti-Patterns in Stemwijzer
category: anti-patterns
severity: critical
---
# Anti-Patterns
> **NOTE**: Some anti-patterns below were investigated and found to be resolved or invalid. See individual entries for details.
## CRITICAL: print() Instead of Logging
**File**: `api_client.py`
**Evidence**: 11 instances of `print(f"...")` instead of `_logger.info(...)`
**Broken code**:
```python
def get_motions(self, ...):
try:
# ...
print(f"Fetched {len(voting_records)} voting records from API") # BAD
print(f"Processed into {len(motions)} unique motions") # BAD
except Exception as e:
print(f"Error fetching motions from API: {e}") # BAD - no traceback
```
**Fix**:
```python
import logging
_logger = logging.getLogger(__name__)
def get_motions(self, ...):
try:
_logger.info("Fetched %d voting records from API", len(voting_records))
_logger.info("Processed into %d unique motions", len(motions))
except Exception as e:
_logger.exception("Error fetching motions from API: %s", e)
return []
```
---
## CRITICAL: Global `_DummySt` Replacement
**File**: `explorer.py`
**Evidence**: Lines ~50-70, module-level `st = _DummySt()` global replacement
**Problem**: Creates a module-level variable `st` that shadows `streamlit` module, causing subtle bugs.
**Fix**: Use conditional flags instead of global replacement:
```python
# GOOD: Use conditional logic
try:
import plotly.express as px
import plotly.graph_objects as go
HAS_PLOTLY = True
except ImportError:
HAS_PLOTLY = False
px = None
go = None
def render_chart(data):
if not HAS_PLOTLY:
_logger.warning("Plotly not available")
return
# ... rest of chart logic
```
---
## WARNING: Logger Naming Inconsistency
**Evidence**: 16 files use `logger`, 17 files use `_logger`
**Files with `logger`** (without underscore):
- api_client.py, ai_provider.py, pipeline files, analysis files
**Files with `_logger`** (with underscore):
- database.py, explorer.py, explorer_helpers.py
**Recommendation**: Standardize on `_logger` for module-level loggers.
---
## WARNING: Bare except with pass
**File**: `database.py`, line 47
```python
# BAD - catches KeyboardInterrupt, SystemExit, MemoryError
try:
conn.execute("CREATE SEQUENCE IF NOT EXISTS motions_id_seq START 1")
except: # bare except
pass
```
**Fix**:
```python
try:
conn.execute("CREATE SEQUENCE IF NOT EXISTS motions_id_seq START 1")
except Exception as exc:
_logger.debug("Sequence creation skipped: %s", exc)
```
---
## INVESTIGATED: Entity-ID / Party-Name Mismatch
**Status**: INVALID - investigated and resolved
**Investigation Summary**: `svd_vectors.entity_id` only contains MP names (not party names). Party centroids are correctly computed via `mp_metadata` lookups. No production bug exists.
---
## Pattern: Three Separate Party Alias Dictionaries
**Problem**: Party name variations exist in 3+ places with no canonical alias mapping.
**Fix**: Create one `PARTY_ALIASES` dict in `config.py`:
```python
PARTY_ALIASES = {
"GroenLinks-PvdA": ["GL-PvdA", "GroenLinks PvdA", "PvdA-GroenLinks"],
"PVV": ["Partij voor de Vrijheid"],
# ...
}
```