From f65f587623839854b79fac51567efe1c65144f0a Mon Sep 17 00:00:00 2001 From: Dieter Blocher Date: Wed, 30 Oct 2024 11:18:42 +0100 Subject: [PATCH] Upload files to "/" --- all_readme.md | 1488 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1488 insertions(+) create mode 100644 all_readme.md diff --git a/all_readme.md b/all_readme.md new file mode 100644 index 0000000..f6832e6 --- /dev/null +++ b/all_readme.md @@ -0,0 +1,1488 @@ +# Bluetooth Data Exchange App +Dieses Repository enthält Informationen und Code aus dem BOGY (Berufsorientierung für Gymnasien), das in Kooperation zwischen dem Leibniz Gymnasium in Rottweil (https://www.lg-rw.de/) und der Firma Mitutoyo CTL Germany GmbH (https://www.mitutoyo-ctl.de/) im Frühjahr 2024 stattfand. + +Es handelt sich um ein erweitertes Praktikum. Das bedeutet, dass es neben der üblichen Praktikums-Woche noch sechs vorbereitende Nachmittage gibt. An diesen Nachmittagen bringen wir den Schülern die Grundlagen bei, damit in der Praktikumswoche auch ein sichtbares Produkt entstehen kann. + +## BOGY Woche, Donnerstag 21.3.2024 + +Wir haben herausgefunden, warum das `LocalStorage` die Daten nicht speichern konnte. Die Erklärung haben wir in [DatenSpeichern (PowerPoint)](doc/DatenSpeicher.pptx) aufgeschrieben. + +## BOGY Woche, Dienstag 19.3.2024 + +Hier der Link zum Beispielcode (C++) wie man die DateTime Werte umrechnen kann: +https://godbolt.org/z/K453oPdov + +Bluetooth Gatt-XML: https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.date_time.xml + +[Ergebnis nach dem heutigem Tag:](https://github.com/BogyMitutoyoCTL/BOGY-App-2024-03/assets/140964926/b2b780a1-3034-4ab4-b11e-b5a0183cd706) + + +## BOGY Woche, Montag 18.3.2024 + +Wir haben nochmal das Thema Objektorientierung wiederholt, weil es bei Flutter so wichtig ist. + +Danach haben wir die ersten Schritte mit [Flutter (Powerpoint)](doc/Flutter.pptx) gemacht. + +## Nachmittag 6, Mittwoch 13.3.2024 + +Wir haben die [Dart (Powerpoint)](doc/Dart.pptx) abgeschlossen. Das wichtigste Thema dabei war sicherlich die Objektorientierung. Die wird uns das BOGY über ständig begleiten. + +Da noch ein wenig Zeit übrig war, haben wir uns zudem noch ein wenig den Aufbau des Flutter Demo Projekts in Android Studio angeschaut, um eine bessere Vorstellung davon zu bekommen, wie sich eine Smartphone-App mit Flutter aufbauen lässt. +Zuletzt haben wir noch probiert, die gesehene Struktur anhand eines kleinen Beispiels selbst zu programmieren. + +## Nachmittag 5, Mittwoch 6.3.2024 +Auch an diesem Nachmittag haben wir weiter mit der [Dart (Powerpoint)](doc/Dart.pptx) gearbeitet. Neu waren: + +- Listen +- Maps +- Methoden +- Funktionen +- Named Arguments +- Scope +- Callbacks + +Wir sind mit allen behandelten Themen fertig geworden und steigen nächste Woche mit Lambdas ein. Wir sind bis einschließlich Folie 70 gekommen. + +## Nachmittag 4, Mittwoch 28.2.2024 + +Wir haben mit der [Dart (Powerpoint)](doc/Dart.pptx) weitergemacht. Neu waren: + +- Strings +- Templates +- Schleifen (```for``` und ```while```) +- Wahrheitswerte +- Verzweigungen + +Die Idee von Listen haben wir am Ende noch kurz angesprochen und werden mit dem Thema Listen am nächsten Mittwoch wieder einsteigen. Wir kamen bis einschließlich Folie 40. + +## Nachmittag 3, Mittwoch 21.2.2024 + +Wir haben heute die Entwicklungsumgebung [Android Studio (Powerpoint)](doc/AndroidStudio.pptx) installiert. Das ist gar nicht so trivial, da es mehrere Komponenten gibt: + +* Amazon Corretto, eine JRE (Java Runtime Environment) als Voraussetzung, dass Android Studio überhaupt läuft +* Android Studio selbst +* SDKs und Plugins für Android Studio +* den Emulator für Android-Geräte auf Windows +* Flutter als Framework für plattformunabhängige Apps + +Nachdem uns diese Installation fast den gesamten Nachmittag gekostet hat, konnten wir noch mit [Dart (Powerpoint)](doc/Dart.pptx) beginnen und tatsächlich noch ein paar Befehle programmieren. Wir sind bis zur Aufgabe auf Folie 20 gekommen. + +## Nachmittag 2, Mittwoch 7.2.2024 + +Wir haben uns heute mit der Programmierung des ESP32, insbesondere der Bluetooth-Anbindung beschäftigt. Den Code dazu haben wir in [esp_32_tutorials](esp_32_tutorials) abgelegt. + +Das lief leider nicht ganz so gut, wie erwartet. Da das Thema BLE (Bluetooth Low Energy) auch für uns noch neu ist, werden wir uns das mal anschauen und fertigstellen. Nächstes Mal beginnen wir daher mit Android Studio. + +## Nachmittag 1, Mittwoch 31.1.2024 + +Wir haben uns das Gebäude angeschaut, damit sich die Schüler auch zurechtfinden. Mit Hilfe der [Firmenpräsentation (Powerpoint)](doc/Firmenpräsentation.pptx) haben wir einen Überblick über den Aufbau der Firma und deren Produkte erhalten. Auch der Ablauf des Studiums wurde besprochen. Da unsere Partner-Hochschule die DHBW in Stuttgart ist, haben wir in Stuttgart eine [Studentenwohnung (Powerpoint)](doc/Studentenwohnung.pptx) gemietet, die wir den Studenten zur Verfügung stellen. + +Wir haben ganz kurz besprochen, was wir programmieren: + +* einen Microcontroller (Typ ESP32), der Daten von einem Temperatursensor per Bluetooth BLE liefert +* eine Smartphone App, die diese Daten empfängt und darstellt + +Wir haben darüber hinaus einige Ideen gesammelt, welche Features die App noch haben könnte: + +* + +Weiterhin haben wir besprochen, wie man sich am Laptop und am WLAN anmeldet. Wir haben Discord Accounts eingerichtet und sind dem Kanal für das BOGY beigetreten. Wir haben Github Accounts angelegt und mit diesem Repository verknüpft. Außerdem haben wir die [Arduino IDE](https://www.arduino.cc/en/software) und [Visual Studio Code](https://code.visualstudio.com/download) installilert, mit denen wir den Microcontroller programmieren möchten, der uns die Daten per Bluetooth liefern soll. + +# Bluetooth Data Exchange App +Dieses Repository enthält Informationen und Code aus dem BOGY (Berufsorientierung für Gymnasien), das in Kooperation zwischen dem Leibniz Gymnasium in Rottweil (https://www.lg-rw.de/) und der Firma Mitutoyo CTL Germany GmbH (https://www.mitutoyo-ctl.de/) im Frühjahr 2024 stattfand. + +Es handelt sich um ein erweitertes Praktikum. Das bedeutet, dass es neben der üblichen Praktikums-Woche noch sechs vorbereitende Nachmittage gibt. An diesen Nachmittagen bringen wir den Schülern die Grundlagen bei, damit in der Praktikumswoche auch ein sichtbares Produkt entstehen kann. + +## BOGY Woche, Donnerstag 21.3.2024 + +Wir haben herausgefunden, warum das `LocalStorage` die Daten nicht speichern konnte. Die Erklärung haben wir in [DatenSpeichern (PowerPoint)](doc/DatenSpeicher.pptx) aufgeschrieben. + +## BOGY Woche, Dienstag 19.3.2024 + +Hier der Link zum Beispielcode (C++) wie man die DateTime Werte umrechnen kann: +https://godbolt.org/z/K453oPdov + +Bluetooth Gatt-XML: https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.date_time.xml + +[Ergebnis nach dem heutigem Tag:](https://github.com/BogyMitutoyoCTL/BOGY-App-2024-03/assets/140964926/b2b780a1-3034-4ab4-b11e-b5a0183cd706) + + +## BOGY Woche, Montag 18.3.2024 + +Wir haben nochmal das Thema Objektorientierung wiederholt, weil es bei Flutter so wichtig ist. + +Danach haben wir die ersten Schritte mit [Flutter (Powerpoint)](doc/Flutter.pptx) gemacht. + +## Nachmittag 6, Mittwoch 13.3.2024 + +Wir haben die [Dart (Powerpoint)](doc/Dart.pptx) abgeschlossen. Das wichtigste Thema dabei war sicherlich die Objektorientierung. Die wird uns das BOGY über ständig begleiten. + +Da noch ein wenig Zeit übrig war, haben wir uns zudem noch ein wenig den Aufbau des Flutter Demo Projekts in Android Studio angeschaut, um eine bessere Vorstellung davon zu bekommen, wie sich eine Smartphone-App mit Flutter aufbauen lässt. +Zuletzt haben wir noch probiert, die gesehene Struktur anhand eines kleinen Beispiels selbst zu programmieren. + +## Nachmittag 5, Mittwoch 6.3.2024 +Auch an diesem Nachmittag haben wir weiter mit der [Dart (Powerpoint)](doc/Dart.pptx) gearbeitet. Neu waren: + +- Listen +- Maps +- Methoden +- Funktionen +- Named Arguments +- Scope +- Callbacks + +Wir sind mit allen behandelten Themen fertig geworden und steigen nächste Woche mit Lambdas ein. Wir sind bis einschließlich Folie 70 gekommen. + +## Nachmittag 4, Mittwoch 28.2.2024 + +Wir haben mit der [Dart (Powerpoint)](doc/Dart.pptx) weitergemacht. Neu waren: + +- Strings +- Templates +- Schleifen (```for``` und ```while```) +- Wahrheitswerte +- Verzweigungen + +Die Idee von Listen haben wir am Ende noch kurz angesprochen und werden mit dem Thema Listen am nächsten Mittwoch wieder einsteigen. Wir kamen bis einschließlich Folie 40. + +## Nachmittag 3, Mittwoch 21.2.2024 + +Wir haben heute die Entwicklungsumgebung [Android Studio (Powerpoint)](doc/AndroidStudio.pptx) installiert. Das ist gar nicht so trivial, da es mehrere Komponenten gibt: + +* Amazon Corretto, eine JRE (Java Runtime Environment) als Voraussetzung, dass Android Studio überhaupt läuft +* Android Studio selbst +* SDKs und Plugins für Android Studio +* den Emulator für Android-Geräte auf Windows +* Flutter als Framework für plattformunabhängige Apps + +Nachdem uns diese Installation fast den gesamten Nachmittag gekostet hat, konnten wir noch mit [Dart (Powerpoint)](doc/Dart.pptx) beginnen und tatsächlich noch ein paar Befehle programmieren. Wir sind bis zur Aufgabe auf Folie 20 gekommen. + +## Nachmittag 2, Mittwoch 7.2.2024 + +Wir haben uns heute mit der Programmierung des ESP32, insbesondere der Bluetooth-Anbindung beschäftigt. Den Code dazu haben wir in [esp_32_tutorials](esp_32_tutorials) abgelegt. + +Das lief leider nicht ganz so gut, wie erwartet. Da das Thema BLE (Bluetooth Low Energy) auch für uns noch neu ist, werden wir uns das mal anschauen und fertigstellen. Nächstes Mal beginnen wir daher mit Android Studio. + +## Nachmittag 1, Mittwoch 31.1.2024 + +Wir haben uns das Gebäude angeschaut, damit sich die Schüler auch zurechtfinden. Mit Hilfe der [Firmenpräsentation (Powerpoint)](doc/Firmenpräsentation.pptx) haben wir einen Überblick über den Aufbau der Firma und deren Produkte erhalten. Auch der Ablauf des Studiums wurde besprochen. Da unsere Partner-Hochschule die DHBW in Stuttgart ist, haben wir in Stuttgart eine [Studentenwohnung (Powerpoint)](doc/Studentenwohnung.pptx) gemietet, die wir den Studenten zur Verfügung stellen. + +Wir haben ganz kurz besprochen, was wir programmieren: + +* einen Microcontroller (Typ ESP32), der Daten von einem Temperatursensor per Bluetooth BLE liefert +* eine Smartphone App, die diese Daten empfängt und darstellt + +Wir haben darüber hinaus einige Ideen gesammelt, welche Features die App noch haben könnte: + +* + +Weiterhin haben wir besprochen, wie man sich am Laptop und am WLAN anmeldet. Wir haben Discord Accounts eingerichtet und sind dem Kanal für das BOGY beigetreten. Wir haben Github Accounts angelegt und mit diesem Repository verknüpft. Außerdem haben wir die [Arduino IDE](https://www.arduino.cc/en/software) und [Visual Studio Code](https://code.visualstudio.com/download) installilert, mit denen wir den Microcontroller programmieren möchten, der uns die Daten per Bluetooth liefern soll. + +# Android Timer App +## Freitag 31.3.2023 + +### Abend der Technik + +Der Abend der Technik findet am Mittwoch, 3.5.2023, statt. Die dort vorgestellte Präsentation arbeitet ihr bitte bis Freitag 28.4.2023 aus. Didi und Thomas kommen am 28.4. ins LFZ. Dort könnt ihr die Präsentation einmal probbehalten. + +Unsere Vorgaben für den Abend der Technik: + +1. Poloshirts anziehen + +2. Präsentation auf Basis der [Vorlage von Mitutoyo](AbendDerTechnik/Vorlage.potx) erstellen + +3. Lasst euch vorher die Bühne zeigen, damit ihr wisst, wo es hinauf und hinunter geht + +4. Aufbau der Präsentation + + 1. Zuschauer motivieren, dass sie die nächsten 5-10 Minuten auch zuhören + 1. Interesse wecken: "Hatten Sie nicht auch schon das Problem, dass ..." + 2. Nicht die Lösung verraten + 2. [Firma vorstellen](Firmenpräsentation.pptx): 1 Folie genügt + 3. Ablauf des Praktikums erklären + 1. Nachmittage: Rundgang, Installation [Android Studio](AndroidStudio.pptx), [Dart](Dart.pptx), [Flutter](Flutter.pptx) + + Fachbegriffe kurz erklären + + Dart: Programmiersprache, ähnlich wie Arduino / C++ + + Flutter: Bibliotheken (geschrieben in Dart) für die Oberfläche, z.B. Buttons, Icons, Scrollbalken, Text, Farben, ... + 2. BOGY-Woche: Ein Problem gelöst / App programmiert + 4. Details + 1. Bildschirme auf Papier aufgemalt (Bild/Foto vom gescannnten Papier) + 2. In einem Online-Kollaborationstool ([Figma](https://www.figma.com)) etwas realistischer gezeichnet (Bild zeigen) + 3. Umsetzung in Widgets (Programmierarbeit) (Screenshot von *Timer anlegen*) + 4. Code austauschen über Github (Push + Pull), + 1. Github ist eine Versionsverwaltung + 2. Github ist auch ein Kollaborationstool (Screenshot zeigen von [Github Issues](https://github.com/BogyMitutoyoCTL/BOGY-App-2023-04/issues)) + 5. Wiederverwendbare Unter-Widgets + 6. Daten + Business Logik (dass die App was tut) + 7. Testen (im Browser + im Emulator) + Fehler finden + Fehler eintragen (bei Github) + Fehler beheben + Abläufe optimieren + 5. Lösung / Ergebnis: hier die coolsten und besten Bilder zeigen + 1. Settings Dialog + 2. Categories + 3. Video von einem Timer der abläuft + 4. ... + 6. Vielen Dank + 7. Fragen: bitte kommt zu unserem Stand + +Messestand: + +* Messestand bringen wir mit +* Laptops zum Ausprobieren bringen wir mit + +## Donnerstag 30.3.2023 + +### Vereinfachung des Datenaustauschs + +Wir haben darauf verzichtet, die Daten eines StatefulWidget an seinen State durchzureichen. Stattdessen geben wir die Daten nur noch an das Widget und greifen dann im State mittels `widget.data` auf die Daten zu. + +Für die Subwidgets haben wir eigene Datenklassen erstellt und Logik ergänzt, damit diese Daten auch benutzt werden. + +### Notifications auf dem Sperrbildschirm + +Um Nachrichten über abgelaufene Timer auf dem Sperrbildschirm anzuzeigen haben wir eine Bibliothek installiert (`pubspec.yaml`): + +``` +flutter_local_notifications: ^9.7.0 +``` +https://pub.dev/packages/flutter_local_notifications + +Dazu muss auch in der Datei `android\app\src\main\AndroidManifest.xml` folgendes eingetragen werden: + +```xml + + +``` + +### App Icon + +Um Icons für verschiedene Plattformen generieren zu lassen kann man folgendes Package verwenden: +https://pub.dev/packages/flutter_launcher_icons + +In unserem Projekt haben wir die Konfiguration in die `pubspec.yaml` integriert. Die Beschreibung dafür findet man auf der Projektseite des Packages. + +**Hinweis:** + +Wenn man weitere Daten zu den Resourcen für Android hinzufügt, muss man darauf achten, dass die Dateinamen klein geschrieben sind. Sonst bekommt man folgende Fehlermeldung: + +``` +ERROR:.\BOGY-App-2023-04\multitimer\android\app\src\main\res\drawable\Logo.png: Resource and asset merger: 'L' is not a valid file-based resource name character: File-based resource names must contain only lowercase a-z, 0-9, or underscore + +FAILURE: Build failed with an exception. +``` + +## Mittwoch 29.3.2023 + +Wir haben weitere Widgets programmiert, die Themes angepasst und schon erste Sub-Widgets erstellt. + +Wir haben die Daten an die Widgets durchgereicht, damit diese irgendwann die echten Daten anzeigen können. + +### Fehlermeldung beim Bauen des APK + +Falls diese Fehlermeldung beim Bauen des APKs (Menü: Build / Flutter / Build APK) erscheint: + +``` +Running Gradle task 'assembleRelease'... + +FAILURE: Build failed with an exception. + +* What went wrong: +The supplied javaHome seems to be invalid. I cannot find the java executable. Tried location: C:\Program Files\Android\Android Studio\jre\bin\java.exe +``` + +dann hilft folgende Vorgehensweise: + +1. Windows Kommandozeile als Administrator starten +2. `cd /d C:\Program Files\Android\Android Studio` +3. `ren jre jre_old` +4. `mklink /D jre jbr` + +## Dienstag 28.3.2023 + +Wir haben mit der Implementierung von Widgets weitergemacht. + +### Speichern von Daten als JSON + +Wir Betreuer haben festgestellt, dass unser Wissen über Dart schon wieder veraltet ist. Das alte `flutter generate` wurde mittlerweile durch `dart pub run build_runner` ersetzt. Das ist allerdings auch schon wieder veraltet und heißt nun `dart run build_runner build`. Mit dem Befehl werden dann Teile von Klassen automatisch generiert. + +Klassen, die als JSON gespeichert werden sollen, brauchen: + +* das Paket `import 'package:json_annotation/json_annotation.dart';` + +* einen anderen, automatisch generierten Teil der Klasse `part 'Klassenname.g.dart';` + +* direkt oberhalb der Klasse `@JsonSerializable(explicitToJson: true, includeIfNull: true)` + +* ```dart + @override + String toString() => toJson().toString(); + + factory Klassenname.fromJson(Map json) => _$KlassennameFromJson(json); + + Map toJson() => _$KlassennameToJson(this); + ``` + +Nach diesen Änderungen muss der Befehl `dart run build_runner build` ausgeführt werden, um die Datei `Klassenname.g.dart` zu erzeugen, die mit Punkt 2 der obigen Liste eingebunden wird. + +### Versionsnummern in pubspec.yaml + +`^` bedeutet: es sind auch alle neueren Versionen dieser Bibliothek zugelassen, die garantiert rückwärtskompatibel mit dieser Version sind. + +`>=` bedeutet: diese Version oder neuer + +### Themes + +Bei der Erstellung von Themes ist uns aufgefallen, dass die Hintergrundfarbe des Themes nicht angewandt wurde. Als Lösung haben wir die Eigenschaft `scaffoldBackgroundColor` gefunden. + +### Navigation + +Neben `.push(...)` und `.pop()` haben wir noch `pushReplacement(...)` entdeckt, das verhindert, dass man z.B. wieder zum Splashscreen zurück navigieren kann. + +### Flutter Upgrade + +Manche Betreuer mussten eine bestehende Flutter Installation mit `flutter upgrade --force` aktualisieren. + +## Montag 27.3.2023 + +Nach einigen organisatorischen Dingen wie z.B. der Bestellung von Mittagessen haben wir das Widget von Folie 26 fertiggestellt, Navigation eingebaut und gelernt, wie wir Daten von einem Widget zum nächsten transferieren. + +Um unsere Arbeit zu vereinfachen, haben wir uns ein paar Live Templates erstellt: + +* Wir haben das Live Template `stless` so modifiziert, dass wir in Zukunft automatisch ein Scaffold, eine AppBar und eine Column bekommen. + +* Wir haben uns Live Templates für TextField und den dazugehörigen TextEditingController angelegt. + +Damit wir eine grobe Vorstellung haben, was wir diese Woche programmieren müssen, haben wir zunächst die Widgets von Hand gezeichnet. + +Folgende Widgets haben wir identifiziert: + +* SplashScreen mit dem Logo unserer App +* Startbildschirm (Main menu) + * Button für Einstellungen + * Button für Benutzerprofile (?) + * Navigation zu den verfügbaren Kategorien +* Widget für Einstellungen + * Dark Mode / Light Mode + * Spende ans Entwicklerteam +* Widget für Benutzerprofile (?) + * ? +* Anzeige der verfügbaren Kategorien + * Liste der Kategorien + * je Button zum Löschen einer Kategorie + * je 1 Button zum Editieren einer Kategorie (Bleistift Icon) + * 1 Button zum Anlegen eines neuen Timers +* Anlegen/Bearbeiten eines Timers + * Textfeld zum Eingeben des Namens des Timers + * Auswahl oder Eingabe der Kategorie für diesen Timer + * je Abschnitt 1 Eingabefeld zum Festlegen der Dauer dieses Timers + * Textfeld für die auszuführende Aktion + * Button zum Hinzufügen einer weiteren Dauer (zusätzlicher Abschnitt mit +/- Button) + * Button zum Speichern +* Anzeige der Timer innerhalb einer Kategorie + * Button zum Starten eines Timers + * Button zum Editieren eines Timers + * Button zum Löschen eines Timers +* Anzeige bei Ablauf eines Timers + * Liste der abgelaufenen Timer + * Name der auszuführenden Aktion + * je 1 Bestätigungsbutton zum Fortsetzen bzw. Beenden des Timers +* Anzeige der aktiven Timer + * Name und Dauer des Timers + * Abbrechen eines Timers +* Meldungen auf dem Sperrbildschirm + +Die Aufgaben zur Erstellung dieser Widgets haben wir als [Issues](issues) in Github hinterlegt. + +## Mittwoch 22.3.2023 + +Zum Einstieg haben wir eine Dart-Aufgabe von [Codewars](https://www.codewars.com) gelöst. + +Anschließend haben wir [Flutter](Flutter.pptx) wiederholt und uns nochmal ein paar Widgets angeschaut. + +Wir haben und dann weitere Beispiele programmiert, die etwas fortgeschrittenere Konzepte mit Layouts benutzen. Bis Folie 26 sind wir gekommen. + +## Mittwoch 15.3.2023 + +Wir haben heute das Thema [Dart](Dart.pptx) abgeschlossen. Neu waren: + +* Lambdas +* Klassen und Objekte + +Wir konnten dann mit [Flutter](Flutter.pptx) beginnen und haben uns bis Folie 8 durchgearbeitet. Die Themen waren: + +* Was ist ein Widget? +* Beispiele für Widgets +* Unser erstes stateless Widget + +## Mittwoch 8.3.2023 + +Da wir beim letzten Mal ziemlich viele Themen behandelt haben, haben wir heute nochmal eine Wiederholung durchgeführt für: + +* `for`-Schleifen +* Verzweigungen +* Listen +* Methoden und Funktionen + +Danach haben wir in der [Dart](Dart.pptx) weitergemacht und die nächsten Themen angeschaut: + +* Named Arguments +* Scope +* Shadowing +* Callbacks + +Wir sind bis Folie 70 gekommen. + +## Mittwoch 1.3.2023 + +Nachdem wir beim letzten Mal das Android Studio installiert haben, konnten wie heute damit beginnen, uns die Programmiersprache [Dart](Dart.pptx) anzuschauen. + +Dart ist von der Syntax her ähnlich zu Arduino, weswegen viele Dinge schon bekannt vorkamen. + +Die behandelten die Themen: + +* kurzer Überblick über unterschiedliche Programmiersprachen +* Dateiformat von Dart +* Rechtschreibprüfung in Android Studio +* Rechnen in Dart +* Bibliotheken +* Code Formatierung (Coding Guidelines) +* Strings (Texte) verarbeiten +* Code Templates +* `for`-Schleife +* Booleans (Wahrheitswerte) +* Verzweigungen +* Listen +* Maps / Dictionaries +* Methoden und Funktionen + +Wir haben es heute geschafft bis Folie 51 und machen dort nächstes Mal wieder weiter. + +## Mittwoch 15.2.2023 + +Zu Beginn des BOGYs steht natürlich die Vorstellungsrunde, damit sich die Teilnehmer des Praktikums und Betreuer kennenlernen. Direkt danach haben wir eine Führung durch das Gebäude gemacht, damit die örtlichen Gegebenheiten bekannt sind. + +Nach dem üblichen Formalismus wie Besucheranmeldung haben wir zunächst einen [Überblick über die Firma Mitutoyo](Firmenpräsentation.pptx) gegeben. Außerdem haben wir einen Einblick in unsere [Studentenwohnung](Studentenwohnung.pptx) gezeigt. + +Anschließend haben wir kurz die Idee der App vorgestellt, damit klar ist, wo das Praktikum hingeht: die App soll benannte, im Vorhinein definierbare Timer zur Verfügung stellen, von denen mehrere gleichzeitig gestartet werden können. + +Anwendungsbeispiele: + +* Kochen + * Eier: 5 Minuten + * Nudeln kochen: 2 Minuten (Wasser erhitzen) + 10 Minuten (kochen) + * Brötchen aufbacken: 3 Minuten (Herd vorheizen) + 10 Minuten (backen) + * Pommes in der Heißluftfriteuse: 8 Minuten, dann wenden + nochmal 8 Minuten + * Suppenmaultaschen: 2 Minuten (Wasser erhitzen) + 8 Minuten (kochen) + * Tee ziehen lassen: 7 Minuten + * Pizza backen: Ofen vorheizen + Pizza belegen + Pizza backen +* Sport + * Hometrainer: 15 Minuten + * Joggen: 20 Minuten, dann umdrehen, nochmal 20 Minuten + * Workout: wiederholende Übungen mit Pausen dazwischen +* Haushalt + * Waschen: 2:36 Stunden + * Spülmaschine: 3:12 Stunden + * Zähneputzen: 2:30 Minuten +* Kinderbetreuung: + * Hausaufgaben machen: 45 Minuten + * Computer spielen oer Fernsehen: 30 Minuten + * Fremdsprachen lernen: 15 Minuten + * Lesen: 20 Minuten + * Klavier spielen: 15 Minuten +* Arbeit + * [Pomodoro](https://de.wikipedia.org/wiki/Pomodoro-Technik)-Timer: 45 Minuten + 5 Minuten Reflexion + 10 Minuten Pause + * Lüftungs-Timer: 1:30 Stunden + +Diese Uhrzeiten sollen natürlich nicht fest hinterlegt sein, sondern jeder Anwender soll seine eigenen Timer erstellen und abspeichern können. + +Ideen für weitere Features: + +* Am Ende des Timers einen Webhook auslösen, z.B. um ein Licht anzuschalten oder eine Discord Nachricht verschicken. + +Wir haben dann [Android Studio](AndroidStudio.pptx) installiert. + +Hausaufgaben für die Teilnehmer bis zum nächsten Mal: + +* Fotofreigabe ausfüllen und von den Eltern unterschreiben lassen +* Unserem Discord Server beitreten, damit ihr uns Fragen stellen könnt +* Github Account anlegen und Einladung zum Repository (diesem hier) akzeptieren + +# Checklisten-App-2022.1 +Checklisten erstellen und ausfüllen mit einer App für Smartphones 📱. + +## Donnerstag 7.4.2022 + +Neben mehreren internen Fortschritten (Code) haben wir ein bisschen was über [Globalisierung (PPTX⇓)](Globalisierung.pptx) gelernt, um unsere App zu übersetzen. + +## Mittwoch 6.4.2022 + +Wir haben uns um die bisher eingetragenen Issues gekümmert und ein bisschen "echte" Funktionalität ergänzt, d.h. dass die App sich erstmals Eingaben merkt. + +Die Umschaltung zwischen Themes klappt schon. Es gibt ein dunkles Theme und ein helles Theme. + + + + + +Ein nicht unerheblicher Teil der Arbeit floss auch in das Icon der App, bis es rund und mit dem richtigen Hintergrund angezeigt wurde: + + + +Die übrigen Arbeiten fanden unsichtbar im Hintergrund statt: es entstand Programmcode für das Speichern von Daten usw. Wir stellen fest, dass das Pareto-Prinzip hier greift: am ersten Tag (20% des Aufwandes) entstand ein großer Teil der Oberfläche (80%). Möglicherweise verbringen wir das restliche BOGY (80%) ohne größere sichtbare Änderungen. + +## Dienstag 5.4.2022 + +Wir haben uns auf einen Namen für unsere App geeinigt: Voodoo-List. + +Unsere Prioritäten für die Umsetzung: + +* Icon und Name +* übersichtliches Menü (neutraler Hintergrund) +* Checklisten-Name (eintippen) +* Dark Mode +* Checklisten-Editor, evtl. mit tabellarischer Darstellung +* mehrere Checklisten erstellen und verwalten +* Fortschrittsanzeige +* Wiederholung einer Checkliste in einem bestimmten Intervall (täglich / wöchentlich) +* Kalender: diese Checkliste brauche ich an diesem Tag / spezialisierter Kalender, Checkliste für einen Tag (Termine; Hausaufgaben) +* Erinnerung an eine Checkliste oder einzelne Einträge davon +* Checklisten miteinander verbinden (Checkliste in Checkliste; Ober-Checkliste mit Unter-Checklisten) +* Übersetzung in mehrere Sprachen +* Warnsystem für nicht ausgefüllte Checklisten +* Hilfe-Funktion / Tutorial oder Einführung +* Pro-Version: unbegrenzte Anzahl Listen und Einträge + * Checkliste mit jemandem teilen / Checkliste an jemanden senden + * Handschrifterkennung + * Bilder an einen Checklisten-Eintrag anhängen +* Gratisversion: nur eine Liste o.ä. +* Werbung einblenden (könnte Beliebtheit reduzieren) +* Geo-Fencing: Checkliste an einem bestimmten Ort aufrufen +* Belohnungssystem / Prokrastinations-Modus +* Sollte flott sein (reagiert in kurzer Zeit) +* für mehrere Geräte (Smartphone, Tablet, Watch), Android und iOS + * Flutter macht das schon + +Wir haben folgende Seiten in unserer App designt: + +Splashscreen für unsere Voodoo-App: + +Splashscreen + +Sprachauswahl: + + + +Theme-Auswahl: + + + +Erstellen der ersten Checkliste: + + + +Editieren einer Checkliste: + + + +Ansicht der verfügbaren Checklisten: + + + + + +## Montag, 4.4.2022 + +Wir haben uns die Gestaltung von Android Apps mit Hilfe von [Flutter (PPTX⇓)](Flutter.pptx) angeschaut ein ein paar Beispiel-Oberflächen inklusive Navigation entwickelt. Wir haben uns auch noch ein wenig mit [Gestalt Principles (Wikipedia)](https://de.wikipedia.org/wiki/Gestaltpsychologie) beschäftigt und ein paar Beispiele besprochen: + +* Proximity (Gruppierung über Nähe bzw. Abstand) +* Similarity (Ähnlichkeit, z.B. Farbe oder Form) +* Continuity (Zusammenhang) + +## Mittwoch 30.3.2022 + +Wir haben den Nachmittag begonnen mit der Kata (Programmierübung) ["Is it a palindrome" bei Codewars](https://www.codewars.com/kata/57a1fd2ce298a731b20006a4). + +Im Anschluss sind wir die letzten Folien der [Dart (PPTX⇓)](Dart.pptx) Präsentation durchgegangen und haben die Objektorientierung behandelt. Damit haben wir die Programmiersprache ziemlich vollständig durchdrungen und können uns in der BOGY-Woche direkt mit der Programmierung einer Oberfläche beschäftigen. + +## Mittwoch 23.3.2022 + +Weiter ging es mit der Programmiersprache [Dart (PPTX⇓)](Dart.pptx). Die Konzepte aus diesem Nachmittag brauchen wir für die Flutter Programmierung: + +* Named Arguments +* Scope +* Callbacks +* Lambdas +* Async / Await + +Wir haben uns bis Folie 79 durchgearbeitet. + +Hausaufgaben (freiwillig): + +* Programmier-Aufgaben bei [Codewars](https://www.codewars.com) lösen + +## Mittwoch 16.3.2022 + +Wir haben die Lösung der Aufgabe von letztem Mal besprochen und dabei Funktionen des Debuggers kennengelernt (Breakpoints, Variableninspektion, ...). Danach haben wir uns die Programmiersprache [Dart (PPTX⇓)](Dart.pptx) weiter zu Gemüte geführt und die Kapitel + +* Listen +* Maps (Dictionaries) +* Methoden +* Funktionen + +bearbeitet. Die Aufgaben auf Folie 51 und 52 haben wir noch gelöst. + +Aufgabe: Programmiere eine Funktion, die das gleiche Ergebnis liefert wie math.pow() + +* [Lösung](https://dartpad.dev/?id=acf8e4c4c1a098d7fd1fa34011174558) + +Aufgabe: Schreibe eine Funktion, die aus einer Liste mit Zahlen die kleinste heraussucht. + +* [Lösung](https://dartpad.dev/?id=f031adea08afe8c848cc6cc9a885c9a0) + +## Mittwoch 9.3.2022 + +Wir haben uns weiter mit der Programmiersprache [Dart (PPTX⇓)](Dart.pptx) beschäftigt und dort die Kapitel + +* Strings +* Wiederholungen +* Wahrheitswerte +* Verzweigungen + +durchgearbeitet. Wir sind bis Folie 37 gekommen. + +Für ein paar Aufgaben stellen wir Euch eine mögliche Lösung auf DartPad vor: + +- [Lösung Übung 1](https://dartpad.dev/?id=bc2ccef0f3caaa3444577838340cb746&null_safety=true): Berechne 356*4³ +- [Lösung Übung 2](https://dartpad.dev/?id=600212c3180ea97c91c25899fe08fe32&null_safety=true): 36² -> WXYZ -> XY -> XY² +- Aufgabe 3: Wie viele Zahlen zwischen 100 und 999 enthalten die Ziffer 3? + - [textuelle Lösung mit `.substring()`](https://dartpad.dev/?id=e7cf8b4b3136d8e34531d672d342a65d&null_safety=true) + - [textuelle Lösung mit `.contains()`](https://dartpad.dev/?id=275d13381ca893879be2b6f6b82559e2&null_safety=true) + - [mathematischer Ansatz explizit für jede Stelle einzeln](https://dartpad.dev/?id=e3d80e324549714017110f64f301fcef&null_safety=true) + - [mathematischer Ansatz von hinten her](https://dartpad.dev/?id=f2be1413b7d7b839a8ce1e1df04ea7dd&null_safety=true) + - [mathematischer Ansatz von vorne her](https://dartpad.dev/?id=79ece0ba0264cb39c437984a0b63202b&null_safety=true) + +Hausaufgaben: + +* freiwillig: Wiederholung der Android Studio Installation auf dem eigenen Rechner daheim. +* freiwillig: Aufgaben nochmal nachvollziehen, Lösung vereinfachen oder verbessern. + +## Mittwoch 23.2.2022 + +Heute beschäftigten wir uns mit der Installation von allem, was man zur Entwicklung einer Smartphone-App braucht. Die [Android Studio Präsentation (PPTX⇓)](AndroidStudio.pptx) erklärt die einzelnen Schritte. + +Die Downloads haben wir bereits erledigt und auf einem USB Stick zur Verfügung gestellt: + +* Java SDK (JDK) namens [Amazon Corretto](https://aws.amazon.com/de/corretto/) +* [Android Studio](https://developer.android.com/studio) +* das Flutter-Plugin für Android Studio (Download innerhalb von Android Studio) +* [Flutter](https://docs.flutter.dev/get-started/install/windows) +* Emulator / virtuelle Geräte (Download innerhalb von Android Studio) + +Nach einer dreistündigen Installationsorgie blieb noch etwas Zeit für die ersten Beispiele mit der Programmiersprache [Dart (PPTX⇓)](Dart.pptx). Wir kamen bis Folie 17. + +Hausaufgaben: + +* Anmeldung im Discord abschließen +* freiwillig: Wiederholung der Installation auf dem eigenen Rechner daheim +* freiwillig: Programmierung eines Hello World Beispiels + +## Mittwoch 16.2.2022 + +In der Vorstellungsrunde haben wir erfahren, dass mehrere Teilnehmer bereits erste Programmiererfahrung mit dem Arduino gemacht haben. Beim Rundgang durch die derzeit recht leere Firma haben wir die Örtlichkeiten kennengelernt. Im Anschluss haben wir Laptops in Betrieb genommen. + +Die [Firmenpräsentation (PPTX ⇓)](Firmenpräsentation.pptx) enthält auch Informationen über das Studium. Ein Blick in die [Studentenwohnung (PPTX ⇓)](Studentenwohnung.pptx) war auch möglich. Zum Schluss haben wir Github Accounts eingerichtet und dem Projekt zugeordnet. + +Hausaufgaben: + +* Fotofreigabe ausfüllen und von den Eltern unterschreiben lassen +* Termin für den Abend der Technik erfragen +* Besuch des Betreuungslehrers klären + +### Ideen und Aufgaben für unsere Checklisten-App + +* Icon und Name +* übersichtliches Menü (neutraler Hintergrund) +* mehrere Checklisten erstellen und verwalten +* Checklisten-Name (eintippen) +* Checklisten-Editor, evtl. mit tabellarischer Darstellung +* Kalender: diese Checkliste brauche ich an diesem Tag / spezialisierter Kalender, Checkliste für einen Tag (Termine; Hausaufgaben) +* Checklisten miteinander verbinden (Checkliste in Checkliste; Ober-Checkliste mit Unter-Checklisten) +* Erinnerung an eine Checkliste oder einzelne Einträge davon +* Warnsystem für nicht ausgefüllte Checklisten +* Dark Mode +* Gratisversion: nur eine Liste o.ä. +* Pro-Version: unbegrenzte Anzahl Listen und Einträge +* Werbung einblenden (könnte Beliebtheit reduzieren) +* Hilfe-Funktion / Tutorial oder Einführung +* Geo-Fencing: Checkliste an einem bestimmten Ort aufrufen +* Wiederholung einer Checkliste in einem bestimmten Intervall (täglich / wöchentlich) +* Checkliste mit jemandem teilen / Checkliste an jemanden senden +* Belohnungssystem / Prokrastinations-Modus +* Fortschrittsanzeige +* Sollte flott sein (reagiert in kurzer Zeit) +* für mehrere Geräte (Smartphone, Tablet, Watch), Android und iOS +* Handschrifterkennung +* Übersetzung in mehrere Sprachen +* berechnete Anzahl eines Checklisteneintrags: z.B. Anzahl der Urlaubstage geteilt durch 2 Pullover mitnehmen oder Menge für Rezept anhand der Personenzahl ausrechnen +* Bilder an einen Checklisten-Eintrag anhängen + +### Mögliche Checklisten + +* Einkaufsliste: Wocheneinkauf, Geburtstagseinkauf +* Todo-Liste für einen Tag +* Schach-Verein: Mannschaft organisieren +* Klassenarbeiten / Hausaufgaben - Lernen auf eine Klausur +* Urlaubs-Checkliste + + +# Snake AI 2021.1 +Dieses Projekt dokumentiert die Entwicklung eines Machine Learning Algorithmus im Rahmen einer Berufsorientierung für Gymnasien (BOGY) für das [Leibnitz-Gymnasium in Rottweil](https://lg.rw.schule-bw.de/home/?page_id=11268) im Schuljahr 2020/2021. Als Firmenpartner stand [Mitutoyo CTL in Oberndorf](http://www.mitutoyo-ctl.de/de/karriere/ausbildungundstudium) mit Hardware und Ansprechpartnern zur Verfügung. + +Es handelt sich um eine erweiterte Berufsorientierung, d.h. zusätzlich zur üblichen BOGY-Woche stehen noch sechs Nachmittage zur Verfügung, um die Schüler auf das Praktikum vorzubereiten. Aufgrund von CODIV-19 finden diese Nachmittage online statt. Wir danken [Discord](https://discord.com/) für die Nutzungserlaubnis. + +## Inspiration + +Inspiration für dieses Projekt war das [Leibniz Forschungszentrum](https://lg.rw.schule-bw.de/home/?cat=120) mit einer Idee, die Bewegung von Ameisen vom Computer vorherzusagen. Die Original-Idee beinhaltete ein Terrarium mit echten Ameisen, Kamera usw. Eine solch reale Umgebung birgt jedoch Schwierigkeiten, die mit den Rahmenbedingungen eines Praktikums schlecht vereinbar sind, z.B.: + +* wer kümmert sich um die Ameisen? Möglicherweise sterben sie ausgerechnet alle am ersten Tag der Praktikumswoche. +* wie nehmen die Teilnehmer das Ergebnis samt Ameisen mit nach Hause, um es Eltern und Freunden zu zeigen? +* sind die Ergebnisse reproduzierbar? Wir können bei einer fehlerhaften Umsetzung nicht nochmal am gleichen Startpunkt beginnen. +* passt das Projekt in den Zeitrahmen? + +Aus diesem Grund haben wir uns entschlossen, zwar ein Machine Learning Projekt durchzuführen, aber die Bedingungen zu unseren Gunsten anzupassen. Entstanden ist ein Snake-Spiel, bei dem der Computer selbst die Spielregeln erlernen soll und dann die richtigen Aktionen durchführt. + +# Projekt-Umgebung + +## Software + +Wir verwenden kostenlose Software: + +* das Betriebssystem [Raspberry Pi OS](https://www.raspberrypi.org/downloads/raspbian/) für den Raspberry Pi 4. Wir verwenden die Version mit 4 GB Speicher, da wir für ein Experiment viel RAM benötigen. +* [Kitty](http://www.9bis.net/kitty/#!index.md) für den Zugriff auf den Raspberry per SSH +* [Bash](https://www.gnu.org/software/bash/) als Kommandozeile +* [xRDP](http://xrdp.org/) für den Zugriff auf die Benutzeroberfläche des Raspberry +* die Programmiersprache [Python](https://www.python.org/) +* die Entwicklungsumgebung [PyCharm von JetBrains](https://www.jetbrains.com/de-de/pycharm/) (Community Edition) +* die Bibliothek [OpenAI Gym](https://gym.openai.com/) +* die Versionsverwaltung [Git](https://git-scm.com/) mit dem Provider [Github](https://github.com/) +* ggf. unter Windows den [Editor Notepad++](https://notepad-plus-plus.org/) und das Difftool [Winmerge](https://winmerge.org/?lang=de) + +## Daten + +Im Rahmen des Projekts erzeugen sich die Daten aus dem Spielverlauf selbst. + +# Vorbereitung / Einführung + +An den sechs vorbereitenden Nachmittagen können Grundlagen vermittelt werden. Dadurch läuft die Praktikumswoche einfach flüssiger und die Schüler erreichen auch echte Ergebnisse. + +## Erster Nachmittag, 3.2.2021 + +Am ersten Nachmittag haben wir uns vorgestellt. Normalerweise führen wir am ersten Tag durch unser Gebäude, um die Räumlichkeiten kennenzulernen. Dies werden wir nachholen, falls wir uns zur Praktikumswoche vor Ort sein können. + +Die [Firmenpräsentation](presentation/Firmenpräsentation.pptx) erklärt unser Firmen-Motto, nennt die von uns entwickelte Software, erklärt das duale Studium und zeigt Beispiele von Praktikumsprojekten. + +Wir arbeiten mit der [DHBW Stuttgart](https://www.dhbw-stuttgart.de/) zusammen und stellen den Studenten eine [Studentenwohnung](presentation/Studentenwohnung.pptx) zur Verfügung, um die Fahrtzeiten während den Theoriephasen zu verkürzen, so dass sie sich auf das Studium vorbereiten können. + +Dann haben wir uns mit dem Thema der Berufsorientierung auseinandergesetzt. Das Spielprinzip ist vermutlich hinreichend bekannt: es handelt sich um ein Snake-Spiel. Die Schlange (grün) frisst mit ihrem Kopf (blau) einen Apfel (rot) und wächst dabei. + +Zum Glück sind wir hier nicht an fächerübergreifenden Unterricht gebunden, ansonsten müsste man sich fragen, seit wann Schlangen vegetarisch sind (Biologie), ob nicht Adam und Eva den Apfel gegessen haben, anstatt der Schlange (Religion) und ob Schlangen mit künstlicher Intelligenz ein Bewusstsein haben, und somit überhaupt in Tierversuchen einsetzbar sind (Ethik). + +Die von uns bereitgestellte Spieleumgebung ist bereits auf KI-Experimente vorbereitet, d.h. ein beliebiger Algorithmus kann in der Umgebung mehrere Spiele nacheinander ohne menschliches Zutun spielen. Zur Spieleumgebung gibt es eine Visualisierung, die folgendermaßen aufgebaut ist: + +- der linke Bereich liefert statistische Daten + - grün: Daten zur Visualisierung, derzeit nur die aktuelle Visualisierungsgeschwindigkeit in Bildern pro Sekunde (fps; frames per second) + - hellblau: Daten zum Training, d.h. mehrere Spiele übergreifend + - violett: Daten zum aktuell laufenden Spiel. Ein Teil dieser Daten könnte als Input für Neuronen dienen. +- der rechte Bereich visualisiert das Spielfeld + - rot: das Futter (angeblich ein Apfel) + - blau: der Kopf der Schlange + - grün: Körper der Schlange, wobei die hellere Teile früher verschwinden als dunklere Teile + +Im Bild sieht man einen von Mitutoyo programmierten Algorithmus, der noch keine künstliche Intelligenz nutzt. Dabei handelt es sich bewusst um einen Algorithmus, der nicht mathematisch als perfekt bewiesen ist. Unsere KI wird sich mit diesem Algorithmus messen müssen. Bei 1000 Spielen erreicht er eine Länge von bis zu 80 Kästchen, was einer Abdeckung von 40% der Fläche entspricht. + +![Snake Beispiel](presentation/Snake.png) + +Die Hardware, ein [Raspberry Pi 4](presentation/Raspberry%20Hardware.pptx), haben wir uns zunächst nur auf Bildern angeschaut. Die echte Hardware ist bereits verschickt, wird aber erst im Laufe der Woche eintreffen. Dank der Speichererweiterung auf 4 GB können auch größere Datenmengen verarbeitet werden, wie sie bei Machine Learning auftreten. + +Um auf den Raspberry zugreifen zu können, wenn er zugestellt wurde, haben wir SSH grob erklärt und [Kitty](http://www.9bis.net/kitty/#!pages/download.md) installiert. + +Um für eine spätere Zusammenarbeit vorbereitet zu sein, haben wir Accounts bei [Github](https://github.com/) angelegt und Zugriff auf dieses Repository gewährt. + +## Zweiter Nachmittag, 10.2.2021 + +### Raspberry Pis anschließen und finden + +Ein Raspberry Pi kam bereits im Laufe der letzten Woche an. Nach dem Anschluss im LAN gab es zunächst Schwierigkeiten, diesen aufzufinden. Selbst der [Advanced IP Scanner](https://www.advanced-ip-scanner.com/de/) half nicht. + +Beim Einsatz solcher Tools ist eine Aufklärung über [§202c StGB](https://www.gesetze-im-internet.de/stgb/__202c.html) angebracht, auch bekannt als "Hackerparagraph". Für private Zwecke im eigenen Netzwerk sind solche Tools zulässig. In fremden Netzwerken, z.B. dem Schulnetz, könnte die Ausführung als Vorbereitung des Ausspähens von Daten gewertet werden und damit strafbar sein. + +Wo wir gerade beim Thema Recht sind: "Unwissenheit schützt vor Strafe nicht" sagt man. Das ergibt sich aus [§17 StGB](https://www.gesetze-im-internet.de/stgb/__17.html). Dort heißt es "*[...] handelt er ohne Schuld, wenn er diesen Irrtum nicht vermeiden konnte*". Allerdings lassen sich durch das Lesen von Gesetzen Irrtümer vermeiden, so dass man wahrscheinlich schlechte Karten hat. + +Letztlich konnte der Raspberry Pi dann doch noch gefunden werden. Grund war, dass der Raspberry lediglich eine IPv6 Adresse und keine IPv4 Adresse bekommen hatte. Damit haben wir nicht gerechnet, sonst hätten wir den Raspberry so konfiguriert, dass er nur IPv4 Adressen akzeptiert. + +Allerdings war der Raspberry Pi über seinen Namen ansprechbar, so dass die Suche nach der IPv6-Adresse gar nicht erforderlich war. Wir haben Euch den Raspberry mit seinem Standard-Namen `raspberry` zugeschickt. Unter "Host Name (or IP address)" trägt man daher `raspberry` ein. + +![Kitty Zugriff über den Namen](presentation/kitty_find_by_name.png) + +Die Nutzung von Kitty ist [in manchen Ländern](http://www.cryptolaw.org/cls-sum.htm) übrigens auch reglementiert, da es Verschlüsselung beinhaltet. In Deutschland ist es jedoch unproblematisch. + +Sobald die Verbindung vom Computer mittels Kitty zum Raspberry hergestellt ist, haben wir einen wichtigen Schritt erreicht: wir haben jetzt Zugriff auf einen Linux-Computer mit Hilfe der Bash. Beides erklären wir am heutigen Nachmittag. + +### Linux + +Linux ist ein Betriebssystem für Computer, also eine Alternative für Windows. Die [Linux-Präsentation](presentation/Linux.pptx) geht auf einige Unterschiede ein. Die Folien sind eher theoretischer Natur, weswegen wir viele Folien ausgeblendet haben. Wer mehr Interesse am Dateisystem hat, kann sich gern die versteckten Folien ansehen. + +Wer sich langfristig mit dem Thema Software-Entwicklung auseinandersetzen möchte, kommt unserer Meinung nach nicht um Linux herum. + +### Bash + +Die Bash ist eine Kommandozeile von Linux. Sie ähnelt der Eingabeaufforderung von Windows, ist jedoch wesentlich mächtiger. Die [Bash-Präsentation](presentation/Bash.pptx) ist weniger theoretisch und enthält viele praktische Übungen. + +## Dritter Nachmittag, 24.2.2021 + +### Remote Desktop + +Nachdem wir am letzten Nachmittag eine Verbindung per SSH zur Bash aufgebaut hatten, haben wir heute eine Verbindung zur grafischen Oberfläche mittels Remote Desktop verwendet. + +![Remote desktop](presentation/rdp.png) + +Dies hat leider nicht auf Anhieb bei allen Systemen geklappt, so dass wir Fehlersuche betreiben mussten. Ursache war in diesem Fall, dass der Raspberry per LAN und der PC per WLAN angebunden waren, diese beiden Netze jedoch vom Router aus Sicherheitsgründen separiert wurden, so dass ein gegenseitiger Zugriff nicht möglich war. + +Ein Zugriff per Remote Desktop ist bei Raspberry Pi OS nicht automatisch möglich. Damit es klappt, musste vorher auf der Shell der entsprechende Dienst installiert werden mit `sudo apt install xrpd`. Dies bestätigt wieder einmal, wie wichtig die Shell (in unserem Fall die Bash) bei Linux ist. + +### PyCharm + +Pycharm hatten wir bereits für Euch heruntergeladen und abgelegt. Wir haben dann gemeinsam PyCharm installiert und uns [einen ersten Überblick](presentation/Pycharm.pptx) verschafft. + +Danach haben wir es auch [für Windows heruntergeladen](https://www.jetbrains.com/de-de/pycharm/download/#section=windows) und ebenfalls installiert, so dass ihr es auch mal ohne Raspberry benutzen könnt. + +### Python + +Wir haben dann eine [Einführung in Python](presentation/Python%20Einführung.pptx) durchgearbeitet, die viele Möglichkeiten für eigenes Ausprobieren bot. Wir sind bis Folie 31 gekommen und machen da nächste Woche weiter. + +### Hausaufgaben + +Bei Interesse könnt ihr ein paar Aufgaben von [Project Euler](https://projecteuler.net/archives) lösen. + +## Vierter Nachmittag, 3.3.2021 + +Wir haben die [Einführung in Python](presentation/Python%20Einführung.pptx) durchgearbeitet. + +## Fünfter Nachmittag, 10.3.2021 + +Wir haben uns das Programmierparadigma [Objektorientierung](presentation/Python%20Objektorientierung.pptx) angeschaut, inklusive Übungen zur Umsetzung in Python. + +## Sechster Nachmittag, 17.3.2021 + +Bei umfangreichen Softwareprojekten ist es nicht mehr möglich, allein an einem Programm zu arbeiten, da es sonst nicht oder nicht schnell genug fertig wird. Daher arbeiten mehrere Programmierer in einem Team zusammen. Dann wiederum muss jeder Programmierer Zugriff auf den Code seiner Teammitglieder haben. Dieses Aufgabe (und noch ein paar mehr) löst ein Versionskontrollsystem. + +Wir haben den Nutzen von [Versionskontrolle allgemein](presentation/Versionskontrolle.pptx) allgemein erklärt. Danach sind wir die [Grundlagen von Git](presentation/Git%20Grundlagen.pptx) erklärt, einem von mehreren kostenlosen Versionsverwaltungssystemen. + +# BOGY Woche + +## Montag, 22.3.2021, Vormittag +### Repository klonen + +Wir haben die Datenbank von Github auf den Raspberry geklont mit + +`git clone https://github.com/BogyMitutoyoCTL/Snake-AI-2021.1.git snake` + +Beim Ausprobieren ist uns aufgefallen, dass für NumPy und Python noch zwei Bibliotheken fehlen. Diese beiden Bibliotheken konnten wir mit folgenden Befehlen nachinstallieren: + +```bash +sudo apt-get install libatlas-base-dev +sudo apt install libsdl2-ttf-2.0-0 +``` + +### Erläuterung des bestehenden Codes + +Da wir uns auf das Machine Learning konzentrieren wollen, hat Mitutoyo das Snake-Spiel bereits implementiert. Über diese Implementierung haben wir uns einen Überblick verschafft. + +#### Snake + +Der Kern des Programms, das Spiel, ist in der Klasse `Snake` untergebracht. Das Spiel akzeptiert 7 mögliche Bewegungen: + +* `north`, um nach oben zu laufen +* `east`, um nach rechts zu laufen +* `south`, um nach unten zu laufen +* `west`, um nach links zu laufen +* `turn left`, um in Laufrichtung der Schlange links abzubiegen +* `turn right`, um in Laufrichtung der Schlange rechts abzubiegen +* `straight`, um weiter geradeaus in Laufrichtung der Schlange zu laufen + +Die Klasse `Snake` nutzt eine andere Klasse `Field`, um sich zu zeichnen. Dabei handelt es sich um ein zweidimensionales Array, das wir als Spielfeld bezeichnen. `Field` enthält bereits die Farben, wie sie später abgebildet werden sollen. + +Normalerweise würde das Snake Spiel von einem Menschen mit einem Controller bedient. Das ist in unserem Fall unpraktisch. Daher gibt es um die Klasse `Snake` herum noch ein sogenanntes Gym (englisch *gymnasium* = Sporthalle), also einen Ort, in der die künstliche Intelligenz trainieren kann. Dieses Gym ist kompatibel zu der Definition eines Gym von OpenAI. Die Klasse dafür bei uns heißt `SnakeGym`. + +#### Algorithmen + +Damit beim Programmieren von unterschiedlichen Strategien der Schlange weder das Gym, noch das Spiel selbst geändert werden muss, haben wir eine Klasse `Algorithm` definiert. Diese Klasse ist vorbereitet auf Machine Learning, d.h. sie hat Methoden und Eigenschaften, die wir am Anfang noch nicht brauchen, sondern erst, wenn wir tatsächlich Machine Learning mit neuronalen Netzen betreiben. Mit dieser Klasse `Algorithm` ist es sehr einfach, selbst eine Idee zu verwirklichen, wie die Schlange sich bewegen soll. + +Ein Beispiel für einen solchen Algorithmus ist `RotateForever`. Dieser Algorithmus basiert auf der Idee, dass Snake möglichst lang gespielt werden soll. Die einfachste Art, ewig zu spielen ist, sich immer im Kreis zu drehen. Leider bekommt man dafür keine Punkte. Die Implementierung dieser Idee ist beinahe trivial: + +```python +from Algorithms.Algorithms import Algorithm +from GameData import GameData + + +class RotateForever(Algorithm): + def __init__(self): + super().__init__() + + def decide(self, info: GameData) -> str: + return "turn left" +``` + +Die ersten Zeilen sind immer identisch. Lediglich die Funktion `decide()` muss angepasst werden. + +Von diesen sehr einfachen Algorithmen haben wir einige zusammengestellt: + +* `RotateForever`: dreht sich immer im Kreis +* `RandomChoice`: wählt eine Zufallsaktion, also ob man einfach blind auf dem Controller herumdrückt + +#### Entscheidungsgrundlagen für Algorithmen + +Das Spielfeld ist folgendermaßen aufgebaut: + +​ ![Aufbau des Spielfelds](presentation/playground.png) + +Diese Richtung der Achsen ist in der Bildverarbeitung üblich. Euer Monitor hat z.B. ebenfalls die Ecke P(0|0) oben links und Q(1920|1080) unten rechts. + +Damit man sich nicht blind für eine Aktion entscheiden muss, bekommt man für die Entscheidung ein paar Grundlagen, und zwar im Parameter `info` vom Typ `GameData`. Darin sind allerhand Informationen zu finden, die man für Entscheidungen braucht: + +* `head_x` bzw. `head_y`: wo der Kopf der Schlange sich befindet. Das Ergebnis ist eine Zahl, entsprechend der Koordinate. +* `snake_length`: Länge der Schlange +* `direction`: Aktuelle Laufrichtung der Schlange. Das Ergebnis ist ein String mit den Werten `"north"`, `"east"`, `"south"` oder `"west"`. +* `food_x` bzw. `food_y`: wo sich das Futter befindet. Das Ergebnis ist eine Zahl, entsprechend der Koordinate. +* `food_direction`: Richtung, in der sich das Futter befindet. Die Winkel sind dabei wie folgt: + ![Richtungen](presentation/directions.png) +* `food_distance_in_steps`: Schritte bis zum Futter (kürzester Weg, ohne Berücksichtigung von Hindernissen) +* `air_line_distance`: Abstand zum Futter in Kästchen (diagonal, Pythagoras) +* `walldistance_`...: Abstand zur Wand (vom Kopf aus) +* u.a. + +Ebenfalls nützlich sind einige Funktionen: + +* `can_move_to(x,y)`: findet heraus, ob an diese Position gelaufen werden kann, ohne zu sterben. Für X und Y setzt man dabei am besten eine Koordinate ein, die sich in der Nähe des Kopfes befindet, also, z.B. + +```python +if info.can_move_to(info.head_x - 1, info.head_y): # Ist links vom Kopf Platz? + return "west" # Dann kann man nach Westen fahren +``` + +* `body_age(x,y)`: findet heraus, wie bald sich der Körper an dieser Stelle hier wegbewegt + +* `is_body(x,y)`, `is_food(x,y)` und `is_head(x,y)`: um abzufragen, um welche Sorte Kästchen es sich handelt + + + +#### Die Anzeige + +Damit wir eine hübsche Anzeige mit allerhand Statistik bekommen, gibt es die Klasse `Visualization`. Diese nutzt die Bibliothek PyGame, um ein Fenster zu zeigen. + +Die Daten der Statistik kommen aus der Klasse `TrainingData`. + +#### Zum lauffähigen Programm zusammengestellt + +Das Programm `main.py` fügt alle Dinge zusammen: + +* es baut das Gym auf +* es zeigt alle Algorithmen an und lässt den Benutzer einen auswählen +* es lässt den Algorithmus in einigen Runden (`max_epochs`) spielen +* zeigt am Ende die Statistik auf der Konsole an. + +Auch das Programm `main.py` ist schon auf Machine Learning vorbereitet. Deshalb gibt es dort auch schon ein Belohnungssystem vom Typ `RewardSystem` und einen Algorithmus für Zufallsentscheidungen, aus denen die KI später lernen wird. + +Die Klassen `Snake`, `Field`,`SnakeGym`, `Algorithm`, `RotateForever`, `RandomChoice` und `GameData` müssen im Laufe des Praktikums nicht geändert werden. + +### Aufgabe: schreibe einen Algorithmus + +Die Aufgabe für diesen Vormittag ist, einen eigenen Algorithmus zu schreiben, der hoffentlich schon besser funktioniert als der Algorithmus, der per Zufall entscheidet. Dazu verwenden wir noch keine KI. Wir möchten zunächst herausfinden, wie schwierig es eigentlich ist, gut Snake zu spielen. + +Das Grundgerüst sieht so aus: + +```python +from Algorithms.Algorithms import Algorithm +from GameData import GameData + + +class B⸻(Algorithm): # Passe den Klassen-Namen hier an + def __init__(self): + super().__init__() + + def decide(self, info: GameData) -> str: + # Programmiere hier +``` + +## Montag, 22.3.2021, Nachmittag + +### Hamiltonweg + +Wir haben uns eine einfache aber perfekte Lösung für das Snake-Spiel ausgedacht: im Zickzack das Feld nach Futter absuchen, so dass man am Ende wieder am Anfang ankommt. + +![Hamiltonweg](presentation/Hamiltonweg.png) + +Diese Art der Lösung ist ein Hamiltonweg. Dazu gibt es bei [Wikipedia](https://de.wikipedia.org/wiki/Hamiltonkreisproblem) noch ein paar Hinweise. In unserer Spielumgebung funktioniert ein Hamiltonweg nur bedingt, da die Schlange nach 117 Schritten verhungert. Ihr bleibt also gar nicht genug Zeit, alle Kästchen nach Futter abzusuchen. + +Um den definierten Anfangspunkt O(0|0) zu erreichen kann man folgenden Code verwenden: + +```python +class ZickZack(Algorithm): + def __init__(self): + super().__init__() + self.fahre = ["north"] * 10 + ["west"] * 5 + + def decide(self, info: GameData) -> str: + # Fahre zu Beginn einer Runde nach oben links + if len(self.fahre) > 0: + action = self.fahre[0] + del self.fahre[0] + return action + # Fahre im Zickzack nach unten + else: + ... +``` + +### Aufgabe: vervollständige den Weg + +Vervollständige den obigen Code an der Stelle `...`, so dass die Schlange im Zickzack nach unten fährt und auf der rechten Seite ein Kästchen übrig lässt, um wieder nach oben zu kommen. + +### Github Token für den Zugriff einrichten + +Damit der Zugriff auf Github einfacher wird und wir uns nicht ständig einloggen müssen, richten wir uns ein Github Token ein. Das geht folgendermaßen: + +1. Logge Dich auf Github ein und gehe zu den Einstellungen Deines Profils. + + ![Github Settings](presentation/githubsettings.png) + +2. Gehe zu *Developer Settings* und dann *Personal Access Tokens* +3. Klicke auf *Generate New Token* +4. Gib dem Token einen Namen als Bedeutung, z.B. "Snake bei Mitutoyo". +5. Setze ein Häkchen bei: **repo**, **read:org** und **gist**. +6. Klicke auf *Generate Token* +7. Klicke auf das Icon, um die Zahlenfolge in die Zwischenablage zu kopieren +8. In PyCharm: gehe zu *File* / *Settings* +9. Gehe zu *Version Control* / *GitHub* +10. Klicke auf `+` und wähle "Login with Token..." +11. Füge die Zahlenfolge in das Feld ein. + +## Dienstag, 23.3.2021, Vormittag + +Am Vormittag haben wir uns ganz allgemein mit [Künstlicher Intelligenz](presentation/Künstliche%20Intelligenz.pptx) befasst. + +## Dienstag, 23.3.2021, Nachmittag + +Wir haben gemeinsam verglichen, was die Ergebnisse unserer eigenen Algorithmen sind. + +* I⸻: bestes Ergebnis 29 in 100 Spielen, max. Schritte 558, Gesamtmenge Futter: 1212, Gesamt-Schritte: 20433, Anzahl der `if`-Anweisungen: 9 + +* J⸻: bestes Ergebnis 27 in 100 Spielen, max. Schritte 298, Gesamtmenge Futter: 802, Gesamt-Schritte: 8442, Anzahl der `if`-Anweisungen: 4 + +* J⸻: bestes Ergebnis 32 in 100 Spielen, max. Schritte 324, Gesamtmenge Futter: 1156, Gesamt-Schritte: 12116, Anzahl der `if`-Anweisungen: 8 + +* T⸻: bestes Ergebnis 51 in 100 Spielen, max. Schritte 709, Gesamtmenge Futter: 2419, Gesamt-Schritte: 28963, Anzahl der `if`-Anweisungen: 20 + +Grob kann man erkennen, dass das Ergebnis besser wird, je mehr Bedingungen oder Situationen im Algorithmus berücksichtigt werden. Das drückt sich häufig durch die Anzahl der `if`/`elif` Abfragen aus. + +### Spaghetti-Code? + +Gleichzeitig merkt man beim Programmieren aber auch, dass es immer schwieriger wird, die richtige Stelle zu finden, an der man noch weiter verbessern kann. Bei Programmierern mit wenig Erfahrung kann das schnell zu so genanntem Spaghetti Code führen. Als Spaghetti Code wird Quellcode bezeichnet, der in sich verstrickt ist. + +Bei Spaghetti Code ist oft nicht klar, was alles passiert, wenn man an einer Stelle etwas ändert. Und man muss sich fragen, ob man selbst das Programm noch verstehen würde, wenn man es in einem halben Jahr noch einmal liest. + +Damit das nicht passiert, haben sich ein paar Regeln und Konzepte gebildet. Einerseits gibt es so genannte Entwurfsmuster (engl. *patterns*), mit denen man bestimmte Probleme lösen kann, zum anderen gibt es eine Initiative namens *Clean Code*, die zumindest Hinweise gibt, was man tun bzw. nicht tun sollte. Und wenn man dann nicht weiter weiß, sollte man einen Entwickler fragen, der mehr Erfahrung hat und vielleicht einen gute Tipp auf Lager hat, wie der Spaghetti Code ordentlicher aussehen könnte. + +Die Präsentation [Von der Spaghetti-Schlange zu Q-Tables](presentation/Von%20der%20Spaghetti-Schlange%20zu%20Q-Tables.pptx) stellt die Problematik vor und schlägt eine Lösung vor. + +### Aufgabe: Umrechnung einer Situation in eine Nummer + +Die Aufgabe ist bereits in der Präsentation beschrieben: schreibe eine Funktion, die + +* einen Ausschnitt aus dem Spielfeld um den Kopf herum in Betracht zieht +* die Situation aus leeren und belegten Feldern in eine Zahl umrechnet +* und dabei bestimmte Felder ausmaskieren (auslassen) kann + +Ausgangspunkt für die Implementierung ist folgende Klasse: + +```python +from Algorithms.Algorithms import Algorithm +from GameData import GameData + + +class QTable⸻(Algorithm): # Passe den Klassen-Namen hier an + def __init__(self): + super().__init__() + + def decide(self, info: GameData) -> str: + situationsnummer = self.umrechnen(info, 3, "111 101 111") + return "north" + + def umrechnen(self, info, kantenlaenge, maske): + # hier rechnen + return situationsnummer +``` + +## Mittwoch, 24.3.2021, Vormittag + +### Aufgabe: Entscheidungen sammeln + +Wir haben ein Programm geschrieben, das Entscheidungen für bestimmte Situationen aufzeichnen und abspeichern kann. Dieses Programm ist kompatibel zu der Art und Weise, wie wir die Situation in eine Nummer umrechnen. Allerdings gilt es nun, 2⁸ Felder * 5 Richtungen, also für 1280 Fälle die Entscheidungen einzusammeln. Diese Arbeit teilen wir uns. + +Bei einem 5x5 Ausschnitt und 5 Richtungen hätten wir schon 83 Millionen Entscheidungen zu treffen. Die wollen wir selbst mit einem Programm nicht durchgehen - das soll der Computer dann lieber selbst lernen. + +Die grafische Oberfläche zum Einsammeln von Entscheidungen sieht folgendermaßen aus: + + ![Entscheidungs-Recorder](presentation/decisionrecorder.png) + +Zu sehen ist ein 3x3 Ausschnitt aus dem Spielfeld. Der dunkelrote Winkel zeigt an, in welcher Richtung sich das Futter befindet. In diesem Fall liegt das Futter auf jeden Fall südlich, es könnte aber zusätzlich noch ein bisschen östlich liegen, vielleicht aber auch westlich. Dass der rote Ausschnitt eher nach Westen zeigt, ist dabei kein Anzeichen für eine höhere Wahrscheinlichkeit, dass das Futter im Westen liegt. + +Welche Aktion die Schlange in dieser Situation auslösen soll, bestimmst Du. Folgende Kriterien sind zu beachten: + +* Die Schlange soll keinesfalls sterben. Fahre also nicht in den Schwanz der Schlange. +* Die Schlange sollte möglichst schnell zum Futter kommen. + +Da der rote Bereich sowohl westlich als auch östlich liegt, ist weder Osten noch Westen im gezeigten Fall eine gute Wahl. Wenn die Schlange allerdings nach Süden fährt, wird irgendwann die Ausprägung zwischen Ost oder West deutlicher: + +* Verschiebung nach Osten, falls das Futter tatsächlich östlich lag: + + ![Ostverschiebung](presentation/ostverschiebung.png) + +* Verschiebung nach Westen, falls das Futter tatsächlich westlich lag: + + ![Westverschiebung](presentation/westverschiebung.png) + +Da das Programm alle Möglichkeiten durchgeht, können Situationen angezeigt werden, die im Spiel nie vorkommen können, beispielsweise: + + ![Unmögliche Situation](presentation/impossible.png) + +Es muss mindestens ein grünes Kästchen an das blaue Kästchen anschließen, da die Schlange nicht diagonal laufen kann. Für diesen Fall ist der Button "Impossible" gedacht. + +Beachte aber, dass nicht alle diagonal aussehenden Felder unmöglich sind. Folgendes Feld beispielsweise ist legal: + + ![Mögliches Spielfeld, kleiner Ausschnitt](presentation/possible.png) + +weil das Spielfeld so aussehen könnte: + + ![Mögliches Spielfeld, größerer Ausschnitt](presentation/possible_field.png) + +Damit wir eine gegenseitige Kontrolle haben, sollten wir jeden Fall zweimal aufzeichnen (1280 → 2560). Zusammen mit einem Mitarbeiter von Mitutoyo haben wir 4 Personen. Somit ergeben sich für jeden Schüler 640 Entscheidungen. + +Die Einstellung erfolgt über die Datei `configuration.json` im Order `decisionrecorder`. Im oben beschriebenen Fall muss sie so aussehen: + +```json +{ + "mask": "000 010 000", + "food_directions": 5, + "field_size": 3, + "number_parallel_workers": 2, + "number_worker": +} +``` + +Anstelle von `` tragen wir folgende Nummer ein: + +* I⸻: 0 + d.h. I⸻ bearbeitet die ersten 640 Fälle +* Ja⸻: 1 + d.h. Ja⸻ bearbeitet die zweiten 640 Fälle +* Ju⸻: 0 + d.h. Ju⸻ bearbeitet die ersten 640 Fälle, zum Gegencheck von I⸻ +* D⸻: 1 + d.h. D⸻ bearbeitet die zweiten 640 Fälle, zum Gegencheck von Ja⸻ + +Um das Tool laufen zu lassen öffnen wir `main.py` aus dem Ordner `decisionrecorder`. + +### JSON + +Das Programm hat die Datei in einer Art Textdatei mit der Endung JSON abgespeichert. Dieses Dateiformat haben wir gewählt, + +1. weil man es (im Gegensatz zu Excel o.ä.) auch in PyCharm noch anschauen und ggf. auch nachträglich bearbeiten kann. +2. weil sich Textdateien bei Änderungen gut vergleichen lassen, z.B. mit einem Programm wie KDiff3 und man mit Hilfe von Git gut nachvollziehen warum es Änderungen gab. + +Ein Ausschnitt aus der Datei könnte folgendermaßen aussehen. + +```json + { + "field": 128, + "food": 0, + "decision": "-" + }, +``` + +`{ ... }` kennzeichnet ein Objekt. + +`field` ist eine Eigenschaft des Objekts und kennzeichnet den hier Ausschnitt aus dem Spielfeld und entspricht der von uns berechneten Situationsnummer. + +`food` bestimmt die Richtung zum Futter. Bei 5 Richtungen geht diese Zahl von 0 bis 4. + +`decision` ist die aufgezeichnete Antwort. `N`, `E`, `S` und `W` sind die Himmelsrichtungen. `-` bedeutet "Impossible" und `null`sagt aus, dass keine Antwort abgegeben wurde. + +### Dateien lesen und verarbeiten + +Um Dateien zu lesen und speziell JSON zu verarbeiten brauchen wir folgende Bibliotheken: + +```python +import glob +import json +``` + +Die Bibliothek `glob` erlaubt uns, Dateien zu finden, zum Beispiel + +```python +dateinamen = glob.glob("./decisionrecorder/*.json") +``` + +Um eine Datei zu lesen wird keine Bibliothek benötigt. Eine Datei kann "von Hand" geöffnet und geschlossen werden mit + +```python +datei = open(dateiname, "r") +# Daten lesen +datei.close() +``` + +oder geöffnet und automatisch geschlossen werden: + +```python +with open(dateiname, "r") as datei: + # Daten lesen (eingerückt) +``` + +Die Bibliothek `json` ermöglicht uns, Daten im JSON-Format zu lesen., zum Beispiel + +```python +daten = json.load(datei) +``` + +### Aufgabe: Die gespeicherten Entscheidungen einlesen + +Die abgespeicherten JSON Dateien sind quasi das Langzeitgedächtnis unserer Schlange. Das Langzeitgedächtnis des PCs ist die Festplatte. Dort überleben Daten auch einen Neustart des PCs. + +Damit die Schlange diese Daten auch abrufen und verarbeiten kann, müssen sie in das Kurzzeitgedächtnis überführt werden. Das Kurzzeitgedächtnis des PCs ist das RAM (Random Access Memory). Variablen von Python befinden sich im RAM. + +Erweitere den bestehenden Algorithmus, so dass er die aufgezeichneten Entscheidungen aus den JSON Dateien einliest und in (einer) Variablen speichert. Dann kann die Schlange später gemäß diesen Entscheidungen spielen. + +Das Lesen der Daten macht die Schlange am besten nur einmal, sofern die Datenmenge dies zulässt. Der geschickteste Ort dafür ist die `__init__()` Methode der Schlange. + +```python + def __init__(self): + super().__init__() + # Schritt 0: Gedächtnis auffrischen + # TODO: hier Daten einlesen +``` + +## Mittwoch, 24.3.2021, Nachmittag + +### Aufgabe: Winkel in Bereiche einteilen + +Der DecisionRecorder hat die Richtung des Futters ziemlich grob in 5 Richtungen eingeteilt. `GameData` liefert uns allerdings einen gradgenauen Winkel zwischen -180° und 180°. + +Schreibe eine Funktion, die den gradgenauen Winkel in *n* Bereiche einteilen kann und eine Zahl zwischen 0 und n-1 liefert. + +```python + def decide(self, info: GameData) -> str: + # Schritt 1: Situationsnummer ausrechnen + situationsnummer = self.umrechnen(info, 3, "111 101 111") + # Schritt 2: Nummer für die Richtung ausrechnen + # TODO: hier grobe Bereichsnummer ermitteln +``` + +### Aufgabe: vervollständige den Algorithmus + +Unser Algorithmus hat jetzt ein "Gehirn" mit den nötigen Entscheidungen, er kann die Situation in eine Zahl umrechnen und die Richtung des Futters grob in Bereiche aufteilen. + +Jetzt muss er "nur noch" diese Informationen alle zusammenbringen und die richtige Aktion auswählen. + +```python +def decide(self, info: GameData) -> str: + # Schritt 1: Situationsnummer ausrechnen + situationsnummer = self.umrechnen(info, 3, "111 101 111") + # Schritt 2: Nummer für die Richtung ausrechnen + richtung = self.grobe_richtung(info.food_direction) + # Schritt 3: Greife auf eine Tabelle von Entscheidungen zu + # und suchen uns die Aktion raus, die ausgeführt werden soll + # TODO: Entscheidung raussuchen +``` + +### Fun! + +Endlich ist der Algorithmus fertig. Die Methode `decide()` kann auf 1280 Entscheidungen zugreifen, hat also quasi 1280 `if`-Anweisungen eingebaut. + +Wie gut macht sich die Schlange? Wir stellen vergleichen Ergebnisse her, indem wir die Schlange 100 Epochen lang beobachten. + +Ergebnisse: + +* I⸻: bestes Ergebnis 48 in 100 Spielen, max. Schritte 674, Gesamtmenge Futter: 2406, Gesamt-Schritte: 29447 +* J⸻: bestes Ergebnis 49 in 100 Spielen, max. Schritte 708, Gesamtmenge Futter: 2484, Gesamt-Schritte: 31200 +* J⸻: bestes Ergebnis 54 in 100 Spielen, max. Schritte 612, Gesamtmenge Futter: 2417, Gesamt-Schritte: 29835 +* D⸻: bestes Ergebnis 55 in 100 Spielen, max. Schritte 701, Gesamtmenge Futter: 2512, Gesamt-Schritte: 30649 +* T⸻: bestes Ergebnis 47 in 100 Spielen, max. Schritte 654, Gesamtmenge Futter: 2360, Gesamt-Schritte: 29085 + +Übersicht: + +| Name | I⸻ vorher | J⸻ vorher | J⸻ vorher | T⸻ vorher | aufgezeichnete Entscheidungen | +| --------------------- | --------- | --------- | --------- | --------- | ----------------------------- | +| Beste Länge | 29 | 27 | 32 | 51 | 47 ... 55 | +| Max. Schritte | 558 | 298 | 324 | 709 | 612 ... 708 | +| Futter gesamt | 1212 | 802 | 1156 | 2419 | 2360 ... 2515 | +| Schritte gesamt | 20433 | 8442 | 12116 | 28963 | 29085 ... 31200 | +| Anzahl if-Anweisungen | 9 | 4 | 8 | 20 | 1175* | +*) 2⁸ \* 5 = 1280, abzgl. 105 unmögliche Situationen + +Warum erreicht unser Algorithmus keine besseren Ergebnisse? + +* Kurzsichtigkeit: die Schlange kann nur 1 Kästchen weit sehen +* Die Anzahl der Richtungen ist gering: es ist manchmal unklar, was die beste Entscheidung ist +* Bedingt dadurch: Fehler in unseren aufgezeichneten Daten + +## Donnerstag, 25.3.2021, Vormittag + +### Kleinere Umstrukturierungen + +Ein paar Kleinigkeiten sind mir noch aufgefallen: + +* Der Name der Klasse `QTableTW` ist noch nicht aussagekräftig. Ja, sie arbeitet irgendwie in Richtung QTables, aber der Begriff QTable sagt eigentlich aus, dass die Schlange selbst lernt. Das ist noch nicht der Fall. Es handelt sich eher um eine Art Record-Playback: wir haben Entscheidungen aufgezeichnet und spielen sie wieder ab. +* Die Methode `lies_alle_dateien()` ist nicht wahrheitsgemäß: sie liest nicht alle Dateien, sondern nur JSON-Dateien und davon auch nur die mit Entscheidungen. Besser wäre `lies_aufgezeichnete_entscheidungen()`. + +### Erweiterung des Blickfeldes + +Die Aufzeichnung unserer Entscheidungen für ein 3x3 Sichtfeld waren in Ordnung, brachten aber keine große Verbesserung in der Leistung der Schlange. Sie schneidet nur marginal besser ab als eine selbst programmierte Schlange mit 20 if-Anweisungen. Wir erhöhen daher die Sichtweite auf 5x5. Bei 83 Millionen Kombinationen aus Spielfeld und Futter soll der Computer dann selbst herausfinden, was gute und schlechte Entscheidungen sind. + +Wir haben dazu unsere 2D Struktur so überarbeitet, dass eine 3D-Struktur entstanden ist, die Werte für die Zuversichtlichkeit von Aktionen aufnimmt. Diese Werte haben wir mit einem Mittelwert von 0,5 initialisiert und in der Feedback-Phase entweder erhöht oder erniedrigt, je nach dem, ob eine Aktion erfolgreich war oder sich schlecht auf die Lebensdauer der Schlange auswirkte. + +Das Feedback erfolgt über eine Methode `train()` mit folgender Struktur: + +```python +def train(self, info: GameData, action, reward) -> None: + pass +``` + +`info` beinhaltet die Angaben zum Spielfeld, wie es vor der Aktion aussah. + +`action` ist die durchgeführte Aktion. + +`reward` ist eine Zahl, deren Maßstab wir einstellen können. In der Standard-Einstellung bedeuten negative Werte schlechte Erlebnisse, positive Werte gute Erlebnisse. Es handelt sich um eine Summe von Erfahrungen wie z.B. Entfernung zum Futter (gering positiv), Fressen von Nahrung (hoch positiv) und Sterben (negativ, abhängig davon wie die Schlange stirbt). + +Der Algorithmus kann auch sein eigenes Belohnungssystem bestimmen. Dazu definiert man die Eigenschaft `self.reward_system` , z.B. + +```python +from RewardSystem import RewardSystem +... +self.reward_system = RewardSystem() +# Belohnungen +self.reward_system.reward_eat_food = 1 +self.reward_system.reward_win = 1 +self.reward_system.reward_closer_function = lambda closer: 1 if closer > 0 else -1 +# Bestrafungen +self.reward_system.reward_killed_by_wall = -1 +self.reward_system.reward_killed_by_tail = -1 +self.reward_system.reward_impossible_move = -1 +self.reward_system.reward_killed_by_starving_function = lambda step, length: 0 +``` + +Es ist sinnvoll, die 3D-Struktur abzuspeichern und wieder zu laden, so dass die Schlange nicht immer von Neuem anfangen muss zu lernen. Das Dateiformat JSON ist dafür zu langsam. Deshalb nutzen wir bei `pickle` und speichern erst nach einer gewissen Anzahl von Epochen, anstatt am Ende jedes Spiels. Die Dateigröße beträgt bei einem 5x5 Spielfeld und 5 Blickrichtungen ca. 230 MB. + +Speichern und Laden funktioniert grundsätzlich so: + +```python +import pickle +... +# Speichern +with open(dateiname, "wb") as datei: + pickle.dump(daten, datei) +... +# Laden +with open(dateiname, "rb") as datei: + daten = pickle.load(datei) +``` + +Zum Speichern bietet unsere Umgebung noch eine Methode an, die am Ende jeder Trainingsrunde aufgerufen wird. Die Rückgabewerte sind das Modell und dessen Fitness. Da wir kein neuronales Netz haben und auch keine Fitnessfunktion erstellt haben, können wir hier leere Werte zurückgeben. + +```python +def epochfinished(self) -> (object, float): + # Hier Speichern oder auch nicht + return None, 0.0 +``` + +### Aufgabe: Passe eine Kopie des 3x3 Algorithmus auf Selbstlernen an + +Kopiere den Algorithmus für das 3x3-Feld. Passe den Namen und die Werte auf ein 5x5-Feld an. Entferne die Funktion zum Einlesen von Daten aus JSON-Dateien. Erweitere dann den Algorithmus so, dass er Wahrscheinlichkeiten berücksichtigt und seine gelernten Erfolge alle 50 Epochen abspeichert. + +## Donnerstag, 25.3.2021, Nacht + +In diesem BOGY wurde sogar nachts gearbeitet. Unermüdlich trainierten zwei Schlangen mehrere Stunden lang. + +## Freitag, 26.3.2021, Vormittag + +### Auswertung + +Die Schlange, die auf dem Rechner von T⸻ trainierte, hatte diesen Trainingsverlauf über 380000 Epochen: + +![Trainingsverlauf](presentation/trainingsverlauf.png) + +Zu Beginn des Trainings hat die Schlange scheinbar recht schnell gelernt, danach flachte die Lernkurve ab. Bei ca. 120000 Epochen sieht es dann nochmal nach einem "Aha-Effekt" aus. + +Allerdings zeigt die grafische Oberfläche auch die Menge des durchschnittlich gefressenen Futters an - und diese Zahlen sehen nicht besonders beeindruckend aus. Der gleitende Durchschnitt über die letzten 10 Epochen liegt knapp unter 14, entsprechend einer Schlangenlänge von 17. + +![Durchschnittswerte](presentation/trainingsverlauf_gui.png) + +### Abgespeichertes Gehirn nutzen + +Das trainierte Gehirn schaffte eine maximale Länge von 34 in 100 Epochen und einen Durchschnittswert von 14 gegessenen Äpfeln pro Epoche. + +### Ideen für bessere/andere Ergebnisse + +Es gibt noch allerhand Möglichkeiten, andere und ggf. bessere Ergebnisse zu erzielen: + +* Wir könnten die Trainingsdauer verlängern. Es ist anzunehmen, dass noch nicht alle möglichen Möglichkeiten ausreichend von der Schlange erkundet wurden, insbesondere die Situationen, in denen sehr viele Kästchen belegt sind. +* Das Sichtfeld der Schlange ist auch mit 5x5 noch ziemlich klein. +* Die Einschätzung der Lage des Futters in 5 groben Richtungen reicht evtl. nicht aus, um eine gute Entscheidung zu treffen. +* Wir könnten die Belohnungen und Bestrafungen anders verrechnen oder das Belohnungssystem anpassen. +* Hin und wieder zufällige Aktionen ausführen, um neue Wege zu entdecken, die die Schlange noch nie beschritten hat. Dieser Ansatz ist im Machine Learning bekannt und wird über die Variable ε (Epsilon) gesteuert. +* Die letzte Aktion eines Spiels führt zwar zum unmittelbaren Tod der Schlange und wird bestraft. Die fatale Entscheidung wurde vielleicht jedoch schon zuvor getroffen, als die Schlange z.B. in eine Sackgasse lief. Die "Bestrafung" für den Tod der Schlange könnte auf die vorherigen Aktionen übertragen werden. + +Den Epsilon-Ansatz haben wir schon vorbereitet. Er kann bei einem Algorithmus ergänzt werden, z.B. + +```python + def epsilon(self, epoch: int, maxepochs: int) -> float: + if epoch < maxepochs/2: + # In der ersten Trainingshälfte 30% Zufall verwenden + return 0.3 + else: + # In der zweiten Trainingshälfte kein Zufall mehr + return 0.0 +``` + +Eine wesentliche Beschränkung bei dem von uns gewählten Ansatz ist allerdings die benötigte Speichermenge. Unser "Gehirn" der Schlange war so ausgelegt, dass sie alle Möglichkeiten für den Ausschnitt des Spielfelds im Kopf haben musste. Eine wesentliche Errungenschaft von Gehirnen ist allerdings das Vergessen. Dadurch wird Speicherplatz eingespart. + +### Neuronale Netze + +[Neuronale Netze](presentation/Neuronale%20Netze.pptx) kommen mit deutlich weniger Speicher aus. Sie arbeiten anhand der Idee einer Nervenzelle. + +Anhand des sehr anschaulichen Beispiel auf [playground.tensorflow.org](https://playground.tensorflow.org) und der Excel-Tabelle [Neuronales Netz Mathematik](presentation/NeuronalesNetz_tanh.xlsx) haben wir die Funktion eines Neurons und von Netzen hoffentlich gut verstanden und konnten die Berechnungen der Webseite nachvollziehen. + +Schon schwieriger wird es mit der Darstellung von Netzen zur Bildverarbeitung. Die [Webseite von Adam Harley](https://www.cs.ryerson.ca/~aharley/vis/conv/) hat dies mal für Handschrifterkennung von Ziffern versucht. + +# Sophy +Softwareunterstützter Physikunterricht +Wie schnell ist eine Kugel auf der Kugelbahn? + +Measurements + +The length of the distance has to be stated in millimeters. + +How to install the light barriers + +The light barriers have to be installed at a position in which they can't be interrupted by an object which should not interrupt them. Especially at the "Aquasol", the light barriers should not be reachable for a person which isn't in the slide yet. If the light barrier isn't installed in the right way, we can't guarantee the accuracy of our measurement results. + +CalculatorCV +============ + +CalculatorCV is a calculator which has a gesture interface for input. It shall +recognize fingers as numerical input and have buttons for the math operations. + +It's written in Python and uses OpenCV for image processing. + + +# Riesen-Tetris +Riesen Tetris Spiel mit pygame und ws2812 leds mit python \ No newline at end of file