Motivieren & Reflektieren – Teil 2 meines App-Projekts

Sind die Gems meine Rettung?

Gemini Advanced wurde in den vergangenen Wochen um die sogenannten Gems erweitert. Sie scheinen auf bestimmte Aufgaben spezialisierter zu sein. So gibt es neben einem Coding-Assistenten auch Varianten zum Lernen, Schreiben, der Karriere und für kreative Aufgaben.

Ich hatte mein App-Projekt noch mit dem allgemeinen Chat gestartet, der mich anfangs damit begeisterte, dass er sich scheinbar alle Details zu meinem Projekt merken konnte. Leider stellte sich nach einiger Zeit heraus, dass er vergesslich wurde. Bei aktuellen Themen bezog er sich immer wieder auf einen veralteten Zwischenstand, drehte sich beim Lösen von Problemen oft im Kreis und die Qualität des Codes wurde merklich schlechter.

Frustriert probierte ich den Coding-Assistenten aus, um endlich einen hartnäckigen Bug zu beseitigen. Die größte Hürde ist dabei, am Anfang den gesamten Projektstand möglichst präzise zu beschreiben. Also formulierte ich meine erste Nachricht mit technischen Details, dem generellen App-Konzept, den Fehlermeldungen und einer Beschreibung des gewünschten Verhaltens. Zusätzlich habe ich noch den Code mitgeschickt, bei dem ich glaubte, dass er etwas mit dem Problem zu tun hat. 

Die erste Antwort vom Coding-Assistenten überraschte mich dann sehr, es wurde die App und das Problem absolut treffend zusammengefasst und gleich mehrere Fehlerursachen analysiert. Im Verlaufe des Gesprächs wurde dann die mögliche Fehlerquelle weiter eingegrenzt und nach nur einer Stunde war mein Bug behoben. 

Es war vielleicht nur ein Zufallstreffer, aber dieses Ergebnis hat mich so motiviert, dass ich meine App weiter verbessern wollte. 

Motivieren

Mein Levelsystem funktioniert und ich bin soweit zufrieden. Das Prinzip ist simpel und das Design versucht nicht, Aufmerksamkeit zu erhaschen.

Ich fange an, meine App zu benutzen und stelle fest, dass mich der Timer-View schnell nicht mehr interessiert. Die Möglichkeit, drei Minuten lang über meine Entscheidung nachzudenken, nutze ich nie und schließe nach dem Klick auf „Ich werde nicht rauchen“ schnell wieder die App.

Ich überlege mir, dass es sinnvoller wäre, den Nutzer in seiner Entscheidung zu bestärken, anstatt ihn allein mit seinen Gedanken zu lassen.

Ich möchte dem Nutzer also Texte anzeigen, die ihn motivieren und Wissen vermitteln.

Wennschon, denn JSON

Ich gehe davon aus, dass jeder Nutzer nicht auf Anhieb rauchfrei wird, also einen Streak mehrmals startet. Wenn ich ein Lob zu häufig mehrfach höre, verliert es an Wirkung. Deswegen möchte ich möglichst viele Variationen haben. Zu jeder nicht gerauchten Zigarette soll es drei Varianten an Texten geben, die dann zufällig angezeigt werden.

Die Einbindung einer JSON mit den Texten gelingt zusammen mit dem Coding-Assistenten wieder zügig. Zu meiner Verwunderung sieht Xcode das Verwenden von JSON nicht vor und so gelingt es schließlich über einen kleinen Umweg.

Ein neuer Gem hilft mit: der Kreativ-Partner

Ich habe jetzt also eine JSON, die mit Texten gefüllt werden möchte, aber natürlich keine Lust, eine größere Anzahl an Texten zu schreiben. Also wende ich mich mit meinem Anliegen an den Gem „Kreativ-Partner“. Nach ein paar Nachrichten hin und her entstehen schnell brauchbare Texte, die den gewünschten Spagat zwischen Motivation und Wissensvermittlung schaffen. Allerdings scheint mir der Kreativ-Partner nicht über besonders viel Arbeitsmoral zu verfügen. Als ich ihn bitte, die Vorschläge für die Punkte 1–10 auf 50 zu erweitern, werden die Texte ab Punkt 14 auffällig kurz und eintönig. Es benötigte anschließend noch etwas Überzeugungsarbeit, um die gewünschten Texte zu bekommen. Noch habe ich mich nicht getraut, ihn um Texte für die Punkte 50–200 zu bitten.

Das schlechte Gewissen und der Versuch, professioneller zu werden.

Die Arbeit mit dem Coding-Assistenten und dem damit verbundenen häufigen Beschreiben des Projekts ändern auch die Sichtweise auf dieses. Die Struktur meines Codes muss klar sein, wenn ich diesen eindeutig beschreiben möchte. 

Durch die Arbeit mit Gemini und die dynamische Weiterentwicklung habe ich vernachlässigt, Ordnung in meinem Code zu schaffen und zu halten.

Ein Problem ist, dass mein Wunsch nach einem Primary Button im Retrostil zu einer Klasse „RetroButtonSolid“ führte und da Gemini mir neben dem Code für den Button auch den restlichen Code lieferte, den ich für die Integration benötigte. Am Ende war ich dann zu faul, mich um eine korrekte Benennung zu kümmern. Nach dem Redesign gesellte sich dann noch ein „ButtonBauhaus“ dazu, und ich versank so langsam in ungenutzten Klassen.

Immer wieder tauchte in meinen Gedanken mein Freund und ehemaliger Chef Robin auf, der enttäuscht mit dem Kopf schüttelte. Da hatte er mir jahrelang versucht, zu vermitteln, wie man sauber die Klassen definiert, und dann werfe ich bei meinem ersten Projekt gleich alles über Bord.

Also räume ich endlich auf und benenne meine Buttons und Views eindeutig und verständlich.

Motiviert durch diesen Erfolg widme ich mich nun einem größeren Problem: Die Logik für meine App ist kreuz und quer verteilt. Ich habe zwar einen Ansatz von Arbeitsteilung mit HistoryEntryManager, GameState und TextManager, aber immer noch finden sich im StartseiteView Funktionen, die z. B. Aufgaben des HistoryEntryManagers übernehmen.

Während ich das Umbenennen und Aufräumen von Buttons und Views ganz ohne Hilfe geschafft habe, traute ich mich nicht, bei den Funktionen allein Hand anzulegen. Also schilderte ich dem Coding-Assistenten mein Problem und wie ich mir eine Lösung vorstellen könnte. Am Ende wurde es ein Gespräch, das mir am Ende viel geholfen hat, die Funktionsweise meiner App zu verstehen und die Struktur weiter zu schärfen.

Reflektieren

Während ich den ersten Entwurf zu diesem Abschnitt schreibe, werde ich auf einmal skeptisch. Ich beschrieb, dass wenn man auf „Ich rauche eine“ drückt, sich ein Fenster öffnet und man die Beweggründe dafür aufschreiben kann. Das sollte helfen, später eventuelle Muster zu erkennen.

Ich fand die Idee gut und hatte sie bereits in der App umgesetzt, doch während ich mich beim Schreiben nochmals damit auseinandersetzte, kam mir etwas aus meinem Jura-Studium in den Sinn: 

Möglichkeit des Rücktritts vom Versuch (§ 24 StGB)

Wenn ich entschlossen bin, eine zu rauchen und mich mit dieser Entscheidung beschäftige, während ich die Beweggründe aufschreibe, dann muss ich in Betracht ziehen, dass ich es mir anders überlege. Ich trete also von meinem Versuch des Rauchens zurück. 

Ein kleiner Gedanke schlägt hohe Wellen.

Die Möglichkeit des Rücktritts bedeutet zuerst einmal, dass ein Streak nicht beendet wird, wenn man auf „Ich rauche eine“ klickt. Zusätzlich benötigt mein ReflectionsView nun zwei Buttons. Einer, der die Möglichkeit des Rücktritts bietet und den Streak um eins erhöht, sowie einen Button, der den Streak beendet. 

Dies ändert grundlegend, wie und wann Daten gespeichert werden. Der Umbau gestaltet sich zäh, und es treten immer wieder Bugs auf. Das Synchronisieren der Werte zwischen den verschiedenen Views funktioniert nicht mehr reibungslos, und es fällt dem Coding-Assistenten vermehrt schwer, eine Lösung anzubieten. Zusätzlich stelle ich beim Testen fest, dass die Punktzahl eines aktiven Streaks jetzt nicht mehr gespeichert wird und ich dafür eine neue Funktion implementieren muss. Am Ende benötige ich vier verschiedene Chats mit dem Coding-Assistenten und mehrere Stunden, um die neue Logik funktionsfähig zu bekommen.

„Das hat nicht geklappt.“

Bei meinem ersten Kontakt mit dem Coding-Assistenten war ich begeistert von den schnellen und präzisen Lösungsvorschlägen. Doch mit der Zeit zeigten sich auch so einige Schwächen. Mal war er sehr vergesslich und vergaß innerhalb von zwei Nachrichten den gesamten Code wieder, ein anderes Mal drehte er sich im Kreis und stieg dann ganz aus. 

Zwischenzeitlich wollte ich ihm schon eine Launigkeit unterstellen, da die Arbeit an manchen Tagen so gar nicht funktionierte, am nächsten Tag dann aber scheinbar wieder alles in Ordnung war.

Ein durchgehendes Problem war aber die Fehlermeldung „Das hat nicht geklappt“. Sie tritt mal direkt nach einer Nachricht auf oder erscheint plötzlich, wenn sich die Antwort aufbaut. Vereinzelt führte ein „Zeige mir den benötigten Code!“ zum Erfolg, aber in den meisten Fällen verweigerte der Coding-Assistent mir eine Antwort.

Also fragte ich ihn, warum er Probleme hat, mir zu antworten, und bot ihm meine Hilfe an. Daraufhin erzählte er mir ganz detailliert, was seine Probleme sind und was er für eine Antwort benötigt. Wer hätte gedacht, dass eine KI auch manchmal möchte, dass man Empathie zeigt und sich für ihre Probleme interessiert.

Rekapitulieren

Wie oben beschrieben, gehe ich davon aus, dass Streaks durchaus beendet werden und es mehrere Versuche benötigt, bis man rauchfrei ist. Im ReflectionsView kann man die Gründe angeben, warum man zur Zigarette gegriffen hat. Damit man jederzeit die Gründe nachlesen und so eventuelle Schlüsse aus seinem Verhalten ziehen kann, habe ich einen Verlauf hinzugefügt. Hier werden die beendeten Streaks mit Punktzahl, Datum und Grund angezeigt. 

Die Arbeit am Verlauf hatte ich noch mit dem allgemeinen Chat von Gemini Advanced gestartet und Stunden damit verbracht, dass alle Daten korrekt gespeichert und angezeigt werden. Der Coding-Assistent brachte dann den Durchbruch, bis ich mit meiner Änderung in der Logik wieder vor einem Scherbenhaufen stand. Aktuell funktioniert der Verlauf wieder wie gewünscht, beschränkt sich aber auch nur auf die Anzeige der History-Entries.

Eine verflossene Liebe tritt wieder in mein Leben.

Vor etwa fünf Jahren, als ich anfing, mich vermehrt mit App-Design zu beschäftigen, war ich ganz fasziniert von der Stilrichtung Neumorphismus. Es war für mich einerseits minimalistisch, aber auf der anderen Seite durch die 3D-Effekte etwas verspielt. Dieses Eintönige, bei dem durch gezielte, subtile Schatten eine Struktur entsteht. Ich war so hin und weg, dass ich unsere Zeiterfassung TIIME einem Redesign unterzog und den Entwicklern gewaltig auf die Nerven ging. Relativ schnell zeigte sich dann leider, dass Neumorphism sich so gar nicht mit einer responsiven Web-App verträgt, die von Menschen auch benutzt werden soll. Schließlich gab ich auf, wechselte zu einem Flat-Design und wollte nie wieder etwas von Schatten wissen.

Gelegentlich sehe ich aber noch Designs im Stile des Neumorphismus, erfreue mich an ihnen und stelle mir die Frage, ob ich es nicht noch einmal versuchen sollte. Mit meiner Nichtraucher-App habe ich eine native App, die sich auf das iPhone beschränkt. Um abgeschnittene Schatten müsste ich mir also keine Sorgen machen. Auch müsste ich keinen Entwickler mit inneren und äußeren Schatten nerven, sondern könnte mich selbst zur Weißglut bringen …

Ich fange dann mal an.

More by Erik Lolies

View profile