Files
3d.lehrstun.de/migrations/2026-05-24_lektion_sprache_3d_modell.py
Hans Puettmann 76addcb846 Herr Rechmann + L3-Titel + L2-Workflow
Drei Aenderungen aus Herbs Feedback:

1. Markus -> Herr Rechmann (60 Treffer in 26 Dateien + DB-Lektionen L2/L3)
   Konvention: Herb bleibt 'Herb' (interne Anrede fuer Claude), Markus
   wird in SuS-sichtbaren Texten als 'Herr Rechmann' ausgeschrieben.
   Wo 'Herb und Markus' stand -> 'Herb und Herr Rechmann'. Wenn das
   stilistisch zu uneinheitlich wirkt, koennen wir Herb spaeter auch
   in SuS-Texten zu 'Herr Puettmann' umziehen.

2. L3-Titel: 'Customizer — parametrisches 3D-Modell anpassen'
   -> 'Mein eigenes 3D-Modell designen'
   Begruendung Herb: 'Customizer' + 'parametrisch' wirken abschreckend.
   Methode kommt in den Aufgabe-Text, nicht in den Titel.

3. L2-Inhalt komplett geschrieben (~4.8 KB):
   - 8-Schritte-Workflow vom Stoebern auf Printables bis zum
     Druck-Abholen
   - A1-mini-Spezifika klar markiert (offen → nur PLA, 18×18 cm)
   - P-Serie-Spezifika fuer groessere Drucke
   - Tipps zur Modell-Wahl (klein anfangen, 4+ Sterne)
   - Was-tun-wenn-Tabelle bei Druckproblemen
   - Lehrer-Eskalations-Pfad: pausieren via Handy-App + Lehrer rufen

   Quellenlage: PDF-Anleitung A1 mini im OneDrive + Bambu-Wiki online
   waren beide nicht maschinell zugaenglich (pdftoppm fehlt, Wiki
   gibt HTTP 402). Workflow basiert auf Standard-Bambu-Studio-Bedienung
   + Konsistenz mit der L1-P2S-Beschreibung. Herb/Herr Rechmann pruefen
   die A1-mini-Spezifika beim Lehrer-Test und korrigieren via Inline-Edit
   (oder per Migration, wenn Inline-Edit-UI noch nicht live ist).
2026-05-24 19:51:19 +02:00

139 lines
5.5 KiB
Python

"""Migration 2026-05-24: Sprachliche Klärung 'Modell''3D-Modell'.
Hintergrund: Herb hat angemerkt, dass 'Modell' mehrdeutig ist —
sowohl Druckermodell (P2S, A1 mini) als auch 3D-Modell (die STL-Datei).
Beim Lesen von L2 ('Fremdes Modell waehlen + drucken') hat er kurz
gedacht, es waere von fremden Druckern (Prusa) die Rede.
Loesung: konsequent '3D-Modell' fuer die Druckdateien, 'Drucker' fuer
die Maschinen.
Aenderungen:
- L2-Titel: 'Fremdes Modell waehlen + drucken' -> '3D-Modell aus dem Netz drucken'
- L3-Titel: 'Customizer / parametrisches Modell' -> 'Customizer — parametrisches 3D-Modell anpassen'
- L1-Text: 'baut ein Modell' -> 'baut ein 3D-Modell' (Schicht fuer Schicht)
+ andere mehrdeutige Stellen praezisiert
- L1-Text: 'vorbereitetes Modell' -> 'vorbereitetes 3D-Modell'
Idempotent ueber Marker im jeweiligen Text.
"""
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from database import get_db
MARKER_L1 = "SPRACHE_3D_MODELL_V1"
MARKER_L2_TITEL = "3D-Modell aus dem Netz drucken"
MARKER_L3_TITEL = "parametrisches 3D-Modell anpassen"
def update_l1(conn):
"""L1 aufgabe_md: Praezisierungen 'Modell' -> '3D-Modell' wo es um Druckdateien geht."""
row = conn.execute("SELECT aufgabe_md FROM lektion WHERE nummer = 1").fetchone()
if not row:
return False
text = row["aufgabe_md"] or ""
if MARKER_L1 in text:
return False # schon migriert
# Konkrete Ersetzungen — gezielt, nicht global, damit "Druckermodell"-Stellen
# nicht versehentlich getroffen werden
ersetzungen = [
("baut ein Modell", "baut ein 3D-Modell"),
("entsteht so dein Modell", "entsteht so dein 3D-Modell"),
("vorbereitetes Modell drucken", "vorbereitetes 3D-Modell drucken"),
("vorbereitetes Modell zeigen", "vorbereitetes 3D-Modell zeigen"),
("ein kleines, getestetes Modell", "ein kleines, getestetes 3D-Modell"),
# "vorbereitetes Modell" generisch falls noch wo
("vorbereitetes Modell", "vorbereitetes 3D-Modell"),
]
geaendert = text
for alt, neu in ersetzungen:
geaendert = geaendert.replace(alt, neu)
# Marker am Ende ergaenzen, damit Re-Run erkennt: schon durch
geaendert += f"\n<!-- {MARKER_L1} -->"
conn.execute("UPDATE lektion SET aufgabe_md = ? WHERE nummer = 1", (geaendert,))
return True
def update_l2(conn):
"""L2: Titel + Platzhalter-Text praeziser."""
row = conn.execute("SELECT titel, aufgabe_md FROM lektion WHERE nummer = 2").fetchone()
if not row:
return False
if row["titel"] == MARKER_L2_TITEL:
return False # schon migriert
neuer_titel = MARKER_L2_TITEL
# aufgabe_md neu formulieren — Inhalt bleibt Platzhalter,
# aber sprachlich klar mit "3D-Modell"
neuer_text = (
"**Was du in dieser Lektion lernst:**\n\n"
"- Auf **Printables** oder **MakerWorld** ein fertiges 3D-Modell finden, das du drucken willst.\n"
"- Das 3D-Modell in **Bambu Studio** importieren und slicen (in Druckanweisungen umwandeln).\n"
"- Druckzeit und Materialbedarf abschaetzen.\n"
"- Den Druck planen und drucken — auf einem unserer 4 Drucker (welcher gerade frei ist).\n\n"
"**Aufgabe:** Such dir ein 3D-Modell aus, das unter 1 h Druckzeit liegt. "
"Etwas, das du wirklich haben willst — der Druck dauert mindestens so lange wie ein Schulfilm.\n\n"
"*Detaillierter Inhalt wird mit Herr Rechmann ausgearbeitet — bis dahin: "
"fragt den Lehrer, der zeigt euch das Suchen + Slicen direkt am Drucker.*"
)
conn.execute(
"UPDATE lektion SET titel = ?, aufgabe_md = ? WHERE nummer = 2",
(neuer_titel, neuer_text)
)
return True
def update_l3(conn):
"""L3: Titel + Platzhalter-Text praeziser."""
row = conn.execute("SELECT titel, aufgabe_md FROM lektion WHERE nummer = 3").fetchone()
if not row:
return False
if row["titel"] == MARKER_L3_TITEL:
return False # schon migriert
neuer_titel = MARKER_L3_TITEL
neuer_text = (
"**Was du in dieser Lektion lernst:**\n\n"
"- Was ein **parametrisches 3D-Modell** ist: ein Modell, bei dem du Werte "
"(Name, Groesse, Schriftart) veraenderst und das Modell sich automatisch anpasst.\n"
"- Den **MakerWorld-Customizer** im Browser bedienen — kein eigenes CAD-Programm noetig.\n"
"- Ein Modell mit deinem **eigenen Namen** drucken (z.B. Schluesselanhaenger).\n\n"
"**Aufgabe:** Mach einen Schluesselanhaenger mit deinem Vornamen drauf — "
"veraendere Schriftart, Groesse, Loch-Position. Dann slicen + drucken.\n\n"
"**Tipp:** Das 3D-Modell *Parametric Name Keychain Creator* auf MakerWorld "
"ist ein guter Einstieg.\n\n"
"*Detaillierter Inhalt wird mit Herr Rechmann ausgearbeitet.*"
)
conn.execute(
"UPDATE lektion SET titel = ?, aufgabe_md = ? WHERE nummer = 3",
(neuer_titel, neuer_text)
)
return True
def main():
conn = get_db()
geaendert = []
if update_l1(conn):
geaendert.append("L1 (Text-Klärungen)")
if update_l2(conn):
geaendert.append("L2 (Titel + Text neu)")
if update_l3(conn):
geaendert.append("L3 (Titel + Text neu)")
conn.commit()
conn.close()
if geaendert:
print(f"[migration] Sprache 3D-Modell durchgesetzt in: {', '.join(geaendert)}")
else:
print("[migration] Alle Lektionen bereits auf neuer Sprache — nichts zu tun.")
if __name__ == "__main__":
main()