如果条件在某段时间内保持为false,则Python会中断

时间:2014-07-21 16:29:02

标签: python

我正在编写一个用于实时音高检测的程序。这是代码的大纲: -

def pitch_detection :

    result = []
    while True :

        // apply pitch detection algorithm

        if pitch_energy > threshold :
            result.append(pitch)

    return result       

如果有pitch_energy > threshold False

,我想在循环中播放

我现在正在做的是在一段时间后超时循环。 像这样 :- How would I stop a while loop after n amount of time?

2 个答案:

答案 0 :(得分:3)

每当您附加到列表时节省时间。然后将其与您未进行更正的当前时间进行比较。如果您上次进行追加的时间大于某个阈值,则会中断:

def pitch_detection :

    result = []
    start = time.time()
    MAX_TIME_ALLOWED = 5 # seconds
    while True :

        // apply pitch detection algorithm

        if pitch_energy > threshold :
            result.append(pitch)
            start = time.time() # reset the time when we append.
        else:
            if (time.time() - start) > MAX_TIME_ALLOWED:
                break

    return result 

这假设您实际上想要使用经过的时间来决定何时休息。如果你想使用循环的迭代次数,只需使用一个从0开始的计数器,然后在else块中递增它,而不是time.time()

def pitch_detection :

    result = []
    no_append = 0
    MAX_TIME_ALLOWED = 5 # seconds
    while True :

        // apply pitch detection algorithm

        if pitch_energy > threshold :
            result.append(pitch)
            no_append = 0
        else:
            no_append += 1
            if no_append > MAX_TIMES_ALLOWED:
                break

    return result 

答案 1 :(得分:1)

您可以使用alarm在四秒钟后自行计时。它需要一些设置才能开始,因为你需要一个函数和一个异常类来使用。

import signal

# Define a couple things.
class TimeoutException(Exception):
  pass

def timeout_handler(signum, frame):
  raise TimeoutException()

# Set the alarm handler.
signal.signal(signal.SIGALRM,timeout_handler)

alarmOn = False
try:
  while True:

    # Pitch detection algorithm

    if pitch_energy <= threshold:
      # False condition - start your alarm.
      if not alarmOn:
        signal.alarm(4)
        alarmOn = True
    else:
      # True condition - turn off the alarm.
      alarmOn = False
      signal.alarm(0)
      result.append(pitch)

except TimeoutException: # This happens if four seconds pass without signal.alarm(0) being called.
  print "We're done."
  signal.alarm(0) # Turn the alarm off

signal.alarm()函数以秒为单位启动一个具有您给出的任何值的计时器。如果在没有重置警报的情况下经过那么多秒,则会发送SIGALRM信号。上面的代码的工作方式,它将捕获SIGALRM信号并抛出我们的自定义TimeoutException。这允许我们突破while循环,因为我们捕获了该异常。

编辑:看看dano的答案,完全有可能这个过于复杂。我们之间的主要区别在于,如果四秒钟通过,此解决方案将立即中断您正在进行的操作 - 这可能会在中间停止您的音高检测算法。 dano的解决方案将一直等到代码中的某一点来检查时间。