2016-06-10 11 views
1

En Python, je voudrais lancer une fonction appelant une action par défaut pendant 20 secondes. Cependant, il y a 5 minutages spécifiques dans ces 20 secondes lorsqu'une autre fonction devrait être déclenchée. Afin de simplifier mon code, j'ai remplacé les fonctions "action" par de simples commandes d'impression.Chronométrage Python pour déclencher des événements spécifiques

Voici ce que j'ai jusqu'à présent - La sortie semble ok, en ce sens qu'elle dure 10 secondes et imprime l'heure et l'état/action par défaut. Mais l'action déclenchée est manquante! Y a-t-il une meilleure façon de faire cela?

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() 

Répondre

0

time.time() retours seconde depuis l'époque comme un nombre à virgule flottante comme:

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

Si votre comparaison:

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

à time.time() est pas correct, jusqu'à la microseconde (cela dépend du système), alors le == ne sera pas Vrai et vous n'obtiendrez jamais votre triggeredAction().

faire des choses par le second si cela fonctionne pour vous, utilisez: int(time.time()) et faire la même chose pour vos uniform_min_range valeurs de retour - en supposant par seconde résolution est ok pour vous. Sinon, vous devrez introduire une plage (+ ou - 1s) à votre vérification d'action déclenchée.

+0

Merci RedCraig! Cela a fonctionné, mais la résolution d'échantillonnage semble plus élevée qu'au niveau de la seconde. Cela signifie que le second 1 est répété pendant un grand nombre de fois. Puis deuxième deux etc. Savez-vous pourquoi cela arrive? – Spica

+0

La raison pour laquelle je demande est que si le second 2 doit déclencher l'action et le second deux est répété, alors l'action sera déclenchée plusieurs fois successivement. Idéalement, le "taux d'échantillonnage" devrait également être chaque seconde. – Spica

+0

Eh bien, le nombre de fois qu'il sera échantillonné par seconde dépend du nombre d'itérations de votre boucle while que votre CPU peut faire en une seconde. Si vous souhaitez que le taux d'échantillonnage soit une fois par seconde, vous pouvez ajouter du code pour le vérifier manuellement. Au lieu de cela, j'utiliserais un objet ['Threading.Timer'] (https://docs.python.org/2/library/threading.html#timer-objects) à la place. Déplacez la boucle 'while' dans une méthode, planifiez la méthode avec un temporisateur, et dans la méthode replanifiez la méthode pour qu'elle s'exécute à nouveau dans une seconde. Comme [this] (http://stackoverflow.com/a/3393759/2175385) réponse fait. – RedCraig