2016-06-10 18 views
1

In Python möchte ich eine Funktion ausführen, die eine Standardaktion für 20 Sekunden aufruft. Innerhalb dieser 20 Sekunden gibt es jedoch 5 spezifische Zeiten, wenn eine andere Funktion ausgelöst werden soll. Um meinen Code zu vereinfachen, habe ich die "Action" -Funktionen durch einfache Druckbefehle ersetzt.Python Timing um bestimmte Ereignisse auszulösen

Hier ist, was ich bisher - Die Ausgabe scheint in Ordnung, in dem es für 10 Sekunden dauert und druckt die Zeit und den Standardzustand/Aktion. Aber die ausgelöste Aktion fehlt! Gibt es einen besseren/richtigen Weg, dies zu tun?

import random 
import time 
import numpy as np 
import itertools 

def uniform_min_range(a, b, n, min_dist): 
    while True: 
     atimes = np.random.uniform(a, b, size=n) 
     np.sort(atimes) 
     if np.all(np.diff(atimes) >= min_dist): 
      return atimes 

def timings(): 
    global times 
    times = uniform_min_range(0, 20, 5, 1.0) 
    print 'beep times: ', times 

def defaultAction(): 
    global start 
    print 'wobble' 

def triggeredAction(): 
    global start 
    print 'actionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn' 

def main(): 
    global times 
    timings() 
    print 'beep times: ', times 
    start = time.time() 
    t_end = time.time() + 20 #### end after 20 seconds 
    while time.time() < t_end: #### for 20 sec/ until end reached 
     print str(time.time()-start) 
     if (time.time()-start) == times[0] or (time.time()-start) == times[1] or (time.time()-start) == times[2] or (time.time()-start) == times[3]: 
      triggeredAction() 
     elif (time.time()-start) != times[0] or (time.time()-start) != times[1] or (time.time()-start) != times[2] or (time.time()-start) != times[3]: 
      defaultAction() 

    print "END" 

main() 

Antwort

0

time.time() kehrt zweite seit Epoche als Gleitkommazahl wie:

>>> import time 
>>> time.time() 
1465572505.891256 

Wenn Ihr Vergleich:

time.time()-start) == times[0]

zu time.time() ist nicht korrekt auf die Mikrosekunde nach unten (das hängt vom System ab), dann wird == nicht True sein und du wirst nie deinebekommen.

Dinge tun durch die zweite, wenn das für Sie arbeitet, Verwendung: int(time.time()) und das Gleiche tun für Ihre uniform_min_range Rückgabewerte - pro Sekunde Auflösung der Annahme ist für Sie in Ordnung. Andernfalls müssen Sie einen Bereich (+ oder - 1s) zu Ihrer ausgelösten Aktionsprüfung hinzufügen.

+0

Danke RedCraig! Es hat funktioniert, aber die Sampling-Auflösung scheint höher zu sein als auf der Ebene der zweiten. Dies bedeutet, dass die zweite 1 für viele Male wiederholt wird. Dann die zweiten zwei usw. Weißt du, warum das passiert? – Spica

+0

Der Grund, warum ich frage, ist, dass, wenn zweite 2 die Aktion auslösen sollte und zweite zwei wiederholt wird, dann die Aktion mehrmals nacheinander ausgelöst wird. Idealerweise sollte die "Abtastrate" auch jede Sekunde sein. – Spica

+0

Nun, die Häufigkeit, mit der es pro Sekunde abgetastet wird, hängt von der Anzahl der Iterationen Ihrer while-Schleife ab, die Ihre CPU in einer Sekunde ausführen kann. Wenn Sie möchten, dass die Abtastrate einmal pro Sekunde ist, können Sie Code hinzufügen, um es manuell zu überprüfen. Stattdessen würde ich stattdessen ein ['Threading.Timer'] (https://docs.python.org/2/library/threading.html#timer-objects) -Objekt verwenden. Verschieben Sie die while-Schleife in eine Methode, planen Sie die Methode mit einem Timer, und planen Sie die Methode in der Methode so ein, dass sie in einer weiteren Sekunde erneut ausgeführt wird. Wie [this] (http://stackoverflow.com/a/3393759/2175385) antwortet. – RedCraig