feat: Füge 20 deutsche 10-Finger-Lektionen aus JSON-Datei hinzu

Co-authored-by: aider (ollama_chat/qwen3-coder:30b) <aider@aider.chat>
This commit is contained in:
jamulix 2025-10-21 12:35:01 +02:00
commit bf5f409485
2 changed files with 45 additions and 35 deletions

60
app.py
View file

@ -1,40 +1,21 @@
import os
import json
from flask import Flask, render_template, request, jsonify
from models import db, Progress, Statistic
import os
import random
import time
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///typewriter.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# Initialisiere die Datenbank
db.init_app(app)
# Beispieltexte für den Tipptrainer
EXAMPLE_TEXTS = [
"Der schnelle braune Fuchs springt über den faulen Hund.",
"In der Sonne tanzen die Blüten im Garten.",
"Ein guter Tipptrainer hilft beim schnellen Lernen.",
"Die moderne Technik macht unser Leben einfacher.",
"Programmieren ist eine spannende Herausforderung."
]
# Laden der Lektionen aus der JSON-Datei
DATA_PATH = os.path.join(app.root_path, "data", "lessons.json")
with open(DATA_PATH, "r", encoding="utf-8") as f:
lessons = json.load(f)
# Erstelle Tabellen vor dem ersten Request
@app.before_request
def create_tables():
# Nur einmal ausführen
if not hasattr(create_tables, 'executed'):
db.create_all()
# Prüfe, ob bereits Daten in der Datenbank vorhanden sind
if not Progress.query.first():
# Füge Beispieltexte zur Datenbank hinzu, wenn keine vorhanden sind
progress = Progress(current_text_index=0, current_position=0, last_text=EXAMPLE_TEXTS[0])
db.session.add(progress)
db.session.commit()
create_tables.executed = True
db.create_all()
@app.route('/')
def index():
@ -43,17 +24,18 @@ def index():
if not progress:
# Falls keine Daten vorhanden sind, initialisiere mit ersten Text
progress = Progress(current_text_index=0, current_position=0, last_text=EXAMPLE_TEXTS[0])
progress = Progress(current_text_index=0, current_position=0, last_text=lessons[0]['text'])
db.session.add(progress)
db.session.commit()
# Hole den aktuellen Text
current_text = EXAMPLE_TEXTS[progress.current_text_index]
current_text = lessons[progress.current_text_index]['text']
return render_template('index.html',
current_text=current_text,
current_position=progress.current_position,
last_text=progress.last_text)
last_text=progress.last_text,
lessons=lessons)
@app.route('/update_progress', methods=['POST'])
def update_progress():
@ -119,6 +101,11 @@ def calculate_statistics(user_input, current_text):
# WPM = (Gesamtzeichen / 5) / (Gesamtzeit in Minuten)
words_per_minute = (total_chars / 5) / (time_taken / 60)
# Berechne Genauigkeit
accuracy = 0
if total_chars > 0:
accuracy = (correct_chars / total_chars) * 100
return {
'correct_chars': correct_chars,
'incorrect_chars': incorrect_chars,
@ -126,7 +113,8 @@ def calculate_statistics(user_input, current_text):
'error_rate': round(error_rate, 1), # Nur eine Dezimalstelle
'typing_speed': round(typing_speed, 2),
'duration_per_char': round(duration_per_char, 3),
'words_per_minute': round(words_per_minute, 2)
'words_per_minute': round(words_per_minute, 2),
'accuracy': round(accuracy, 2)
}
@app.route('/next_text', methods=['POST'])
@ -134,19 +122,19 @@ def next_text():
progress = Progress.query.first()
# Wechsel zum nächsten Text
if progress.current_text_index < len(EXAMPLE_TEXTS) - 1:
if progress.current_text_index < len(lessons) - 1:
progress.current_text_index += 1
else:
# Wenn wir am Ende sind, starten wir von vorne
progress.current_text_index = 0
progress.current_position = 0
progress.last_text = EXAMPLE_TEXTS[progress.current_text_index]
progress.last_text = lessons[progress.current_text_index]['text']
db.session.commit()
return jsonify({
'text': EXAMPLE_TEXTS[progress.current_text_index]
'text': lessons[progress.current_text_index]['text']
})
@app.route('/end_session', methods=['POST'])
@ -163,7 +151,9 @@ def end_session():
incorrect_chars=0,
error_rate=0,
typing_speed=0,
duration_per_char=0
duration_per_char=0,
accuracy=0,
wpm=0
)
db.session.add(statistic)

View file

@ -60,6 +60,10 @@
Wörter pro Minute (WPM)
<span id="wpm" class="badge bg-info rounded-pill">0</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
Genauigkeit
<span id="accuracy" class="badge bg-success rounded-pill">0%</span>
</li>
</ul>
</div>
</div>
@ -88,6 +92,22 @@
</div>
</div>
<!-- Lektionen -->
<div class="mb-4">
<h5 class="card-title">Lektionen</h5>
<div class="row">
{% for lesson in lessons %}
<div class="col-md-3 mb-2">
<button class="btn btn-outline-primary w-100 lesson-btn"
data-lesson="{{ lesson.lesson }}"
data-text="{{ lesson.text }}">
Lektion {{ lesson.lesson }}
</button>
</div>
{% endfor %}
</div>
</div>
<!-- Buttons -->
<div class="d-flex justify-content-between">
<button id="next-btn" class="btn btn-success">