Programmieren

Bye-bye Bitterstoffe: Warum mein Tee mit Python besser schmeckt

Tea Time

Bildquelle: Pexels

Liebes Tagebuch,

aus meinem Berufsleben darf ich dir einen gut gemeinten Rat mitgeben: Begebe dich niemals – nie-mals – an deinen Rechner zurück, wenn du gerade Tee aufgegossen hast. Aus dem flüchtigen Check des Posteingangs wird unweigerlich ein „oh da guck ich eben…“. Und wenn „eben“ vorüber ist, ist dein Grüntee irgendwas zwischen beige und braun. Und kalt.

Über diese Sachlage muss ich mich wohl schon oft genug geärgert haben. Jedenfalls war es das Erste, das mir in den Sinn kam, als ich nach einem Einstiegsprojekt für Python suchte.
Ich hatte ja schon gelernt, dass man mit Python einfache und wiederkehrende Dinge automatisieren kann (mehr dazu hier). Dann konnte es mich bestimmt auch erinnern, den Teebeutel rechtzeitig rauszunehmen. Und schon war mein erstes Projekt geboren: Ein eigens entwickelter Tea Timer!

Um deine Frage vorwegzunehmen: Jawohl, ich weiß Bescheid von der Wecker-App auf meinem Handy. Nur finde ich schlichtweg, dass ein selbstprogrammierter Timer mehr Pointe hat. (Falls du noch nicht lachst, sei ergänzt: Ich kann überhaupt nicht programmieren.)
Tatsächlich brauchte es gerade einmal 8 Schritte – und schon mutierte ich vom hilflosen Wecker-App Nutzer zu einem Programmer-to-be.

Selbstverständlich habe ich diese Reise für meine IT-Mission genauestens dokumentiert – mehr zu den einzelnen Schritten gibt’s weiter unten in der Tea Timer Doku. Doch zusammengefasst hat mich das Projekt um die folgenden drei Erkenntnisse aufgeschlaut:

Erste Schritte mit Python: Top 3 Lessons Learned

1. Das Internet ist dein bester Freund
Programmieren ist ein Synonym für gut-googlen-können

2. Eins nach dem anderen
Wenn du nicht sofort zum Ziel kommst, unterteile es in sinnvolle Etappen. Löse erst jede für sich, und puzzle die Elemente anschließend zusammen.

3. Auf die Details kommt’s an:
Falsch eingerückt oder ein Zeichen zuviel gelöscht? Dann hat Python leider kein Foto für dich. Umgekehrt liegt die Lösung meist nicht weit, wenn das Skript einfach nicht funktionieren will.

Neben diesen Tipps war es wohl auch meiner Sturheit zu verdanken, dass ich am Ende wirklich einen funktionsfähigen Tea Timer in den Händen hielt.
Das bedeutete nicht nur, dass die Zeit der ungewünschten Bitterstoffe vorüber war, sondern auch:
Man kann Programmieren, ohne es zu können!

Zur Verteidigung aller „echten“ Programmierer da draußen: Von gut habe ich nichts gesagt. Mein Code ist mit Sicherheit länger und chaotischer, als er sein müsste. Auch könnte man den Ablauf schlauer gestalten. Solange der Timer rattert, friert bspw. der Rest des Skripts ein. Dann kannst du ja mal versuchen, das Menüfenster zu minimieren.

Fakt ist: Meine selbstgebastelte Lösung funktioniert gut genug, dass ich mich nun unbesorgt in meine Arbeitshypnose zurückversetzen kann. Ganz ehrlich habe ich dem Skript die ein oder andere genießbare Tasse Tee zu verdanken. Und viele lehrreiche Einblicke in die Welt von Python. Take that, Wecker-App!


Der Tea Timer in Aktion: Das Ergebnis im Zeitraffer

Die Tea Timer Doku: In 8 Schritten zum Erfolg

Regel Nummer 1 beim Programmieren: Kein Code ohne Algorithmus. Erst braucht es das Konzept, bevor das erste Wort in Programmiersprache entsteht. Zuerst skizzierte ich also die Strategie:

Bildquelle: Powered by Elisabeth Thirmeyer

Manche Ideen kamen mir erst im Laufe der Zeit – wie zum Beispiel, die Ziehzeit von der Sorte abhängig zu machen. Das Konzept zeigte mir jedoch von Anfang an, was wann passiert und wo die Zusammenhänge liegen.

Nachdem alle Welt von Stackoverflow schwärmt, suchte ich dort zuerst nach einer Vorlage für meinen Timer. Ich wühlte mich durch Fälle wie „Fenster nach bestimmter Zeit schließen“ und landete zwischenzeitlich sogar bei einem Mathespiel (Rechnen auf Zeit, wie grausam). Als ich nicht fündig wurde, wechselte ich doch auf das gute alte Google.

Bei GeeksforGeeks fand ich dann endlich einen sehr ähnlichen Fall.1. Ich musste nur den Benachrichtigungstext ändern und eine Zeit eingeben. Et voilà, ich hatte eine funktionierende Pilot-Version des Tea-Timers!

Bildquelle: Autor

Ich erlaubte mir, die Ansprüche hochzuschrauben: Ich trinke schließlich nicht jeden Tag das Gleiche. Also brachte ich verschiedene Teesorten ins Spiel. Der Timer sollte von selbst mit der hinterlegten Ziehzeit starten, je nachdem, welche Sorte ich wählte.

Dafür kommt in Python ein sogenanntes Dictionary zum Einsatz – ein Nachschlagewerk, bei dem man einem Key (hier die Teesorte) einen oder mehrere Values (hier die Ziehzeit) zuordnet. Wie bei einem Wörterbuch: Ein englischer Begriff kann dort auch mehrere deutsche Übersetzungen haben.
Ich übersetzte also Grüntee mit 120 Sekunden, Schwarztee mit 180 Sekunden usw. Natürlich brauchte ich dafür wieder jemanden, der besser coden kann als ich. Diesmal wurde ich auf Stackoverflow fündig und probierte die Vorlage zunächst in einem separaten Skript aus.2. Bingo: Ich bekam eine 120 zu sehen, als ich Grüntee eingab.

Zurück in meinem Timer-Skript machte ich mir die Input-Funktion zunutze, die schon in der Code-Vorlage enthalten war. Ursprünglich wurde hier eine Zeitangabe abgefragt – diesen Part ersetzte ich einfach mit dem zuvor erstellten Dictionary (vgl. Zeile 24ff. im Bild unten). Plangemäß sollte ich nun den Timer stellen können, indem ich eine Sorte eintippte.

Damit ich nicht so lange auf ein Ergebnis hinfiebern musste, kürzte ich die Ziehzeit auf 1-3 Sekunden herunter. Und tadaa, es funktionierte!

Bildquelle: Autor

Als nächstes nahm ich mir die Optik vor. Mein Skript sollte ein eigenes Menü bekommen und sich mit Pop Up Fenstern bemerkbar machen. Wenn es in Python um grafische Benutzeroberflächen (im Fachjargon: GUI) geht, kommt die sogenannte Tkinter-Library ins Spiel.

Exkurs: Libraries sind themenbezogene Code-Sammlungen, die bei Bedarf in das eigene Skript geladen werden können. Die Library enthält dann bereits viel Vorarbeit, sodass ein einziger Befehl abdeckt, was sonst einige Zeilen Code erfordern würde.

Mein Plan war, dass der Tea Timer eine Sortenliste präsentierte, aus der ich eine Auswahl treffen konnte. Für die Eingabe von Werten über ein Drop Down Menü fand ich einen gut geeigneten Code im Netz.3. Ich musste lediglich den Befehl von „multiple choice“ auf „single choice“ ändern4. – so verrückt, dass ich zwei verschiedene Teesorten auf einmal trinke, bin ich dann auch wieder nicht.

Daneben fand ich einen separaten Code, der neben einem Menü sogar mit Pop Up Fenstern aufwarten konnte. Nachdem ich die unnötigen Funktionalitäten entfernt hatte, nutzte ich diesen Code als Grundlage und bastelte für die Sortenauswahl den Drop Down Part mit hinein.5.
Mein Zwischenergebnis war, dass ich in einem Menü die Teesorte auswählen konnte.

Bildquelle: Autor

Nun kommen wir zur härtesten Stelle des Projekts. Ich hatte schon zuvor einige Anpassungen und Verflechtungen vorgenommen. Doch als es darum ging, das Teesorten-Menü auch noch mit der Timer-Funktion zu verbinden, erreichte das Code-Gebastel seinen Höhepunkt.

Der fieseste Stolperstein: Die Sortenauswahl wurde im Drop Down Skript in eine Variable i geschrieben. Also war ich gezwungen, mich für den Timer auf ebendieses „i“ zu beziehen. Beim Ausführen wollte mir Python glatt erzählen, dass die Variable i nicht definiert sei. Dabei hatte ich die Definition aus einem funktionierenden Skript und sah sie auch noch mit eigenen Augen! Kurzer Nervenzusammenbruch, ob das denn wirklich der Ernst sein könnte. Dann fand ich zum Glück des Rätsels Lösung: An der Stelle war das richtige Einrücken wesentlich. Ich ruckte eine Zeile weiter nach rechts, und plötzlich zeigte sich Python kooperativ:

Nun konnte ich die Teesorte über ein Menü auswählen und damit die Ziehzeit bestimmen. Der Timer tat sein Werk im Hintergrund und nach Ablauf der Zeit bekam ich ein Pop Up, das mich wie gewünscht an meinen Teebeutel erinnerte – sowie kurze Zeit später daran, dass ich den Tee auch trinken sollte.

Bildquelle: Autor

Euphorisch probierte ich meinen Timer aus. Ich tat so, als würde ich mich auf etwas anderes konzentrieren, öffnete eine x-beliebige Anwendung und wartete zuversichtlich auf das Pop Up.
Leider vergebens.
Wie sich herausstellte, funktionierte es zwar – doch die Pop Up Erinnerung an meinen Teebeutel übertrumpfte nicht meine Anwendung. Stattdessen versumpfte die Benachrichtigung in einem minimierten Fenster. Ja was brachte mir denn das? Rein gar nichts!

Also verwendete ich Schritt 6 darauf, das Pop Up Fenster im Vordergrund auszuführen. Nach einer zähen Google-Suche stellte ich fest, dass ich eine andere Art von Pop Up benötigte.6. Ich tauschte also den Typ der Messagebox aus – und siehe da, endlich drängelte sich das Fenster in mein Sichtfeld, selbst wenn ich gerade etwas anderes tat als gespannt auf seine Anwesenheit zu warten.

Die nachfolgende Galerie zeigt die Transformation vom ursprünglichen Pop Up zu einer prominenteren Variante.

Bildquelle: Autor

Das Pop Up war nun zwar visuell prominent, aber für meinen Geschmack noch nicht aufmüpfig genug. Was, wenn ich gerade etwas anderes tat als am Rechner zu sitzen? Ich wollte, dass mein Tea Timer auch auf der Tonspur mit mir kommunizierte, und reicherte die Textbenachrichtigungen um einen Soundeffekt an.

Dieser Schritt war zur Abwechslung einmal kurz und schmerzlos per Stackoverflow – Code kam, sah, siegte.7. Alles was ich tun musste war, eine Audio Library in mein Skript aufzunehmen und den Ton-Befehl jeweils vor den Pop Ups zu platzieren.

Bildquelle: Autor

Im letzten Schritt ging es darum, meinen Tea Timer in eine eigenständige Applikation zu verwandeln. Schließlich wollte ich nicht erst die Python Konsole laden müssen, um meinen Tea Timer zu bedienen.

Es gibt online Anleitungen dazu, wie man Python Skripte in eine ausführbare Datei verwandelt.8. Meine Geduld neigte sich langsam dem Ende entgegen, also habe ich mich für eine Abkürzung entschieden: Eine Verknüpfung des Skripts direkt auf meinen Desktop.

Ich richtete per Rechtsklick auf den Desktop eine neue Verknüpfung ein, die auf den Speicherpfad meines fertigen Skripts führte. Zunächst wusste mein Rechner nicht, mit welchen Programm es denn bitte dieses merkwürdige Etwas ausführen sollte. Also ergänzte ich in den Einstellungen der Verknüpfung noch den Pfad des Python Interpreters.

Dort hätte ich mir sogar noch ein Bild aussuchen können, um meiner Tea Timer Applikation ein eigenes Icon zu verpassen. Da ich allerdings noch nicht unter die Designer gegangen bin, genügte mir einstweilen das Standard-Icon von Python.

Und dann war es tatsächlich vollbracht: Mein erstes eigenes Python Projekt war erfolgreich umgesetzt und wartete nun direkt im Desktop auf seine Einsätze.

Bildquelle: Autor

Wie mein Projekt am Ende geworden ist, darf ich dir stolz im Tea Timer Video zeigen. Die Magie dahinter steckt im nachfolgenden Code.
Dir fällt etwas auf, das ich daran verbessern könnte? Hinterlasse mir unten gerne einen Kommentar!

import time
from tkinter import *
import ctypes

import winsound
duration = 1000  # milliseconds
freq = 440  # Hz

#---TIMER PART 1---
# define the countdown func.
def countdown(t):
	
	while t:
		mins, secs = divmod(t, 60)
		timer = '{:02d}:{:02d}'.format(mins, secs)
		print(timer, end="\r")
		time.sleep(1)
		t -= 1
 #--TIMER PART 1 Ende---       


def selected_item():
# Get Value selected from Dropdown via curselection
    for i in listbox.curselection():
        print(listbox.get(i))
        #--- TIMER PART 2---
        Sortenauswahl = listbox.get(i)
        Ziehzeit  = {'Grüntee': 120, 'Schwarztee': 180, 'Früchtetee':360}
        #print(Ziehzeit[Sortenauswahl])
        t = Ziehzeit[Sortenauswahl]
        # function call
        countdown(t)
        #after countdown ends make a tone and show a message:
        winsound.Beep(freq, duration)
        ctypes.windll.user32.MessageBoxExW(0, "Der Beutel ruft", "Tea Timer",0x40000)
        #Start second timer for the right temperature
        countdown(600-t)
        #after countdown ends make a tone and show a message:
        winsound.Beep(freq, duration)
        ctypes.windll.user32.MessageBoxExW(0, "Kurze Pause – gönn dir einen heißen Tee. ", "Tea Timer",0x40000)
        #--- TIMER PART 2 ENDE--

# creating Tk window
root = Tk()

# setting geometry of tk window
root.geometry("350x250")

# Using title() to display a message in
# the dialogue box of the message in the
# title bar and using label for the message above the drop down menue
root.title("Tea Timer")
Label(root, text="Welchen Tee trinkst du?").pack()

# Create a listbox
listbox = Listbox(root, width=40, height=10, selectmode=SINGLE)
# Inserting the listbox items
listbox.insert(1, "Grüntee")
listbox.insert(2, "Schwarztee")
listbox.insert(3, "Früchtetee")


# Create a button widget and
# map the command parameter to
# selected_item function. If button is clicked, above-mentioned command is run
btn = Button(root, text='Tea Timer starten', command=selected_item)
btn.place(x = 70,y = 120)

# Placing the button and listbox
btn.pack(side='bottom')
listbox.pack()
root.mainloop()



Quellen:

  1. https://www.geeksforgeeks.org/how-to-create-a-countdown-timer-using-python/
  2. https://stackoverflow.com/questions/55485344/find-a-value-from-a-dictionary-in-python-by-taking-a-key-from-user-input
  3. https://hasilcopa.com/how-to-get-selected-value-from-dropdown-list-in-python-tkinter
  4. https://www.pythontutorial.net/tkinter/tkinter-listbox/
  5. https://www.geeksforgeeks.org/create-countdown-timer-using-python-tkinter/?ref=rp
  6. https://stackoverflow.com/questions/50086178/python-how-to-keep-messageboxw-on-top-of-all-other-windows
  7. https://stackoverflow.com/questions/16573051/sound-alarm-when-code-finishes
  8. https://towardsdatascience.com/how-to-easily-convert-a-python-script-to-an-executable-file-exe-4966e253c7e9

2 Kommentare

Eine Antwort schreiben

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Cookie Consent mit Real Cookie Banner