Skip to content

Commit 39e7308

Browse files
committed
dashboard refinement
1 parent 7b67d4d commit 39e7308

File tree

1 file changed

+127
-84
lines changed

1 file changed

+127
-84
lines changed

game13/dashboard_quiz.py

Lines changed: 127 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -20,63 +20,23 @@
2020
# ========================================
2121
# CARICAMENTO DATI
2222
# ========================================
23-
# Carica i 3 CSV
2423
df_domande = pl.read_csv("domande.csv")
2524
df_risposte = pl.read_csv("risposte.csv")
2625
df_studenti = pl.read_csv("risposte_tutti.csv")
2726

2827
# ========================================
29-
# SEZIONE 1: STATISTICHE GENERALI
28+
# JOIN E CALCOLO CORRETTEZZA
3029
# ========================================
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
5330
df_con_corrette = df_studenti.join(
5431
df_risposte,
5532
on="id_domanda",
5633
how="left"
57-
)
58-
59-
# Aggiungi colonna che indica se la risposta è corretta
60-
df_con_corrette = df_con_corrette.with_columns(
34+
).with_columns(
6135
(pl.col("numero_risposta_fornita") == pl.col("numero_risposta_corretta"))
6236
.alias("corretta")
6337
)
6438

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
39+
# Classifica studenti
8040
classifica = (
8141
df_con_corrette
8242
.group_by("nome_utente")
@@ -85,22 +45,31 @@
8545
pl.col("id_domanda").count().alias("domande_risposte"),
8646
pl.col("tempo_risposta").mean().alias("tempo_medio")
8747
])
88-
.sort("risposte_corrette", descending=True)
89-
)
90-
91-
# Mostra la classifica
92-
st.dataframe(
93-
classifica,
94-
width='stretch',
95-
hide_index=True
48+
.with_columns(
49+
(pl.col("risposte_corrette") / pl.col("domande_risposte") * 100)
50+
.round(1)
51+
.alias("percentuale_corrette")
52+
)
53+
.sort(["risposte_corrette", "tempo_medio"], descending=[True, False])
9654
)
9755

9856
# ========================================
99-
# SEZIONE 4: DIFFICOLTÀ DOMANDE
57+
# SEZIONE 1: STATISTICHE GENERALI
10058
# ========================================
101-
st.header("📈 Difficoltà Domande")
59+
st.header("📊 Statistiche Generali")
10260

103-
# Calcola percentuale di successo per domanda
61+
num_studenti = df_studenti.select("nome_utente").unique().height
62+
num_domande = df_domande.height
63+
totale_risposte = df_studenti.height
64+
risposte_corrette = df_con_corrette.filter(pl.col("corretta") == True).height
65+
percentuale_corrette = (risposte_corrette / totale_risposte * 100) if totale_risposte > 0 else 0
66+
tempo_medio_globale = df_studenti.select(pl.col("tempo_risposta").mean())[0, 0]
67+
68+
# Studente migliore e peggiore
69+
migliore = classifica.row(0, named=True)
70+
peggiore = classifica.row(-1, named=True)
71+
72+
# Domanda più difficile (minor percentuale di successo)
10473
difficolta = (
10574
df_con_corrette
10675
.group_by("id_domanda")
@@ -110,50 +79,109 @@
11079
])
11180
.with_columns(
11281
(pl.col("risposte_corrette") / pl.col("totale_risposte") * 100)
82+
.round(1)
11383
.alias("percentuale_corrette")
11484
)
11585
.sort("percentuale_corrette")
11686
)
87+
id_domanda_difficile = difficolta.row(0, named=True)["id_domanda"]
11788

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-
)
89+
col1, col2, col3 = st.columns(3)
90+
with col1:
91+
st.metric("👥 Studenti partecipanti", num_studenti)
92+
with col2:
93+
st.metric("❓ Domande totali", num_domande)
94+
with col3:
95+
st.metric("✍️ Risposte date", totale_risposte)
12496

125-
# Mostra tabella difficoltà
126-
st.dataframe(
127-
difficolta.select(["id_domanda", "domanda", "percentuale_corrette"]),
128-
width='stretch',
129-
hide_index=True
130-
)
97+
col4, col5, col6 = st.columns(3)
98+
with col4:
99+
st.metric("✅ Risposte corrette (media classe)", f"{percentuale_corrette:.1f}%")
100+
with col5:
101+
st.metric("⏱️ Tempo medio per risposta", f"{tempo_medio_globale:.0f} ms")
102+
with col6:
103+
st.metric("❓ Domanda più difficile", f"Domanda #{id_domanda_difficile}")
104+
105+
col7, col8 = st.columns(2)
106+
with col7:
107+
st.metric(
108+
"🥇 Studente migliore",
109+
migliore["nome_utente"],
110+
f"{migliore['risposte_corrette']} risposte corrette"
111+
)
112+
with col8:
113+
st.metric(
114+
"📚 Da migliorare",
115+
peggiore["nome_utente"],
116+
f"{peggiore['risposte_corrette']} risposte corrette",
117+
delta_color="inverse"
118+
)
131119

132120
# ========================================
133-
# SEZIONE 5: GRAFICO A BARRE
121+
# SEZIONE 2: CLASSIFICA STUDENTI (grafico)
134122
# ========================================
135-
st.header("📊 Grafico Prestazioni")
123+
st.header("🏆 Classifica Studenti")
136124

137-
# Prepara dati per il grafico
138-
dati_grafico = classifica.select(["nome_utente", "risposte_corrette"])
125+
# Classifica con barre progress: ordine garantito, nessuna libreria extra
126+
max_corrette = classifica["risposte_corrette"].max()
127+
128+
for i, row in enumerate(classifica.iter_rows(named=True)):
129+
st.write(f"{i+1}° **{row['nome_utente']}** — {row['risposte_corrette']} risposte corrette")
130+
st.progress(int(row["risposte_corrette"]) / int(max_corrette))
131+
132+
# Tabella dettagliata sotto il grafico
133+
with st.expander("📋 Vedi tabella dettagliata"):
134+
st.dataframe(
135+
classifica.select([
136+
"nome_utente",
137+
"risposte_corrette",
138+
"domande_risposte",
139+
"percentuale_corrette",
140+
"tempo_medio"
141+
]),
142+
width="stretch",
143+
hide_index=True,
144+
column_config={
145+
"nome_utente": "Studente",
146+
"risposte_corrette": "✅ Corrette",
147+
"domande_risposte": "❓ Risposte",
148+
"percentuale_corrette": st.column_config.NumberColumn("% Corrette", format="%.1f%%"),
149+
"tempo_medio": st.column_config.NumberColumn("⏱️ Tempo medio (ms)", format="%.0f")
150+
}
151+
)
139152

140-
# Crea grafico a barre
141-
st.bar_chart(
142-
dati_grafico,
143-
x="nome_utente",
144-
y="risposte_corrette",
145-
width='stretch'
153+
# ========================================
154+
# SEZIONE 3: DIFFICOLTÀ DOMANDE
155+
# ========================================
156+
st.header("📈 Difficoltà Domande")
157+
158+
difficolta_con_testo = difficolta.join(
159+
df_domande.select(["id_domanda", "domanda"]),
160+
on="id_domanda",
161+
how="left"
162+
)
163+
164+
st.dataframe(
165+
difficolta_con_testo.select(["id_domanda", "domanda", "percentuale_corrette"]),
166+
width="stretch",
167+
hide_index=True,
168+
column_config={
169+
"id_domanda": "ID",
170+
"domanda": "Domanda",
171+
"percentuale_corrette": st.column_config.ProgressColumn(
172+
"% Risposte Corrette",
173+
format="%.1f%%",
174+
min_value=0,
175+
max_value=100
176+
)
177+
}
146178
)
147179

148180
# ========================================
149-
# SEZIONE 6: TEMPO MEDIO DI RISPOSTA
181+
# SEZIONE 4: TEMPO DI RISPOSTA PER DOMANDA
150182
# ========================================
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")
183+
st.header("⏱️ Tempo di Risposta per Domanda")
155184

156-
# Grafico tempo per domanda
157185
tempo_per_domanda = (
158186
df_studenti
159187
.group_by("id_domanda")
@@ -165,5 +193,20 @@
165193
tempo_per_domanda,
166194
x="id_domanda",
167195
y="tempo_medio",
168-
width='stretch'
169-
)
196+
width="stretch"
197+
)
198+
199+
# ========================================
200+
# SEZIONE 5: DOMANDE E RISPOSTE CORRETTE
201+
# ========================================
202+
with st.expander("📖 Visualizza domande e risposte corrette"):
203+
domande_con_risposta = (
204+
df_domande.join(df_risposte, on="id_domanda", how="left")
205+
.sort("id_domanda")
206+
)
207+
for row in domande_con_risposta.iter_rows(named=True):
208+
numero = row["numero_risposta_corretta"]
209+
risposta_corretta = row[f"risposta_{numero}"]
210+
st.markdown(f"**#{row['id_domanda']}{row['domanda']}**")
211+
st.success(f"✅ {risposta_corretta}")
212+
st.divider()

0 commit comments

Comments
 (0)