/** * 🩺 PYTHON TRACEBACK & FEHLER-DOLMETSCHER 🩺 * ============================================ * Basiert auf der didaktischen Fehlerforschung (Brett Becker et al., SIGCSE). * Übersetzt kryptische Python-Fehlermeldungen in einfühlsames, klares Deutsch * mit konkreten Handlungsanweisungen für Schülerinnen und Schüler. */ (function () { const ERROR_RULES = [ { type: "IndentationError", pattern: /IndentationError: (expected an indented block|unindent does not match)/i, title: "📐 Einrückungsfehler (IndentationError)", explanation: "Python nutzt Einrückungen (Standard: genau 4 Leerzeichen), um zu erkennen, welcher Code zu einer Funktion, `if`-Bedingung oder Schleife gehört.", causes: [ "Nach einem Doppelpunkt (def ...:, if ...:, for ...:) fehlt die Einrückung.", "Leerzeichen und Tabulatoren wurden versehentlich gemischt." ], fix: "Drücke nach dem Doppelpunkt Enter und rücke die Zeile mit Tab oder 4 Leerzeichen ein. Mit Umschalt + Tab kannst du Zeilen wieder nach links rücken." }, { type: "TypeError NoneType", pattern: /TypeError: 'NoneType' object is not (subscriptable|iterable|callable)/i, title: "🕳️ Zugriff auf 'None' (TypeError)", explanation: "Du versuchst auf ein Objekt zuzugreifen, das gar nicht existiert oder den Wert None hat.", causes: [ "Eine aufgerufene Funktion hat vergessen, ihr Ergebnis mit return zurückzugeben.", "Eine Listen-Methode wie liste.sort() oder liste.append() gibt immer None zurück (sie verändert die Liste direkt!)." ], fix: "Prüfe in deinen Funktionen, ob am Ende ein return ergebnis steht. Schreibe niemals x = liste.sort(), sondern nur liste.sort()." }, { type: "AttributeError", pattern: /AttributeError: '([^']+)' object has no attribute '([^']+)'/i, title: "🔍 Unbekanntes Attribut oder Methode (AttributeError)", explanation: "Python konnte an dem Objekt die gewünschte Methode oder Eigenschaft nicht finden.", causes: [ "Tippfehler im Namen der Methode oder Variable (z.B. anhängen statt append).", "Groß- und Kleinschreibung nicht beachtet (z.B. .Name statt .name).", "In der Klassen-Methode wurde self. vergessen (z.B. alter statt self.alter)." ], fix: "Überprüfe die Schreibweise des Attributs exakt Buchstabe für Buchstabe. Nutze in Klassen immer self.attributname." }, { type: "TypeError self missing", pattern: /TypeError: ([^\(]+)\(\) takes \d+ positional arguments? but \d+ were given/i, title: "🧩 Fehlendes 'self' in Methoden-Definition (TypeError)", explanation: "Eine Methode in einer Klasse erwartet weniger oder mehr Parameter als übergeben wurden.", causes: [ "Der klassische Anfängerfehler: Du hast im Methodenkopf das self als ersten Parameter vergessen! (z.B. def fahren(): statt def fahren(self):)." ], fix: "Schreibe in jeder Methode deiner Klasse als allerersten Parameter immer self: z.B. def beschleunigen(self, kmh):." }, { type: "IndexError", pattern: /IndexError: (list index out of range|string index out of range)/i, title: "🎯 Index außerhalb des gültigen Bereichs (IndexError)", explanation: "Du greifst auf eine Position (Index) in einer Liste oder einem String zu, die gar nicht existiert.", causes: [ "Off-by-One Fehler: In Python beginnt die Zählung bei 0! Eine Liste mit 3 Elementen hat nur die Indizes 0, 1, 2 (nicht 3).", "Die Liste ist noch leer." ], fix: "Prüfe die Länge der Liste mit len(liste). Das letzte Element erreichst du immer sicher mit liste[-1]." }, { type: "KeyError", pattern: /KeyError: (.+)/i, title: "🔑 Schlüssel nicht im Dictionary gefunden (KeyError)", explanation: "Du hast versucht, aus einem Dictionary dict[schluessel] einen Eintrag abzufragen, der nicht existiert.", causes: [ "Der gesuchte Key ist nicht im Dictionary vorhanden oder falsch geschrieben." ], fix: "Nutze die sichere Abfrage mit dict.get(key, standardwert) statt der eckigen Klammern, um Abstürze zu vermeiden!" }, { type: "NameError", pattern: /NameError: name '([^']+)' is not defined/i, title: "❓ Name nicht definiert (NameError)", explanation: "Python kennt das Wort oder die Variable an dieser Stelle nicht.", causes: [ "Die Variable wurde weiter unten oder in einer anderen Funktion definiert (Gültigkeitsbereich/Scope).", "Ein Tippfehler im Variablennamen.", "Ein Modul wie import math wurde noch nicht importiert." ], fix: "Prüfe, ob du die Variable vor ihrer Benutzung angelegt hast und ob alle benötigten Module oben mit import ... eingebunden sind." }, { type: "ZeroDivisionError", pattern: /ZeroDivisionError: division by zero/i, title: "➗ Division durch Null (ZeroDivisionError)", explanation: "In der Mathematik und in Python ist das Teilen durch 0 nicht erlaubt.", causes: [ "Der Nenner / Teiler hat den Wert 0." ], fix: "Sichere die Division mit einer if teiler != 0: Bedingung oder fange sie mit try-except ZeroDivisionError: ab." } ]; window.interpretiereTraceback = function (errorText) { if (!errorText || !errorText.trim()) { return { matched: false, title: "💡 Bitte füge eine Fehlermeldung ein", explanation: "Kopiere deinen Traceback aus dem Terminal und füge ihn hier ein.", fix: "Starte dein Skript im Terminal mit python3 test_aufgabe.py" }; } for (let rule of ERROR_RULES) { if (rule.pattern.test(errorText)) { return { matched: true, type: rule.type, title: rule.title, explanation: rule.explanation, causes: rule.causes, fix: rule.fix }; } } return { matched: false, title: "🔍 Allgemeiner Python-Fehler", explanation: "Lies den Traceback immer von ganz unten nach oben: In der allerletzten Zeile nennt Python die genaue Fehlerart und Zeilennummer.", causes: ["Syntax- oder Logikfehler in deinem Code."], fix: "Überprüfe die in der letzten Zeile genannte Zeilennummer in deiner aufgabe.py Datei." }; }; // Widget rendern, falls Container vorhanden document.addEventListener("DOMContentLoaded", () => { const interpreterEl = document.getElementById("error-interpreter-widget"); if (!interpreterEl) return; interpreterEl.innerHTML = `

🩺 Interaktiver Python-Fehler-Dolmetscher

Du verstehst eine Fehlermeldung aus dem Terminal nicht? Füge sie hier ein und erhalte sofort eine schülerfreundliche deutsche Erklärung mit Reparatur-Anleitung!

`; const input = document.getElementById("traceback-input"); const btn = document.getElementById("btn-interpret"); const result = document.getElementById("interpreter-result"); btn.addEventListener("click", () => { const res = window.interpretiereTraceback(input.value); result.innerHTML = `
${res.title}

Was bedeutet das? ${res.explanation}

${res.causes ? `

Mögliche Ursachen:

` : ''}
🔧 So behebst du den Fehler:

${res.fix}

`; result.style.display = "block"; }); }); })();