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/analysis/right_wing/migrate_mp_level_metrics.py

89 lines
2.5 KiB

"""Add MP-weighted centrist_support column to right_wing_motions.
The existing centrist_support is party-bloc-level (fraction of centrist
parties where >=50% of MPs voted voor). This adds centrist_support_mp which
is the fraction of individual centrist MPs who voted voor, weighted by party
size.
"""
import duckdb
from pathlib import Path
CANONICAL_CENTRIST = frozenset({"VVD", "D66", "CDA", "NSC", "BBB", "CU"})
def compute_mp_support(
votes: dict[str, dict[str, int]], parties: frozenset[str]
) -> float | None:
total_voor = 0
total_cast = 0
for party, pv in votes.items():
if party not in parties:
continue
voor = pv.get("voor", 0)
tegen = pv.get("tegen", 0)
tv = voor + tegen
if tv == 0:
continue
total_voor += voor
total_cast += tv
if total_cast == 0:
return None
return total_voor / total_cast
def main(db_path: str = "data/motions.db"):
db = Path(db_path)
con = duckdb.connect(str(db))
votemap: dict[int, dict[str, dict[str, int]]] = {}
vote_rows = con.execute(
"""
SELECT motion_id, party, vote, COUNT(*) as n
FROM mp_votes
WHERE party IS NOT NULL
GROUP BY motion_id, party, vote
"""
).fetchall()
for motion_id, party, vote, n in vote_rows:
mv = votemap.setdefault(motion_id, {})
pv = mv.setdefault(party, {"voor": 0, "tegen": 0, "afwezig": 0})
pv[vote] = pv.get(vote, 0) + n
# Add column
col_check = con.execute(
"SELECT column_name FROM information_schema.columns "
"WHERE table_name = 'right_wing_motions' AND column_name = 'centrist_support_mp'"
).fetchone()
if col_check is None:
con.execute(
"ALTER TABLE right_wing_motions ADD COLUMN centrist_support_mp DOUBLE"
)
print("Added centrist_support_mp column")
# Update rows
rows = con.execute(
"SELECT motion_id FROM right_wing_motions"
).fetchall()
updated = 0
skipped = 0
for (motion_id,) in rows:
votes = votemap.get(motion_id)
if votes is None:
skipped += 1
continue
cs_mp = compute_mp_support(votes, CANONICAL_CENTRIST)
con.execute(
"UPDATE right_wing_motions SET centrist_support_mp = ? WHERE motion_id = ?",
[cs_mp, motion_id],
)
updated += 1
con.close()
print(f"Updated {updated} rows, skipped {skipped}")
if __name__ == "__main__":
main()