diff --git a/app.py b/app.py index 61a457a..cbd9575 100644 --- a/app.py +++ b/app.py @@ -70,32 +70,42 @@ def upload(): secret = session.get('secret') if not secret or secret not in games: return redirect(url_for('host')) + game = games[secret] + # retrieve uploaded file file = request.files.get('file') if not file: return render_template('upload.html', error='Keine Datei ausgewählt') + # try to read Excel try: df = pd.read_excel(file) except Exception: return render_template('upload.html', error='Ungültige Excel-Datei') + + # enforce maximum of 100 questions + max_questions = 100 + if df.shape[0] > max_questions: + return render_template( + 'upload.html', + error=f'Maximal dürfen {max_questions} Fragen hochgeladen werden. Ihre Datei enthält {df.shape[0]}.') + # mandatory columns - required = ['question','answer1','answer2','answer3','answer4','correct'] - # ermittelt, welche der benötigten Spalten nicht im DataFrame sind + required = ['question', 'answer1', 'answer2', 'answer3', 'answer4', 'correct'] missing = [col for col in required if col not in df.columns] if missing: return render_template( 'upload.html', error=f"Fehler in Datei: Fehlende Spalte(n): {', '.join(missing)}" ) + # validate that 'correct' references one of the answer columns - valid_keys = ['answer1','answer2','answer3','answer4'] + valid_keys = ['answer1', 'answer2', 'answer3', 'answer4'] invalid_mask = ~df['correct'].isin(valid_keys) if invalid_mask.any(): - # finde den ersten Invalid-Eintrag - idx = invalid_mask.idxmax() # DataFrame-Index - excel_line = idx + 2 # Header ist Zeile 1 + idx = invalid_mask.idxmax() + excel_line = idx + 2 # Header is line 1 bad_value = df.at[idx, 'correct'] return render_template( 'upload.html', @@ -104,19 +114,23 @@ def upload(): f'"correct" enthält "{bad_value}", ' f'muss einer der Werte {valid_keys} sein.' ) - ) # build per-game question list + ) + + # build per-game question list questions = [] for _, row in df.iterrows(): col = row['correct'] questions.append({ - 'question': row['question'], - 'options': [row[f'answer{i}'] for i in range(1,5)], - 'correct': row[col] + 'question': str(row['question']), + 'options': [str(row[f'answer{i}']) for i in range(1, 5)], + 'correct': str(row[col]) }) + game['questions'] = questions - # once upload and validation succeeds, redirect to host view (which will show the QR) + # redirect to host view, which will show the QR code return redirect(url_for('host')) + @app.route('/new_game', methods=['POST']) def new_game(): if session.get('role') != 'host': @@ -419,7 +433,12 @@ def _send_question(secret): def _score_and_emit(secret): game = games[secret] - score_map = {1: 4, 2: 3, 3: 2, 4: 1} + # Punkteverteilung: + # 1. richtige Antwort → 5 Punkte + # 2. richtige Antwort → 4 Punkte + # 3. richtige Antwort → 3 Punkte + # alle weiteren richtigen Antworten → 1 Punkt + score_map = {1: 5, 2: 4, 3: 3} per_q = [] # grab the current question’s correct answer @@ -431,9 +450,10 @@ def _score_and_emit(secret): prev_correct = sum(1 for p, a in game['answered'][:-1] if a == correct) rank = prev_correct + 1 - # assign points only if this one is correct and within top‐4 - if ans == correct and rank <= 4: - pts = score_map[rank] + # assign points only if korrekt + if ans == correct: + # für Platz 1–3 nach Mapping, ab Platz 4 immer 1 Punkt + pts = score_map.get(rank, 1) game['players'][pid]['score'] += pts per_q.append({ 'name': game['players'][pid]['name'], diff --git a/templates/upload.html b/templates/upload.html index 8cc576d..e2f1bab 100644 --- a/templates/upload.html +++ b/templates/upload.html @@ -4,27 +4,43 @@
- Willkommen beim interaktiven Gruppen-Quiz! Lade hier deinen eigenen Fragebogen hoch, - um ein spannendes Live-Quiz zu starten. Deine Teilnehmer bearbeiten die Fragen schnell - und wettbewerbsorientiert, direkt über ihre Smartphones. + Willkommen zum interaktiven Gruppenquiz! Lade deinen eigenen Fragebogen hoch und starte ein spannendes Live-Quiz. + Deine Teilnehmer beantworten die Fragen schnell und wettbewerbsorientiert direkt über ihre Smartphones.
- +- Verwende die Beispieldatei als Vorlage und trage deine Fragen und Antwortoptionen - ein. Achte darauf, dass deine Excel-Datei folgende Spalten enthält: + Schnelle und richtige Antworten werden mit mehr Punkten belohnt. Jeder Spieler hat pro Frage nur einen Versuch. + Ein guter Mix aus Schnelligkeit und Genauigkeit zahlt sich aus! +
++ Hinweis: Die ersten drei richtigen Antworten erhalten höhere Punktwerte, alle weiteren richtigen Antworten bringen jeweils 1 Punkt.
question: Der Fragentext (z.B. "Wer baute die Arche?")answer1 bis answer4: Vier mögliche Antwortencorrect: Name der richtigen Spalte (answer1–answer4)Sobald die richtige Antwort für alle anzeigt wird, werden keine weiteren Punkte verteilt.
+ + ++ Nutze die Beispieldatei als Vorlage und trage deine Fragen sowie die Antwortoptionen ein. + Deine Excel-Datei sollte folgende Spalten enthalten: +
+question: Text der Frage (z. B. „Wer baute die Arche?“)answer1 bis answer4: Vier Antwortmöglichkeitencorrect: Spaltenname der richtigen Antwort (answer1-answer4)
- Unterstützte Formate: .xlsx, .xls. Maximal 100 Fragen empfohlen.
+ Unterstützte Formate: .xlsx, .xls
+ Maximal 100 Fragen!