1+ # dashboard_quiz.py
2+ import streamlit as st
3+ import polars as pl
4+
5+ # ========================================
6+ # CONFIGURAZIONE PAGINA
7+ # ========================================
8+ st .set_page_config (
9+ page_title = "Risultati Quiz Python" ,
10+ page_icon = "🎮" ,
11+ layout = "wide"
12+ )
13+
14+ # ========================================
15+ # TITOLO PRINCIPALE
16+ # ========================================
17+ st .title ("🎮 Dashboard Risultati Quiz Python" )
18+ st .write ("Analisi delle risposte degli studenti" )
19+
20+ # ========================================
21+ # CARICAMENTO DATI
22+ # ========================================
23+ # Carica i 3 CSV
24+ df_domande = pl .read_csv ("domande.csv" )
25+ df_risposte = pl .read_csv ("risposte.csv" )
26+ df_studenti = pl .read_csv ("risposte_tutti.csv" )
27+
28+ # ========================================
29+ # SEZIONE 1: STATISTICHE GENERALI
30+ # ========================================
31+ st .header ("📊 Statistiche Generali" )
32+
33+ # Calcola metriche base
34+ num_studenti = df_studenti .select ("nome_utente" ).unique ().height
35+ num_domande = df_domande .height
36+ totale_risposte = df_studenti .height
37+
38+ # Mostra le metriche in colonne
39+ col1 , col2 , col3 = st .columns (3 )
40+ with col1 :
41+ st .metric ("👥 Studenti partecipanti" , num_studenti )
42+ with col2 :
43+ st .metric ("❓ Domande totali" , num_domande )
44+ with col3 :
45+ st .metric ("✍️ Risposte date" , totale_risposte )
46+
47+ # ========================================
48+ # SEZIONE 2: ANALISI CORRETTEZZA
49+ # ========================================
50+ st .header ("✅ Analisi Correttezza Risposte" )
51+
52+ # Join per verificare le risposte corrette
53+ df_con_corrette = df_studenti .join (
54+ df_risposte ,
55+ on = "id_domanda" ,
56+ how = "left"
57+ )
58+
59+ # Aggiungi colonna che indica se la risposta è corretta
60+ df_con_corrette = df_con_corrette .with_columns (
61+ (pl .col ("numero_risposta_fornita" ) == pl .col ("numero_risposta_corretta" ))
62+ .alias ("corretta" )
63+ )
64+
65+ # Calcola percentuale risposte corrette
66+ risposte_corrette = df_con_corrette .filter (pl .col ("corretta" ) == True ).height
67+ percentuale_corrette = (risposte_corrette / totale_risposte * 100 ) if totale_risposte > 0 else 0
68+
69+ st .metric (
70+ "Percentuale risposte corrette" ,
71+ f"{ percentuale_corrette :.1f} %"
72+ )
73+
74+ # ========================================
75+ # SEZIONE 3: CLASSIFICA STUDENTI
76+ # ========================================
77+ st .header ("🏆 Classifica Studenti" )
78+
79+ # Calcola punteggio per studente
80+ classifica = (
81+ df_con_corrette
82+ .group_by ("nome_utente" )
83+ .agg ([
84+ pl .col ("corretta" ).sum ().alias ("risposte_corrette" ),
85+ pl .col ("id_domanda" ).count ().alias ("domande_risposte" ),
86+ pl .col ("tempo_risposta" ).mean ().alias ("tempo_medio" )
87+ ])
88+ .sort ("risposte_corrette" , descending = True )
89+ )
90+
91+ # Mostra la classifica
92+ st .dataframe (
93+ classifica ,
94+ width = 'stretch' ,
95+ hide_index = True
96+ )
97+
98+ # ========================================
99+ # SEZIONE 4: DIFFICOLTÀ DOMANDE
100+ # ========================================
101+ st .header ("📈 Difficoltà Domande" )
102+
103+ # Calcola percentuale di successo per domanda
104+ difficolta = (
105+ df_con_corrette
106+ .group_by ("id_domanda" )
107+ .agg ([
108+ pl .col ("corretta" ).sum ().alias ("risposte_corrette" ),
109+ pl .col ("corretta" ).count ().alias ("totale_risposte" )
110+ ])
111+ .with_columns (
112+ (pl .col ("risposte_corrette" ) / pl .col ("totale_risposte" ) * 100 )
113+ .alias ("percentuale_corrette" )
114+ )
115+ .sort ("percentuale_corrette" )
116+ )
117+
118+ # Join con il testo delle domande
119+ difficolta = difficolta .join (
120+ df_domande .select (["id_domanda" , "domanda" ]),
121+ on = "id_domanda" ,
122+ how = "left"
123+ )
124+
125+ # Mostra tabella difficoltà
126+ st .dataframe (
127+ difficolta .select (["id_domanda" , "domanda" , "percentuale_corrette" ]),
128+ width = 'stretch' ,
129+ hide_index = True
130+ )
131+
132+ # ========================================
133+ # SEZIONE 5: GRAFICO A BARRE
134+ # ========================================
135+ st .header ("📊 Grafico Prestazioni" )
136+
137+ # Prepara dati per il grafico
138+ dati_grafico = classifica .select (["nome_utente" , "risposte_corrette" ])
139+
140+ # Crea grafico a barre
141+ st .bar_chart (
142+ dati_grafico ,
143+ x = "nome_utente" ,
144+ y = "risposte_corrette" ,
145+ width = 'stretch'
146+ )
147+
148+ # ========================================
149+ # SEZIONE 6: TEMPO MEDIO DI RISPOSTA
150+ # ========================================
151+ st .header ("⏱️ Tempo Medio di Risposta" )
152+
153+ tempo_medio_globale = df_studenti .select (pl .col ("tempo_risposta" ).mean ())[0 , 0 ]
154+ st .metric ("Tempo medio per risposta" , f"{ tempo_medio_globale :.0f} ms" )
155+
156+ # Grafico tempo per domanda
157+ tempo_per_domanda = (
158+ df_studenti
159+ .group_by ("id_domanda" )
160+ .agg (pl .col ("tempo_risposta" ).mean ().alias ("tempo_medio" ))
161+ .sort ("id_domanda" )
162+ )
163+
164+ st .bar_chart (
165+ tempo_per_domanda ,
166+ x = "id_domanda" ,
167+ y = "tempo_medio" ,
168+ width = 'stretch'
169+ )
0 commit comments