@Jonas1243: Hm, hier hat wahrscheinlich noch niemand geantwortet weil es noch keiner geschafft hat freundliche Worte für den notwendingen Totalverriss zu finden. Ich entschuldige mich schon mal im Voraus…
Den Code zum laufen zu bringen, heisst ihn erst einmal komplett zu verwerfen, und als nächstes Programmieren/Python zu lernen. Das geht so gar nicht. Weder von vom Inhalt, noch von der Form her betrachtet.
Kommentare sollten einen Mehrwert zum Code liefern und deshalb nicht das Offensichtliche was schon als Code da steht noch einmal wiederholen. Wer bei einem Haufen ``import``-Anweisungen nicht weiss das dort importiert wird, für den ist auch ein entsprechender Kommentar sinnlos. Wobei der Kommentar bei den Importen nicht stimmt, denn da wird gar nicht alles importiert. Alse weder *alles*

, noch alles was das Modul importiert, denn etwas später steht dann ja noch mal ein durch anderen Code getrennter Import aus dem `Tkinter`-Modul. Importe sollten in der Regel am Anfang stehen, damit man leicht erkennen kann was für Abhängigkeiten eine Modul hat.
Es wird zwar nicht *alles* importiert, aber deutlich zu viel, denn von den Importen wird über die Hälfte überhaupt gar nicht verwendet. `subprocess` sollte vielleicht verwendet werden, denn `os.system()` sollte man *nicht* verwenden. Die Dokumentation der Funktion verweist auf das `subprocess`-Modul. Allerdings würde ich davon abraten ``clear`` aufzurufen. Für so einen Unsinn wird man schnell gehasst wenn man den Leuten einfach so Informationen aus einem Terminal löscht. Man weiss nicht was der Benutzer vorher gemacht hat und was man da weglöscht. Normale Programme löschen da nichts, also kommt das überraschend, und solche Überraschungen sollte man vermeiden. Damit sind wir dann auf nur noch zwei Importe runter.
Sternchen-Importe sind Böse™. Das holt Dir im Fall von Tkinter ca. 190 Namen ins Modul von denen Du nur einen ganz kleinen Bruchteil tatsächlich verwendest. Solche Importe machen den Code unübersichtlicher, weil man nicht mehr so leicht nachvollziehen kann was woher kommt. Zudem besteht die Gefahr von Namenskollisionen. `Tkinter` wird üblicherweise als `tk` importiert und der Modulinhalt dann über diesen Namen referenziert.
Noch mal zu den Kommentaren eine Faustregel: Nicht kommentieren was der Code macht, denn das steht da ja bereits als Code, sondern höchsten *warum* der Code das macht was er macht, aber nur sofern das nicht offensichtlich ist. Diese Abschnittskommentare sind unüblich. Zudem sind die Kommentarzeilen zu lang. Ich weiss, der Style Guide ist da mittlerweile ein bisschen entspannter (bis 120 Zeichen) aber ich persönlich finde 80 immer noch eine wichtige Grenze die einem oft genug begegnet (Terminals, E-Mail-Clients, …) wo alles über 80 Zeichen Probleme mit der Lesbarkeit bereiten kann.
Variablen gehören nicht auf Modulebene. Da gehört nur Code hin der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst. Und zwar das *ganze* Hauptprogramm und die Funktion wird auch erst am Ende aufgerufen. Wenn nachdem die Funktion abgelaufen ist noch GUI-Elemente erstellt werden, dann kann das nicht das Hauptprogramm gewesen sein.
Der
Style Guide for Python Code sagt auch etwas über Namensschreibweisen. klein_mit_unterstrichen für alles ausser Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase). Namen wie `WeAAnAus` und `VWeAZeitS` gehen aber auch unabhängig von der Schreibweise so gar nicht. Namen sollen dem Leser vermitteln was der Wert dahinter bedeutet, also müssen die verständlich sein wenn man die liest und nicht Fragezeichen hinterlassen. Also keine kryptischen Abkürzungen. Besonders Unsinnig wird es, wenn man erst so einen KryAbkNmn schreibt und dann einen Kommentar dazu das das kryptisch abkekürzter Name bedeuten soll. Den Kommentar kann man sich sparen wenn man den Namen gleich passend und lesbar gewählt hätte. Und man wüsste dann nicht nur bei der Definition was der Name bedeutet, weil dort ein Kommentar steht, sondern jedes mal wenn der Name verwendet wird, weiss man auch was er bedeutet, ohne einen Kommentar irgendwo an anderer Stelle suchen zu müssen.
Bei `WeAAnAus` rate ich mal das der Wert aussagen soll ob der Audiowecker scharf geschaltet ist oder nicht. Dann könnte das beispielsweise `is_audio_alarm_armed` oder so ähnlich heissen, damit man das nicht raten muss. Und ganze Zahlen sind dafür der falsche Datentyp. Wenn irgendwo eine 0 zugewiesen wird, erwartet der Leser dass man vielleicht auch 42 oder -23 zuweisen kann. Wenn da `False` zugewiesen wird, dann weiss der Leser das sehr wahrscheinlich nur die Werte `True` und `False` für diese Variable als Wertebereich in Frage kommt.
Die GUI-Elemente und die ”Funktionen” haben das gleiche Problem mit kryptischen Namen und Kommentaren die die erklären müssen. Funktionen und Methoden werden üblicherweise nach Tätigkeiten benannt. `alarm_clock` ist keine Tätigkeit, das wäre ein Name bei dem man einen Wert/ein Objekt erwarten würde der/das einen Wecker repräsentiert, und keine Funktion.
Das `alarm_clock()` den Wert `True` zurück gibt, macht keinen Sinn. Was soll das bedeuten? Die Funktion gibt ja *immer* `True` zurück, nie etwas anderes, das heisst der Aufrufer kann an diesem Wert nichts erkennen oder entscheiden. Im Code machst Du mit diesem Wert ja auch gar nichts.
Funktionen ”Unterprogramme” zu nennen kann auf eine falsche Vorstellung hindeuten, insbesondere wenn die dann alle keine Argumente bekommen und auf globalen Variablen operieren (wollen). Was so wie's da steht auch nicht wirklich funktioniert, weil Namen in Funktion in Python lokal sind sobald irgendwo innerhalb der Funktion eine Zuweisung an den Namen steht. `WeAAnAus` in `PrgAWeAn()` und `PrgAWeAus()` ist ein anderes `WeAAnAus` als das auf Modulebene. Und das ist auch gut so, denn das auf Modulebene sollte dort gar nicht stehen. Wenn eine Funktion einen Wert/Zustand über Aufrufe hinweg ändern/behalten soll, dann braucht man objektorientierte Programmierung (OOP). Da führt in Python spätestens bei GUI-Programmierung kein sinnvoller Weg dran vorbei. Denn alles was Funktionen ausser Konstanten verwenden, sollte als Argument in die Funktion/Methode hinein kommen, und nicht auf ”magische” und damit schwer nachvollziehbare Weise irgendwo global aus der ”Umgebung” kommen.
`place()` ist umständlich, fehleranfällig, und hat das Problem, dass die Angaben nur solange funktionieren, wie die Einstellungen/Anzeigehardware ähnlich genug dem Rechner sind, auf dem das entwickelt und getestet wurde. So etwas macht heute niemand mehr. `pack()` und `grid()` sind viel flexibler und die GUI passt sich automatisch an. Man muss dann auch die Fenstergrösse nicht mehr selber vorgeben. Die GUI lässt sich auch einfacher verändern oder erweitern.
Statt des `time`-Moduls würde ich für die Zeitoperationen das `datetime`-Modul verwenden. `datetime.time`-Objekte kann man beispielsweise miteinander vergleichen und die fassen Stunden und Minuten auch schon zu einem Wert/Objekt zusammen, so dass man das nicht als zwei Einzelwerte behandeln muss.
Last but not least funktioniert GUI-Programmierung nicht mehr so linear wie die `alarm_clock()`-Funktion. Bei einer GUI muss in der Regel die GUI-Hauptschleife laufen um die GUI ”am Leben” zu halten und sich um Ereignisse kümmern zu können und den Programmfluss zu steuern. Der ist ereignisbasiert. Das heisst man programmiert nicht mehr selbst lang laufende Schleifen und bestimmt was wann passiert, sondern man registriert bei der GUI Rückruffunktionen/-methoden die bei bestimmten Ereignissen *kurz* etwas machen und dann die Kontrolle wieder an die GUI-Hauptschleife zurück geben. Solche Ereignisse können das klicken des Benutzers auf eine Schaltfläche sein, aber auch das eine bestimmte Zeit, beispielsweise 10 Sekunden vergangen sind. Man würde also nicht mehr eine Schleife schreiben, die etwas testet und dann 10 Sekunden schläft, sondern eine Funktion/Methode die alle 10 Sekunden von der GUI-Hauptschleife aufgerufen wird und dann kurz etwas testet. In Tk gibt es dafür die `after()`-Methode auf Widgets um so einen (einmaligen) Rückruf nach einer bestimmten Zeit zu registrieren.