Stopuhr und Alarm

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
d.straub
User
Beiträge: 9
Registriert: Samstag 28. Januar 2023, 13:43

Ich habe das eigentlich nur zum Spaß gemacht und weil Windows kein Alarm mit Sekunden integriert hat. Hab das mit chat gpt zusammen gemacht.


import tkinter as tk
import time
from tkinter import messagebox

root = tk.Tk()
root.title("Stopwatch/Alarm Clock")

time_var = tk.StringVar()
time_var.set("0:00.00")

label = tk.Label(root, textvariable=time_var, font=("Helvetica", 20))
root.geometry("800x600+{}+{}".format(int((root.winfo_screenwidth()/2)-400), int((root.winfo_screenheight()/2)-300)))


start_time = None
alarm_time = None

def start_stopwatch():
global start_time
start_time = time.time()
tick()

def set_alarm():
global alarm_time
try:
alarm_time = time.time() + int(entry.get())
alarm_label.config(text="Alarm is set for {} seconds from now".format(int(alarm_time - time.time())))
except ValueError:
messagebox.showinfo("Error", "Please enter a valid number.")

def stop_stopwatch():
global start_time
start_time = None

def reset_stopwatch():
global start_time
start_time = None
time_var.set("0:00.00")

def tick():
if start_time:
elapsed_time = time.time() - start_time
m, s = divmod(elapsed_time, 60)
ms = int((s - int(s)) * 100)
time_var.set("{:02d}:{:02d}.{:02d}".format(int(m), int(s), ms))
root.after(10, tick)

def check_alarm():
global alarm_time
if alarm_time:
remaining_time = alarm_time - time.time()
if remaining_time > 0:
alarm_label.config(text="Alarm is set for {} seconds from now".format(int(remaining_time)))
elif remaining_time <= 0:
messagebox.showinfo("Alarm", "Wake up!")
alarm_time = None
alarm_label.config(text="Alarm is not set")
root.after(1000, check_alarm)

def switch_to_stopwatch():
label.pack()
start_button.pack()
stop_button.pack()
reset_button.pack()
alarm_label.pack_forget()
entry.pack_forget()
set_alarm_button.pack_forget()
alarm_button.config(state="normal")
stopwatch_button.config(state="disabled")


def switch_to_alarm():
label.pack_forget()
start_button.pack_forget()
stop_button.pack_forget()
reset_button.pack_forget()
alarm_label.pack()
entry.pack()
set_alarm_button.pack()
alarm_button.config(state="disabled")
stopwatch_button.config(state="normal")

start_button = tk.Button(root, text="Start", command=start_stopwatch)
stop_button = tk.Button(root, text="Stop", command=stop_stopwatch)
reset_button = tk.Button(root, text="Reset", command=reset_stopwatch)
alarm_label = tk.Label(root, text="Enter time in seconds:")
entry = tk.Entry(root)
set_alarm_button = tk.Button(root, text="Set Alarm", command=set_alarm)

stopwatch_button = tk.Button(root, text="Stop watch", command=switch_to_stopwatch)
alarm_button = tk.Button(root, text="Alarm", command=switch_to_alarm)

label.pack()
start_button.pack()
stop_button.pack()
reset_button.pack()
stopwatch_button.pack(side="left")
alarm_button.pack(side="right")

root.after(10, tick)
root.after(1000, check_alarm)
root.mainloop()
Benutzeravatar
Axel-WAK
User
Beiträge: 62
Registriert: Dienstag 29. November 2022, 11:52

Nutze für Code bitte den Code Button </>
OS: LMDE5 *** Homepage *** Github Seite
d.straub
User
Beiträge: 9
Registriert: Samstag 28. Januar 2023, 13:43

OK werde ich nächstes mal machen.
Benutzeravatar
sparrow
User
Beiträge: 4165
Registriert: Freitag 17. April 2009, 10:28

@d.straub: Ich bin beim der ersten Verwendung von "global" ausgestiegen.
Funktionen bekommen alles, was sie zum Arbeiten gebrauchen, als Parameter und geben das Ergebnis mit return zurück. Ich sehe in deinem Code viele "global" und kein einziges "return". Das heißt, du verwendest Funkltionen völlig falsch.

Jedes nicht triviale GUI-Programm ist auf Objektoriente Programmierung angewiesen.

Also: Nee, nicht so schön. Da hat dich ChatGPT schlecht beraten.
Benutzeravatar
__blackjack__
User
Beiträge: 13006
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Weitere Anmerkung `time.time()` ist für so etwas falsch, weil das im Gegensatz zu `time.monotonic()` nicht garantiert das die Zeit nur ”vorwärts” läuft.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
d.straub
User
Beiträge: 9
Registriert: Samstag 28. Januar 2023, 13:43

sparrow hat geschrieben: Samstag 28. Januar 2023, 21:20 @d.straub: Ich bin beim der ersten Verwendung von "global" ausgestiegen.
Funktionen bekommen alles, was sie zum Arbeiten gebrauchen, als Parameter und geben das Ergebnis mit return zurück. Ich sehe in deinem Code viele "global" und kein einziges "return". Das heißt, du verwendest Funkltionen völlig falsch.

Jedes nicht triviale GUI-Programm ist auf Objektoriente Programmierung angewiesen.

Also: Nee, nicht so schön. Da hat dich ChatGPT schlecht beraten.
Autsch das sitzt und ich versteh noch nichtmal die hälfte deiner Kritik. Ich bin aber so schlecht im progammieren das ich es ohne chatGPT nicht hingekriegt hätte. Aber Danke das du mich aufklärst das der Code schlecht ist. Ich glaube auch ein guter Progammierer hätte es besser in kürzerer Zeit geschrieben, weil ich hab bestimmt 3 Stunden dran gesessen. Es war ein hin und her mit der KI.
d.straub
User
Beiträge: 9
Registriert: Samstag 28. Januar 2023, 13:43

Code: Alles auswählen

import tkinter as tk
import time
from tkinter import messagebox

root = tk.Tk()
root.title("Stopwatch/Alarm Clock")

time_var = tk.StringVar()
time_var.set("0:00.00")

label = tk.Label(root, textvariable=time_var, font=("Helvetica", 20))
root.geometry("800x600+{}+{}".format(int((root.winfo_screenwidth()/2)-400), int((root.winfo_screenheight()/2)-300)))


start_time = None
alarm_time = None


def start_stopwatch():
    global start_time
    start_time = time.monotonic()
    tick()


def set_alarm():
    global alarm_time
    try:
        alarm_time = time.monotonic() + int(entry.get())
        alarm_label.config(text="Alarm is set for {} seconds from now".format(int(alarm_time - time.monotonic())))
    except ValueError:
        messagebox.showinfo("Error", "Please enter a valid number.")


def stop_stopwatch():
    global start_time
    start_time = None


def reset_stopwatch():
    global start_time
    start_time = None
    time_var.set("0:00.00")


def tick():
    if start_time:
        elapsed_time = time.monotonic() - start_time
        m, s = divmod(elapsed_time, 60)
        ms = int((s - int(s)) * 100)
        time_var.set("{:02d}:{:02d}.{:02d}".format(int(m), int(s), ms))
        root.after(10, tick)


def check_alarm():
    global alarm_time
    if alarm_time:
        remaining_time = alarm_time - time.monotonic()
        if remaining_time > 0:
            alarm_label.config(text="Alarm is set for {} seconds from now".format(int(remaining_time)))
        elif remaining_time <= 0:
            messagebox.showinfo("Alarm", "Wake up!")
            alarm_time = None
            alarm_label.config(text="Alarm is not set")
    root.after(1000, check_alarm)


def switch_to_stopwatch():
    label.pack()
    start_button.pack()
    stop_button.pack()
    reset_button.pack()
    alarm_label.pack_forget()
    entry.pack_forget()
    set_alarm_button.pack_forget()
    alarm_button.config(state="normal")
    stopwatch_button.config(state="disabled")


def switch_to_alarm():
    label.pack_forget()
    start_button.pack_forget()
    stop_button.pack_forget()
    reset_button.pack_forget()
    alarm_label.pack()
    entry.pack()
    set_alarm_button.pack()
    alarm_button.config(state="disabled")
    stopwatch_button.config(state="normal")


start_button = tk.Button(root, text="Start", command=start_stopwatch)
stop_button = tk.Button(root, text="Stop", command=stop_stopwatch)
reset_button = tk.Button(root, text="Reset", command=reset_stopwatch)
alarm_label = tk.Label(root, text="Enter time in seconds:")
entry = tk.Entry(root)
set_alarm_button = tk.Button(root, text="Set Alarm", command=set_alarm)

stopwatch_button = tk.Button(root, text="Stop watch", command=switch_to_stopwatch)
alarm_button = tk.Button(root, text="Alarm", command=switch_to_alarm)

label.pack()
start_button.pack()
stop_button.pack()
reset_button.pack()
stopwatch_button.pack(side="left")
alarm_button.pack(side="right")

root.after(10, tick)
root.after(1000, check_alarm)
root.mainloop()
Zuletzt geändert von d.straub am Sonntag 29. Januar 2023, 00:17, insgesamt 1-mal geändert.
d.straub
User
Beiträge: 9
Registriert: Samstag 28. Januar 2023, 13:43

Ich hab es jetzt doch noch richtig nachgepostet, sonst ist es ja echt unnütze. Weil das Programm funktioniert ja, auch wenn es anscheinend schlecht programmiert ist.
Benutzeravatar
__blackjack__
User
Beiträge: 13006
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@d.straub: Kommt ein bisschen auf die Definition von “funktioniert“ an. `time.time()` funktioniert halt nur so fast. Und das mit den ganzen ``global`` ist halt auch falsch. Nicht alles was funktioniert ist dadurch automatisch richtig.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
d.straub
User
Beiträge: 9
Registriert: Samstag 28. Januar 2023, 13:43

__blackjack__ hat geschrieben: Sonntag 29. Januar 2023, 00:06 @d.straub: Kommt ein bisschen auf die Definition von “funktioniert“ an. `time.time()` funktioniert halt nur so fast. Und das mit den ganzen ``global`` ist halt auch falsch. Nicht alles was funktioniert ist dadurch automatisch richtig.
Also habe die time.time() jetzt mit time.monotonic() ausgetauscht. Muss jetzt mal gucken was ich mit den global mache.
d.straub
User
Beiträge: 9
Registriert: Samstag 28. Januar 2023, 13:43

Da ChatGPT eh das meiste programmiert hat bekommt ihr jetzt auch die Antwort von der streitfreudigen KI:
In diesem Code werden die globalen Variablen start_time und alarm_time verwendet, um den Startzeitpunkt der Stoppuhr und die Alarmzeit zu speichern. Durch das Verwenden von globalen Variablen wird sichergestellt, dass dieselben Variablen in verschiedenen Funktionen verwendet werden können, anstatt jeweils eine lokale Kopie der Variablen in jeder Funktion zu erstellen.
Es gibt keine Rückgabewerte, da der Code hauptsächlich GUI-Elements erstellt und verwaltet und keine Berechnungen durchführt, die einen Rückgabewert erfordern.
Es gibt jedoch auch noch andere Möglichkeiten die Variablen zu speichern, z.B. man könnte die Variablen als Argumente in die Funktionen übergeben und dann in der Funktion verwenden und ändern.

Es kann jedoch sein, dass die Verwendung von globalen Variablen und das Fehlen von "return"-Anweisungen für manche Entwickler ungewöhnlich ist und sie in ihrer Arbeitsweise unvorteilhaft finden. Es ist jedoch wichtig zu beachten, dass es keine allgemein anerkannten "richtigen" oder "falschen" Möglichkeiten gibt, Code zu schreiben und dass es oft mehrere gültige Ansätze für ein bestimmtes Problem gibt.
d.straub
User
Beiträge: 9
Registriert: Samstag 28. Januar 2023, 13:43

Hab ich es jetzt richtig verstanden das ich die "global" nur so flasch verwenden konnte weil ich gar keine Rückgabewerte habe und brauche?

Ich weiß jetzt wieso time.time() statt time.monotonic() verwendet wurde: weil time.monotonic() nur in Python 3.3 und höher verfügbar ist. time.time() ist vielleicht veraltet aber geht dafür auch in ältern version. ich lasse jetzt aber time.monotonic().
Zuletzt geändert von d.straub am Sonntag 29. Januar 2023, 01:00, insgesamt 1-mal geändert.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was sagt den ChatGPT zu der Frage?
d.straub
User
Beiträge: 9
Registriert: Samstag 28. Januar 2023, 13:43

__deets__ hat geschrieben: Sonntag 29. Januar 2023, 00:46 Was sagt den ChatGPT zu der Frage?
"Ja, das ist richtig. Da Sie die Variablen start_time, alarm_time, label, start_button, stop_button und reset_button nur innerhalb der Methoden der Stopwatch-Klasse verwenden und nicht zurückgeben, benötigen Sie keine globalen Variablen. Es ist ausreichend, diese Variablen als Attribute der Stopwatch-Instanz zu speichern.

Wenn Sie jedoch eine Variable innerhalb einer Methode verwenden und sie außerhalb der Methode zurückgeben oder speichern möchten, müssten Sie sie als globale Variable deklarieren."
Antworten