Seite 1 von 1
time.sleep alternative
Verfasst: Mittwoch 26. September 2018, 18:48
von Daniel Schreiber
Hallo, ich habe ein programm, in welchem in einer while schleife ein bild für ein paar sekunden erscheinen soll, während, sobald ich eine taste drücke die jetztige zeit gemessen werden soll. Dafür benutze ich die time.sleep methode. Mein Problem ist allerdings, dass während das bild angezeigt wird, also time.sleep aktiv ist, keine zeit gemessen wird, weil alles schläft, nicht nur das bild. Kennt jemand eine Alternative, um einen delay einzubauen, der nicht global ist, sondern nur bei bestimmten objekten? oder eine möglichkeit, ein bild für nur ein paar sekunden anzuzeigen ?
Ich hoffe, jemand kann mir helfen und bin sehr dankbar für jegliche Vorschläge.
Re: time.sleep alternative
Verfasst: Mittwoch 26. September 2018, 18:50
von Sirius3
Welches Rahmenwerk benutzt Du denn zum Anzeigen?
Re: time.sleep alternative
Verfasst: Mittwoch 26. September 2018, 19:45
von codemode89
Ohne Code schwer zu sagen.
Aber wenn der Thread schläft läuft die Zeit im Universum weiter

und ist über print (datetime.datetime.now()) abzurufen.
Endzeit-Startzeit = vergangene Zeit.
Code: Alles auswählen
import time
import datetime
start_time = datetime.datetime.now()
time.sleep(5)
end_time = datetime.datetime.now()
print("elapsed time: " + str((end_time-start_time)))
Wobei ich denke das time.sleep hier wohl überhaupt nicht gebraucht wird, aber das ist nur eine Vermutung da kein Code vorhanden ist.
Oder ich habe das Problem falsch verstanden
Hier nochmal eine andere delay Methode
Code: Alles auswählen
import datetime
def delay(duration_in_seconds):
current_time = datetime.datetime.now()
end_time = current_time + datetime.timedelta(0,duration_in_seconds)
while current_time<end_time:
current_time = datetime.datetime.now()
print("start: " + str(datetime.datetime.now()))
delay(5)
print("end: " + str(datetime.datetime.now()))
Re: time.sleep alternative
Verfasst: Donnerstag 27. September 2018, 15:47
von Daniel Schreiber
Hallo, ich benutze einen Turtle, der als shape ein entsprechendes Bild hat
Re: time.sleep alternative
Verfasst: Donnerstag 27. September 2018, 15:48
von Daniel Schreiber
Vielen Dank für deine Vorschläge, der code sieht so aus. Es ist so, dass wenn ich am ende die Reaktionszeit anzeigen lassen will, eine Liste erscheint, die exakt die zeitverzögerung enthält, die dem wert von time.sleep entspricht. Das ist natürlich falsch, sie soll ja die differenz zwischen anzeigezeit und drückzeit enthalten. Vielen Dank für alle Antworten
Code: Alles auswählen
f = turtle.Screen()
f.bgcolor("black")
f.title("Reaktionszeittest")
bilder = ["dome.gif","annegret.gif","marcel.gif","andreas.gif","regrecht.gif"]
bild = turtle.Turtle()
bild.hideturtle()
for bild in bilder:
f.register_shape(bild)
zeiten_true = list([])
zeiten_false = list([])
zeiten_dif = list([])
def zeitmessen():
zeiten_false.append(time.time())
f.listen()
turtle.onkey(zeitmessen,"space")
w = True
while w == True:
bild = turtle.Turtle()
bild.hideturtle()
f.update()
if len(zeiten_true) != 3:
time.sleep(3)
bild.shape(random.choice(bilder))
bild.showturtle()
time.sleep(0.85)
bild.hideturtle()
time.sleep(random.randint(2,7))
zeiten_true.append(time.time())
elif len(zeiten_true) == 3:
for i in range(len(zeiten_true)):
zeiten_dif.append(int(zeiten_true[i]) - int(zeiten_false[i]))
print(zeiten_true)
w = False
Re: time.sleep alternative
Verfasst: Donnerstag 27. September 2018, 23:19
von __deets__
Ich blicke da nicht durch. Aber wenn du statt Zeitpunkten Abstände haben willst, dann subtrahier doch deine Zeitpunkte in der Liste voneinander. Oder Merk dir den letzten Zeitpunkt, subtrahier “jetzt”, und setzte jetzt als neue letzten Zeitpunkt.
Re: time.sleep alternative
Verfasst: Freitag 28. September 2018, 00:08
von __blackjack__
@Daniel Schreiber: Bei dem Code fehlen Importe.
`f` ist eine komische Abkürzung für `Screen`. Einbuchstabige Namen sind selten eine gute Idee. Ein Name soll dem Leser vermitteln was der Wert im Programm bedeutet, und nicht zum rätselraten zwingen.
An einen Namen sollten im gleichen Gültigkeitsbereich nur Objekte vom gleichen (Duck) Typ gebunden werden. Das `bild` mal für ein `Turtle`-Objekt und mal für Dateinamen verwendet wird, ist ein wenig verwirrend. Die erste für diesen Namen erstellte Schildkröte wird auch gar nicht verwendet. Das in der ``while``-Schleife immer neue Schildkröten erzeugt und am Ende ”versteckt” werden, ist auch nicht sinnvoll. Da würde man vor der Schleife *eine* erstellen und die bei Bedarf zeigen und verstecken und die Form, also das angezeigte Bild ändern.
``list([])`` ist ein komisches Konstrukt. Entweder ``list()`` *oder* ``[]``, aber beides kombiniert macht wenig Sinn.
Bei dem ``if``/``elif`` in der ``while``-Schleife ist die ``elif``-Bedingung genau dann wahr wenn die ``if``-Bedingung nicht mehr wahr ist. dafür gibt es ``else``. Wobei die ``while``-Schleife selbst aber schon zu umständlich ist mit dem `w`-Flag und dem Prüfen der Listenlänge. Du willst die Schleife genau 3× durchlaufen, das macht man mit einer ``for``-Schleife.
Code wie ``for i in range(len(zeiten_true)):`` ist in Python ein „anti pattern“. Man kann über Elemente von Sequenzen *direkt* iterieren, ohne den Umweg über einen Laufindex. Wenn man über ”parallele” Sequenzen iterieren möchte gibt es die `zip()`-Funktion.
Da hier eine leere Liste mit Werten befüllt werden soll, bietet sich zudem die „list comprehension“-Syntax an.
Auf Modulebene gehört nur Code der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst. Funktionen (und Methoden) sollten alles was sie ausser Konstanten benötigen als Argumente übergeben bekommen.
Zwischenstand wäre dann ungefähr das hier:
Code: Alles auswählen
#!/usr/bin/env python3
import random
import time
import turtle
from functools import partial
def zeitmessen(zeiten_false):
zeiten_false.append(time.time())
def main():
screen = turtle.Screen()
screen.bgcolor('black')
screen.title('Reaktionszeittest')
bild_dateinamen = [
'dome.gif', 'annegret.gif', 'marcel.gif', 'andreas.gif', 'regrecht.gif'
]
for dateiname in bild_dateinamen:
screen.register_shape(dateiname)
zeiten_true = list()
zeiten_false = list()
screen.listen()
turtle.onkey(partial(zeitmessen, zeiten_false), 'space')
bild = turtle.Turtle()
bild.hideturtle()
for _ in range(3):
time.sleep(3)
bild.shape(random.choice(bild_dateinamen))
bild.showturtle()
time.sleep(0.85)
bild.hideturtle()
time.sleep(random.randint(2, 7))
zeiten_true.append(time.time())
zeiten_diff = [
int(zeit_true) - int(zeit_false)
for zeit_true, zeit_false in zip(zeiten_true, zeiten_false)
]
print(zeiten_true)
if __name__ == '__main__':
main()
Das Problem bei `time.sleep()` ist, das die GUI-Hauptschleife dann nicht läuft und damit auch nicht auf den Tastendruck reagieren kann. Du musst dafür `turtle.mainloop()` aufrufen. Was aber bedeutet das Du Deine ``while``-Schleife nicht gleichzeitig laufen lassen kannst, was wiederum bedeutet, das Du das über `turtle.ontimer()` lösen musst, was wiederum bedeutet, das man das sauber nur über objektorientierte Programmierung lösen kann.
Re: time.sleep alternative
Verfasst: Freitag 28. September 2018, 22:58
von Daniel Schreiber
Wow, echt nett von dir, das so ausführlich zu betrachten. Warum braucht es am Ende "if __name__ == '__main__': main()", anstatt einfach "main()" aufzurufen?
Re: time.sleep alternative
Verfasst: Freitag 28. September 2018, 23:34
von __blackjack__
@Daniel Schreiber: Weil das dann auch aufgerufen wird wenn `__name__` nicht den Wert '__main__' hat. Also auch dann wenn man das Modul einfach nur importiert, statt es als Programm auszuführen.