Software
Hier findet sich ein Teil der von mir entwickelten Softwareprojekte.
Weiter unten finden sich die Projekte, die ich im Rahmen meiner Ausbildung zum Full-Stack-Web-Entwickler entwickelt habe.
Derzeit arbeite ich als Consultant bei der Woodmark Consulting GmbH.
Tech Stack, den ich bisher verwendet habe:
Frontend: HTML, CSS, JavaScript, React.js, Vue.js, Nuxt.js, QML, LiveScript, jQuery
Backend: Node.js/Express, Python, Java, Spring Boot
Datenbanken: PostgreSQL, SQLite
Cloud Computing: AWS (ECR, EC2, S3, CloudWatch, CodePipeline, Lambda, ParameterStore), Terraform
CICD: GitHub Actions, AWS
Tests: Jest, jUnit, PyTest, unittest
Monitoring/Alerting: DataDog
IDEs: IntelliJ, PyCharm, Visual Studio Code, QtCreator
Versionsverwaltung: Git, GitHub, GitLab
GRAIL_upload

App zum Kopieren von Dateien und Erstellen von Graphen
Technologien: Python 3.8, Matplotlib, Pandas, NumPy, PySimpleGUI, poetry, pyinstaller
Versionskontrolle: Git, GitLab
IDE: PyCharm
Funktionalität: Grafische Benutzer:innenoberfläche, Suche nach Patient:innen, Kopieren aller relevanten lokalen Dateien auf Server mit veränderter Ordnerstruktur und Erstellen von Graphen mit einem einfachen Klick, Rückmeldung des Bearbeitungsstands, umfangreiche Fehleranzeige, Erstellen eines debug logfiles
- Genau herausfinden, was die Mitarbeitenden der Charité benötigen und eine kund:innenorientierte Software entwickeln (aus diesen Gesprächen ist in mehreren Iterationen das Programm entstanden)
- Das Programm soll zuverlässig, schnell und vollständig kopieren
- Das Programm soll einfach bedienbar sein
- Das Programm soll schöne .svg-Graphen erstellen
- Software schreiben, die lokale Daten von verschiedenen Rechner auf einen Server kopiert, dabei auf diesem eine bestimmte Ordnerstruktur anlegt und den Datumsordner von 8- zu 6-stellig ändert
- Erstellen von .svg-Graphen aus .csv-Datei(en), sofern diese vorliegt/-en; dabei zusätzliche Verwendung von xml-Layout-Dateien
- Nutzer:innenfreundliche grafische Oberfläche
- Erstellen einer JSON-Datei mit relevanten Werten zur späteren Verwendung
- Das Programm muss in einer Windows-Umgebung laufen, Erstellen einer .exe-Datei
GRAIL_upload kopiert die lokalen Daten vom GRAIL- und Vicon-Rechner auf den BeMoveD-Server der Charité Berlin und erstellt .svg-Graphen, wenn es die richtige .csv-Datei findet.
Wenn das Programm läuft, öffnet sich eine (deutschsprachige) Benutzer:innenoberfläche (GUI) und der:die Benutzer:in wird aufgefordert, eine Patient:innen-ID einzugeben. Die App prüft, ob der:die Patient:in existiert (z.B. P100). Wenn er:sie gefunden wird, zeigt die GUI den Quell- und Zielpfad an und ob .csv-Dateien gefunden wurden.
Wenn der Knopf gedrückt wird und eine .csv-Datei vorhanden ist
- kopiert die Anwendung die .layout-Dateien in jeden Datumsordner, säubert sie (löscht alle HTML-Tags), ersetzt die Pfeile durch besser aussehende und benennt sie um ('walk.layout', 'run.layout')
- erstellt eine .json-Datei zur späteren Verwendung mit den keys 'title', 'graphname' und 'channelname' aus der .csv-Datei
- erstellt einen Ordner 'cascade-graphs' und einen Unterordner für jeden Zeitpunkt (z.B. '1013'), der im Dateinamen der .csv-Datei steht
- erstellt aus jeder .csv-Datei (in der Regel) 89 .svg-Graphen und speichert sie in das entsprechende Zeit-Unterordner.
- schreibt eine Readme-Datei in jeden Zeit-Unterordner
- legt 3 Ordner auf dem Server an: 'Dokumente', 'GRAIL', 'Vicon'
- kopiert alles aus den lokalen Patient:innendaten (z.B. P100/20211016) in den GRAIL-Unterordner auf dem Server ('P100/211016/GRAIL'). Dazu gehören die Patient:innendaten, die .layout-Dateien, die .json-Datei und die Graphen, falls es eine .csv-Datei gibt.
- kopiert jede Datei aus dem lokalen Vicon-Pfad 'D:/BeMovedDB/gait analysis bemoved/P100/New Session' in den entsprechenden Vicon-Ordner auf dem Server ('P100/211016/Vicon'). 'Entsprechend' bedeutet hier, dass das Erstellungsdatum der Datei mit dem Datum übereinstimmen muss (z. B. wird eine am 16. Oktober 2021 erstellte Datei in 'P100/211016/Vicon' abgelegt). Da das Erstellungsdatum unter Windows und Linux/Mac unterschiedlich ist, wird zunächst geprüft, welches Betriebssystem verwendet wird.
- zeigt dem:r Benutzer:in an, dass der Kopiervorgang noch läuft. Wenn der Vorgang abgeschlossen ist, wird dem:r Benutzer:in angezeigt, dass er beendet ist.
Wenn keine .csv-Datei vorhanden ist, werden die Schritte a-e übersprungen.
Daten und Zeiten werden mit regular expressions gefunden.
Die GUI von GRAIL_upload zeigt dem Benutzer eine Reihe von möglichen Fehlern an:
- Wenn der:die Benutzer:in etwas anderes als Ziffern eingibt
- Wenn der:die Benutzer:in weniger als 3 oder mehr als 4 Ziffern eingibt
- Wenn der:die Patient:in nicht existiert
- Wenn keine .csv-Datei vorhanden ist
- Wenn die .csv-Datei falsch ist (das erste Feld enthält nicht den String 'left')
- Wenn es keinen lokalen Datumsordner gibt
- Wenn der lokale Datumsordner nicht genau 8 Ziffern hat
- Wenn die .layout-Datei unter dem angegebenen Pfad nicht existiert
- Wenn das Kopieren fehlschlägt
Zusätzlich wird eine Logdatei für die Fehlersuche erstellt.
- Größter Erfolg: Feedback der Charité-Mitarbeitenden, dass ihnen das Programm pro Patient:in 2-5 Minuten Zeit erspart und sie es täglich benutzen
- Differenzierte Fehlerbehandlung mit genauer Rückmeldung an Benutzer:in
- Lust, mehr mit Python zu programmieren 😊
Scraping WGcompany

Automatisierte E-Mail bei neuen WG-Angeboten
Technologien: Python 3.10, selenium, chromedriver-autoinstaller, chromedriver-py, dateparser, poetry, python-dotenv
Versionskontrolle: Git, GitHub
IDE: PyCharm
Funktionalität: Die App scraped die neuesten Einträge auf wgcompany.de und sendet sie automatisch an eine angegebene E-Mail-Adresse.
Abfrage von lokalen Umgebungsvariablen oder GitHub-secrets (remote) für GitHub-Actions, Headless Selenium Chrome Webdriver, Passung von Chrome-Browser und Chromedriver-Version, Überprüfung ob die zu scrapende Seite korrekt ist, relevante Daten mit XPath- und RegEx-Mustern erlangen, Ändern von Datumsmustern, Versenden von E-Mails über SSL-Verbindung mit allen relevanten Informationen in utf-8 encoding, Funktionen: Typing von Parametern und Rückgabewerten und umfangreiche erklärende Docstrings.
Soziales Netzwerk

Facebook-inspirierte Single-Page-Application (SPA)
Technologien: React & Redux, Node, Express, PostgreSQL, Socket.io, Amazon S3 and SES, CSS, HTML
Funktionalität: Registrierung, Login, persönliches Profil mit Bio- und Bild-Upload, Senden, Empfangen und Annehmen von Freundschaftsanfragen, Freundschaft beenden, Gespräche in einem Chat-Raum führen, Anzeige der letzten 3 registrierten Benutzer:innen, Suche nach Benutzer:innen mit Vor- und Nachnamen, Anzeigen von Freund:innen von Freund:innen, Abmelden
Benutzer:innen können einem Sozialen Netzwerk beitreten, in diesem Fall einem für inklusive Kitesurfing-Communities.
Eine hohe Priorität hat konditionales Rendering, Sicherheitsfragen (Passwort-Hashing, Schutz vor SQL-Injektion, CSRF- und XSS-Angriffen, Reset-Code per E-Mail) und eine differenzierte Fehlerbehandlung (verschiedene Fehlermeldungen werden angezeigt, z.B. wenn die E-Mail nicht in der Datenbank ist, das erneut eingegebene Passwort nicht mit dem ersten Passwort übereinstimmt oder die Eingabefelder leer bleiben) in den Registrierungs-, Login- und Reset-Passwort-Komponenten.
Petition
Online-Petition gegen algorithmische Diskriminierung
Technologien: Express handlebars, Node, PostgreSQL, jQuery, CSS, HTML
Funktionalität: Unterstützer:innen können sich registrieren, einloggen, ihre Profilinformationen aktualisieren, unterschreiben, die Unterschrift wieder zurückziehen, Mitunterzeichnende nach Ort sortiert anzeigen lassen, sich abmelden
Diese Petition plädiert für die Unterzeichnung der Algo.Rules und gegen algorithmische Diskriminierung. Je nachdem, ob sich Benutzer:innen registrieren und unterschreiben, werden ihnen unterschiedliche Seiten angezeigt. Wenn sie unterzeichnen, werden andere Unterzeichnende, deren Homepages, ihr Alter und ihre Stadt angezeigt.
Ich habe viel über Datenfluss gelernt, die Arbeit mit Session-Cookies, Get- und Post-Routen und wie man sie mit Supertest testet. Ich habe auch mit promises, Passwort-Hashing und inserts, updates, upserts und deletes in der Datenbank gearbeitet. Besonders herausfordernd fand ich die Unterschrift mit canvas und das konditionale Bearbeiten des Benutzer:innen-Profils.
Die Seite verfügt über eine differenzierte Fehlerbehandlung und ist gegen SQL-Injektion, Clickjacking, XSS- und CSRF-Angriffe geschützt.
Imageboard
Instagram-inspirierte Single-Page-Application (SPA)
Technologien: Vue, Node, Express, PostgreSQL, Amazon S3, Jest, CSS, HTML
Funktionalität: Hochladen von Bildern mit Titel, Beschreibung und Benutzernamen, jedes Bild kann angeklickt und groß angezeigt werden mit mehr Informationen und der Möglichkeit, das Bild zu kommentieren und auch zu löschen, weitere Bilder können geladen werden
Jede:r kann Bilder ihrer Wahl hochladen; das Thema dieses Imageboards ist Graffiti und Street Art.
Ich habe viel über Vue.js und die Arbeit mit state, un-/mounting, dynamischem Routing, Click-Handlern, Event-Emittern und Wächtern (watchers) gelernt. Das Imageboard ist gegen SQL-Injektion, Clickjacking, XSS- und CSRF-Angriffe geschützt.
Kaleidoskop
Meine kleineren und mittelgroßen Projekte
Technologien: Express handlebars, CSS, HTML
Funktionalität: Alle Projekte werden mit Überschrift und Bild angezeigt und für jedes Projekt gibt es eine eigene Seite mit ausführlicher Beschreibung
Skalierte Bilder
Funktionalität: Schieberegler für Skalierung der Bildgröße, Anzeige des einen oder des anderen Bildes
2 übereinander gelegte Bilder, die normalerweise für Vorher-Nachher-Situationen verwendet werden. Ich benutze es zum Gedenken an meine Urgroßmutter Emilie Rau. Wird der weiße Schieberegler nach links geschoben, ist mehr vom Bild auf der rechten Seite zu sehen und umgekehrt. Auf der Programmiere-Ebene habe ich Mousedown, Mousemove und Mouseup-Ereignisse verwendet und offset().left wurde zu einem guten Freund. Schwierig fand ich, das Gleiten des Schiebereglers innerhalb der Grenzen des Bildes zu beenden.
Spotify-Suche
Funktionalität: Spotify-Datenbank über API durchsuchen, Album/Künstler:in mit verlinktem Cover und Namen anzeigen, mehr Daten durch Button oder Endlos-Scroll laden
Trotz des Nicht-Vorhandenseins eines eigenen Spotify-Kontos, habe ich trotzdem eine Benutzeroberfläche programmiert, um über eine API die Spotify-Datenbank durchsuchen zu können. Wird nach einer:m Künstler:in oder Album gesucht, werden die ersten 20 Suchbegriffe mit einem Bild des Albums und dem Namen des:r Künstler:in angezeigt. Unten angekommen, kann für die nächsten 20 Suchbegriffe auf 'More' geklickt werden. Endlos-Scroll ist auch möglich. Ich habe jQuery, Clickhandler, mehrere Ajax-'GET'-Requests, CSS-Flexbox und Pseudo-Selektoren verwendet. Ich fand es schwierig, die Reihenfolge herauszufinden, wann welche Funktion aufgerufen werden soll und dass sie sich nicht gegenseitig stören. Schlussendlich habe ich es geschafft, und wer auf den Link unten klickt, hat einen unbegrenzten Vorrat an Suchergebnissen - hoffentlich hast DU ein Spotify-Konto...
Kätzchen-Karussell
Funktionalität: Die Kätzchen kommen von rechts und wandern der Reihe nach nach links, ein bestimmtes Bild kann gezielt angezeigt werden
4 Bilder von Kätzchen bewegen sich in einer Endlosschleife von rechts nach links, ein Bild pro Sekunde. Es kann auch ein bestimmtes Bild ausgewählt werden, indem auf den entsprechenden weißen Punkt geklickt wird. Bei der Programmierung waren timing und Raum wichtig, einschließlich des Hinzufügens und Entfernens von QuerySelectors, eventListeners und clickHandlers. Es war das erste Mal, dass ich mit CSS-transitions gearbeitet habe. Niedlich, nicht wahr? Klick auf den Link, um das Kätzchen-Karussell zu sehen...
Ticker
Funktionalität: Die neuesten Nachrichten werden angezeigt und können bei Interesse angeklickt werden
Ticker sind etwas veraltet, aber eine gute Programmierübung. Meiner läuft von rechts nach links, und wird mit der Maus über einen der Titel gefahren, hört der Ticker auf zu laufen, der Hyperlink wird blau und unterstrichen, und wenn er angeklickt wird, öffnet sich die gewünschte Information in einem neuen Tab. Die Programmierung ist in Vanilla-JavaScript u.a. mit Event Listener, Mouseovers, Mouseoutss, OffsetWidth und AnimationFrames. Wer tiefer in meinen Ticker eintauchen will, findet alle meine Texte, die ins Englische übersetzt wurden... In einer späteren Übung haben wir ein Backend hinzugefügt und Live-Tweets von bestehenden Twitter-Accounts über die twitter-API mittels Token abgerufen.
Lokaler Speicher
Funktionalität: Nachricht schreiben und im lokalen Speicher speichern, Nachricht anzeigen und/oder löschen
Die Arbeit mit dem lokalen Speicher hat Spaß gemacht. Wenn man etwas in das Textfeld schreibt und auf die Schaltfläche 'Keep it a secret!' klickt, verschwindet der Text und die Schaltfläche kann nicht mehr angeklickt werden (um das, was im lokalen Speicher gespeichert wurde, zu behalten). Die Schaltfläche links daneben ('Tell me the secret!') zeigt an, was gespeichert wurde, auch nachdem der Browser geschlossen wurde. Die letzte Schaltfläche ('I don't trust you anymore - forget my secret!') löscht den lokalen Speicher und die Konsole. Ich habe mit jQuery unter Verwendung von Click-Handlern und Try-Catch-Fehlerbehandlung gearbeitet.
JSON-Validator
Funktionalität: Test, ob Daten JSON sind oder nicht
Dieser einfache Validierungstest prüft, ob JSON vorliegt oder nicht. Einfach per Copy-Paste in das Textfeld kopieren und auf die Schaltfläche 'Validate JSON' anklicken. Wenn JSON vorliegt, färbt sich der Rand des Textfelds grün und unten im Textfeld blinkt der Text 'Valid JSON!'. Handelt es sich nicht um JSON, färbt sich der Rand des Textfelds rot und es erfolgt ein entsprechender Hinweis. Für den nächste Überprüfung einfach 'Clear textarea' klicken... Programmiert mit jQuery mit der parse()-Methode und Flexbox und Keyframes in CSS.
4 Gewinnt
Funktionalität: 2 Spieler:innen können gegeneinander spielen, horizontale, vertikale oder diagonale Siege, Animation, wenn ein:e Spieler:in gewinnt, die Farbe des Gewinners wird angezeigt, erneut spielen
Schon als Kind habe ich gerne 4 gewinnt gespielt - und tue es bis heute! Ich hätte nie gedacht, dass ich das mal als Computerspiel programmieren würde. Das Schwierigste war das Herausfinden und Programmieren der Diagonalsiege. Man kann entweder dunkelrot oder pink zum Spielen auswählen. Jeder Spielzug wird von einem Klick-Geräusch begleitet. Wenn eine Farbe gewinnt, dehnt sich das ganze Brett aus und die Gewinner-Farbe füllt den ganzen Bildschirm. Diese Animation habe ich mit jQuery erstellt. Zusätzlich gibt es eine Gewinnerinnen-Meldung, die blinkt - diese habe ich mit CSS-Animationen und Keyframes erstellt. Der 'Play again'-Knopf startet ein neues Spiel - Viel Spaß dabei!
Spiced Homepage
Funktionalität: Pop-up Anzeige, Hamburger-Menü, von rechts hereingleitende Navigation, auch für kleinere Bildschirme geeignet
Eine Übung zur Erstellung einer Homepage für Spiced mit HTML, CSS und JavaScript/jQuery ohne Flexbox oder Grid - recht anspruchsvoll! Ich habe eine Pop-up-Anzeige und ein von rechts hereingleitendes Menü hinzugefügt. Es ist auch für einen kleineren Bildschirm mit @media screen ausgelegt. Ich habe Animationen und Click-Handler verwendet und mit Un/Sichtbarkeit gespielt.
Funktionalität: Ländersuche, geht mit Maus oder Tasten
Ich habe in meinem Leben viele Male inkrementelle Suchen verwendet und kannte diesen Begriff noch nicht einmal, bis ich eine programmieren sollte... Ich habe nie über all die verschiedenen Schritte nachgedacht, die dafür notwendig sind. Ich habe gelernt, wie man mit Mouseovers, Mousedowns und Tastenbefehlen arbeitet und wie man ein Suchergebnis hervorhebt - alles programmiert mit jQuery. Ich habe auch Fokus und Unschärfe verwendet, sollte die Aufmerksamkeit einer Benutzer:in schwinden 😉, und schlussendlich war es mein erster Ajax-'GET'-Request, um von einer Länder-API aus suchen zu können.











