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.
89 lines
2.5 KiB
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()
|
|
|