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

3.2 KiB

title category severity
Anti-Patterns in Stemwijzer anti-patterns 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:

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:

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:

# 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

# BAD - catches KeyboardInterrupt, SystemExit, MemoryError
try:
    conn.execute("CREATE SEQUENCE IF NOT EXISTS motions_id_seq START 1")
except:  # bare except
    pass

Fix:

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:

PARTY_ALIASES = {
    "GroenLinks-PvdA": ["GL-PvdA", "GroenLinks PvdA", "PvdA-GroenLinks"],
    "PVV": ["Partij voor de Vrijheid"],
    # ...
}