diff --git a/app.py b/app.py index bda9315..c8e91b8 100644 --- a/app.py +++ b/app.py @@ -8,19 +8,45 @@ app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///typewriter.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db.init_app(app) +# Fallback-Lektionen für den Fall, dass die JSON-Datei nicht geladen werden kann +FALLBACK_LESSONS = [ + {"text": "Dies ist der erste Übungstext für den Tipptrainer. Beginne mit diesem einfachen Text."}, + {"text": "Übung macht den Meister. Tippe weiter, um deine Geschwindigkeit und Genauigkeit zu verbessern."}, + {"text": "Die schnelle braune Fuchs springt über den faulen Hund. Dies ist ein klassischer Übungstext."}, + {"text": "Programmieren lernen mit Python macht Spaß und eröffnet viele Möglichkeiten in der Softwareentwicklung."} +] + # Laden der Lektionen aus der JSON-Datei DATA_PATH = os.path.join(app.root_path, "data", "lessons.json") +lessons = [] + try: - with open(DATA_PATH, "r", encoding="utf-8") as f: - lessons = json.load(f) + if os.path.exists(DATA_PATH): + with open(DATA_PATH, "r", encoding="utf-8") as f: + lessons = json.load(f) + print(f"Erfolgreich {len(lessons)} Lektionen aus {DATA_PATH} geladen") + else: + print(f"Warnung: Datei {DATA_PATH} nicht gefunden. Verwende Fallback-Lektionen.") + lessons = FALLBACK_LESSONS except json.JSONDecodeError as e: print(f"Fehler beim Laden der JSON-Datei: {e}") - # Fallback: leere Liste, falls die Datei beschädigt ist - lessons = [] + print("Verwende Fallback-Lektionen") + lessons = FALLBACK_LESSONS +except Exception as e: + print(f"Unerwarteter Fehler beim Laden der Lektionen: {e}") + print("Verwende Fallback-Lektionen") + lessons = FALLBACK_LESSONS -@app.before_request +# Sicherstellen, dass Lektionen vorhanden sind +if not lessons: + print("Keine Lektionen verfügbar, verwende Fallback-Lektionen") + lessons = FALLBACK_LESSONS + +@app.before_first_request def create_tables(): + """Erstelle Datenbanktabellen beim ersten Request""" db.create_all() + print("Datenbanktabellen wurden initialisiert") @app.route('/') def index(): @@ -30,14 +56,38 @@ def index(): if not progress: # Falls keine Daten vorhanden sind, initialisiere mit ersten Text if lessons: - progress = Progress(current_text_index=0, current_position=0, last_text=lessons[0]['text']) + initial_text = lessons[0]['text'] + progress = Progress( + current_text_index=0, + current_position=0, + last_text=initial_text + ) + db.session.add(progress) + db.session.commit() + print(f"Neuen Fortschritt initialisiert mit Text: {initial_text[:50]}...") else: - progress = Progress(current_text_index=0, current_position=0, last_text="") - db.session.add(progress) - db.session.commit() + # Fallback, falls lessons immer noch leer sein sollte + progress = Progress( + current_text_index=0, + current_position=0, + last_text="Keine Lektionen verfügbar" + ) + db.session.add(progress) + db.session.commit() # Hole den aktuellen Text - current_text = lessons[progress.current_text_index]['text'] if lessons else "" + current_text = "" + if lessons and progress.current_text_index < len(lessons): + current_text = lessons[progress.current_text_index]['text'] + else: + # Fallback, falls Index ungültig ist + current_text = lessons[0]['text'] if lessons else "Keine Lektionen verfügbar" + progress.current_text_index = 0 + progress.current_position = 0 + progress.last_text = current_text + db.session.commit() + + print(f"Rendering Index - Current Text: {current_text[:50]}...") return render_template('index.html', current_text=current_text, @@ -45,6 +95,26 @@ def index(): last_text=progress.last_text, lessons=lessons) +@app.route('/debug') +def debug(): + """Debug-Route zum Überprüfen der Lektionen und Konfiguration""" + progress = Progress.query.first() + + debug_info = { + 'lessons_loaded': len(lessons), + 'lessons_content': lessons, + 'data_path': DATA_PATH, + 'file_exists': os.path.exists(DATA_PATH), + 'current_progress': { + 'current_text_index': progress.current_text_index if progress else None, + 'current_position': progress.current_position if progress else None, + 'last_text': progress.last_text[:100] + '...' if progress and progress.last_text else None + } if progress else None, + 'app_root_path': app.root_path + } + + return jsonify(debug_info) + @app.route('/update_progress', methods=['POST']) def update_progress(): data = request.get_json() @@ -54,17 +124,20 @@ def update_progress(): # Hole den aktuellen Fortschritt progress = Progress.query.first() - # Aktualisiere den Fortschritt - progress.current_position = len(user_input) - progress.last_text = user_input - - # Speichere in der Datenbank - db.session.commit() - - # Berechne Statistiken - stats = calculate_statistics(user_input, current_text) - - return jsonify(stats) + if progress: + # Aktualisiere den Fortschritt + progress.current_position = len(user_input) + progress.last_text = user_input + + # Speichere in der Datenbank + db.session.commit() + + # Berechne Statistiken + stats = calculate_statistics(user_input, current_text) + + return jsonify(stats) + else: + return jsonify({'error': 'Progress nicht gefunden'}), 400 def calculate_statistics(user_input, current_text): # Berechne die Anzahl der korrekten und falschen Zeichen @@ -84,30 +157,24 @@ def calculate_statistics(user_input, current_text): error_rate = (incorrect_chars / total_chars) * 100 # Berechne durchschnittliche Tippgeschwindigkeit (Zeichen pro Minute) - # Für diese Version: Simuliere eine Zeitmessung - # In einer echten Anwendung würden wir die tatsächliche Zeit messen - # Hier simulieren wir eine Zeit basierend auf der Länge des eingegebenen Textes if total_chars > 0: # Simulierte Zeit: Je länger der Text, desto länger dauert es - # Wir verwenden eine realistischere Formel: Zeit = (Anzahl der Zeichen * 0.05) Sekunden - # Das entspricht etwa 120 Zeichen pro Minute (typisch für Anfänger) time_taken = total_chars * 0.05 # Sekunden typing_speed = (total_chars / time_taken) * 60 if time_taken > 0 else 0 else: typing_speed = 0 + time_taken = 0 # Zeichen pro Sekunden duration_per_char = 0 - if total_chars > 0: - duration_per_char = time_taken / total_chars if time_taken > 0 else 0 + if total_chars > 0 and time_taken > 0: + duration_per_char = time_taken / total_chars # Berechne Wörter pro Minute (WPM) words_per_minute = 0 - if total_chars > 0: - time_taken = total_chars * 0.05 # Sekunden - if time_taken > 0: - # WPM = (Gesamtzeichen / 5) / (Gesamtzeit in Minuten) - words_per_minute = (total_chars / 5) / (time_taken / 60) + if total_chars > 0 and time_taken > 0: + # WPM = (Gesamtzeichen / 5) / (Gesamtzeit in Minuten) + words_per_minute = (total_chars / 5) / (time_taken / 60) # Berechne Genauigkeit accuracy = 0 @@ -118,7 +185,7 @@ def calculate_statistics(user_input, current_text): 'correct_chars': correct_chars, 'incorrect_chars': incorrect_chars, 'total_chars': total_chars, - 'error_rate': round(error_rate, 1), # Nur eine Dezimalstelle + 'error_rate': round(error_rate, 1), 'typing_speed': round(typing_speed, 2), 'duration_per_char': round(duration_per_char, 3), 'words_per_minute': round(words_per_minute, 2), @@ -129,6 +196,9 @@ def calculate_statistics(user_input, current_text): def next_text(): progress = Progress.query.first() + if not progress: + return jsonify({'error': 'Progress nicht gefunden'}), 400 + # Wechsel zum nächsten Text if lessons and progress.current_text_index < len(lessons) - 1: progress.current_text_index += 1 @@ -174,4 +244,8 @@ def end_session(): if __name__ == '__main__': with app.app_context(): db.create_all() + print("Datenbank initialisiert") + print(f"{len(lessons)} Lektionen geladen") + app.run(debug=True) +