Skip to content

Commit acdb8fa

Browse files
committed
quiz with csv library for writing csv
1 parent 88d887a commit acdb8fa

File tree

2 files changed

+123
-49
lines changed

2 files changed

+123
-49
lines changed

game05_1/domande.csv

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
id,domanda,risposta1,risposta2,risposta3,risposta4,corretta
2+
1,Quale rapper ha pubblicato l'album 'X2VR' nel 2023?,Sfera Ebbasta,Guè,Geolier,Lazza,1
3+
2,In quale anno è avvenuta l'Unità d'Italia?,1946,1848,1861,1915,3
4+
3,Chi interpreta il personaggio di Ciro Ricci in 'Mare Fuori'?,Giacomo Giorgio,Massimiliano Caiazzo,Nicolas Maupas,Matteo Paolillo,1
5+
4,Quale artista ha vinto Sanremo 2024?,Geolier,Annalisa,Angelina Mango,Mahmood,3
6+
5,In che anno è finita la Seconda Guerra Mondiale?,1918,1945,1939,1968,2
7+
6,Quale rapper ha lanciato il brano 'Red Bull 64 Bars' più iconico del 2024?,Kid Yugi,Artie 5ive,Tony Effe,Simba La Rue,1
8+
7,Chi è il creator noto per le sue sfide di sopravvivenza estreme?,MrBeast,Blur,Gianmarco Tanza,Il Rosso,1
9+
8,Quale di questi rapper fa parte della 'BNKR44'?,Finesse,Erin,Sacky,Rondodasosa,2
10+
9,Chi ha vinto l'ultima edizione della Kings League Italia?,Stallions,FC Zeta,Boomers,Muccia,1

game05_1/quiz.py

Lines changed: 113 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import pgzrun
22
import polars as pl
3+
import csv
34
import os
45
from pgzero.keyboard import keys
56

67
# ───────────────── CONFIG ─────────────────
7-
TITLE = "Cyber Quiz Polars Edition"
8+
TITLE = "Cyber Quiz"
89
WIDTH = 900
910
HEIGHT = 600
1011
TEMPO_DOMANDA = 15
@@ -20,7 +21,7 @@
2021
TEXT_MAIN = (255, 255, 255)
2122

2223
# ───────────────── STATO ─────────────────
23-
lista_domande = [] # Qui finira il nostro mazzo rimescolato
24+
lista_domande = [] # Qui finirà il nostro mazzo rimescolato
2425
domanda_corrente = None
2526
indice_domande = 0
2627
contatore_totale = 0
@@ -35,10 +36,15 @@
3536

3637
# Box
3738
question_box = Rect(50, 90, 800, 150)
38-
answer_boxes = [Rect(50, 300, 380, 110), Rect(470, 300, 380, 110),
39-
Rect(50, 430, 380, 110), Rect(470, 430, 380, 110)]
39+
answer_boxes = [
40+
Rect(50, 300, 380, 110),
41+
Rect(470, 300, 380, 110),
42+
Rect(50, 430, 380, 110),
43+
Rect(470, 430, 380, 110),
44+
]
4045
timer_bar_box = Rect(50, 260, 800, 12)
4146

47+
4248
# ───────────────── LOGICA DATI CON POLARS ─────────────────
4349
def carica_e_mischia():
4450
global lista_domande, contatore_totale
@@ -71,31 +77,36 @@ def prossima_domanda():
7177

7278
# ───────────────── SALVATAGGIO RISPOSTE ─────────────────
7379
def init_file_risposte():
74-
"""Crea il file risposte con header se non esiste."""
80+
"""Crea il file risposte con header se non esiste (usando csv)."""
7581
if not os.path.exists(NOME_FILE_RISPOSTE):
76-
df = pl.DataFrame({
77-
"nome_utente": pl.Series([], dtype=pl.Utf8),
78-
"id_domanda": pl.Series([], dtype=pl.Int64),
79-
"numero_risposta_fornita": pl.Series([], dtype=pl.Int64),
80-
"tempo_risposta": pl.Series([], dtype=pl.Int64),
81-
})
82-
df.write_csv(NOME_FILE_RISPOSTE)
83-
84-
85-
def salva_risposta(nome, id_dom, numero_risposta, tempo_risposta):
82+
with open(NOME_FILE_RISPOSTE, mode="w", newline="", encoding="utf-8") as f:
83+
writer = csv.writer(f)
84+
writer.writerow(
85+
[
86+
"nome_utente",
87+
"id_domanda",
88+
"numero_risposta_fornita",
89+
"tempo_risposta",
90+
]
91+
)
92+
93+
94+
def salva_risposta(nome, id_domanda, numero_risposta, tempo_risposta):
95+
"""Append della risposta al CSV (una riga). id_domanda può essere None -> scriviamo vuoto."""
8696
init_file_risposte()
8797

88-
nuova_riga = pl.DataFrame({
89-
"nome_utente": [str(nome)],
90-
"id_domanda": [int(id_dom)],
91-
"numero_risposta_fornita": [int(numero_risposta)],
92-
"tempo_risposta": [int(tempo_risposta)],
93-
})
98+
# Normalizziamo i valori per sicurezza
99+
nome_s = str(nome) if nome is not None else ""
100+
id_s = "" if id_domanda is None else str(id_domanda)
101+
num_s = str(int(numero_risposta)) if numero_risposta is not None else ""
102+
tempo_s = str(int(tempo_risposta)) if tempo_risposta is not None else ""
94103

95-
# Append leggendo + concatenando (approccio semplice e robusto)
96-
df_esistente = pl.read_csv(NOME_FILE_RISPOSTE)
97-
df_finale = pl.concat([df_esistente, nuova_riga])
98-
df_finale.write_csv(NOME_FILE_RISPOSTE)([nome, id_dom, numero_risposta, tempo_risposta])
104+
try:
105+
with open(NOME_FILE_RISPOSTE, mode="a", newline="", encoding="utf-8") as f:
106+
writer = csv.writer(f)
107+
writer.writerow([nome_s, id_s, num_s, tempo_s])
108+
except Exception as e:
109+
print(f"Errore salvataggio risposta: {e}")
99110

100111

101112
# ───────────────── DISEGNO ─────────────────
@@ -109,37 +120,76 @@ def draw():
109120

110121
# Se siamo nella fase di inserimento nickname
111122
if entering_name:
112-
screen.draw.text("Benvenuto a Cyber Quiz!", center=(WIDTH // 2, 120), fontsize=48, color=COLOR_ACCENT)
113-
screen.draw.text("Inserisci il tuo nickname e premi ENTER per iniziare:", center=(WIDTH // 2, 180), fontsize=28, color=TEXT_MAIN)
123+
screen.draw.text(
124+
"Benvenuto a Cyber Quiz!",
125+
center=(WIDTH // 2, 120),
126+
fontsize=48,
127+
color=COLOR_ACCENT,
128+
)
129+
screen.draw.text(
130+
"Inserisci il tuo nickname e premi ENTER per iniziare:",
131+
center=(WIDTH // 2, 180),
132+
fontsize=28,
133+
color=TEXT_MAIN,
134+
)
114135

115136
# box input
116137
input_box = Rect(WIDTH // 2 - 300, 230, 600, 60)
117138
draw_styled_rect(input_box, COLOR_CARD)
118139
display_name = nome_utente if nome_utente != "" else "(digita qui...)"
119-
screen.draw.text(display_name, center=input_box.center, fontsize=36, color=TEXT_MAIN)
140+
screen.draw.text(
141+
display_name, center=input_box.center, fontsize=36, color=TEXT_MAIN
142+
)
120143
return
121144

122145
if game_over:
123-
screen.draw.text(f"SESSIONE FINITA\nPunteggio: {punteggio}/{contatore_totale}",
124-
center=(WIDTH // 2, HEIGHT // 2), fontsize=50, color=COLOR_ACCENT)
146+
screen.draw.text(
147+
f"SESSIONE FINITA\nPunteggio: {punteggio}/{contatore_totale}",
148+
center=(WIDTH // 2, HEIGHT // 2),
149+
fontsize=50,
150+
color=COLOR_ACCENT,
151+
)
125152
return
126153

127154
# Info
128-
screen.draw.text(f"GIOCATORE: {nome_utente}", (50, 20), color=COLOR_ACCENT, fontsize=22)
129-
screen.draw.text(f"DOMANDA {indice_domande}/{contatore_totale}", (50, 50), color=COLOR_ACCENT, fontsize=22)
130-
screen.draw.text(f"PUNTI: {punteggio}", (WIDTH - 150, 20), color=TEXT_MAIN, fontsize=25)
155+
screen.draw.text(
156+
f"GIOCATORE: {nome_utente}", (50, 20), color=COLOR_ACCENT, fontsize=22
157+
)
158+
screen.draw.text(
159+
f"DOMANDA {indice_domande}/{contatore_totale}",
160+
(50, 50),
161+
color=COLOR_ACCENT,
162+
fontsize=22,
163+
)
164+
screen.draw.text(
165+
f"PUNTI: {punteggio}", (WIDTH - 150, 20), color=TEXT_MAIN, fontsize=25
166+
)
131167

132168
# Box Domanda
133169
draw_styled_rect(question_box, COLOR_CARD)
134170
if domanda_corrente:
135-
screen.draw.textbox(str(domanda_corrente.get('domanda', '')) , question_box.inflate(-40, -40), color=TEXT_MAIN)
171+
screen.draw.textbox(
172+
str(domanda_corrente.get("domanda", "")),
173+
question_box.inflate(-40, -40),
174+
color=TEXT_MAIN,
175+
)
136176
else:
137-
screen.draw.textbox("Caricamento...", question_box.inflate(-40, -40), color=TEXT_MAIN)
177+
screen.draw.textbox(
178+
"Caricamento...", question_box.inflate(-40, -40), color=TEXT_MAIN
179+
)
138180

139181
# Timer Progressivo
140182
percent = secondi_mancanti / TEMPO_DOMANDA if TEMPO_DOMANDA > 0 else 0
141183
screen.draw.filled_rect(timer_bar_box, COLOR_SHADOW)
142-
screen.draw.filled_rect(Rect(timer_bar_box.x, timer_bar_box.y, int(timer_bar_box.w * percent), timer_bar_box.h), COLOR_ACCENT)
184+
screen.draw.filled_rect(
185+
Rect(
186+
timer_bar_box.x,
187+
timer_bar_box.y,
188+
int(timer_bar_box.w * percent),
189+
timer_bar_box.h,
190+
),
191+
COLOR_ACCENT,
192+
)
143193

144194
# Risposte
145195
for i in range(4):
@@ -148,7 +198,11 @@ def draw():
148198
is_hover = box.collidepoint(mouse_pos)
149199
draw_styled_rect(box, (60, 60, 90) if is_hover else COLOR_CARD)
150200
if domanda_corrente:
151-
screen.draw.textbox(str(domanda_corrente.get(chiave, '')), box.inflate(-20, -20), color=TEXT_MAIN)
201+
screen.draw.textbox(
202+
str(domanda_corrente.get(chiave, "")),
203+
box.inflate(-20, -20),
204+
color=TEXT_MAIN,
205+
)
152206

153207

154208
# ───────────────── INPUT & TIMER ─────────────────
@@ -169,20 +223,25 @@ def on_mouse_down(pos):
169223
# tempo di risposta = tempo passato dalla visualizzazione (tempo iniziale - secondi_mancanti)
170224
tempo_risposta = TEMPO_DOMANDA - secondi_mancanti
171225
# Troviamo un id per la domanda: preferiamo campi 'id_domanda' o 'id', altrimenti usiamo l'indice attuale
172-
id_dom = None
226+
id_domanda = None
173227
if domanda_corrente is not None:
174-
id_dom = domanda_corrente.get('id_domanda') if 'id_domanda' in domanda_corrente else domanda_corrente.get('id')
175-
if id_dom is None:
176-
id_dom = indice_domande
228+
# se è salvato come stringa nel CSV, manteniamo la stringa (salveremo come testo)
229+
id_domanda = (
230+
domanda_corrente.get("id_domanda")
231+
if "id_domanda" in domanda_corrente
232+
else domanda_corrente.get("id")
233+
)
234+
if id_domanda is None:
235+
id_domanda = indice_domande
177236

178237
numero_risposta = i + 1
179238

180239
# Salviamo la risposta nel CSV
181-
salva_risposta(nome_utente, id_dom, numero_risposta, tempo_risposta)
240+
salva_risposta(nome_utente, id_domanda, numero_risposta, tempo_risposta)
182241

183242
# Controlliamo correttezza (forziamo a stringa)
184243
try:
185-
if str(numero_risposta) == str(domanda_corrente.get('corretta')):
244+
if str(numero_risposta) == str(domanda_corrente.get("corretta")):
186245
punteggio += 1
187246
except Exception:
188247
pass
@@ -221,19 +280,23 @@ def tick():
221280
secondi_mancanti -= 1
222281
else:
223282
# se finisce il tempo, salviamo una risposta vuota/timeout
224-
# id domanda
225-
id_dom = None
283+
id_domanda = None
226284
if domanda_corrente is not None:
227-
id_dom = domanda_corrente.get('id_domanda') if 'id_domanda' in domanda_corrente else domanda_corrente.get('id')
228-
if id_dom is None:
229-
id_dom = indice_domande
285+
id_domanda = (
286+
domanda_corrente.get("id_domanda")
287+
if "id_domanda" in domanda_corrente
288+
else domanda_corrente.get("id")
289+
)
290+
if id_domanda is None:
291+
id_domanda = indice_domande
230292
# numero_risposta 0 per timeout
231-
salva_risposta(nome_utente, id_dom, 0, TEMPO_DOMANDA)
293+
salva_risposta(nome_utente, id_domanda, 0, TEMPO_DOMANDA)
232294
prossima_domanda()
233295

234296

235297
# ───────────────── CONTROLLO START / RESTART ─────────────────
236298

299+
237300
def start_game():
238301
global entering_name, nome_utente
239302
entering_name = False
@@ -246,6 +309,7 @@ def start_game():
246309
except Exception:
247310
pass
248311

312+
249313
# AVVIO: non carichiamo automaticamente le domande, aspettiamo il nickname
250314
init_file_risposte()
251315
pgzrun.go()

0 commit comments

Comments
 (0)