From 3a126cc45a6530ee04191ace210f85c215c8d4f1 Mon Sep 17 00:00:00 2001 From: Max <m.giller.dev@gmail.com> Date: Wed, 20 Oct 2021 16:00:18 +0200 Subject: [PATCH] Working merge with master --- config.js | 3 +- datasets/AuD-Inhalt2.xlsx | Bin 35983 -> 35980 bytes datasets/aud1v3.json | 106 +++++++++++++++++------------------ datasets/datasets.js | 44 ++++++++------- datasets/datasets.php | 48 +++++++++------- datasets/space.json | 94 +++++++++++++++---------------- datasets/xlsxTOjson.ipynb | 64 ++++++++++++--------- display/graph.js | 13 +++-- display/overlays/nodeinfo.js | 7 ++- editor/js/editor.js | 5 +- editor/js/state.js | 20 +++++++ editor/js/tools/tool.js | 12 ++++ knowledge-space.php | 46 +++++++++------ 13 files changed, 271 insertions(+), 191 deletions(-) diff --git a/config.js b/config.js index e1c17d8..2e077a9 100644 --- a/config.js +++ b/config.js @@ -9,4 +9,5 @@ export const COLOR_PALETTE = [ ]; // Just renaming a variable which is given by the PHP script. This avoids errors in all other files. -export const PLUGIN_PATH = plugin_path; +export const PLUGIN_PATH = plugin.path; +export const SPACE = space.id; diff --git a/datasets/AuD-Inhalt2.xlsx b/datasets/AuD-Inhalt2.xlsx index 3eef912de1b19d3d2535e0d80a8465047f519bdf..eb43c7b8be4a57b3c217022c32dac1fba4dd04d5 100644 GIT binary patch delta 28520 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 X$YTe`kVoobOUK-eWXC5(qA&X|&dHSu delta 28511 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 TakMs;RFZi#^JUTqG~53Gfvc-I diff --git a/datasets/aud1v3.json b/datasets/aud1v3.json index fa2c308..9c7f868 100644 --- a/datasets/aud1v3.json +++ b/datasets/aud1v3.json @@ -2,8 +2,8 @@ "nodes": [ { "id": 1, - "name": "Einführung", - "description": "Eine Einführung in die Algorithmen und Datenstrukturen\\n+ Links zu Video und Folien", + "name": "Begrüßung und Organisatorisches", + "description": "Eine Einführung in die Algorithmen und Datenstrukturen", "type": "Vorlesung" }, { @@ -21,13 +21,13 @@ { "id": 4, "name": "Algorithmus-Definition", - "description": "“Ein Algorithmus ist eine aus endlich vielen Schritten bestehende eindeutige Handlungsvorschrift zur Lösung eines Problems oder einer Klasse von Problemen.â€-Wikipedia. Dabei wird als Input eine Problembeschreibung gegeben und durch Anwendung des Algorithmus eine fertige Lösung des Problems ermittelt. Oft spielt die Laufzeit des Algorithmus eine große Rolle. Sie beschreibt, wie viele einzelne Schritte nötig sind um das Problem zu lösen, in Abhängigkeit von der Größe des Problems.", + "description": "Zitat: 'Ein Algorithmus ist eine aus endlich vielen Schritten bestehende eindeutige Handlungsvorschrift zur Lösung eines Problems oder einer Klasse von Problemen.'-Wikipedia. Dabei wird als Input eine Problembeschreibung gegeben und durch Anwendung des Algorithmus eine fertige Lösung des Problems ermittelt. Oft spielt die Laufzeit des Algorithmus eine große Rolle. Sie beschreibt, wie viele einzelne Schritte nötig sind um das Problem zu lösen, in Abhängigkeit von der Größe des Problems.", "type": "Definition" }, { "id": 5, "name": "Kofferpacken", - "description": "Kann ich alle meine Gepäckstücke auf zwei gleich große Koffer aufteilen? Gegeben: Eine Menge von n Objekten, jedes mit\\neiner Größe li; Gesamtgröße ∑ li = 2K\\nGesucht: Eine Verteilung auf zwei Koffer der Größe K", + "description": "Kann ich alle meine Gepäckstücke auf zwei gleich große Koffer aufteilen? <br>Gegeben: Eine Menge von n Objekten, jedes mit einer Größe li; <br>Gesamtgröße ∑ li = 2K<br>Gesucht: Eine Verteilung auf zwei Koffer der Größe K", "type": "Beispiel" }, { @@ -38,8 +38,8 @@ }, { "id": 7, - "name": "Algorithmen und Datenstrukturen", - "description": "In dieser Vorlesung wird der Begriff \'Algorithmus\' definiert und erklärt.\\n+ Links zu Video und Folien", + "name": "Einführung des Algorithmusbegriffs", + "description": "In dieser Vorlesung wird der Begriff 'Algorithmus' definiert und erklärt.", "type": "Vorlesung" }, { @@ -51,19 +51,19 @@ { "id": 21, "name": "Organisation und Pseudocode", - "description": "In dieser Ãœbung haben wir noch einmal organisatorische Dinge besprochen und uns mit dem Thema Pseudocode auseinandergesetzt.\\n+ Links zu Video und Folien", + "description": "In dieser Ãœbung haben wir noch einmal organisatorische Dinge besprochen und uns mit dem Thema Pseudocode auseinandergesetzt.", "type": "Ãœbung" }, { "id": 9, "name": "Pseudocode", - "description": "Pseudocode ist eine Art Algorithmen einigermaßen einheitlich zu notieren. Dabei werden zwar Schlüsselwörter genutzt um eine gewisse Einheitlichkeit zu bieten und gleichzeitig die Logik zu beschreiben, allerdings geht es noch nicht darum einen compilierbaren Code mit korrekter Syntax zu schreiben.\\n+ Link zu Pseudocodeblatt, Ãœbung 1", + "description": "Pseudocode ist eine Art Algorithmen einigermaßen einheitlich zu notieren. Dabei werden zwar Schlüsselwörter genutzt um eine gewisse Einheitlichkeit zu bieten und gleichzeitig die Logik zu beschreiben, allerdings geht es noch nicht darum einen compilierbaren Code mit korrekter Syntax zu schreiben.", "type": "Definition" }, { "id": 10, "name": "Einleitung in die Graphen", - "description": "Eine Einleitung in die Welt der Graphen am wohl bekanntesten Beispiel, dem Haus des Nikolaus.\\n+ Links zu Video und Folien", + "description": "Eine Einleitung in die Welt der Graphen am wohl bekanntesten Beispiel, dem Haus des Nikolaus.", "type": "Vorlesung" }, { @@ -81,7 +81,7 @@ { "id": 13, "name": "Graphenbegriffe", - "description": "Ein Graph besteht aus Knoten und Kanten das sollte inzwischen jeder wissen, doch was parallele Kanten, Schleifen, (geschlossene) Wege, Pfade, Kreise, Eulerwege/-touren, sowie Hamiltonpfade und -kreise sind wird in dieser Vorlesung noch einmal genau definiert.\\n+ Links zu Video und Folien", + "description": "Ein Graph besteht aus Knoten und Kanten das sollte inzwischen jeder wissen, doch was parallele Kanten, Schleifen, (geschlossene) Wege, Pfade, Kreise, Eulerwege/-touren, sowie Hamiltonpfade und -kreise sind wird in dieser Vorlesung noch einmal genau definiert.", "type": "Vorlesung" }, { @@ -98,14 +98,14 @@ }, { "id": 16, - "name": "Beweistechniken", - "description": "In der Mathematik und auch in der Algorithmik spielen Beweise immer wieder eine große Rolle. Es geht darum Aussagen zu belegen, zu widerlegen oder auf bestimmte Elemente anzuwenden. Dazu gibt es verschiedene Beweistechniken, welche ihr hier finden könnt:\\n+ Link zu Beweisblatt, Ãœbung 2", + "name": "Beweistechniken Teil 1", + "description": "In der Mathematik und auch in der Algorithmik spielen Beweise immer wieder eine große Rolle. Es geht darum Aussagen zu belegen, zu widerlegen oder auf bestimmte Elemente anzuwenden. Dazu gibt es verschiedene Beweistechniken, welche ihr hier finden könnt:", "type": "Ãœbung" }, { "id": 17, - "name": "Eulertouren", - "description": "In dieser Vorlesung werden notwendige Bedingungen für Eulertouren erleutert. Zusätzlich wird das Kapitel 2 noch einmal zusammengefasst und es werden Algorithmen eingeführt um die uns bisher bekannten Probleme zu lösen.\\n+ Links zu Video und Folien", + "name": "Bedingungen für Eulertouren", + "description": "In dieser Vorlesung werden notwendige Bedingungen für Eulertouren erleutert. Zusätzlich wird das Kapitel 2 noch einmal zusammengefasst und es werden Algorithmen eingeführt um die uns bisher bekannten Probleme zu lösen.", "type": "Vorlesung" }, { @@ -123,25 +123,25 @@ { "id": 20, "name": "Algorithmus von Fleury", - "description": "Dieser Algorithmus(2.13) erhält als Input einen Graphen G mit höchstens 2 ungeraden Knoten und liefert als Output einen Weg in G. Der Algorithmus hat als Grundlage Algorithmus 2.7 zum Finden von Wegen. Auch lässt sich zeigen, dass man mit diesem Algorithmus eine Eulertour/einen Eulerweg finden kann", + "description": "Dieser Algorithmus(2.13) erhält als Input einen Graphen G mit höchstens 2 ungeraden Knoten und liefert als Output einen Weg in G. Der Algorithmus hat als Grundlage Algorithmus 2.7 zum Finden von Wegen. Auch lässt sich zeigen, dass man mit diesem Algorithmus eine Eulertour/einen Eulerweg finden kann.", "type": "Algorithmus" }, { "id": 22, "name": "Anwendung von Graphen", - "description": "In dieser Vorlesung geht es um den Einsatzzweck von Graphen und es wird am Beispiel der Erdös- und der Kevin Bacon Zahl gezeigt, welche Zusammenhänge dargestellt werden können.\\n+ Links zu Video und Folien", + "description": "In dieser Vorlesung geht es um den Einsatzzweck von Graphen und es wird am Beispiel der Erdös- und der Kevin Bacon Zahl gezeigt, welche Zusammenhänge dargestellt werden können.", "type": "Vorlesung" }, { "id": 23, "name": "Beweistechniken Teil 2", - "description": "In dieser Ãœbung geht es um die Beweistechnik der vollständigen Induktion. Diese ist die wohl meist benutzte Beweistechnik in der Algorithmik. Auch werden Anwendungsbeispiele wie z.B. die Gauß\'sche Summenformel oder der Zusammenhang in Graphen erläutert.\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Ãœbung geht es um die Beweistechnik der vollständigen Induktion. Diese ist die wohl meist benutzte Beweistechnik in der Algorithmik. Auch werden Anwendungsbeispiele wie z.B. die Gauß'sche Summenformel oder der Zusammenhang in Graphen erläutert.", "type": "Ãœbung" }, { "id": 24, "name": "Graphenscan", - "description": "In dieser Vorlesung wird der Graphenscanalgorithmus vorgestellt um Zusammenhangskomponenten in Graphen zu finden.\\n+ Links zu Video und Folien/Notizen/Beweis", + "description": "In dieser Vorlesung wird der Graphenscanalgorithmus vorgestellt um Zusammenhangskomponenten in Graphen zu finden.", "type": "Vorlesung" }, { @@ -153,19 +153,19 @@ { "id": 26, "name": "Datenstrukturen Teil 1", - "description": "In dieser Vorlesung werden die Datenstrukturen Warteschlange (First In - First Out) und Stapel (Last In - First Out) vorgestellt. Außerdem geht es um ihre Rolle für Algorithmen und wie man sie implementieren kann. Das ganze wird am Beispiel des Graphscan Algorithmus gezeigt und somit werden auch Breiten- und Tiefensuche eingeführt.\\n+ Links zu Video und Folien/Beispiel", + "description": "In dieser Vorlesung werden die Datenstrukturen Warteschlange (First In - First Out) und Stapel (Last In - First Out) vorgestellt. Außerdem geht es um ihre Rolle für Algorithmen und wie man sie implementieren kann. Das ganze wird am Beispiel des Graphscan Algorithmus gezeigt und somit werden auch Breiten- und Tiefensuche eingeführt.", "type": "Vorlesung" }, { "id": 27, "name": "Warteschlange", - "description": "Eine Warteschlange ist eine Datenstruktur, welche nach dem Prinzip \'First In - First Out\' arbeitet. Man findet sie auch im alltäglichen Leben oft wieder, wenn man sich beispielsweise an der Kasse anstellen muss. Der Kunde der zuerst da war, wir auch zuerst bedient.", + "description": "Eine Warteschlange ist eine Datenstruktur, welche nach dem Prinzip 'First In - First Out' arbeitet. Man findet sie auch im alltäglichen Leben oft wieder, wenn man sich beispielsweise an der Kasse anstellen muss. Der Kunde der zuerst da war, wir auch zuerst bedient.", "type": "Definition" }, { "id": 28, "name": "Stapel", - "description": "Ein Stapel ist eine Datenstruktur, welche nach dem Prinzip \'Last In - First Out\' arbeitet. Im alltäglichen Leben findet man diese Form der Datenstruktur beim Geschirr abwaschen, man stapelt die Teller und der Teller der zuletzt dreckig wurde wird als erstes gereinigt, da man die Teller von oben herunter nimmt.", + "description": "Ein Stapel ist eine Datenstruktur, welche nach dem Prinzip 'Last In - First Out' arbeitet. Im alltäglichen Leben findet man diese Form der Datenstruktur beim Geschirr abwaschen, man stapelt die Teller und der Teller der zuletzt dreckig wurde wird als erstes gereinigt, da man die Teller von oben herunter nimmt.", "type": "Definition" }, { @@ -183,7 +183,7 @@ { "id": 31, "name": "Datenstrukturen Teil 2", - "description": "In dieser Vorlesung geht es einerseits um die Anwendung der Breitensuche, andererseits werden noch 2 weitere Datenstrukturen eingeführt: Die Inzidenz/-Adjazenzmatrix, sowie die Kantenliste\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Vorlesung geht es einerseits um die Anwendung der Breitensuche, andererseits werden noch 2 weitere Datenstrukturen eingeführt: Die Inzidenz/-Adjazenzmatrix, sowie die Kantenliste.", "type": "Vorlesung" }, { @@ -201,7 +201,7 @@ { "id": 34, "name": "Wachstum/O-Notation", - "description": "In dieser Vorlesung wird noch einmal mit den Adjazenz- und Kantenlisten abgeschlossen. Außerdem schauen wir uns einmal das Wachstum von Funktionen an und definieren und die O-Notation um damit zu arbeiten.\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Vorlesung wird noch einmal mit den Adjazenz- und Kantenlisten abgeschlossen. Außerdem schauen wir uns einmal das Wachstum von Funktionen an und definieren und die O-Notation um damit zu arbeiten.", "type": "Vorlesung" }, { @@ -224,14 +224,14 @@ }, { "id": 38, - "name": "Wiederholung oder\\nSuche in Graphen Zusammenfassung", - "description": "Noch einmal ein Rückblick auf alles, was bisher in \'Kapitel 3: Suche in Graphen\' passiert ist. \\n+ Links zu Video und Folien", + "name": "Wiederholung: Suche in Graphen", + "description": "Noch einmal ein Rückblick auf alles, was bisher in 'Kapitel 3: Suche in Graphen' passiert ist. ", "type": "Vorlesung" }, { "id": 39, "name": "Eigenschaften von DFS und BFS", - "description": "In dieser Vorlesung betrachten wir die Breiten- und Tiefensuche im Hinblick auf ihre Laufzeit. Dabei wird anschaulich, wie die Algorithmen arbeiten, wann man sie am besten nutzen sollte und wie man Laufzeiten beweisen kann.\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Vorlesung betrachten wir die Breiten- und Tiefensuche im Hinblick auf ihre Laufzeit. Dabei wird anschaulich, wie die Algorithmen arbeiten, wann man sie am besten nutzen sollte und wie man Laufzeiten beweisen kann.", "type": "Vorlesung" }, { @@ -254,8 +254,8 @@ }, { "id": 43, - "name": "Dynamische Datenstrukturen", - "description": "In dieser Vorlesung beginnen wir dynamische Datenstrukturen einzuführen. Es werden Stapel, Warteschlangen und verkettete Listen vorgestellt. Außerdem beschäftigen wir uns mit binärer Suche.\\n+ Links zu Video und Folien", + "name": "Verschiedene dynamische Datenstrukturen", + "description": "In dieser Vorlesung beginnen wir dynamische Datenstrukturen einzuführen. Es werden Stapel, Warteschlangen und verkettete Listen vorgestellt. Außerdem beschäftigen wir uns mit binärer Suche.", "type": "Vorlesung" }, { @@ -285,13 +285,13 @@ { "id": 48, "name": "Binäre Suchbäume", - "description": "In dieser Vorlesung beschäftigen wir uns genauer mit binären Suchbäumen und den darauf anwendbaren Operationen, wie Maximum, Minimum, einfügen und löschen von Knoten, sowie mit der binären Suche.\\n+ Links zu Video und Folien", + "description": "In dieser Vorlesung beschäftigen wir uns genauer mit binären Suchbäumen und den darauf anwendbaren Operationen, wie Maximum, Minimum, einfügen und löschen von Knoten, sowie mit der binären Suche.", "type": "Vorlesung" }, { "id": 49, "name": "Binärer Suchbaum", - "description": "In dieser Definition werden die Begriffe \'gerichteter Graph/Baum\', \'Höhe eines Baumes\', \'(voller/vollständiger) binärer Baum\', \'Blatt eines Baumes\', \'Teilbaum eines Knotens\' und \'binärer Suchbaum\' definiert und erklärt.", + "description": "In dieser Definition werden die Begriffe 'gerichteter Graph/Baum', 'Höhe eines Baumes', '(voller/vollständiger) binärer Baum', 'Blatt eines Baumes', 'Teilbaum eines Knotens' und 'binärer Suchbaum' definiert und erklärt.", "type": "Definition" }, { @@ -303,7 +303,7 @@ { "id": 51, "name": "AVL-Bäume", - "description": "In dieser Vorlesung beschäftigen wir uns mit speziellen binären Suchbäumen, den AVL-Bäumen und ihren Eigenschaften.\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Vorlesung beschäftigen wir uns mit speziellen binären Suchbäumen, den AVL-Bäumen und ihren Eigenschaften.", "type": "Vorlesung" }, { @@ -315,7 +315,7 @@ { "id": 53, "name": "dyn. Operationen auf AVL-Bäumen", - "description": "In dieser Vorlesung beschäftigen wir uns mit dem Erhalt der AVL-Eigenschaft eines binären Suchbaumes bei Einfüge- und Löschoperationen. Außerdem werfen wir einen Blick auf die Fibonacci-Zahlen.\\n+ Links zu Video und Folien", + "description": "In dieser Vorlesung beschäftigen wir uns mit dem Erhalt der AVL-Eigenschaft eines binären Suchbaumes bei Einfüge- und Löschoperationen. Außerdem werfen wir einen Blick auf die Fibonacci-Zahlen.", "type": "Vorlesung" }, { @@ -344,7 +344,7 @@ }, { "id": 58, - "name": "Grundoperationen Suchbaum", + "name": "Beispiel Suchbaumoperationen", "description": "In diesem Teil der Ãœbung werden einmal die Operationen Einfügen, Suchen, Vorgänger/Nachfolger finden, löschen und verschmelzen von binären Suchbäumen geübt.", "type": "Beispiel" }, @@ -357,13 +357,13 @@ { "id": 60, "name": "Dynamische Datenstrukturen 2", - "description": "In dieser Vorlesung schauen wir noch einmal auf das bisher in Kapitel 4 gelernte zurück. Außerdem geben wir einen Ãœberblick über einige weitere dynamische Datenstrukturen wie Rot-Scharz-Bäumme, B-Bäume und Heaps.\\n+ Links zu Video und Folien", + "description": "In dieser Vorlesung schauen wir noch einmal auf das bisher in Kapitel 4 gelernte zurück. Außerdem geben wir einen Ãœberblick über einige weitere dynamische Datenstrukturen wie Rot-Scharz-Bäumme, B-Bäume und Heaps.", "type": "Vorlesung" }, { "id": 61, "name": "Rot-Schwarz-Bäume", - "description": "Ein binärer Suchbaum heißt Rot-Schwarz-Baum, wenn er die folgenden Eigenschaften erfüllt:\\n1. Jeder Knoten ist entweder rot oder schwarz.\\n2. Die Wurzel ist schwarz.\\n3. Jedes Blatt (NIL) ist schwarz.\\n4. Wenn ein Knoten rot ist, sind seine beiden Kinder schwarz.\\n5. Für jeden Knoten enthalten alle Pfade nach unten zu einem Blatt des Teilbaumes die gleiche Anzahl schwarzer Knoten.", + "description": "Ein binärer Suchbaum heißt Rot-Schwarz-Baum, wenn er die folgenden Eigenschaften erfüllt:<br>1. Jeder Knoten ist entweder rot oder schwarz.<br>2. Die Wurzel ist schwarz.<br>3. Jedes Blatt (NIL) ist schwarz.<br>4. Wenn ein Knoten rot ist, sind seine beiden Kinder schwarz.<br>5. Für jeden Knoten enthalten alle Pfade nach unten zu einem Blatt des Teilbaumes die gleiche Anzahl schwarzer Knoten.", "type": "Definition" }, { @@ -375,13 +375,13 @@ { "id": 63, "name": "Heaps", - "description": "Ein gerichteter binärer Baum heißt binärer Min/Max-Heap, wenn jeder Knoten einen Schlüssel hat, alle Ebenen außer der \'letzten\' genau 2 Knoten haben, auf der \'letzten\' Ebene die linken n-(2^h)+1 Positionen besetzt sind und jeder Schlüssel eines Knotens höchstens/mindestens so groß ist wie die seiner Kinder.", + "description": "Ein gerichteter binärer Baum heißt binärer Min/Max-Heap, wenn jeder Knoten einen Schlüssel hat, alle Ebenen außer der 'letzten' genau 2 Knoten haben, auf der 'letzten' Ebene die linken n-(2^h)+1 Positionen besetzt sind und jeder Schlüssel eines Knotens höchstens/mindestens so groß ist wie die seiner Kinder.", "type": "Definition" }, { "id": 64, - "name": "Sortieren", - "description": "In dieser Vorlesung geben wir eine Einführung in das Oberthema Sortieren. Wir stellen außerdem einen Sortieralgorithmus mit dem Namen Mergesort vor und stellen grundlegende Ãœberlegungen zur Laufzeit von Sortieralgorithmen an.\\n+ Links zu Video und Folien/Notizen", + "name": "Einführung in das Sortieren", + "description": "In dieser Vorlesung geben wir eine Einführung in das Oberthema Sortieren. Wir stellen außerdem einen Sortieralgorithmus mit dem Namen Mergesort vor und stellen grundlegende Ãœberlegungen zur Laufzeit von Sortieralgorithmen an.", "type": "Vorlesung" }, { @@ -393,7 +393,7 @@ { "id": 66, "name": "Sortier-Laufzeitschranken", - "description": "In dieser Vorlesung leiten wir konkrete Laufzeitschranken für das Problem des Sortierens einer Liste von Zahlen her. Zudem machen wir uns Gedanken über das Lösen von Rekursionsgleichungen.\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Vorlesung leiten wir konkrete Laufzeitschranken für das Problem des Sortierens einer Liste von Zahlen her. Zudem machen wir uns Gedanken über das Lösen von Rekursionsgleichungen.", "type": "Vorlesung" }, { @@ -411,7 +411,7 @@ { "id": 69, "name": "Erzeugende Funktionen/Mastertheorem", - "description": "In dieser Vorlesung besprechen wir weitere Details zu erzeugenden Funktionen und führen das Master-Theorem ein.\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Vorlesung besprechen wir weitere Details zu erzeugenden Funktionen und führen das Master-Theorem ein.", "type": "Vorlesung" }, { @@ -435,7 +435,7 @@ { "id": 73, "name": "Sortieralgorithmen und Master-Theorem", - "description": "Wir betrachten ein weiteres Beispiel für Mergesort und leiten erneut die Laufzeit des Sortieralgorithmus her, indem das Master-Theorem benutzt wird. Außerdem betrachten wir einen weiteren Sortieralgorithmus: Heapsort.\\n+ Links zu Video und Folien", + "description": "Wir betrachten ein weiteres Beispiel für Mergesort und leiten erneut die Laufzeit des Sortieralgorithmus her, indem das Master-Theorem benutzt wird. Außerdem betrachten wir einen weiteren Sortieralgorithmus: Heapsort.", "type": "Ãœbung" }, { @@ -458,7 +458,7 @@ }, { "id": 77, - "name": "Max-Heaps", + "name": "Max-Heaps Anwendung", "description": "Hier wird der Algorithmus aus der Ãœbung 6 zum Erstellen eines Max-Heaps einmal an einem Beispiel angewandt.", "type": "Beispiel" }, @@ -471,7 +471,7 @@ { "id": 79, "name": "nichtlineare Rekursionen (Exkurs)", - "description": "In dieser Vorlesung haben wir einen Exkurs in die nichtlineare Rekursion gemacht.\\n+ Links zu Video und Folien", + "description": "In dieser Vorlesung haben wir einen Exkurs in die nichtlineare Rekursion gemacht.", "type": "Vorlesung" }, { @@ -501,13 +501,13 @@ { "id": 84, "name": "Game of Life", - "description": "Das \'Game of Life\' ist das wohl bekannteste Beispiel eines zellulären Automaten. ", + "description": "Das 'Game of Life' ist das wohl bekannteste Beispiel eines zellulären Automaten. ", "type": "Beispiel" }, { "id": 85, - "name": "Quick-Sort", - "description": "In dieser Vorlesung kehren wir zurück zu Sortieralgorithmen und stellen den Quicksort-Algorithmus vor.\\n+ Links zu Video und Folien/Notizen", + "name": "Einführung von Quick-Sort", + "description": "In dieser Vorlesung kehren wir zurück zu Sortieralgorithmen und stellen den Quicksort-Algorithmus vor.", "type": "Vorlesung" }, { @@ -525,7 +525,7 @@ { "id": 88, "name": "Mediane", - "description": "In dieser Vorlesung beschäftigen wir uns mit Medianen.\\n+ Links zu Video und Folien", + "description": "In dieser Vorlesung beschäftigen wir uns mit Medianen.", "type": "Vorlesung" }, { @@ -537,7 +537,7 @@ { "id": 90, "name": "Median (diskret)", - "description": "Der Rank k eines Elements x (auch \'k-tes Element\') ist definiert durch |{y ∈ X |y<=x}| = k. Also die Anzahl der Elemente, welche kleiner oder gleich x sind. Speziell heißt x Median, wenn er das [n/2]-te Element ist. [n/2] wird dabei abgerundet.", + "description": "Der Rank k eines Elements x (auch 'k-tes Element') ist definiert durch |{y ∈ X |y<=x}| = k. Also die Anzahl der Elemente, welche kleiner oder gleich x sind. Speziell heißt x Median, wenn er das [n/2]-te Element ist. [n/2] wird dabei abgerundet.", "type": "Definition" }, { @@ -549,7 +549,7 @@ { "id": 92, "name": "Sortieralgorithmen Sonderfälle", - "description": "In dieser Vorlesung beschäftigen wir uns mit Sonderfällen für Sortieralgorithmen, durch die Sortieren in linearer Zeit ermöglicht wird. Dabei werfen wir einen näheren Blick auf die Sortierverfahren Countingsort und Radixsort.\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Vorlesung beschäftigen wir uns mit Sonderfällen für Sortieralgorithmen, durch die Sortieren in linearer Zeit ermöglicht wird. Dabei werfen wir einen näheren Blick auf die Sortierverfahren Countingsort und Radixsort.", "type": "Vorlesung" }, { @@ -567,7 +567,7 @@ { "id": 95, "name": "Quick-Sort, Mediane, kd-Bäume", - "description": "In dieser Ãœbung schauen wir uns noch einmal das Sortierverfahren Quicksort an und sprechen über die Berechnung von Medianen. Außerdem schauen wir uns mit den kd-Bäumen eine spezielle Datenstruktur für mehrdimensionale Daten an.\\n+ Links zu Video und Folien", + "description": "In dieser Ãœbung schauen wir uns noch einmal das Sortierverfahren Quicksort an und sprechen über die Berechnung von Medianen. Außerdem schauen wir uns mit den kd-Bäumen eine spezielle Datenstruktur für mehrdimensionale Daten an.", "type": "Ãœbung" }, { @@ -591,7 +591,7 @@ { "id": 99, "name": "(parallelisierte) Sortierverfahren", - "description": "In dieser Vorlesung beenden wir das Kapitel zum Thema Sortieralgorithmen und werfen abschließend einen Blick auf parallelisierte Sortierverfahren.\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Vorlesung beenden wir das Kapitel zum Thema Sortieralgorithmen und werfen abschließend einen Blick auf parallelisierte Sortierverfahren.", "type": "Vorlesung" }, { @@ -615,13 +615,13 @@ { "id": 103, "name": "Zusammenfassung", - "description": "Diese Vorlesung markiert das Ende der Vorlesungszeit. Wir gehen deshalb noch einmal Rückblickend über die verschiedenen Themen die in den vergangenen Monaten behandelt wurden und geben die Möglichkeit Fragen zu stellen.\\n+ Links zu Video und Folien", + "description": "Diese Vorlesung markiert das Ende der Vorlesungszeit. Wir gehen deshalb noch einmal Rückblickend über die verschiedenen Themen die in den vergangenen Monaten behandelt wurden und geben die Möglichkeit Fragen zu stellen.", "type": "Vorlesung" }, { "id": 104, "name": "Klausurvorbereitung", - "description": "Die letzte große Ãœbung von AuD mit Spiel, Spaß, Spannung und vielen Fragen.\\n+ Links zu Video und Folien", + "description": "Die letzte große Ãœbung von AuD mit Spiel, Spaß, Spannung und vielen Fragen.", "type": "Ãœbung" }, { diff --git a/datasets/datasets.js b/datasets/datasets.js index b2bbde0..3b14ee3 100644 --- a/datasets/datasets.js +++ b/datasets/datasets.js @@ -1,17 +1,26 @@ import { PLUGIN_PATH } from "../config"; - -export const DATASETS_URL = PLUGIN_PATH + "datasets/datasets.php"; +import jQuery from "jquery"; /** * Returns the json object from the stored graph as promise. * * @param {String} spaceId Identification of graph to load. - * + * * @returns Promise returning graph object */ export function loadGraphJson(spaceId) { - return fetch(DATASETS_URL + "?space_id=" + spaceId) - .then((r) => r.json()); + let payload = { + action: "get_space", + space: spaceId, + }; + + return jQuery + .ajax({ + type: "POST", + url: ajax_object.ajax_url, + data: payload, + }) + .then((data) => JSON.parse(data)); } /** @@ -21,23 +30,16 @@ export function loadGraphJson(spaceId) { * @param {object} json Graph object */ export function saveGraphJson(spaceId, json) { - var payload = { - space_id: spaceId, + let payload = { + action: "update_space", graph: JSON.stringify(json), + space: spaceId, }; - var auth = getAuthPayload(); - if (auth === undefined) { - return undefined; - } - - return fetch(DATASETS_URL, { - method: "POST", - body: JSON.stringify(Object.assign(payload, auth)), - }); -} - -function getAuthPayload() { - //! TODO: Implement auth - return {}; + return jQuery + .ajax({ + type: "POST", + url: ajax_object.ajax_url, + data: payload, + }); } diff --git a/datasets/datasets.php b/datasets/datasets.php index cc93dc3..d147b0d 100644 --- a/datasets/datasets.php +++ b/datasets/datasets.php @@ -1,34 +1,42 @@ <?php -function handle_request() -{ - if ($_SERVER["REQUEST_METHOD"] == "GET") { - handle_get($_GET); - } else if ($_SERVER["REQUEST_METHOD"] == "POST") { - handle_post(get_post_data()); - } -} +add_action("wp_ajax_get_space", "get_space"); // Fires only for logged-in-users +add_action("wp_ajax_nopriv_get_space", 'get_space' ); // Fires for everyone +function get_space() { + $file_path = get_space_file_path($_POST["space"]); + $content = file_get_contents($file_path); + echo $content; -function get_post_data() -{ - return json_decode(file_get_contents('php://input'), true); + wp_die(); } -function handle_get($request_data) { - $file_path = get_space_file_path($request_data["space_id"]); +add_action("wp_ajax_update_space", "update_space"); // Fires only for logged-in-users +//add_action("wp_ajax_nopriv_update_space", 'update_space' ); // Fires for everyone +function update_space() { + // Check user capabilities + if (current_user_can("edit_posts")) { + // Use json encoding. + $graph = stripslashes($_POST["graph"]); - $content = file_get_contents($file_path); - echo $content; + store_new_graph($graph, $_POST["space"]); + + wp_die(); + } else { + echo "Insufficient permissions!"; + } } -function handle_post($request_data) { - $file_path = get_space_file_path($request_data["space_id"]); +function store_new_graph($graph, $space_id) { + $file_path = get_space_file_path($space_id); + $result = file_put_contents($file_path, $graph); - file_put_contents($file_path, $request_data["graph"]); + //echo print_r($_POST); + echo "Saved file at "; + echo $file_path; + echo " "; + echo $result; } function get_space_file_path($space_id) { return __DIR__."/".$space_id.".json"; } - -handle_request(); diff --git a/datasets/space.json b/datasets/space.json index 3fbe564..78fed00 100644 --- a/datasets/space.json +++ b/datasets/space.json @@ -2,8 +2,8 @@ "nodes": [ { "id": 1, - "name": "Einführung", - "description": "Eine Einführung in die Algorithmen und Datenstrukturen\\n+ Links zu Video und Folien", + "name": "Begrüßung und Organisatorisches", + "description": "Eine Einführung in die Algorithmen und Datenstrukturen", "type": "Vorlesung" }, { @@ -21,13 +21,13 @@ { "id": 4, "name": "Algorithmus-Definition", - "description": "“Ein Algorithmus ist eine aus endlich vielen Schritten bestehende eindeutige Handlungsvorschrift zur Lösung eines Problems oder einer Klasse von Problemen.â€-Wikipedia. Dabei wird als Input eine Problembeschreibung gegeben und durch Anwendung des Algorithmus eine fertige Lösung des Problems ermittelt. Oft spielt die Laufzeit des Algorithmus eine große Rolle. Sie beschreibt, wie viele einzelne Schritte nötig sind um das Problem zu lösen, in Abhängigkeit von der Größe des Problems.", + "description": "Zitat: 'Ein Algorithmus ist eine aus endlich vielen Schritten bestehende eindeutige Handlungsvorschrift zur Lösung eines Problems oder einer Klasse von Problemen.'-Wikipedia. Dabei wird als Input eine Problembeschreibung gegeben und durch Anwendung des Algorithmus eine fertige Lösung des Problems ermittelt. Oft spielt die Laufzeit des Algorithmus eine große Rolle. Sie beschreibt, wie viele einzelne Schritte nötig sind um das Problem zu lösen, in Abhängigkeit von der Größe des Problems.", "type": "Definition" }, { "id": 5, "name": "Kofferpacken", - "description": "Kann ich alle meine Gepäckstücke auf zwei gleich große Koffer aufteilen? Gegeben: Eine Menge von n Objekten, jedes mit\\neiner Größe li; Gesamtgröße ∑ li = 2K\\nGesucht: Eine Verteilung auf zwei Koffer der Größe K", + "description": "Kann ich alle meine Gepäckstücke auf zwei gleich große Koffer aufteilen? <br>Gegeben: Eine Menge von n Objekten, jedes mit einer Größe li; <br>Gesamtgröße ∑ li = 2K<br>Gesucht: Eine Verteilung auf zwei Koffer der Größe K", "type": "Beispiel" }, { @@ -38,8 +38,8 @@ }, { "id": 7, - "name": "Algorithmen und Datenstrukturen", - "description": "In dieser Vorlesung wird der Begriff 'Algorithmus' definiert und erklärt.\\n+ Links zu Video und Folien", + "name": "Einführung des Algorithmusbegriffs", + "description": "In dieser Vorlesung wird der Begriff 'Algorithmus' definiert und erklärt.", "type": "Vorlesung" }, { @@ -51,19 +51,19 @@ { "id": 21, "name": "Organisation und Pseudocode", - "description": "In dieser Ãœbung haben wir noch einmal organisatorische Dinge besprochen und uns mit dem Thema Pseudocode auseinandergesetzt.\\n+ Links zu Video und Folien", + "description": "In dieser Ãœbung haben wir noch einmal organisatorische Dinge besprochen und uns mit dem Thema Pseudocode auseinandergesetzt.", "type": "Ãœbung" }, { "id": 9, "name": "Pseudocode", - "description": "Pseudocode ist eine Art Algorithmen einigermaßen einheitlich zu notieren. Dabei werden zwar Schlüsselwörter genutzt um eine gewisse Einheitlichkeit zu bieten und gleichzeitig die Logik zu beschreiben, allerdings geht es noch nicht darum einen compilierbaren Code mit korrekter Syntax zu schreiben.\\n+ Link zu Pseudocodeblatt, Ãœbung 1", + "description": "Pseudocode ist eine Art Algorithmen einigermaßen einheitlich zu notieren. Dabei werden zwar Schlüsselwörter genutzt um eine gewisse Einheitlichkeit zu bieten und gleichzeitig die Logik zu beschreiben, allerdings geht es noch nicht darum einen compilierbaren Code mit korrekter Syntax zu schreiben.", "type": "Definition" }, { "id": 10, "name": "Einleitung in die Graphen", - "description": "Eine Einleitung in die Welt der Graphen am wohl bekanntesten Beispiel, dem Haus des Nikolaus.\\n+ Links zu Video und Folien", + "description": "Eine Einleitung in die Welt der Graphen am wohl bekanntesten Beispiel, dem Haus des Nikolaus.", "type": "Vorlesung" }, { @@ -81,7 +81,7 @@ { "id": 13, "name": "Graphenbegriffe", - "description": "Ein Graph besteht aus Knoten und Kanten das sollte inzwischen jeder wissen, doch was parallele Kanten, Schleifen, (geschlossene) Wege, Pfade, Kreise, Eulerwege/-touren, sowie Hamiltonpfade und -kreise sind wird in dieser Vorlesung noch einmal genau definiert.\\n+ Links zu Video und Folien", + "description": "Ein Graph besteht aus Knoten und Kanten das sollte inzwischen jeder wissen, doch was parallele Kanten, Schleifen, (geschlossene) Wege, Pfade, Kreise, Eulerwege/-touren, sowie Hamiltonpfade und -kreise sind wird in dieser Vorlesung noch einmal genau definiert.", "type": "Vorlesung" }, { @@ -98,14 +98,14 @@ }, { "id": 16, - "name": "Beweistechniken", - "description": "In der Mathematik und auch in der Algorithmik spielen Beweise immer wieder eine große Rolle. Es geht darum Aussagen zu belegen, zu widerlegen oder auf bestimmte Elemente anzuwenden. Dazu gibt es verschiedene Beweistechniken, welche ihr hier finden könnt:\\n+ Link zu Beweisblatt, Ãœbung 2", + "name": "Beweistechniken Teil 1", + "description": "In der Mathematik und auch in der Algorithmik spielen Beweise immer wieder eine große Rolle. Es geht darum Aussagen zu belegen, zu widerlegen oder auf bestimmte Elemente anzuwenden. Dazu gibt es verschiedene Beweistechniken, welche ihr hier finden könnt:", "type": "Ãœbung" }, { "id": 17, - "name": "Eulertouren", - "description": "In dieser Vorlesung werden notwendige Bedingungen für Eulertouren erleutert. Zusätzlich wird das Kapitel 2 noch einmal zusammengefasst und es werden Algorithmen eingeführt um die uns bisher bekannten Probleme zu lösen.\\n+ Links zu Video und Folien", + "name": "Bedingungen für Eulertouren", + "description": "In dieser Vorlesung werden notwendige Bedingungen für Eulertouren erleutert. Zusätzlich wird das Kapitel 2 noch einmal zusammengefasst und es werden Algorithmen eingeführt um die uns bisher bekannten Probleme zu lösen.", "type": "Vorlesung" }, { @@ -123,25 +123,25 @@ { "id": 20, "name": "Algorithmus von Fleury", - "description": "Dieser Algorithmus(2.13) erhält als Input einen Graphen G mit höchstens 2 ungeraden Knoten und liefert als Output einen Weg in G. Der Algorithmus hat als Grundlage Algorithmus 2.7 zum Finden von Wegen. Auch lässt sich zeigen, dass man mit diesem Algorithmus eine Eulertour/einen Eulerweg finden kann", + "description": "Dieser Algorithmus(2.13) erhält als Input einen Graphen G mit höchstens 2 ungeraden Knoten und liefert als Output einen Weg in G. Der Algorithmus hat als Grundlage Algorithmus 2.7 zum Finden von Wegen. Auch lässt sich zeigen, dass man mit diesem Algorithmus eine Eulertour/einen Eulerweg finden kann.", "type": "Algorithmus" }, { "id": 22, "name": "Anwendung von Graphen", - "description": "In dieser Vorlesung geht es um den Einsatzzweck von Graphen und es wird am Beispiel der Erdös- und der Kevin Bacon Zahl gezeigt, welche Zusammenhänge dargestellt werden können.\\n+ Links zu Video und Folien", + "description": "In dieser Vorlesung geht es um den Einsatzzweck von Graphen und es wird am Beispiel der Erdös- und der Kevin Bacon Zahl gezeigt, welche Zusammenhänge dargestellt werden können.", "type": "Vorlesung" }, { "id": 23, "name": "Beweistechniken Teil 2", - "description": "In dieser Ãœbung geht es um die Beweistechnik der vollständigen Induktion. Diese ist die wohl meist benutzte Beweistechnik in der Algorithmik. Auch werden Anwendungsbeispiele wie z.B. die Gauß'sche Summenformel oder der Zusammenhang in Graphen erläutert.\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Ãœbung geht es um die Beweistechnik der vollständigen Induktion. Diese ist die wohl meist benutzte Beweistechnik in der Algorithmik. Auch werden Anwendungsbeispiele wie z.B. die Gauß'sche Summenformel oder der Zusammenhang in Graphen erläutert.", "type": "Ãœbung" }, { "id": 24, "name": "Graphenscan", - "description": "In dieser Vorlesung wird der Graphenscanalgorithmus vorgestellt um Zusammenhangskomponenten in Graphen zu finden.\\n+ Links zu Video und Folien/Notizen/Beweis", + "description": "In dieser Vorlesung wird der Graphenscanalgorithmus vorgestellt um Zusammenhangskomponenten in Graphen zu finden.", "type": "Vorlesung" }, { @@ -153,7 +153,7 @@ { "id": 26, "name": "Datenstrukturen Teil 1", - "description": "In dieser Vorlesung werden die Datenstrukturen Warteschlange (First In - First Out) und Stapel (Last In - First Out) vorgestellt. Außerdem geht es um ihre Rolle für Algorithmen und wie man sie implementieren kann. Das ganze wird am Beispiel des Graphscan Algorithmus gezeigt und somit werden auch Breiten- und Tiefensuche eingeführt.\\n+ Links zu Video und Folien/Beispiel", + "description": "In dieser Vorlesung werden die Datenstrukturen Warteschlange (First In - First Out) und Stapel (Last In - First Out) vorgestellt. Außerdem geht es um ihre Rolle für Algorithmen und wie man sie implementieren kann. Das ganze wird am Beispiel des Graphscan Algorithmus gezeigt und somit werden auch Breiten- und Tiefensuche eingeführt.", "type": "Vorlesung" }, { @@ -183,7 +183,7 @@ { "id": 31, "name": "Datenstrukturen Teil 2", - "description": "In dieser Vorlesung geht es einerseits um die Anwendung der Breitensuche, andererseits werden noch 2 weitere Datenstrukturen eingeführt: Die Inzidenz/-Adjazenzmatrix, sowie die Kantenliste\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Vorlesung geht es einerseits um die Anwendung der Breitensuche, andererseits werden noch 2 weitere Datenstrukturen eingeführt: Die Inzidenz/-Adjazenzmatrix, sowie die Kantenliste.", "type": "Vorlesung" }, { @@ -201,7 +201,7 @@ { "id": 34, "name": "Wachstum/O-Notation", - "description": "In dieser Vorlesung wird noch einmal mit den Adjazenz- und Kantenlisten abgeschlossen. Außerdem schauen wir uns einmal das Wachstum von Funktionen an und definieren und die O-Notation um damit zu arbeiten.\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Vorlesung wird noch einmal mit den Adjazenz- und Kantenlisten abgeschlossen. Außerdem schauen wir uns einmal das Wachstum von Funktionen an und definieren und die O-Notation um damit zu arbeiten.", "type": "Vorlesung" }, { @@ -224,14 +224,14 @@ }, { "id": 38, - "name": "Wiederholung oder\\nSuche in Graphen Zusammenfassung", - "description": "Noch einmal ein Rückblick auf alles, was bisher in 'Kapitel 3: Suche in Graphen' passiert ist. \\n+ Links zu Video und Folien", + "name": "Wiederholung: Suche in Graphen", + "description": "Noch einmal ein Rückblick auf alles, was bisher in 'Kapitel 3: Suche in Graphen' passiert ist. ", "type": "Vorlesung" }, { "id": 39, "name": "Eigenschaften von DFS und BFS", - "description": "In dieser Vorlesung betrachten wir die Breiten- und Tiefensuche im Hinblick auf ihre Laufzeit. Dabei wird anschaulich, wie die Algorithmen arbeiten, wann man sie am besten nutzen sollte und wie man Laufzeiten beweisen kann.\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Vorlesung betrachten wir die Breiten- und Tiefensuche im Hinblick auf ihre Laufzeit. Dabei wird anschaulich, wie die Algorithmen arbeiten, wann man sie am besten nutzen sollte und wie man Laufzeiten beweisen kann.", "type": "Vorlesung" }, { @@ -254,8 +254,8 @@ }, { "id": 43, - "name": "Dynamische Datenstrukturen", - "description": "In dieser Vorlesung beginnen wir dynamische Datenstrukturen einzuführen. Es werden Stapel, Warteschlangen und verkettete Listen vorgestellt. Außerdem beschäftigen wir uns mit binärer Suche.\\n+ Links zu Video und Folien", + "name": "Verschiedene dynamische Datenstrukturen", + "description": "In dieser Vorlesung beginnen wir dynamische Datenstrukturen einzuführen. Es werden Stapel, Warteschlangen und verkettete Listen vorgestellt. Außerdem beschäftigen wir uns mit binärer Suche.", "type": "Vorlesung" }, { @@ -285,7 +285,7 @@ { "id": 48, "name": "Binäre Suchbäume", - "description": "In dieser Vorlesung beschäftigen wir uns genauer mit binären Suchbäumen und den darauf anwendbaren Operationen, wie Maximum, Minimum, einfügen und löschen von Knoten, sowie mit der binären Suche.\\n+ Links zu Video und Folien", + "description": "In dieser Vorlesung beschäftigen wir uns genauer mit binären Suchbäumen und den darauf anwendbaren Operationen, wie Maximum, Minimum, einfügen und löschen von Knoten, sowie mit der binären Suche.", "type": "Vorlesung" }, { @@ -303,7 +303,7 @@ { "id": 51, "name": "AVL-Bäume", - "description": "In dieser Vorlesung beschäftigen wir uns mit speziellen binären Suchbäumen, den AVL-Bäumen und ihren Eigenschaften.\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Vorlesung beschäftigen wir uns mit speziellen binären Suchbäumen, den AVL-Bäumen und ihren Eigenschaften.", "type": "Vorlesung" }, { @@ -315,7 +315,7 @@ { "id": 53, "name": "dyn. Operationen auf AVL-Bäumen", - "description": "In dieser Vorlesung beschäftigen wir uns mit dem Erhalt der AVL-Eigenschaft eines binären Suchbaumes bei Einfüge- und Löschoperationen. Außerdem werfen wir einen Blick auf die Fibonacci-Zahlen.\\n+ Links zu Video und Folien", + "description": "In dieser Vorlesung beschäftigen wir uns mit dem Erhalt der AVL-Eigenschaft eines binären Suchbaumes bei Einfüge- und Löschoperationen. Außerdem werfen wir einen Blick auf die Fibonacci-Zahlen.", "type": "Vorlesung" }, { @@ -344,7 +344,7 @@ }, { "id": 58, - "name": "Grundoperationen Suchbaum", + "name": "Beispiel Suchbaumoperationen", "description": "In diesem Teil der Ãœbung werden einmal die Operationen Einfügen, Suchen, Vorgänger/Nachfolger finden, löschen und verschmelzen von binären Suchbäumen geübt.", "type": "Beispiel" }, @@ -357,13 +357,13 @@ { "id": 60, "name": "Dynamische Datenstrukturen 2", - "description": "In dieser Vorlesung schauen wir noch einmal auf das bisher in Kapitel 4 gelernte zurück. Außerdem geben wir einen Ãœberblick über einige weitere dynamische Datenstrukturen wie Rot-Scharz-Bäumme, B-Bäume und Heaps.\\n+ Links zu Video und Folien", + "description": "In dieser Vorlesung schauen wir noch einmal auf das bisher in Kapitel 4 gelernte zurück. Außerdem geben wir einen Ãœberblick über einige weitere dynamische Datenstrukturen wie Rot-Scharz-Bäumme, B-Bäume und Heaps.", "type": "Vorlesung" }, { "id": 61, "name": "Rot-Schwarz-Bäume", - "description": "Ein binärer Suchbaum heißt Rot-Schwarz-Baum, wenn er die folgenden Eigenschaften erfüllt:\\n1. Jeder Knoten ist entweder rot oder schwarz.\\n2. Die Wurzel ist schwarz.\\n3. Jedes Blatt (NIL) ist schwarz.\\n4. Wenn ein Knoten rot ist, sind seine beiden Kinder schwarz.\\n5. Für jeden Knoten enthalten alle Pfade nach unten zu einem Blatt des Teilbaumes die gleiche Anzahl schwarzer Knoten.", + "description": "Ein binärer Suchbaum heißt Rot-Schwarz-Baum, wenn er die folgenden Eigenschaften erfüllt:<br>1. Jeder Knoten ist entweder rot oder schwarz.<br>2. Die Wurzel ist schwarz.<br>3. Jedes Blatt (NIL) ist schwarz.<br>4. Wenn ein Knoten rot ist, sind seine beiden Kinder schwarz.<br>5. Für jeden Knoten enthalten alle Pfade nach unten zu einem Blatt des Teilbaumes die gleiche Anzahl schwarzer Knoten.", "type": "Definition" }, { @@ -380,8 +380,8 @@ }, { "id": 64, - "name": "Sortieren", - "description": "In dieser Vorlesung geben wir eine Einführung in das Oberthema Sortieren. Wir stellen außerdem einen Sortieralgorithmus mit dem Namen Mergesort vor und stellen grundlegende Ãœberlegungen zur Laufzeit von Sortieralgorithmen an.\\n+ Links zu Video und Folien/Notizen", + "name": "Einführung in das Sortieren", + "description": "In dieser Vorlesung geben wir eine Einführung in das Oberthema Sortieren. Wir stellen außerdem einen Sortieralgorithmus mit dem Namen Mergesort vor und stellen grundlegende Ãœberlegungen zur Laufzeit von Sortieralgorithmen an.", "type": "Vorlesung" }, { @@ -393,7 +393,7 @@ { "id": 66, "name": "Sortier-Laufzeitschranken", - "description": "In dieser Vorlesung leiten wir konkrete Laufzeitschranken für das Problem des Sortierens einer Liste von Zahlen her. Zudem machen wir uns Gedanken über das Lösen von Rekursionsgleichungen.\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Vorlesung leiten wir konkrete Laufzeitschranken für das Problem des Sortierens einer Liste von Zahlen her. Zudem machen wir uns Gedanken über das Lösen von Rekursionsgleichungen.", "type": "Vorlesung" }, { @@ -411,7 +411,7 @@ { "id": 69, "name": "Erzeugende Funktionen/Mastertheorem", - "description": "In dieser Vorlesung besprechen wir weitere Details zu erzeugenden Funktionen und führen das Master-Theorem ein.\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Vorlesung besprechen wir weitere Details zu erzeugenden Funktionen und führen das Master-Theorem ein.", "type": "Vorlesung" }, { @@ -435,7 +435,7 @@ { "id": 73, "name": "Sortieralgorithmen und Master-Theorem", - "description": "Wir betrachten ein weiteres Beispiel für Mergesort und leiten erneut die Laufzeit des Sortieralgorithmus her, indem das Master-Theorem benutzt wird. Außerdem betrachten wir einen weiteren Sortieralgorithmus: Heapsort.\\n+ Links zu Video und Folien", + "description": "Wir betrachten ein weiteres Beispiel für Mergesort und leiten erneut die Laufzeit des Sortieralgorithmus her, indem das Master-Theorem benutzt wird. Außerdem betrachten wir einen weiteren Sortieralgorithmus: Heapsort.", "type": "Ãœbung" }, { @@ -458,7 +458,7 @@ }, { "id": 77, - "name": "Max-Heaps", + "name": "Max-Heaps Anwendung", "description": "Hier wird der Algorithmus aus der Ãœbung 6 zum Erstellen eines Max-Heaps einmal an einem Beispiel angewandt.", "type": "Beispiel" }, @@ -471,7 +471,7 @@ { "id": 79, "name": "nichtlineare Rekursionen (Exkurs)", - "description": "In dieser Vorlesung haben wir einen Exkurs in die nichtlineare Rekursion gemacht.\\n+ Links zu Video und Folien", + "description": "In dieser Vorlesung haben wir einen Exkurs in die nichtlineare Rekursion gemacht.", "type": "Vorlesung" }, { @@ -506,8 +506,8 @@ }, { "id": 85, - "name": "Quick-Sort", - "description": "In dieser Vorlesung kehren wir zurück zu Sortieralgorithmen und stellen den Quicksort-Algorithmus vor.\\n+ Links zu Video und Folien/Notizen", + "name": "Einführung von Quick-Sort", + "description": "In dieser Vorlesung kehren wir zurück zu Sortieralgorithmen und stellen den Quicksort-Algorithmus vor.", "type": "Vorlesung" }, { @@ -525,7 +525,7 @@ { "id": 88, "name": "Mediane", - "description": "In dieser Vorlesung beschäftigen wir uns mit Medianen.\\n+ Links zu Video und Folien", + "description": "In dieser Vorlesung beschäftigen wir uns mit Medianen.", "type": "Vorlesung" }, { @@ -549,7 +549,7 @@ { "id": 92, "name": "Sortieralgorithmen Sonderfälle", - "description": "In dieser Vorlesung beschäftigen wir uns mit Sonderfällen für Sortieralgorithmen, durch die Sortieren in linearer Zeit ermöglicht wird. Dabei werfen wir einen näheren Blick auf die Sortierverfahren Countingsort und Radixsort.\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Vorlesung beschäftigen wir uns mit Sonderfällen für Sortieralgorithmen, durch die Sortieren in linearer Zeit ermöglicht wird. Dabei werfen wir einen näheren Blick auf die Sortierverfahren Countingsort und Radixsort.", "type": "Vorlesung" }, { @@ -567,7 +567,7 @@ { "id": 95, "name": "Quick-Sort, Mediane, kd-Bäume", - "description": "In dieser Ãœbung schauen wir uns noch einmal das Sortierverfahren Quicksort an und sprechen über die Berechnung von Medianen. Außerdem schauen wir uns mit den kd-Bäumen eine spezielle Datenstruktur für mehrdimensionale Daten an.\\n+ Links zu Video und Folien", + "description": "In dieser Ãœbung schauen wir uns noch einmal das Sortierverfahren Quicksort an und sprechen über die Berechnung von Medianen. Außerdem schauen wir uns mit den kd-Bäumen eine spezielle Datenstruktur für mehrdimensionale Daten an.", "type": "Ãœbung" }, { @@ -591,7 +591,7 @@ { "id": 99, "name": "(parallelisierte) Sortierverfahren", - "description": "In dieser Vorlesung beenden wir das Kapitel zum Thema Sortieralgorithmen und werfen abschließend einen Blick auf parallelisierte Sortierverfahren.\\n+ Links zu Video und Folien/Notizen", + "description": "In dieser Vorlesung beenden wir das Kapitel zum Thema Sortieralgorithmen und werfen abschließend einen Blick auf parallelisierte Sortierverfahren.", "type": "Vorlesung" }, { @@ -615,13 +615,13 @@ { "id": 103, "name": "Zusammenfassung", - "description": "Diese Vorlesung markiert das Ende der Vorlesungszeit. Wir gehen deshalb noch einmal Rückblickend über die verschiedenen Themen die in den vergangenen Monaten behandelt wurden und geben die Möglichkeit Fragen zu stellen.\\n+ Links zu Video und Folien", + "description": "Diese Vorlesung markiert das Ende der Vorlesungszeit. Wir gehen deshalb noch einmal Rückblickend über die verschiedenen Themen die in den vergangenen Monaten behandelt wurden und geben die Möglichkeit Fragen zu stellen.", "type": "Vorlesung" }, { "id": 104, "name": "Klausurvorbereitung", - "description": "Die letzte große Ãœbung von AuD mit Spiel, Spaß, Spannung und vielen Fragen.\\n+ Links zu Video und Folien", + "description": "Die letzte große Ãœbung von AuD mit Spiel, Spaß, Spannung und vielen Fragen.", "type": "Ãœbung" }, { diff --git a/datasets/xlsxTOjson.ipynb b/datasets/xlsxTOjson.ipynb index 093a548..ac31a40 100644 --- a/datasets/xlsxTOjson.ipynb +++ b/datasets/xlsxTOjson.ipynb @@ -16,72 +16,86 @@ "execution_count": 2, "id": "b6873712-56e4-46a9-8bec-031093dd28b1", "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "ImportError", + "evalue": "Missing optional dependency 'openpyxl'. Use pip or conda to install openpyxl.", + "output_type": "error", + "traceback": [ + "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[1;31mImportError\u001B[0m Traceback (most recent call last)", + "\u001B[1;32m~\\AppData\\Local\\Temp/ipykernel_4788/3644074374.py\u001B[0m in \u001B[0;36m<module>\u001B[1;34m\u001B[0m\n\u001B[1;32m----> 1\u001B[1;33m \u001B[0mtable\u001B[0m \u001B[1;33m=\u001B[0m \u001B[0mpd\u001B[0m\u001B[1;33m.\u001B[0m\u001B[0mread_excel\u001B[0m\u001B[1;33m(\u001B[0m\u001B[1;34m\"AuD-Inhalt2.xlsx\"\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0m\u001B[0;32m 2\u001B[0m \u001B[1;33m\u001B[0m\u001B[0m\n", + "\u001B[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python38\\site-packages\\pandas\\util\\_decorators.py\u001B[0m in \u001B[0;36mwrapper\u001B[1;34m(*args, **kwargs)\u001B[0m\n\u001B[0;32m 309\u001B[0m \u001B[0mstacklevel\u001B[0m\u001B[1;33m=\u001B[0m\u001B[0mstacklevel\u001B[0m\u001B[1;33m,\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0;32m 310\u001B[0m )\n\u001B[1;32m--> 311\u001B[1;33m \u001B[1;32mreturn\u001B[0m \u001B[0mfunc\u001B[0m\u001B[1;33m(\u001B[0m\u001B[1;33m*\u001B[0m\u001B[0margs\u001B[0m\u001B[1;33m,\u001B[0m \u001B[1;33m**\u001B[0m\u001B[0mkwargs\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0m\u001B[0;32m 312\u001B[0m \u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0;32m 313\u001B[0m \u001B[1;32mreturn\u001B[0m \u001B[0mwrapper\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n", + "\u001B[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python38\\site-packages\\pandas\\io\\excel\\_base.py\u001B[0m in \u001B[0;36mread_excel\u001B[1;34m(io, sheet_name, header, names, index_col, usecols, squeeze, dtype, engine, converters, true_values, false_values, skiprows, nrows, na_values, keep_default_na, na_filter, verbose, parse_dates, date_parser, thousands, comment, skipfooter, convert_float, mangle_dupe_cols, storage_options)\u001B[0m\n\u001B[0;32m 362\u001B[0m \u001B[1;32mif\u001B[0m \u001B[1;32mnot\u001B[0m \u001B[0misinstance\u001B[0m\u001B[1;33m(\u001B[0m\u001B[0mio\u001B[0m\u001B[1;33m,\u001B[0m \u001B[0mExcelFile\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m:\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0;32m 363\u001B[0m \u001B[0mshould_close\u001B[0m \u001B[1;33m=\u001B[0m \u001B[1;32mTrue\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[1;32m--> 364\u001B[1;33m \u001B[0mio\u001B[0m \u001B[1;33m=\u001B[0m \u001B[0mExcelFile\u001B[0m\u001B[1;33m(\u001B[0m\u001B[0mio\u001B[0m\u001B[1;33m,\u001B[0m \u001B[0mstorage_options\u001B[0m\u001B[1;33m=\u001B[0m\u001B[0mstorage_options\u001B[0m\u001B[1;33m,\u001B[0m \u001B[0mengine\u001B[0m\u001B[1;33m=\u001B[0m\u001B[0mengine\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0m\u001B[0;32m 365\u001B[0m \u001B[1;32melif\u001B[0m \u001B[0mengine\u001B[0m \u001B[1;32mand\u001B[0m \u001B[0mengine\u001B[0m \u001B[1;33m!=\u001B[0m \u001B[0mio\u001B[0m\u001B[1;33m.\u001B[0m\u001B[0mengine\u001B[0m\u001B[1;33m:\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0;32m 366\u001B[0m raise ValueError(\n", + "\u001B[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python38\\site-packages\\pandas\\io\\excel\\_base.py\u001B[0m in \u001B[0;36m__init__\u001B[1;34m(self, path_or_buffer, engine, storage_options)\u001B[0m\n\u001B[0;32m 1231\u001B[0m \u001B[0mself\u001B[0m\u001B[1;33m.\u001B[0m\u001B[0mstorage_options\u001B[0m \u001B[1;33m=\u001B[0m \u001B[0mstorage_options\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0;32m 1232\u001B[0m \u001B[1;33m\u001B[0m\u001B[0m\n\u001B[1;32m-> 1233\u001B[1;33m \u001B[0mself\u001B[0m\u001B[1;33m.\u001B[0m\u001B[0m_reader\u001B[0m \u001B[1;33m=\u001B[0m \u001B[0mself\u001B[0m\u001B[1;33m.\u001B[0m\u001B[0m_engines\u001B[0m\u001B[1;33m[\u001B[0m\u001B[0mengine\u001B[0m\u001B[1;33m]\u001B[0m\u001B[1;33m(\u001B[0m\u001B[0mself\u001B[0m\u001B[1;33m.\u001B[0m\u001B[0m_io\u001B[0m\u001B[1;33m,\u001B[0m \u001B[0mstorage_options\u001B[0m\u001B[1;33m=\u001B[0m\u001B[0mstorage_options\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0m\u001B[0;32m 1234\u001B[0m \u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0;32m 1235\u001B[0m \u001B[1;32mdef\u001B[0m \u001B[0m__fspath__\u001B[0m\u001B[1;33m(\u001B[0m\u001B[0mself\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m:\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n", + "\u001B[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python38\\site-packages\\pandas\\io\\excel\\_openpyxl.py\u001B[0m in \u001B[0;36m__init__\u001B[1;34m(self, filepath_or_buffer, storage_options)\u001B[0m\n\u001B[0;32m 519\u001B[0m \u001B[0mpassed\u001B[0m \u001B[0mto\u001B[0m \u001B[0mfsspec\u001B[0m \u001B[1;32mfor\u001B[0m \u001B[0mappropriate\u001B[0m \u001B[0mURLs\u001B[0m \u001B[1;33m(\u001B[0m\u001B[0msee\u001B[0m\u001B[0;31m \u001B[0m\u001B[0;31m`\u001B[0m\u001B[0;31m`\u001B[0m\u001B[0m_get_filepath_or_buffer\u001B[0m\u001B[0;31m`\u001B[0m\u001B[0;31m`\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0;32m 520\u001B[0m \"\"\"\n\u001B[1;32m--> 521\u001B[1;33m \u001B[0mimport_optional_dependency\u001B[0m\u001B[1;33m(\u001B[0m\u001B[1;34m\"openpyxl\"\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0m\u001B[0;32m 522\u001B[0m \u001B[0msuper\u001B[0m\u001B[1;33m(\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m.\u001B[0m\u001B[0m__init__\u001B[0m\u001B[1;33m(\u001B[0m\u001B[0mfilepath_or_buffer\u001B[0m\u001B[1;33m,\u001B[0m \u001B[0mstorage_options\u001B[0m\u001B[1;33m=\u001B[0m\u001B[0mstorage_options\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0;32m 523\u001B[0m \u001B[1;33m\u001B[0m\u001B[0m\n", + "\u001B[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python38\\site-packages\\pandas\\compat\\_optional.py\u001B[0m in \u001B[0;36mimport_optional_dependency\u001B[1;34m(name, extra, errors, min_version)\u001B[0m\n\u001B[0;32m 116\u001B[0m \u001B[1;32mexcept\u001B[0m \u001B[0mImportError\u001B[0m\u001B[1;33m:\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0;32m 117\u001B[0m \u001B[1;32mif\u001B[0m \u001B[0merrors\u001B[0m \u001B[1;33m==\u001B[0m \u001B[1;34m\"raise\"\u001B[0m\u001B[1;33m:\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[1;32m--> 118\u001B[1;33m \u001B[1;32mraise\u001B[0m \u001B[0mImportError\u001B[0m\u001B[1;33m(\u001B[0m\u001B[0mmsg\u001B[0m\u001B[1;33m)\u001B[0m \u001B[1;32mfrom\u001B[0m \u001B[1;32mNone\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0m\u001B[0;32m 119\u001B[0m \u001B[1;32melse\u001B[0m\u001B[1;33m:\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0;32m 120\u001B[0m \u001B[1;32mreturn\u001B[0m \u001B[1;32mNone\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n", + "\u001B[1;31mImportError\u001B[0m: Missing optional dependency 'openpyxl'. Use pip or conda to install openpyxl." + ] + } + ], "source": [ "table = pd.read_excel(\"AuD-Inhalt2.xlsx\")" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "e9481135-3734-45ed-9847-8f9426bd0f00", "metadata": {}, "outputs": [], "source": [ - "nodes = []\n", - "links = []" + "nds = []\n", + "lks = []" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "a138d20d-4dc3-4eb8-8ebd-71d1fb3f0cbf", "metadata": {}, "outputs": [], "source": [ "for row in table.itertuples():\n", - " nodes.append({'id':row[1], 'name':row[5], 'description':row[9], 'type':row[4]})\n", + " nds.append({'id':row[1], 'name':row[5], 'description':row[9], 'type':row[4]})\n", " for link in str(row[7]).split(', '):\n", " if link != \"nan\": \n", - " links.append({'source':row[1], 'target':int(link)})" + " lks.append({'source':row[1], 'target':int(link)})" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "c06e658c-33d1-4ba8-8a47-ae857984d6ce", "metadata": {}, "outputs": [], "source": [ - "result = {'nodes':nodes, 'links':links}" + "result = {'nodes':nds, 'links':lks}" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "565d11cd-47b6-402e-a734-b4b8a5a66181", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "'{\"nodes\": [{\"id\": 1, \"name\": \"Einführung\", \"description\": \"Eine Einführung in die Algorithmen und Datenstrukturen\\\\n+ Links zu Video und Folien\", \"type\": \"Vorlesung\"}, {\"id\": 2, \"name\": \"Rundreise Problem\", \"description\": \"Gegeben: Ein Graph G = (V, E) mit Kantenlängen we, Gesucht: Eine kürzeste Rundreise, welche alle Knoten im Graphen einmal besucht und im Startknoten wieder endet.\", \"type\": \"Beispiel\"}, {\"id\": 3, \"name\": \"Puzzle\", \"description\": \"Jeder hat schon einmal ein Puzzle gelöst, doch wie sieht das aus algorithmischer Sicht aus?\", \"type\": \"Beispiel\"}, {\"id\": 4, \"name\": \"Algorithmus-Definition\", \"description\": \"“Ein Algorithmus ist eine aus endlich vielen Schritten bestehende eindeutige Handlungsvorschrift zur Lösung eines Problems oder einer Klasse von Problemen.â€-Wikipedia. Dabei wird als Input eine Problembeschreibung gegeben und durch Anwendung des Algorithmus eine fertige Lösung des Problems ermittelt. Oft spielt die Laufzeit des Algorithmus eine große Rolle. Sie beschreibt, wie viele einzelne Schritte nötig sind um das Problem zu lösen, in Abhängigkeit von der Größe des Problems.\", \"type\": \"Definition\"}, {\"id\": 5, \"name\": \"Kofferpacken\", \"description\": \"Kann ich alle meine Gepäckstücke auf zwei gleich große Koffer aufteilen? Gegeben: Eine Menge von n Objekten, jedes mit\\\\neiner Größe li; Gesamtgröße ∑ li = 2K\\\\nGesucht: Eine Verteilung auf zwei Koffer der Größe K\", \"type\": \"Beispiel\"}, {\"id\": 6, \"name\": \"P und NP\", \"description\": \"Die Klassen P und NP teilen algorithmische Probleme in zwei Kategorien auf. Die eine, bei der man mithilfe eines Algorithmus eine Lösung Pfinden kann (P) und eine zweite, bei der bisher nur das NachPrüfen einer existierenden Lösung gelingt (NP). Wenn es allerdings keine Lösung gibt, so lässt sich das bei Problemen der Klasse NP nur schlecht beweisen.\", \"type\": \"Definition\"}, {\"id\": 7, \"name\": \"Algorithmen und Datenstrukturen\", \"description\": \"In dieser Vorlesung wird der Begriff \\'Algorithmus\\' definiert und erklärt.\\\\n+ Links zu Video und Folien\", \"type\": \"Vorlesung\"}, {\"id\": 8, \"name\": \"Datenstrukturen\", \"description\": \"Eine Datenstruktur erlaubt es, die für eine Aufgabe notwendigen Informationen geeignet zu repräsentieren und den Zugriff und die Verwaltung während der Bearbeitung in effizienter Weise zu ermöglichen.\", \"type\": \"Definition\"}, {\"id\": 21, \"name\": \"Organisation und Pseudocode\", \"description\": \"In dieser Ãœbung haben wir noch einmal organisatorische Dinge besprochen und uns mit dem Thema Pseudocode auseinandergesetzt.\\\\n+ Links zu Video und Folien\", \"type\": \"Ãœbung\"}, {\"id\": 9, \"name\": \"Pseudocode\", \"description\": \"Pseudocode ist eine Art Algorithmen einigermaßen einheitlich zu notieren. Dabei werden zwar Schlüsselwörter genutzt um eine gewisse Einheitlichkeit zu bieten und gleichzeitig die Logik zu beschreiben, allerdings geht es noch nicht darum einen compilierbaren Code mit korrekter Syntax zu schreiben.\\\\n+ Link zu Pseudocodeblatt, Ãœbung 1\", \"type\": \"Definition\"}, {\"id\": 10, \"name\": \"Graphen\", \"description\": \"Eine Einleitung in die Welt der Graphen am wohl bekanntesten Beispiel, dem Haus des Nikolaus.\\\\n+ Links zu Video und Folien\", \"type\": \"Vorlesung\"}, {\"id\": 11, \"name\": \"Haus des Nikolaus\", \"description\": \"Jeder kennt das Haus vom Nikolaus, doch wie wird es gemalt? Wo setzt man den Stift an und wo wieder ab?\", \"type\": \"Beispiel\"}, {\"id\": 12, \"name\": \"Eulertouren\", \"description\": \"Ein Eulerweg ist ein Weg in einem Graphen, welcher alle Kanten nutzt. Eine Eulertour kehrt darüber hinaus auch zum Startknoten zurück.\", \"type\": \"Definition\"}, {\"id\": 13, \"name\": \"Graphenbegriffe\", \"description\": \"Ein Graph besteht aus Knoten und Kanten das sollte inzwischen jeder wissen, doch was parallele Kanten, Schleifen, (geschlossene) Wege, Pfade, Kreise, Eulerwege/-touren, sowie Hamiltonpfade und -kreise sind wird in dieser Vorlesung noch einmal genau definiert.\\\\n+ Links zu Video und Folien\", \"type\": \"Vorlesung\"}, {\"id\": 14, \"name\": \"Graph\", \"description\": \"Ãœber Graphen haben wir bereits viel gesprochen, doch was ein Graph genau ist und wie man ihn definiert erfährst du hier.\", \"type\": \"Definition\"}, {\"id\": 15, \"name\": \"Wege in Graphen\", \"description\": \"Eine Kantenfolge W in einem Graphen G heißt Weg, wenn sich keine Kante darin wiederholt und geschlossener Weg (Tour), wenn man am Ende wieder am Startknoten ankommt. Wiederholt sich kein Knoten spricht man von einem Pfad. Ein Kreis ist ein geschlossener Pfad. Bei einem Eulerweg/ einer Eulertour werden alle Kanten des Graphen genutzt. Ein Hamiltonpfad/kreis nutzt hingegen alle Knoten.\", \"type\": \"Definition\"}, {\"id\": 16, \"name\": \"Beweistechniken\", \"description\": \"In der Mathematik und auch in der Algorithmik spielen Beweise immer wieder eine große Rolle. Es geht darum Aussagen zu belegen, zu widerlegen oder auf bestimmte Elemente anzuwenden. Dazu gibt es verschiedene Beweistechniken, welche ihr hier finden könnt:\\\\n+ Link zu Beweisblatt, Ãœbung 2\", \"type\": \"Ãœbung\"}, {\"id\": 17, \"name\": \"Eulertouren\", \"description\": \"In dieser Vorlesung werden notwendige Bedingungen für Eulertouren erleutert. Zusätzlich wird das Kapitel 2 noch einmal zusammengefasst und es werden Algorithmen eingeführt um die uns bisher bekannten Probleme zu lösen.\\\\n+ Links zu Video und Folien\", \"type\": \"Vorlesung\"}, {\"id\": 18, \"name\": \"Algorithmus Wegfindung\", \"description\": \"Dieser Algorithmus (2.7) erhält als Input einen Graphen G mit höchstens zwei ungeraden Knoten und liefert als Output einen Weg in G\", \"type\": \"Algorithmus\"}, {\"id\": 19, \"name\": \"Algorithmus von Hierholzer\", \"description\": \"Dieser Algorithmus (2.8) erhält als Input einen zusammenhängenden Graphen G mit höchstens zwei ungeraden Knoten und liefert als Output einen Eulerweg, bzw. eine Eulertour in G. Dazu wird auch Algorithmus 2.7 zum Finden von Wegen in G verwendet.\", \"type\": \"Algorithmus\"}, {\"id\": 20, \"name\": \"Algorithmus von Fleury\", \"description\": \"Dieser Algorithmus(2.13) erhält als Input einen Graphen G mit höchstens 2 ungeraden Knoten und liefert als Output einen Weg in G. Der Algorithmus hat als Grundlage Algorithmus 2.7 zum Finden von Wegen. Auch lässt sich zeigen, dass man mit diesem Algorithmus eine Eulertour/einen Eulerweg finden kann\", \"type\": \"Algorithmus\"}, {\"id\": 22, \"name\": \"Anwendung von Graphen\", \"description\": \"In dieser Vorlesung geht es um den Einsatzzweck von Graphen und es wird am Beispiel der Erdös- und der Kevin Bacon Zahl gezeigt, welche Zusammenhänge dargestellt werden können.\\\\n+ Links zu Video und Folien\", \"type\": \"Vorlesung\"}, {\"id\": 23, \"name\": \"Beweistechniken Teil 2\", \"description\": \"In dieser Ãœbung geht es um die Beweistechnik der vollständigen Induktion. Diese ist die wohl meist benutzte Beweistechnik in der Algorithmik. Auch werden Anwendungsbeispiele wie z.B. die Gauß\\'sche Summenformel oder der Zusammenhang in Graphen erläutert.\\\\n+ Links zu Video und Folien/Notizen\", \"type\": \"Ãœbung\"}, {\"id\": 24, \"name\": \"Graphenscan\", \"description\": \"In dieser Vorlesung wird der Graphenscanalgorithmus vorgestellt um Zusammenhangskomponenten in Graphen zu finden.\\\\n+ Links zu Video und Folien/Notizen/Beweis\", \"type\": \"Vorlesung\"}, {\"id\": 25, \"name\": \"Algorithmus Graphenscan\", \"description\": \"Dieser Algorithmus (3.7) erhählt als Input einen Graphen G = (V,E) und einen Knoten s darin und liefert als Output eine Knotenmenge Y aus V, die von s aus erreichbar ist, sowie eine Kantenmenge T aus E, welche die Erreichbarkeit sicherstellt\", \"type\": \"Algorithmus\"}, {\"id\": 26, \"name\": \"Datenstrukturen Teil 1\", \"description\": \"In dieser Vorlesung werden die Datenstrukturen Warteschlange (First In - First Out) und Stapel (Last In - First Out) vorgestellt. Außerdem geht es um ihre Rolle für Algorithmen und wie man sie implementieren kann. Das ganze wird am Beispiel des Graphscan Algorithmus gezeigt und somit werden auch Breiten- und Tiefensuche eingeführt.\\\\n+ Links zu Video und Folien/Beispiel\", \"type\": \"Vorlesung\"}, {\"id\": 27, \"name\": \"Warteschlange\", \"description\": \"Eine Warteschlange ist eine Datenstruktur, welche nach dem Prinzip \\'First In - First Out\\' arbeitet. Man findet sie auch im alltäglichen Leben oft wieder, wenn man sich beispielsweise an der Kasse anstellen muss. Der Kunde der zuerst da war, wir auch zuerst bedient.\", \"type\": \"Definition\"}, {\"id\": 28, \"name\": \"Stapel\", \"description\": \"Ein Stapel ist eine Datenstruktur, welche nach dem Prinzip \\'Last In - First Out\\' arbeitet. Im alltäglichen Leben findet man diese Form der Datenstruktur beim Geschirr abwaschen, man stapelt die Teller und der Teller der zuletzt dreckig wurde wird als erstes gereinigt, da man die Teller von oben herunter nimmt.\", \"type\": \"Definition\"}, {\"id\": 29, \"name\": \"Breitensuche\", \"description\": \"Die Breitensuche ist im Prinzip der Graphscan Algorithmus, ausgeführt mithilfe einer Warteschlange als Datenstruktur. Sie breitet sich aus wie eine Welle.\", \"type\": \"Algorithmus\"}, {\"id\": 30, \"name\": \"Tiefensuche\", \"description\": \"Die Breitensuche ist im Prinzip der Graphscan Algorithmus, ausgeführt mithilfe eines Stapels als Datenstruktur. Dabei werden eher einzelne Pfade gelaufen.\", \"type\": \"Algorithmus\"}, {\"id\": 31, \"name\": \"Datenstrukturen Teil 2\", \"description\": \"In dieser Vorlesung geht es einerseits um die Anwendung der Breitensuche, andererseits werden noch 2 weitere Datenstrukturen eingeführt: Die Inzidenz/-Adjazenzmatrix, sowie die Kantenliste\\\\n+ Links zu Video und Folien/Notizen\", \"type\": \"Vorlesung\"}, {\"id\": 32, \"name\": \"Inzidenz/-Adjazenzmatrix\", \"description\": \"In einer Inzidenzmatrix wird mithilfe von 1en und 0en dargestellt, welche Knoten mit welchen Kanten inzident (zusammentreffend) sind. Bei einer Adjazenzmatrix wird dargestellt, welche Knoten adjazent (durch eine Kante verbunden) sind.\", \"type\": \"Definition\"}, {\"id\": 33, \"name\": \"Kanten-/Adjazenzliste\", \"description\": \"Eine Kantenliste ist eine Liste bestehend aus einträgen der Form {vx, vy}, welche bedeuten, dass eine Kante zwischen vx und vy im Graphen existiert.\", \"type\": \"Definition\"}, {\"id\": 34, \"name\": \"Wachstum/O-Notation\", \"description\": \"In dieser Vorlesung wird noch einmal mit den Adjazenz- und Kantenlisten abgeschlossen. Außerdem schauen wir uns einmal das Wachstum von Funktionen an und definieren und die O-Notation um damit zu arbeiten.\\\\n+ Links zu Video und Folien/Notizen\", \"type\": \"Vorlesung\"}, {\"id\": 35, \"name\": \"O-Notation\", \"description\": \"Die O-Notation wird genutzt um das Wachstum von Funktionen abzuschätzen. Damit können Größenordnungen und Wachstumsverhalten beschrieben werden.\", \"type\": \"Definition\"}, {\"id\": 36, \"name\": \"Graphscan Ãœbung\", \"description\": \"Simple Anwengung des Graphscan Algorithmus, einmal als Breiten- und als Tiefensuche. Wann welcher Algorithmus besser geeignet ist wird in dieser Ãœbung erklärt.\", \"type\": \"Ãœbung\"}, {\"id\": 37, \"name\": \"Wachstum\", \"description\": \"Die O-Notation wird genutzt um das Wachstum von Funktionen abzuschätzen. In dieser Ãœbung werden Zusammenhänge zwischen der Größe des Inputs und dem Wachstum, sowie Relationen zwischen Laufzeitklassen näher beleuchtet. Auch wird die O-Notation an verschiedenen Beispielen erklärt.\", \"type\": \"Ãœbung\"}, {\"id\": 38, \"name\": \"Wiederholung oder\\\\nSuche in Graphen Zusammenfassung\", \"description\": \"Noch einmal ein Rückblick auf alles, was bisher in \\'Kapitel 3: Suche in Graphen\\' passiert ist. \\\\n+ Links zu Video und Folien\", \"type\": \"Vorlesung\"}, {\"id\": 39, \"name\": \"Eigenschaften von DFS und BFS\", \"description\": \"In dieser Vorlesung betrachten wir die Breiten- und Tiefensuche im Hinblick auf ihre Laufzeit. Dabei wird anschaulich, wie die Algorithmen arbeiten, wann man sie am besten nutzen sollte und wie man Laufzeiten beweisen kann.\\\\n+ Links zu Video und Folien/Notizen\", \"type\": \"Vorlesung\"}, {\"id\": 40, \"name\": \"Induktionsbeweise Bsp.\", \"description\": \"Einige Beispiele, bei denen der Induktionsbeweis auch in der Graphentheorie zum Einsatz kommt. \", \"type\": \"Beispiel\"}, {\"id\": 41, \"name\": \"Adjazenzliste\", \"description\": \"Wie eine Adjazenzliste für einen Graphen erstellt werden kann wird hier einmal genauer beleuchtet.\", \"type\": \"Beispiel\"}, {\"id\": 42, \"name\": \"Graphscan Beispiel\", \"description\": \"Hier wird der Graphscan Algorithmus einmal mithilfe einer Adjazenzliste als Datenstruktur durchgeführt.\", \"type\": \"Beispiel\"}, {\"id\": 43, \"name\": \"Dynamische Datenstrukturen\", \"description\": \"In dieser Vorlesung beginnen wir dynamische Datenstrukturen einzuführen. Es werden Stapel, Warteschlangen und verkettete Listen vorgestellt. Außerdem beschäftigen wir uns mit binärer Suche.\\\\n+ Links zu Video und Folien\", \"type\": \"Vorlesung\"}, {\"id\": 44, \"name\": \"Verkettete Liste\", \"description\": \"Eine verkettete Liste ist eine dynamische Datenstruktur. Dabei werden für die einzelnen Elemente jeweils Vorgänger und Nachfolger mit gespeichert. Der Vorteil hierbei ist, dass neue Einträge überall eingefügt werden können.\", \"type\": \"Definition\"}, {\"id\": 45, \"name\": \"Binäre Suche\", \"description\": \"Dieser Algorithmus (4.1) erhält als Input einen sortierten Array mit Einträgen S[I], Suchwert WERT, linke Randposition LINKS, rechte Randposition RECHTS und liefert als Output die Position von WERT zwischen Arraypositionen LINKS und RECHTS, falls existent.\", \"type\": \"Algorithmus\"}, {\"id\": 46, \"name\": \"Binäre Suche Idee\", \"description\": \"Ein einleitendes Beispiel zur Binären Suche.\", \"type\": \"Beispiel\"}, {\"id\": 47, \"name\": \"Binäre Suche Beispiel\", \"description\": \"Der Algorithmus für die binäre Suche einmal an zwei Beispielen angewandt.\", \"type\": \"Beispiel\"}, {\"id\": 48, \"name\": \"Binäre Suchbäume\", \"description\": \"In dieser Vorlesung beschäftigen wir uns genauer mit binären Suchbäumen und den darauf anwendbaren Operationen, wie Maximum, Minimum, einfügen und löschen von Knoten, sowie mit der binären Suche.\\\\n+ Links zu Video und Folien\", \"type\": \"Vorlesung\"}, {\"id\": 49, \"name\": \"Binärer Suchbaum\", \"description\": \"In dieser Definition werden die Begriffe \\'gerichteter Graph/Baum\\', \\'Höhe eines Baumes\\', \\'(voller/vollständiger) binärer Baum\\', \\'Blatt eines Baumes\\', \\'Teilbaum eines Knotens\\' und \\'binärer Suchbaum\\' definiert und erklärt.\", \"type\": \"Definition\"}, {\"id\": 50, \"name\": \"Grundoperationen Suchbaum\", \"description\": \"Minimum/Maximum finden, Suche im Baum, Nachfolger finden, Einfügen und Löschen sind die Grundoperationen, welche auf binäre Suchbäume angewendet werden können. Und hier findet ihr die Algorithmen dazu.\", \"type\": \"Algorithmus\"}, {\"id\": 51, \"name\": \"AVL-Bäume\", \"description\": \"In dieser Vorlesung beschäftigen wir uns mit speziellen binären Suchbäumen, den AVL-Bäumen und ihren Eigenschaften.\\\\n+ Links zu Video und Folien/Notizen\", \"type\": \"Vorlesung\"}, {\"id\": 52, \"name\": \"AVL-Baum\", \"description\": \"Ein binärer Suchbaum ist höhenbalanciert, wenn sich für jeden Knoten v die Höhe der beiden Kinder von v um höchstens 1 unterscheidet. Ein höhenbalancierter Suchbaum heißt auch AVL-Baum.\", \"type\": \"Definition\"}, {\"id\": 53, \"name\": \"dyn. Operationen auf AVL-Bäumen\", \"description\": \"In dieser Vorlesung beschäftigen wir uns mit dem Erhalt der AVL-Eigenschaft eines binären Suchbaumes bei Einfüge- und Löschoperationen. Außerdem werfen wir einen Blick auf die Fibonacci-Zahlen.\\\\n+ Links zu Video und Folien\", \"type\": \"Vorlesung\"}, {\"id\": 54, \"name\": \"AVL-Rotation\", \"description\": \"Dieser Algorithmus (4.9) erhält als Input einen Knoten x eines binären Suchbaumes T, Vaterknoten y, Großvaterknoten z und liefert als Output den binären Suchbaum T nach Umstrukturierung mit x, y, z.\", \"type\": \"Algorithmus\"}, {\"id\": 55, \"name\": \"Fibonacci-Zahlen\", \"description\": \"Die Fibonacci-Zahlen sind eine rekursiv definierte Zahlenfolge, bei der sich eine Zahl aus der Summe ihrer zwei Vorgänger ergibt. Dabei sind die ersten beiden Elemente gegeben als 1. Die Fibonacci-Zahlen finden sich überall in der Natur wieder und haben nicht wenig mit unserer Auffassung von Schönheit zu tun.\", \"type\": \"Definition\"}, {\"id\": 56, \"name\": \"Bäume-Ãœbung\", \"description\": \"In dieser Ãœbung beschäftigen wir uns noch einmal genauer mit einigen Datenstrukturen wie verketteten Listen, binären Bäumen und AVL-Bäumen.\", \"type\": \"Ãœbung\"}, {\"id\": 57, \"name\": \"Laufzeit von Algorithmus 2.7\", \"description\": \"Wir betrachten einmal die Laufzeit des Hierholzer-Algorithmus (2.7) und im Zusammenhang damit auch verkettete Listen.\", \"type\": \"Beispiel\"}, {\"id\": 58, \"name\": \"Grundoperationen Suchbaum\", \"description\": \"In diesem Teil der Ãœbung werden einmal die Operationen Einfügen, Suchen, Vorgänger/Nachfolger finden, löschen und verschmelzen von binären Suchbäumen geübt.\", \"type\": \"Beispiel\"}, {\"id\": 59, \"name\": \"AVL-Baum-Operationen\", \"description\": \"Wir schauen uns noch einmal genauer die AVL-Bäume an und was man damit machen kann. Insbesondere auch die Operationen Löschen und Einfügen.\", \"type\": \"Beispiel\"}, {\"id\": 60, \"name\": \"Dynamische Datenstrukturen 2\", \"description\": \"In dieser Vorlesung schauen wir noch einmal auf das bisher in Kapitel 4 gelernte zurück. Außerdem geben wir einen Ãœberblick über einige weitere dynamische Datenstrukturen wie Rot-Scharz-Bäumme, B-Bäume und Heaps.\\\\n+ Links zu Video und Folien\", \"type\": \"Vorlesung\"}, {\"id\": 61, \"name\": \"Rot-Schwarz-Bäume\", \"description\": \"Ein binärer Suchbaum heißt Rot-Schwarz-Baum, wenn er die folgenden Eigenschaften erfüllt:\\\\n1. Jeder Knoten ist entweder rot oder schwarz.\\\\n2. Die Wurzel ist schwarz.\\\\n3. Jedes Blatt (NIL) ist schwarz.\\\\n4. Wenn ein Knoten rot ist, sind seine beiden Kinder schwarz.\\\\n5. Für jeden Knoten enthalten alle Pfade nach unten zu einem Blatt des Teilbaumes die gleiche Anzahl schwarzer Knoten.\", \"type\": \"Definition\"}, {\"id\": 62, \"name\": \"B-Bäume\", \"description\": \"B-Bäume sind binäre Suchbäume, welche für externen Speicher (HDDs) optimiert sind. Dabei wird die Höhe des Baumes minimiert und es werden den Knoten mehr Schlüssel zugewiesen.\", \"type\": \"Definition\"}, {\"id\": 63, \"name\": \"Heaps\", \"description\": \"Ein gerichteter binärer Baum heißt binärer Min/Max-Heap, wenn jeder Knoten einen Schlüssel hat, alle Ebenen außer der \\'letzten\\' genau 2 Knoten haben, auf der \\'letzten\\' Ebene die linken n-(2^h)+1 Positionen besetzt sind und jeder Schlüssel eines Knotens höchstens/mindestens so groß ist wie die seiner Kinder.\", \"type\": \"Definition\"}, {\"id\": 64, \"name\": \"Sortieren\", \"description\": \"In dieser Vorlesung geben wir eine Einführung in das Oberthema Sortieren. Wir stellen außerdem einen Sortieralgorithmus mit dem Namen Mergesort vor und stellen grundlegende Ãœberlegungen zur Laufzeit von Sortieralgorithmen an.\\\\n+ Links zu Video und Folien/Notizen\", \"type\": \"Vorlesung\"}, {\"id\": 65, \"name\": \"Merge-Sort\", \"description\": \"Dieser Algorithmus (5.1) erhält als Input ein Subarray von A=[1,...,n], der bei Index p beginnt und bei Index r endet, d.h. A[p,...,r] und liefert als Output ein sortiertes Subarray. Wichtig ist dafür auch die Subroutine (5.2), welche als Input zwei sortierte Subarrays von A=[1,...,n], d.h. A[p,...,q] und A[q+1,...,r] erhält und als Output das sortierte Subarray A[p,...,r] liefert.\", \"type\": \"Algorithmus\"}, {\"id\": 66, \"name\": \"Sortier-Laufzeitschranken\", \"description\": \"In dieser Vorlesung leiten wir konkrete Laufzeitschranken für das Problem des Sortierens einer Liste von Zahlen her. Zudem machen wir uns Gedanken über das Lösen von Rekursionsgleichungen.\\\\n+ Links zu Video und Folien/Notizen\", \"type\": \"Vorlesung\"}, {\"id\": 67, \"name\": \"Permutation\", \"description\": \"Eine Permutation P ist eine Umsortierung von n Objekten.\", \"type\": \"Definition\"}, {\"id\": 68, \"name\": \"Erzeugende Funktionen\", \"description\": \"Erzeugende Funktionen können genutzt werden um Rekursionen zu lösen.\", \"type\": \"Definition\"}, {\"id\": 69, \"name\": \"Erzeugende Funktionen/Mastertheorem\", \"description\": \"In dieser Vorlesung besprechen wir weitere Details zu erzeugenden Funktionen und führen das Master-Theorem ein.\\\\n+ Links zu Video und Folien/Notizen\", \"type\": \"Vorlesung\"}, {\"id\": 70, \"name\": \"erzeugende Funktionen Fibonacci-Zahlen\", \"description\": \"In diesem Beispiel wird einmal die erzeugende Funktion der Fibonacci-Zahlen hergeleitet.\", \"type\": \"Beispiel\"}, {\"id\": 71, \"name\": \"Master-Theorem\", \"description\": \"Das Master-Theorem bietet eine schnelle Lösung für die Frage, in welcher Laufzeitklasse eine gegebene rekursiv definierte Funktion liegt. Dies funktioniert leider nur, solange einer der drei Fälle des Theorems auf die Funktion angewandt werden kann, ansonsten liefert das Theorem keine Aussage.\", \"type\": \"Definition\"}, {\"id\": 72, \"name\": \"Master-Theorem Beispiele\", \"description\": \"Einige Beispiele, an denen das Master-Theorem und seine Funktion noch einmal verdeutlicht wird.\", \"type\": \"Beispiel\"}, {\"id\": 73, \"name\": \"Sortieralgorithmen und Master-Theorem\", \"description\": \"Wir betrachten ein weiteres Beispiel für Mergesort und leiten erneut die Laufzeit des Sortieralgorithmus her, indem das Master-Theorem benutzt wird. Außerdem betrachten wir einen weiteren Sortieralgorithmus: Heapsort.\\\\n+ Links zu Video und Folien\", \"type\": \"Ãœbung\"}, {\"id\": 74, \"name\": \"Merge-Sort Beispiel\", \"description\": \"Hier wird der Merge-Sort Algorithmus einmal mit einem Beispiel komplett durchgeführt und die Laufzeit des Algorithmus betrachtet.\", \"type\": \"Beispiel\"}, {\"id\": 75, \"name\": \"Master-Theorem Beispiel\", \"description\": \"3 weitere Beispiele, welche dabei helfen das Master-Theorem zu verstehen und anzuwenden.\", \"type\": \"Beispiel\"}, {\"id\": 76, \"name\": \"Max-Heaps\", \"description\": \"Hier wir aufgezeigt, wie man mithilfe eines Algorithmus Max-Heaps bildet. \", \"type\": \"Algorithmus\"}, {\"id\": 77, \"name\": \"Max-Heaps\", \"description\": \"Hier wird der Algorithmus aus der Ãœbung 6 zum Erstellen eines Max-Heaps einmal an einem Beispiel angewandt.\", \"type\": \"Beispiel\"}, {\"id\": 78, \"name\": \"Heapsort\", \"description\": \"Heapsort ist ein Algorithmus bei dem mithilfe von Max-Heaps eine Reihe von Elementen sortiert werden kann. Der Algorithmus hat dabei eine Laufzeit von O(n log n), wie auch in Ãœbung 6 bewiesen wird.\", \"type\": \"Algorithmus\"}, {\"id\": 79, \"name\": \"nichtlineare Rekursionen (Exkurs)\", \"description\": \"In dieser Vorlesung haben wir einen Exkurs in die nichtlineare Rekursion gemacht.\\\\n+ Links zu Video und Folien\", \"type\": \"Vorlesung\"}, {\"id\": 80, \"name\": \"logistische Rekursion\", \"description\": \"Logistische Rekursion bezeichnet ein Wachstum proportional zu einer Größe. Dabei betrachtet man beispielsweise eine Bevölkerung, welche zwar durch Fruchtbarkeit immer weiter wächst, aber beispielsweise durch Tod auch wieder im Wachstum beschränkt wird.\", \"type\": \"Definition\"}, {\"id\": 81, \"name\": \"Mandelbrot-Menge\", \"description\": \"Die Mandelbrot-Menge, benannt nach Benoît Mandelbrot, ist eine Menge in den komplexen Zahlen. Interpretiert man sie als geometrische Figur, so ergibt sich ein Fraktal, welches im allgemeinen Sprachgebrauch auch als Apfelmännchen bekannt ist.\", \"type\": \"Definition\"}, {\"id\": 82, \"name\": \"Fraktale\", \"description\": \"Ein Fraktal beschreibt natürliche oder künstliche Gebilde oder geometrische Muster und ist ein von Benoît Mandelbrot geprägter Begriff. - Wikipedia\", \"type\": \"Definition\"}, {\"id\": 83, \"name\": \"Zelluläre Automaten\", \"description\": \"Zelluläre oder auch zellulare Automaten dienen der Modellierung räumlich diskreter dynamischer Systeme, wobei die Entwicklung einzelner Zellen zum Zeitpunkt t+1 primär von den Zellzuständen in einer vorgegebenen Nachbarschaft und vom eigenen Zustand zum Zeitpunkt t abhängt. - Wikipedia\", \"type\": \"Definition\"}, {\"id\": 84, \"name\": \"Game of Life\", \"description\": \"Das \\'Game of Life\\' ist das wohl bekannteste Beispiel eines zellulären Automaten. \", \"type\": \"Beispiel\"}, {\"id\": 85, \"name\": \"Quick-Sort\", \"description\": \"In dieser Vorlesung kehren wir zurück zu Sortieralgorithmen und stellen den Quicksort-Algorithmus vor.\\\\n+ Links zu Video und Folien/Notizen\", \"type\": \"Vorlesung\"}, {\"id\": 86, \"name\": \"Quick-Sort\", \"description\": \"Dieser Algorithmus (5.14) erhält als Input ein Subarray von A=[1,...,n], der bei Index p beginnt und bei Index r endet, d.h. A[p,...,r] und liefert als Output einen sortierten Subarray. Dabei ist auch Subroutine 5.15 wichtig, welche als Input ein Subarray von A=[1,...,n], d.h. A[p,...,r] erhält und als Output zwei Subarrays A[p,...,q-1] und A[q+1,...,r] mit A[i]≤A[q] und A[q]<A[j] für i=p,...,q-1 und j=q+1,...,r liefert.\", \"type\": \"Algorithmus\"}, {\"id\": 87, \"name\": \"Laufzeit von Quick-Sort\", \"description\": \"Die Laufzeit des Quick-Sort Algorithmus lässt sich mithilfe vom Master-Theorem ermitteln. Dazu betrachten wir die 3 Fälle best-case, average-case und worst-case für den Algorithmus.\", \"type\": \"Beispiel\"}, {\"id\": 88, \"name\": \"Mediane\", \"description\": \"In dieser Vorlesung beschäftigen wir uns mit Medianen.\\\\n+ Links zu Video und Folien\", \"type\": \"Vorlesung\"}, {\"id\": 89, \"name\": \"Standortprobleme\", \"description\": \"Was ist der optimale Standort für beispielsweise ein Amazon-Lagerhaus? Idee: Die durchschnittliche Distanz zu den zu beliefernden Gebäuden minimieren. In Amerika ist dies leicht umgesetzt mit der sogenannten Manhatten-Distanz. Dieses Problem ist die Einführung in das Thema der Mediane.\", \"type\": \"Definition\"}, {\"id\": 90, \"name\": \"Median (diskret)\", \"description\": \"Der Rank k eines Elements x (auch \\'k-tes Element\\') ist definiert durch |{y ∈ X |y<=x}| = k. Also die Anzahl der Elemente, welche kleiner oder gleich x sind. Speziell heißt x Median, wenn er das [n/2]-te Element ist. [n/2] wird dabei abgerundet.\", \"type\": \"Definition\"}, {\"id\": 91, \"name\": \"Median (kontinuierlich)\", \"description\": \"Der kontinuierliche Median hat als Eigenschaft, dass das sowohl Integral bis zum Median, als auch ab dem Median größer-gleich 1/2 ist.\", \"type\": \"Definition\"}, {\"id\": 92, \"name\": \"Sortieralgorithmen Sonderfälle\", \"description\": \"In dieser Vorlesung beschäftigen wir uns mit Sonderfällen für Sortieralgorithmen, durch die Sortieren in linearer Zeit ermöglicht wird. Dabei werfen wir einen näheren Blick auf die Sortierverfahren Countingsort und Radixsort.\\\\n+ Links zu Video und Folien/Notizen\", \"type\": \"Vorlesung\"}, {\"id\": 93, \"name\": \"Counting-Sort\", \"description\": \"Dieser Algorithmus (5.14) erhält als Input ein Array von A=[1],...,A[n] mit Schlüsselwerten aus {1,…, k} und liefert als Output eine sortierte Kopie B[1],…,B[n] von [1],...,A[n].\", \"type\": \"Algorithmus\"}, {\"id\": 94, \"name\": \"Radix-Sort\", \"description\": \"Dieser Algorithmus (5.18) erhält als Input n Zahlen mit je d Ziffern, die k verschiedene Werte annehmen können, [1],...,A[n] und liefert als Output einen sortierten Array. Dabei geht Radix-Sort im Gegensatz zu anderen Sortieralgorithmen ziffernweise vor.\", \"type\": \"Algorithmus\"}, {\"id\": 95, \"name\": \"Quick-Sort, Mediane, kd-Bäume\", \"description\": \"In dieser Ãœbung schauen wir uns noch einmal das Sortierverfahren Quicksort an und sprechen über die Berechnung von Medianen. Außerdem schauen wir uns mit den kd-Bäumen eine spezielle Datenstruktur für mehrdimensionale Daten an.\\\\n+ Links zu Video und Folien\", \"type\": \"Ãœbung\"}, {\"id\": 96, \"name\": \"Quick-Sort Beispiel\", \"description\": \"In diesem Beispiel wird die Funktionsweise von Quick-Sort, sowie die Laufzeit betrachtet.\", \"type\": \"Beispiel\"}, {\"id\": 97, \"name\": \"Mediane Beispiel\", \"description\": \"In diesem Teil der Ãœbung schauen wir uns noch einmal genauer an, was Mediane sind, wie man sie algorithmisch bestimmen kann und in welcher Laufzeit das möglich ist.\", \"type\": \"Beispiel\"}, {\"id\": 98, \"name\": \"kd-Bäume (Exkurs)\", \"description\": \"kd-Bäume sind Bäume mit einer höheren Dimension. Mithilfe der Idee den Baum abwechselnd nach x- und y-Koordinate zu durchsuchen und so zu konstruieren entsteht ein Algorithmus mit dem man mehrdimensionale Suchbäume erstellen kann. Auch schauen wir uns an, wie man in einem solchen Baum sucht.\", \"type\": \"Definition\"}, {\"id\": 99, \"name\": \"(parallelisierte) Sortierverfahren\", \"description\": \"In dieser Vorlesung beenden wir das Kapitel zum Thema Sortieralgorithmen und werfen abschließend einen Blick auf parallelisierte Sortierverfahren.\\\\n+ Links zu Video und Folien/Notizen\", \"type\": \"Vorlesung\"}, {\"id\": 100, \"name\": \"Bubble-Sort Beispiel\", \"description\": \"Einige Beispiele, wie Bubble-Sort funktioniert, inklusive einiger verschiedener Darstellungen/Animationen und dem Vergleich mit Quick-Sort.\", \"type\": \"Algorithmus\"}, {\"id\": 101, \"name\": \"paralleles Bubble-Sort\", \"description\": \"Mithilfe von Parallelisierung lässt sich Bubble-Sort auch in linearer Zeit umsetzen. Die Idee dafür wird hier einmal erläutert.\", \"type\": \"Definition\"}, {\"id\": 102, \"name\": \"Bogo-Sort\", \"description\": \"Bogo-Sort ist ein eher als Scherz gemeinter Sortieralgorithmus. Dabei wird die gegebene Menge solange zufällig durchpermutiert und überprüft bis die korrekte Lösung erreicht ist.\", \"type\": \"Algorithmus\"}, {\"id\": 103, \"name\": \"Zusammenfassung\", \"description\": \"Diese Vorlesung markiert das Ende der Vorlesungszeit. Wir gehen deshalb noch einmal Rückblickend über die verschiedenen Themen die in den vergangenen Monaten behandelt wurden und geben die Möglichkeit Fragen zu stellen.\\\\n+ Links zu Video und Folien\", \"type\": \"Vorlesung\"}, {\"id\": 104, \"name\": \"Klausurvorbereitung\", \"description\": \"Die letzte große Ãœbung von AuD mit Spiel, Spaß, Spannung und vielen Fragen.\\\\n+ Links zu Video und Folien\", \"type\": \"Ãœbung\"}, {\"id\": 105, \"name\": \"Einleitung\", \"description\": \"Eine Einleitung in die Welt der Algorithmen und Datenstrukturen. Was ist ein Algorithmus und wozu wird er benötigt? Und was haben Datenstrukturen damit zu tun?\", \"type\": \"Kapitel\"}, {\"id\": 106, \"name\": \"Graphen\", \"description\": \"Graphen sind eine wichtige Darstellungsform von Daten in der Informatik. Wie Graphen aufgebaut sind und was man alles mit ihnen machen kann wird in diesem Kapitel behandelt.\", \"type\": \"Kapitel\"}, {\"id\": 107, \"name\": \"Suche in Graphen\", \"description\": \"Die Suche in Graphen ist ein wichtiges Werkzeug. Allerdings gibt es mehrere Wege, welche zum Ziel führen und nicht alle funktionieren gleich gut. Wie man effizient in Graphen sucht wird in diesem Kapitel behandelt.\", \"type\": \"Kapitel\"}, {\"id\": 108, \"name\": \"Dynamische Datenstrukturen\", \"description\": \"Im Laufe der Vorlesung wurden bereits einige Datenstrukturen vorgestellt. In diesem Kapitel beschäftigen wir uns mit einer weiteren Klasse der Datenstrukturen, den dynamischen Datenstrukturen. Und damit, welche Möglichkeiten sie bieten.\", \"type\": \"Kapitel\"}, {\"id\": 109, \"name\": \"Sortieren\", \"description\": \"Neben der Suche von Elementen spielt auch das Sortieren in der Informatik eine große Rolle. Wie man das macht wird in diesem Kapitel behandelt.\", \"type\": \"Kapitel\"}, {\"id\": 0, \"name\": \"AuD1\", \"description\": \"Algorithmen und Datenstrukturen 1\", \"type\": \"Kapitel\"}], \"links\": [{\"source\": 1, \"target\": 105}, {\"source\": 2, \"target\": 1}, {\"source\": 3, \"target\": 1}, {\"source\": 4, \"target\": 105}, {\"source\": 4, \"target\": 7}, {\"source\": 5, \"target\": 1}, {\"source\": 6, \"target\": 1}, {\"source\": 7, \"target\": 105}, {\"source\": 8, \"target\": 7}, {\"source\": 21, \"target\": 105}, {\"source\": 9, \"target\": 105}, {\"source\": 9, \"target\": 21}, {\"source\": 10, \"target\": 106}, {\"source\": 11, \"target\": 14}, {\"source\": 12, \"target\": 106}, {\"source\": 12, \"target\": 15}, {\"source\": 12, \"target\": 17}, {\"source\": 12, \"target\": 19}, {\"source\": 12, \"target\": 20}, {\"source\": 13, \"target\": 14}, {\"source\": 13, \"target\": 15}, {\"source\": 14, \"target\": 106}, {\"source\": 15, \"target\": 106}, {\"source\": 16, \"target\": 106}, {\"source\": 17, \"target\": 18}, {\"source\": 18, \"target\": 106}, {\"source\": 19, \"target\": 18}, {\"source\": 20, \"target\": 18}, {\"source\": 22, \"target\": 107}, {\"source\": 23, \"target\": 107}, {\"source\": 23, \"target\": 16}, {\"source\": 24, \"target\": 25}, {\"source\": 25, \"target\": 107}, {\"source\": 26, \"target\": 27}, {\"source\": 26, \"target\": 28}, {\"source\": 26, \"target\": 29}, {\"source\": 26, \"target\": 30}, {\"source\": 26, \"target\": 31}, {\"source\": 27, \"target\": 107}, {\"source\": 28, \"target\": 107}, {\"source\": 29, \"target\": 107}, {\"source\": 29, \"target\": 25}, {\"source\": 30, \"target\": 107}, {\"source\": 30, \"target\": 25}, {\"source\": 31, \"target\": 32}, {\"source\": 31, \"target\": 33}, {\"source\": 32, \"target\": 107}, {\"source\": 33, \"target\": 107}, {\"source\": 34, \"target\": 33}, {\"source\": 34, \"target\": 35}, {\"source\": 35, \"target\": 107}, {\"source\": 36, \"target\": 30}, {\"source\": 36, \"target\": 29}, {\"source\": 36, \"target\": 24}, {\"source\": 37, \"target\": 35}, {\"source\": 38, \"target\": 107}, {\"source\": 39, \"target\": 35}, {\"source\": 39, \"target\": 29}, {\"source\": 39, \"target\": 30}, {\"source\": 40, \"target\": 23}, {\"source\": 41, \"target\": 33}, {\"source\": 42, \"target\": 25}, {\"source\": 42, \"target\": 33}, {\"source\": 43, \"target\": 26}, {\"source\": 43, \"target\": 44}, {\"source\": 44, \"target\": 108}, {\"source\": 45, \"target\": 108}, {\"source\": 46, \"target\": 45}, {\"source\": 47, \"target\": 45}, {\"source\": 48, \"target\": 49}, {\"source\": 48, \"target\": 50}, {\"source\": 49, \"target\": 108}, {\"source\": 50, \"target\": 108}, {\"source\": 50, \"target\": 49}, {\"source\": 51, \"target\": 52}, {\"source\": 52, \"target\": 49}, {\"source\": 52, \"target\": 108}, {\"source\": 53, \"target\": 52}, {\"source\": 54, \"target\": 108}, {\"source\": 54, \"target\": 53}, {\"source\": 54, \"target\": 52}, {\"source\": 55, \"target\": 108}, {\"source\": 56, \"target\": 44}, {\"source\": 56, \"target\": 45}, {\"source\": 56, \"target\": 49}, {\"source\": 56, \"target\": 50}, {\"source\": 56, \"target\": 52}, {\"source\": 56, \"target\": 54}, {\"source\": 57, \"target\": 18}, {\"source\": 57, \"target\": 44}, {\"source\": 58, \"target\": 50}, {\"source\": 58, \"target\": 49}, {\"source\": 59, \"target\": 54}, {\"source\": 59, \"target\": 52}, {\"source\": 60, \"target\": 48}, {\"source\": 60, \"target\": 61}, {\"source\": 60, \"target\": 62}, {\"source\": 60, \"target\": 63}, {\"source\": 61, \"target\": 108}, {\"source\": 61, \"target\": 49}, {\"source\": 62, \"target\": 108}, {\"source\": 62, \"target\": 49}, {\"source\": 63, \"target\": 108}, {\"source\": 64, \"target\": 65}, {\"source\": 64, \"target\": 66}, {\"source\": 65, \"target\": 109}, {\"source\": 66, \"target\": 67}, {\"source\": 66, \"target\": 68}, {\"source\": 67, \"target\": 109}, {\"source\": 68, \"target\": 109}, {\"source\": 69, \"target\": 68}, {\"source\": 70, \"target\": 68}, {\"source\": 70, \"target\": 55}, {\"source\": 71, \"target\": 109}, {\"source\": 72, \"target\": 71}, {\"source\": 73, \"target\": 65}, {\"source\": 73, \"target\": 71}, {\"source\": 74, \"target\": 65}, {\"source\": 75, \"target\": 71}, {\"source\": 76, \"target\": 63}, {\"source\": 76, \"target\": 77}, {\"source\": 76, \"target\": 109}, {\"source\": 76, \"target\": 74}, {\"source\": 77, \"target\": 76}, {\"source\": 78, \"target\": 109}, {\"source\": 78, \"target\": 76}, {\"source\": 78, \"target\": 74}, {\"source\": 79, \"target\": 80}, {\"source\": 79, \"target\": 81}, {\"source\": 79, \"target\": 82}, {\"source\": 79, \"target\": 83}, {\"source\": 80, \"target\": 109}, {\"source\": 81, \"target\": 109}, {\"source\": 82, \"target\": 109}, {\"source\": 82, \"target\": 81}, {\"source\": 83, \"target\": 109}, {\"source\": 84, \"target\": 83}, {\"source\": 85, \"target\": 86}, {\"source\": 86, \"target\": 109}, {\"source\": 87, \"target\": 86}, {\"source\": 87, \"target\": 71}, {\"source\": 88, \"target\": 90}, {\"source\": 88, \"target\": 91}, {\"source\": 89, \"target\": 88}, {\"source\": 90, \"target\": 109}, {\"source\": 91, \"target\": 109}, {\"source\": 91, \"target\": 90}, {\"source\": 92, \"target\": 93}, {\"source\": 92, \"target\": 94}, {\"source\": 93, \"target\": 109}, {\"source\": 94, \"target\": 109}, {\"source\": 95, \"target\": 86}, {\"source\": 95, \"target\": 90}, {\"source\": 95, \"target\": 91}, {\"source\": 96, \"target\": 86}, {\"source\": 97, \"target\": 90}, {\"source\": 97, \"target\": 91}, {\"source\": 98, \"target\": 109}, {\"source\": 98, \"target\": 49}, {\"source\": 98, \"target\": 95}, {\"source\": 99, \"target\": 100}, {\"source\": 99, \"target\": 101}, {\"source\": 99, \"target\": 102}, {\"source\": 100, \"target\": 109}, {\"source\": 100, \"target\": 86}, {\"source\": 101, \"target\": 100}, {\"source\": 102, \"target\": 109}, {\"source\": 103, \"target\": 0}, {\"source\": 104, \"target\": 103}, {\"source\": 105, \"target\": 0}, {\"source\": 106, \"target\": 0}, {\"source\": 107, \"target\": 0}, {\"source\": 108, \"target\": 0}, {\"source\": 109, \"target\": 0}]}'" - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "json.dumps(result, ensure_ascii=False)" + "jr = json.dumps(result, ensure_ascii = False)" ] }, { "cell_type": "code", - "execution_count": 6, - "id": "841e41aa-edcf-4b6a-b946-e4696b9e5ddc", - "metadata": {}, + "execution_count": null, "outputs": [], - "source": [] + "source": [ + "print(jr.replace('\\\\n','<br>'))" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } } ], "metadata": { diff --git a/display/graph.js b/display/graph.js index 32ba3da..e1c22e0 100644 --- a/display/graph.js +++ b/display/graph.js @@ -452,15 +452,20 @@ class Graph { // Draw node circle image const textureLoader = new THREE.TextureLoader(); + textureLoader.setCrossOrigin("anonymous"); const imageAlpha = textureLoader.load( Config.PLUGIN_PATH + "datasets/images/alpha.png" ); let imageTexture = null; if ("image" in node) { - imageTexture = textureLoader.load( - Config.PLUGIN_PATH + "datasets/images/" + node.image - ); + if (node.image.startsWith("http")) { + imageTexture = textureLoader.load(node.image); + } else { + imageTexture = textureLoader.load( + Config.PLUGIN_PATH + "datasets/images/" + node.image + ); + } } else { imageTexture = textureLoader.load( Config.PLUGIN_PATH + "datasets/images/default.jpg" @@ -520,7 +525,7 @@ let infoOverlay = null; // Only execute, if corresponding dom is present if (document.getElementById("3d-graph") !== null) { - G = new Graph(space_id); // space_id defined globaly through knowledge-space.php + G = new Graph(Config.SPACE); // space_id defined globaly through knowledge-space.php filterOverlay = new FilterOverlay(G, "node"); infoOverlay = new NodeInfoOverlay(G); G.infoOverlay = infoOverlay; diff --git a/display/overlays/nodeinfo.js b/display/overlays/nodeinfo.js index 8e408de..37b34c3 100644 --- a/display/overlays/nodeinfo.js +++ b/display/overlays/nodeinfo.js @@ -86,7 +86,7 @@ class NodeInfoOverlay { const textArea = Helpers.createDiv("detail-view-text-area", infoArea); Helpers.createHTMLElement("p", textArea, { id: "infoOverlayDescription", - innerText: "Default Text", + innerHTML: "Default Text", }); const videoDiv = Helpers.createDiv("detail-view-media-area", infoArea); @@ -139,9 +139,10 @@ class NodeInfoOverlay { } if ("description" in node) { - jQuery("#infoOverlayDescription").text(node.description); + jQuery("#infoOverlayDescription").html(node.description); + //jQuery("#infoOverlayDescription").text(node.description); } else { - jQuery("#infoOverlayDescription").text("Default Text"); + jQuery("#infoOverlayDescription").html("Default Text"); } if ("video" in node) { diff --git a/editor/js/editor.js b/editor/js/editor.js index c9fd936..e6a0dc0 100644 --- a/editor/js/editor.js +++ b/editor/js/editor.js @@ -3,6 +3,7 @@ import * as Graph from "./graph"; import { loadGraphJson } from "../../datasets/datasets"; import ForceGraph from "force-graph"; import * as Interactions from "./interactions"; +import { SPACE } from "../../config"; export var state; @@ -20,7 +21,7 @@ window.onload = function () { Interactions.initInteractions(); - loadGraphJson(space_id) // space_id defined globaly through knowledge-space.php + loadGraphJson(SPACE) // space_id defined globaly through knowledge-space.php .then((graphConfig) => { state = new State(); graph = new Graph.Graph(graphConfig); @@ -61,6 +62,8 @@ function load() { ) .nodeCanvasObjectMode((node) => state.nodeCanvasObjectMode(node)) .nodeCanvasObject((node, ctx, globalScale) => state.nodeCanvasObject(node, ctx, globalScale)) + .linkCanvasObjectMode((link) => state.linkCanvasObjectMode(link)) + .linkCanvasObject((link, ctx, globalScale) => state.linkCanvasObject(link, ctx, globalScale)) .onLinkClick((link) => state.onLinkClick(link)); graph.onChangeCallbacks.push((data) => { diff --git a/editor/js/state.js b/editor/js/state.js index a8fae50..5c41d79 100644 --- a/editor/js/state.js +++ b/editor/js/state.js @@ -203,6 +203,26 @@ export class State extends Tool { return "after"; } + linkCanvasObjectMode(link) { + var toolValue = this.tool.linkCanvasObjectMode(link); + + if (toolValue !== undefined) { + return toolValue; + } + + return "after"; + } + + linkCanvasObject(link, ctx, globalScale) { + var toolValue = this.tool.linkCanvasObject(link, ctx); + + if (toolValue !== undefined) { + return toolValue; + } + + return undefined; + } + linkWidth(link) { var toolValue = this.tool.linkWidth(link); diff --git a/editor/js/tools/tool.js b/editor/js/tools/tool.js index 0c7b3ad..63ab117 100644 --- a/editor/js/tools/tool.js +++ b/editor/js/tools/tool.js @@ -93,6 +93,18 @@ export default class Tool { } } + linkCanvasObject(link, ctx, globalScale) { + if (this.warnings) { + console.warn('Method "linkCanvasObject" not implemented.'); + } + } + + linkCanvasObjectMode(link) { + if (this.warnings) { + console.warn('Method "linkCanvasObjectMode" not implemented.'); + } + } + nodePointerAreaPaint(node, color, ctx) { if (this.warnings) { console.warn('Method "nodePointerAreaPaint" not implemented.'); diff --git a/knowledge-space.php b/knowledge-space.php index cdf7f30..53dc519 100644 --- a/knowledge-space.php +++ b/knowledge-space.php @@ -14,17 +14,21 @@ function ks_add_graph($atts = []): string $space_id = get_space_id_from_atts($atts); $div = '<div id="3d-graph"></div>'; // The id "3d-graph" indicates, that the javascript associated with this should automatically be executed $plugin_dir = plugin_dir_url(__FILE__); - //$dataset = $plugin_dir.'datasets/miserables.json'; - $variables = "<script> - var plugin_path = '$plugin_dir'; - var space_id = '$space_id'; - </script>"; - - $script_path = $plugin_dir . 'build' . DIRECTORY_SEPARATOR . $GLOBALS['build'] . DIRECTORY_SEPARATOR . 'graph.js'; - $script = "<script src='$script_path'></script>"; + + $script_path = 'build' . DIRECTORY_SEPARATOR . $GLOBALS['build'] . DIRECTORY_SEPARATOR . 'graph.js'; + // $script = "<script src='$script_path'></script>"; //wp_enqueue_script('kg-script', $script_path); + wp_enqueue_script("ks-display-js", plugins_url($script_path, __FILE__), array('jquery'), false); + wp_localize_script( + 'ks-display-js', + 'ajax_object', + array('ajax_url' => admin_url('admin-ajax.php')) + ); + wp_localize_script("ks-display-js", "space", array('id' => $space_id)); + wp_localize_script("ks-display-js", "plugin", array('path' => $plugin_dir)); - return $div . $variables . $script; + return $div . $variables; + // return $div . $variables . $script; } function ks_add_editor($atts = []) @@ -33,10 +37,8 @@ function ks_add_editor($atts = []) $space_id = get_space_id_from_atts($atts); $plugin_dir = plugin_dir_url(__FILE__); - echo "<script> - var plugin_path = '$plugin_dir'; - var space_id = '$space_id'; - </script>"; + wp_localize_script("ks-editor-js", "space", array('id' => $space_id)); + wp_localize_script("ks-editor-js", "plugin", array('path' => $plugin_dir)); require_once(__DIR__ . '/editor/editor.php'); } @@ -45,8 +47,16 @@ function ks_add_editor_dependencies() { $script_path = 'build' . DIRECTORY_SEPARATOR . $GLOBALS['build'] . DIRECTORY_SEPARATOR . 'graph.js'; - wp_enqueue_script('jquery'); - wp_enqueue_script("ks-editor-js", plugins_url($script_path, __FILE__), array(), false); + // wp_enqueue_script('jquery'); + wp_enqueue_script("ks-editor-js", plugins_url($script_path, __FILE__), array('jquery'), false); + //wp_register_script("ks-editor-js", plugins_url($script_path, __FILE__), array('jquery'), false); + + wp_localize_script( + 'ks-editor-js', + 'ajax_object', + array('ajax_url' => admin_url('admin-ajax.php')) + ); + //wp_enqueue_script("ks-editor-js"); $style_file_version = date("ymd-Gis", filemtime(plugin_dir_path(__FILE__) . "editor/css/editor.css")); wp_enqueue_style("ks-editor-css", plugins_url("editor/css/editor.css", __FILE__), array(), $style_file_version); @@ -71,7 +81,8 @@ function escape_space_id($id) ); } -function get_space_id_from_atts($atts) { +function get_space_id_from_atts($atts) +{ if ($atts != "" && array_key_exists("space", $atts)) { return escape_space_id($atts["space"]); } else { @@ -79,6 +90,9 @@ function get_space_id_from_atts($atts) { } } + +require_once(__DIR__ . '/datasets/datasets.php'); + add_action('wp_enqueue_scripts', 'kg_load_css'); add_shortcode('knowledge-space', 'ks_add_graph'); add_shortcode('knowledge-space-editor', 'ks_add_editor'); -- GitLab