@ -731,21 +731,20 @@ def build_mp_quiz_tab(db_path: str) -> None:
if " mp_quiz_asked " not in st . session_state :
st . session_state [ " mp_quiz_asked " ] = [ ]
from database import MotionDatabase as _MotionDatabase
db_inst = _MotionDatabase ( db_path )
df = load_motions_df ( db_path )
if df . empty :
st . warning ( " Geen moties beschikbaar om de quiz te starten. " )
return
# seed motions by controversy_score, prefer those with layman_explanation
candidates_df = df [ df [ " layman_explanation " ] . notna ( ) ]
if candidates_df . empty :
candidates_df = df
seed = (
candidates_df . sort_values ( by = " controversy_score " , ascending = False )
. head ( SEED_MOTIONS )
. copy ( )
)
seed_ids = [ int ( x ) for x in seed [ " id " ] . tolist ( ) ]
# seed from motions that actually have individual MP vote records
seed_ids = db_inst . get_motions_with_individual_votes ( k = SEED_MOTIONS )
if not seed_ids :
st . warning ( " Geen individuele stemdata beschikbaar voor de quiz. " )
return
# Determine next motion to ask
def _next_motion_id ( ) :
@ -755,13 +754,12 @@ def build_mp_quiz_tab(db_path: str) -> None:
return mid
# otherwise ask discriminating motion based on remaining candidate MPs
# compute current candidate set
from database import db as global_db
try :
user_votes = {
int ( k ) : v for k , v in st . session_state [ " mp_quiz_votes " ] . items ( )
}
ranked = global_ db. match_mps_for_votes ( user_votes , limit = 200 )
ranked = db_inst . match_mps_for_votes ( user_votes , limit = 200 )
except Exception :
ranked = [ ]
@ -770,9 +768,7 @@ def build_mp_quiz_tab(db_path: str) -> None:
if not candidates :
return None
try :
next_ids = global_db . choose_discriminating_motions (
candidates , excluded , k = 1
)
next_ids = db_inst . choose_discriminating_motions ( candidates , excluded , k = 1 )
return next_ids [ 0 ] if next_ids else None
except Exception :
return None
@ -786,14 +782,20 @@ def build_mp_quiz_tab(db_path: str) -> None:
if st . button ( " Reset quiz " ) :
st . session_state [ " mp_quiz_votes " ] = { }
st . session_state [ " mp_quiz_asked " ] = [ ]
st . experimental_ rerun( )
st . rerun ( )
# main question loop (single question per render)
next_mid = _next_motion_id ( )
if next_mid is None :
st . info ( " Geen nieuwe vragen beschikbaar om kandidaten te scheiden. " )
else :
motion_row = df [ df [ " id " ] == next_mid ] . iloc [ 0 ]
motion_rows = df [ df [ " id " ] == next_mid ]
if motion_rows . empty :
# motion has votes but isn't in the motions DataFrame — skip it
st . session_state [ " mp_quiz_votes " ] [ str ( next_mid ) ] = " Geen stem "
st . rerun ( )
return
motion_row = motion_rows . iloc [ 0 ]
st . markdown ( f " ### { motion_row . get ( ' title ' ) or f ' Motie # { next_mid } ' } " )
if motion_row . get ( " layman_explanation " ) :
st . info ( motion_row . get ( " layman_explanation " ) )
@ -808,14 +810,12 @@ def build_mp_quiz_tab(db_path: str) -> None:
if st . button ( " Beantwoord en verder " , key = f " mp_quiz_submit_ { next_mid } " ) :
st . session_state [ " mp_quiz_votes " ] [ str ( next_mid ) ] = choice
st . session_state [ " mp_quiz_asked " ] . append ( next_mid )
st . experimental_ rerun( )
st . rerun ( )
# display current ranking
from database import db as global_db
try :
user_votes = { int ( k ) : v for k , v in st . session_state [ " mp_quiz_votes " ] . items ( ) }
ranking = global_ db. match_mps_for_votes ( user_votes , limit = 50 )
ranking = db_inst . match_mps_for_votes ( user_votes , limit = 50 )
except Exception :
ranking = [ ]
@ -901,9 +901,9 @@ def run_app() -> None:
build_search_tab ( db_path , show_rejected )
with tab4 :
build_browser_tab ( db_path , show_rejected )
with tab6 :
build_mp_quiz_tab ( db_path )
with tab5 :
build_mp_quiz_tab ( db_path )
with tab6 :
build_svd_components_tab ( db_path )
else :
# Fallback for environments where `st.tabs` is not available: use a radio selector