## Entwicklungshistorie Ursprünglich wurde dieses Modul als Auftragsarbeit von einer externen Firma entwickelt. Unglücklicherweise wurden während der Entwicklungsphase keine Code-Audits durchgeführt und die Qualität des gelieferten Codes ließ zu wünschen übrig. Teile des Codes mussten komplett neu entwickelt werden, da eine Fehlerbehebung nicht anders möglich erschien. Dies führte zu einer heterogenen Software-Architektur, da bei der Neuentwicklung in erster Linie auf Wartbarkeit und Verständlichkeit Wert gelegt wurde und einer angemessenen Dokumentierung. ### Gründe für eine teilweise Neu-Implementierung des Moduls Teile des Codes mussten neu entwickelt werden, da insbesondere die originale Implementierung der Visualisierungs-Komponente größtenteils unwartbar war. Einfache Fehler zu beheben war nur schwer möglich, da der Code mit einer unerkennbaren Logik in Module aufgeteilt war und gängige Techniken und von d3 ignoriert wurden. 1. Ein "Modul" mit dem Namen "redraw" war nur dazu gedacht, SVG-Elemente, die in anderen Code-Fragmenten erstellt wurden, zu aktualisieren. ﴾͡๏̯͡๏﴿ Um Wartbarkeit als Feature zu integrieren, wurde stattdessen die damals übliche Vorgehensweise implementiert ([General update pattern][d3-update-pattern]). Inzwischen wird diese schon wieder als veraltet bezeichnet, und die Verwendung von [selection.join][d3-selection-join] empfohlen. 2. Multiple-Choice-Fragen wurden ursprünglich gegen die Labels der Antworten validiert. Dabei wurde die Javascript Funktion `parseInt` auf alphanumerische Strings angewendet, bzw. unflexible Reguläre Ausdrücke verwendet, die scheitern würden, sobald sich die Struktur der Labels oder die natürliche Sprache änderte. ( ・\_・)ノ⌒●~\* Um dieses Problem zu beheben, wurde dem *offline*-Datensatz die notwendigen Daten hinzugefügt, um mathematische Validierung über Funktionen zu ermöglichen. Für jede Frage wird nun eine Referenz zu einer *Validator*-Funktion angegeben, die die Daten, die mit der gegebenen Antwort verknüpft sind, mit dem errechneten Ergebnis vergleicht. Aktuell ist die *online*-Version des Moduls nicht funktionsfähig, da die API noch nicht aktualisiert wurde (Stand Juni 2020). 3. Die aktuelle Implementierung ist nach wie vor sehr unflexibel bezogen auf die Anordnung der verschiedenen Fragetypen. Die Fragen sind in einem zweidimensionalen Array angeordnet, wobei der erste Index den Fragetyp und der zweite die Reihenfolge innerhalb der Gruppe definiert. Verschiedene Fragetypen können daher momentan nicht willkürlich abgewechselt werden. Immerhin wurde der größte Fehler behoben, der beim einfachen Umordnen von Fragen innerhalb einer Gruppe zum "abstürzen" der Web App führte. ٩(̾●̮̮̃̾•̃̾)۶ 4. Die Implementierung des Aufgabentyps zum Manipulieren von Graphen war fehlerhaft. Das Ergebnis wurde nur dann richtigerweise als korrekt erkannt, wenn exakt das Intervall wie in der Aufgabenstellung ausgewählt wurde. Mehrere "falsche Lösungen" konnten gefunden werden. Dadurch konnte der Nutzer mit der folgenden Aufgabe fortführen, auch wenn die Steigung des betrachteten Intervalls außerhalb der Toleranzgrenzen lag. Auch waren Konstellationen möglich, bei denen der betrachtete Teil des Graphen außerhalb des sichtbaren Bereichs lag. Transformationen des Auswahlbereichs wurden durch das *Parsen* von Werten aus dem SVG DOM mit Hilfe von wackeligen Regulären Ausdrücken durchgeführt. Fügte man der Transformation eine Rotation hinzu, funktionierte nichts mehr. Das weckt die Vermutung, dass die Geometrie der Anfasser aus diesem Grund zweimal definiert wurde, siehe 5. Dieser Teil wurde nahezu komplett neu implementiert, da der ursprüngliche Code zusätzlich zu den beschriebenen Fehlern unverständlich, verworren und dadurch unwartbar war. Es wurden "Techniken" verwendet, bei denen ein Modul in den SVG-DOM hineinschrieb und ein anderes Modul diesen Wert wieder auslas. ⊂(©෴©)つ Zur Verbesserung der Verständlichkeit wurde eine Controller-zentrische Architektur in Verbindung mit spezifischem Event-Dispatching gewählt. Zur Validierung der Nutzer-gewählten Auswahl werden drei Auswahlbereiche definiert: die `reference range` bezeichnet den ursprünglich ausgewählten Bereich, auf den der benutzerdefinierte Bereich (`selected range`) initialisiert wird. Der Graph wird anhand letzterer transformiert. Die `solution range` definiert die exakte Lösung und wird für die Validierung der Nutzerauswahl verwendet. Sobald der betrachtete Teil des Graphen sichtbar ist und das Validierungskriterium der Frage erfüllt ist, wird die benutzerdefinierte Auswahl als Lösung anerkannt und das Fortfahren zur folgenden Frage wird ermöglicht. 5. Die Geometrie der Anfasser zum Skalieren der Graphen wurde zweimal definiert, einmal für die horizontale und einmal für die vertikale Version, auch wenn sie sich nur durch eine 90 Grad Rotation unterscheiden (ganz der Wahrheit entsprechend ist das nicht, die inneren Linien waren in einem Fall falsch ausgerichtet). Auch dieser Code war so verworren und verständlich wie ein Stück Hirn in Aspik. In einem Aufruf der Funktion bezog sich die Variable "width" tatsächlich auf die Breite, im anderen Fall auf die Höhe (und umgekehrt bei "height"). Dieser Fakt wurde, vermutlich aus Scham, mit keinem Kommentar erwähnt. ℃ↂ\_ↂ Die Geometrie ist nun nur einmal definiert und wird als SVG Symbol jeweils referenziert und durch Matrizen transformiert. Nebenbei wurde ein zeichnerisches Problem behoben. Dies sind nur Beispiele für die Probleme, die der ursprüngliche Code mitgebracht hat. Die Liste ist sicherlich nicht vollständig und es befinden sich höchstwahrscheinlich nach wie vor Eigenheiten und Fehler im Code, die man hinterfragen kann bzw. sollte. [d3-update-pattern]: https://observablehq.com/@d3/general-update-pattern?collection=@d3/d3-selection [d3-selection-join]: https://observablehq.com/@d3/selection-join