zeit different

Fragen zu Tkinter.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Hallo,
ich möchte gerne zeit differenz berechnen, ich habe 2 buttons start und stop, dabei möchte ich die zeit in sec berechnen die vergeht zwischen klick auf die 2 buttons.
Leider hänge ich fest beim Ergebnis, vielleicht hat jemand so etwas schon gehabt und gelöst.

Code: Alles auswählen

def start():
	time1 = datetime.now()
        #2016-05-06 17:14:04.183500
	return t1

def stop():
        time2 = datetime.now()
        #2016-05-06 17:14:06.032784
        diff = t2 - start()
       print (diff)
       #-1 day, 23:59:59.999958  # wie kann ich das hier in sec, msec umwandeln
       #print (diff).total_seconds()
       #-5.6e-05 # bekomme das
wie bekomme ich als Ergebnis 2,15
was mache ich hier falsch, warum klappt es nicht, es soll auf einem raspberry laufen?

Danke

Gruß
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@ganja: Du rufst die start() Funktion in der stop() Funktion auf; daher entspricht das Resultat nicht dem, was Du messen möchtest. Zur Formatierung verfügen datetime-Objekte über die strftime() Methode.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

wenn ich das benutze
t1=time.strftime('%H:%M:%S')

print (t2 - start())
bekomme ich diesen Fehler
TypeError: unsupported operand type(s) for -: 'str' and 'str'
BlackJack

@ganja: Was ja auch irgendie klar sein sollte. Was hättest Du denn anderes erwartet?

Du musst die Zeiten voneinander abziehen, nicht die Zeichenkettendarstellung von Zeiten.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

habt ihr ein bsp. vielleicht, ich komme nicht auf die Lösung
BlackJack

@ganja: In der Dokumentation zum `datetime`-Modul gibt es sogar Beispiele.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@ganja: wo wird denn start() und stop() aufgerufen? Was machst Du dann mit den Rückgabewerten?
Bei Deinem gezeigten Code stimmt die Einrückung und die Variablennamen nicht. Computer sind unkreativ. Wenn Du ihnen nicht exakte Anweisungen gibts, zucken sie nur mit den Schultern und tun nichts.
BlackJack

Bezüglich Beispiele könnte man auch selber einfach mal ein bisschen ausprobieren.

Code: Alles auswählen

In [5]: from datetime import datetime as DateTime

In [6]: DateTime.now() - DateTime.now()
Out[6]: datetime.timedelta(-1, 86399, 999982)

In [7]: print DateTime.now() - DateTime.now()
-1 day, 23:59:59.999983

In [8]: print -(DateTime.now() - DateTime.now())
0:00:00.000017

In [9]: td = -(DateTime.now() - DateTime.now())

In [10]: td.total_seconds()
Out[10]: 1.5e-05

In [11]: print td.total_seconds()
1.5e-05

In [12]: format(td.total_seconds(), '.50f')
Out[12]: '0.00001500000000000000038001286145616930411961220670'

In [13]: td.
td.days           td.microseconds   td.resolution     td.total_seconds
td.max            td.min            td.seconds        

In [13]: td.seconds
Out[13]: 0

In [14]: td.microseconds
Out[14]: 15
BlackJack

Mal eine eher funktionale Variante einer Stoppuhr in Hy. :-)
[codebox=clojure file=Unbenannt.txt]#!/usr/bin/env hy
(import
[collections [namedtuple]]
[datetime [datetime :as DateTime timedelta :as TimeDelta]]
[functools [partial]]
[Tkinter :as tk]
[Tkinter [*left* *top*]])

(def *zero-timedelta* (TimeDelta))


(def now (. DateTime utcnow))


(def Stopwatch (namedtuple "Stopwatch" "start_time elapsed_time"))

(defn make-stopwatch []
(reset-stopwatch (Stopwatch None None)))

(defn running-stopwatch? [stopwatch]
(not (none? (. stopwatch start-time))))

(defn get-elapsed-time-stopwatch [stopwatch]
(+ (. stopwatch elapsed-time)
(if (running-stopwatch? stopwatch)
(- (now) (. stopwatch start-time))
*zero-timedelta*)))

(defn reset-stopwatch [stopwatch]
((if (running-stopwatch? stopwatch) start-stopwatch identity)
(Stopwatch (. stopwatch start-time) *zero-timedelta*)))

(defn start-stopwatch [stopwatch]
(Stopwatch (now) (. stopwatch elapsed-time)))

(defn stop-stopwatch [stopwatch]
(Stopwatch None (get-elapsed-time-stopwatch stopwatch)))

(defn toggle-stopwatch [stopwatch]
((if (running-stopwatch? stopwatch) stop-stopwatch start-stopwatch)
stopwatch))


(defn make-stopwatch-ui [parent stopwatch]
(setv ui {}
frame (tk.Frame parent)
timer-id None
elapsed-time-label (tk.Label frame)
button-frame (tk.Frame frame)
toggle-button
(tk.Button frame :command (partial do-something ui toggle-stopwatch))
reset-button
(tk.Button
frame
:text "Reset"
:command (partial do-something ui reset-stopwatch)))

(.pack elapsed-time-label :side *top*)
(.pack toggle-button :side *left*)
(.pack reset-button :side *left*)
(.pack button-frame :side *top*)

(.update ui
{:frame frame
:stopwatch stopwatch
:timer-id timer-id
:elapsed-time-label elapsed-time-label
:toggle-button toggle-button})
(update-ui ui)
ui)

(defn -update-elapsed-time [ui]
(update-elapsed-time ui)
(assoc ui :timer-id (.after (:frame ui) 100 -update-elapsed-time ui)))

(defn update-elapsed-time [ui]
(assoc (:elapsed-time-label ui)
"text" (get-elapsed-time-stopwatch (:stopwatch ui))))

(defn update-ui [ui]
(update-elapsed-time ui)
(setv running? (running-stopwatch? (:stopwatch ui)))
(assoc (:toggle-button ui) "text" (if running? "Stop" "Start"))
(setv timer-id (:timer-id ui))
(if running?
(when (none? timer-id) (-update-elapsed-time ui))
(unless (none? timer-id)
(.after-cancel (:frame ui) timer-id)
(assoc ui :timer-id None))))

(defn do-something [ui func]
(assoc ui :stopwatch (func (:stopwatch ui)))
(update-ui ui))


(defmain [&rest args]
(setv root (tk.Tk))
(.title root "Stoppuhr")
(setv ui (make-stopwatch-ui root (make-stopwatch)))
(.pack (:frame ui))
(.mainloop root))[/code]
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Jedesmal wenn ich Lisp Code sehe bin ich wieder enttäuchst dass man in anderen Sprachen nicht - als Teil des Namens nehmen kann :/ Dabei wäre es so einfach Whitespace zu erzwingen und - in Namen zu erlauben.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Hallo,
das sieht gut aus @blackjack leider weiß ich nicht was .hy ist, habe dann google gefragt, habe es mal versucht auf ubuntu auszuführen hat leider nicht geklappt da tkinter nicht gefunden werden kann, vielen dank für die ganzen Beispiele mit Date.

Hier habe ich etwas neues, soll eine art Stoppuhr sein, man soll aber nicht sehen das die Uhr läuft, ich möchte das über taste 's' starten, stoppen, reset, im moment habe ich es leider an taste 's'-start,'d'-stop,'r'-reset, komme nicht dahinter wie alles mit taste 's' gehen soll, denke mal das ich einen Zähler brauche der die Eingabe der taste zählt! Bin mir aber nicht sicher. Und beim start läuft die zeit halt, das weis ich im moment auch nicht wie ich das mache das die zeit nur im Hintergrund läuft und erst bei stop die zeit angezeigt wird
Hier mein code, Vielen Dank an alle die sich hier beteiligen, mir als Anfänger hilft das sehr viel.

Code: Alles auswählen


#!/usr/bin/python
# -*- coding: utf-8 -*

import Tkinter as tk
import numpy as np
#import os

state = False


def update_timeText():
	if (state):
		global timer
		timer[2] += 1
        
		if (timer[2] >= 100):
			timer[2] = 0
			timer[1] += 1
      
		if (timer[1] >= 60):
			timer[0] += 1
			timer[1] = 0
            
		timeString = pattern.format(timer[0], timer[1], timer[2]) 
		timeText.configure(text=timeString)
	root.after(10, update_timeText)


def sKey(event):
	print "s"
	if True:
		global state
		state = True

def dKey(event):
	#print "d"
	if True:
		global state
		state = False

	#print "Zeit: ", timer
	ergString = np.array(vorgabe) - np.array(timer)
	ergString =  str(ergString[-2]) +":"+ str(ergString[-1])
	#print "ergebnis: ", ergString
 
	ergText.configure(text=ergString)
	
def rKey(event):
	global timer
	timer = [0, 0, 0]
	timeText.configure(text='00:00:00')
	

root = tk.Tk()
root.title('Wie gut bist du?')
root.configure(background='yellow')
root.geometry("1020x815+0+0")#+24+10

vorgabe = [0, 5, 100]
timer = [0, 0, 0]

pattern = '{0:02d}:{1:02d}:{2:02d}'

frame = tk.Frame(root, background='yellow', relief=tk.SUNKEN, border=2)
frame.pack(fill=tk.X, pady=1)
info_label = tk.Label(frame, text='Vorgabe 5 Sekunden', justify=tk.LEFT, font="bold", bg='white',width=50)
info_label.pack()


timeText = tk.Label(root, text="00:00:00", font=("Helvetica", 150),background='yellow')
timeText.pack()

frame1 = tk.Frame(root, background='yellow', relief=tk.SUNKEN, border=2)
frame1.pack(fill=tk.X, pady=1)
ergText = tk.Label(frame1, text="", justify=tk.LEFT, font=("Helvetica", 50), bg='yellow',width=50)
ergText.pack()

#frame2 = tk.Frame(root, background='red', relief=tk.SUNKEN, border=2)
#frame2.pack(fill=tk.X, pady=1)
#info_label = tk.Label(frame2, text="", justify=tk.LEFT, font=("Helvetica", 50), bg='yellow',width=50)
#info_label.pack()

root.bind('<s>', sKey)
root.bind('<d>', dKey)
root.bind('<r>', rKey)
root.focus_set()

update_timeText()
root.mainloop()

BlackJack

Hy ist ein Lisp-Dialekt und in Python implementiert: http://docs.hylang.org/en/stable/

Du solltest vielleicht mal objektorientierte Programmierung lernen. Eventuell unabhängig vom aktuellen Problem. Denn das alles auf Modulebene zu schreiben und mit ``global`` zu arbeiten führt zu nichts gutem. ``global`` ist eigentlich immer ein Problem und keine Lösung.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

@blackjack das versuche ich, aber das alter, ist halt nicht einfach.
warum wird dann tkinter nicht gefunden in ubuntu bei hylang
BlackJack

@ganja: tkinter wird ja gar nicht gesucht sondern Tkinter. Und falls das nicht gefunden wird hast Du vielleich Hy für Python 3 installiert‽
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

das habe ich gemacht:
sudo apt-get install hy

das habe ich
Python 2.7.11+ (default, Apr 17 2016, 14:00:29)
hy 0.11.1 using CPython(default) 3.5.1+ on Linux

fehler
Traceback (most recent call last):
File "/usr/bin/hy", line 9, in <module>
load_entry_point('hy==0.11.1', 'console_scripts', 'hy')()
File "/usr/lib/python3/dist-packages/hy/cmdline.py", line 347, in hy_main
sys.exit(cmdline_handler("hy", sys.argv))
File "/usr/lib/python3/dist-packages/hy/cmdline.py", line 335, in cmdline_handler
return run_file(options.args[0])
File "/usr/lib/python3/dist-packages/hy/cmdline.py", line 210, in run_file
import_file_to_module("__main__", filename)
File "/usr/lib/python3/dist-packages/hy/importer.py", line 78, in import_file_to_module
eval(ast_compile(_ast, fpath, "exec"), mod.__dict__)
File "./zeitdifferent.hy", line 2, in <module>
(import
ImportError: No module named 'Tkinter'
BlackJack

@ganja: Das ist ziemlich eindeutig Python 3 für das Hy installiert ist.

Die beiden Vorkommen von Tkinter am Anfang in tkinter umbenennen reicht aus um das mit Hy für Python 3 auszuführen.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Guten Morgen,

@BlackJack Vielen Dank für den tip mit umbenennen läuft ist echt cool das es so etwas gibt.
Ich habe leider nicht jeden tag zeit um zu Programmieren, ich habe alle paar Monate 2-3 Tage dafür zeit, muß aber jetzt öfter mir die zeit nehmen.

Ich würde gerne für meine Kinder und mich das fertig stellen was ich bis jetzt habe, leider komme ich im moment nicht weiter wie lass ich den timer im Hintergrund laufen wenn start gedrückt wird, es sollen nur 00:00:00 angezeigt werden erst bei stop soll die zeit angezeigt werden zb. 00:04.98. Damit will ich die Kinder einwenig beschäftigen und ärgern :)

Wie du @BlackJack gesagt hast ich sollte objektprogrammiert lernen, ich werde versuchen das was ich bis jetzt habe umzuschreiben, vielleicht könnt ihr mir noch ein tip geben, ich schreibe das alles mit texteditor(kwrite), gibt es vielleicht eine Umgebung die mir einwenig die Arbeit erleichtert?

Danke

Gruß
ganja
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@ganja: Wenn Du nur die Zeitdifferenz am Ende anzeigen willst, brauchst Du selbst ja gar nichts im Hintergrund zu tun, weil die Uhr läuft automatisch mit. Also quasi nur:

Code: Alles auswählen

def start_key(self, event):
    self.start_time = datetime.datetime.now()

def stop_key(self, event):
    time_diff = datetime.datetime.now() - self.start_time
    self.timeText.configure(text=str(time_diff))
BlackJack

Ich hatte in meiner Hy-Stopuhr `utcnow()` verwendet, sonst kann es passieren das die zweimal im Jahr zu bestimmten Zeiten nicht so funktioniert wie man das erwartet. :-D
BlackJack

Mal mit Trennung von Geschäftslogik und GUI:

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf-8
from __future__ import absolute_import, division, print_function
import Tkinter as tk
from datetime import datetime as DateTime, timedelta as TimeDelta


class Stopwatch(object):

    def __init__(self):
        self.start_time = None
        self.elapsed_time = TimeDelta()

    def __str__(self):
        return str(self.elapsed_time)

    @property
    def is_running(self):
        return bool(self.start_time)

    def start(self):
        self.start_time = DateTime.utcnow()
        self.elapsed_time = TimeDelta()

    def stop(self):
        self.elapsed_time = DateTime.utcnow() - self.start_time
        self.start_time = None

    def toggle(self):
        if self.is_running:
            self.stop()
        else:
            self.start()


class StopwatchUI(tk.Frame):

    def __init__(self, parent, stopwatch):
        tk.Frame.__init__(self, parent)
        self.stopwatch = stopwatch
        self.display = tk.Label(self)
        self.display.pack(side=tk.TOP)
        self.toggle_button = tk.Button(self, command=self.do_toggle)
        self.toggle_button.pack(side=tk.TOP)
        self.update_display()

    def update_display(self):
        self.display['text'] = self.stopwatch
        self.toggle_button['text'] = (
            'Stop' if self.stopwatch.is_running else 'Start'
        )

    def do_toggle(self):
        self.stopwatch.toggle()
        self.update_display()


def main():
    root = tk.Tk()
    root.title('Zeit stoppen')
    ui = StopwatchUI(root, Stopwatch())
    ui.pack()
    root.mainloop()


if __name__ == '__main__':
    main()
Antworten