Pregunta

¿Hay alguna forma de hacer una función (las que estoy pensando están en el estilo de las simples que he hecho que generan la secuencia de Fibonnacci de 0 a un punto, y todos los números primos entre dos puntos) correr indefinidamente P.ej. hasta que presione una tecla determinada o hasta que haya pasado un tiempo, en lugar de hasta que un número llegue a cierto punto?

Además, si se basa en el tiempo, ¿hay alguna forma de que pueda extender el tiempo y comenzar de nuevo desde ese punto, en lugar de tener que comenzar de nuevo desde 0? Soy consciente de que hay un módulo de tiempo, simplemente no sé mucho al respecto.

¿Fue útil?

Solución

La forma más sencilla es escribir un programa con un bucle infinito y luego presionar control-C para detenerlo. Sin más descripción, es difícil saber si esto funciona para usted.

Si lo hace en función del tiempo, no necesita un generador. Puede hacer que se detenga para la entrada del usuario, algo así como un " ¿Continuar? [y / n] " ;, leer desde stdin, y dependiendo de lo que obtenga, salga del bucle o no.

Otros consejos

Podría usar un generador para esto:

def finished():
    "Define your exit condition here"
    return ...

def count(i=0):
    while not finished():
        yield i
        i += 1

for i in count():
    print i

Si desea cambiar la condición de salida, puede volver a pasar un valor a la función del generador y usar ese valor para determinar cuándo salir.

Como en casi todos los idiomas:

while True:
  # check what you want and eventually break
  print nextValue()

La segunda parte de su pregunta es más interesante:

  

Además, si se basa en el tiempo, ¿está ahí de todos modos? Podría extender el tiempo y comenzar de nuevo desde ese punto en lugar de tener que comenzar de nuevo desde 0

puede usar un rendimiento en lugar de return en la función nextValue()

Si usa un hilo secundario para ejecutar la función mientras el hilo principal espera la entrada de caracteres, debería funcionar. Solo recuerde tener algo que detenga el hilo secundario (en el ejemplo debajo del hilo de ejecución global)

Por ejemplo:

import threading, time
runthread = 1
def myfun():
   while runthread:
      print "A"
      time.sleep(.1)

t = threading.Thread(target=myfun)
t.start()
raw_input("")
runthread = 0
t.join()

hace exactamente eso

Si realmente desea que su función se ejecute y aún desea la entrada del usuario (o sistema), tiene dos soluciones:

  1. multihilo
  2. multiproceso

Dependerá de qué tan bien la interacción. Si solo desea interrumpir la función y no le importa la salida, entonces el multiproceso está bien.

En ambos casos, puede confiar en algunos recursos compartidos (archivo o memoria compartida para subprocesos múltiples, variable con mutex asociado para subprocesos múltiples) y verificar regularmente el estado de ese recurso en su función. Si está configurado para decirle que abandone, simplemente hágalo.

Ejemplo en subprocesos múltiples:

from threading import Thread, Lock
from time import sleep

class MyFct(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.mutex = Lock()
        self._quit = False

    def stopped(self):
        self.mutex.acquire()
        val = self._quit
        self.mutex.release()
        return val

    def stop(self):
        self.mutex.acquire()
        self._quit = True
        self.mutex.release()

    def run(self):
        i = 1
        j = 1
        print i
        print j
        while True:
            if self.stopped():
                return
            i,j = j,i+j
            print j

def main_fct():
    t = MyFct()
    t.start()
    sleep(1)
    t.stop()
    t.join()
    print "Exited"

if __name__ == "__main__":
    main_fct()

Si desea salir en función del tiempo, puede usar la función de alarma (hora) del módulo de señal y capturar el SIGALRM: aquí hay un ejemplo http://docs.python.org/library/signal.html#example

Puede permitir que el usuario interrumpa el programa de una manera sensata si atrapa KeyboardInterrupt. Simplemente detecte la excepción KeyboardInterrupt desde fuera de su bucle principal y realice la limpieza que desee.

Si desea continuar más tarde donde lo dejó, deberá agregar algún tipo de persistencia. Me gustaría pickle una estructura de datos en el disco, que podría leer de nuevo en continuar las operaciones.

No he intentado algo como esto, pero podrías considerar usar algo como memorizar y almacenar en caché en el disco.

Podría hacer algo como esto para generar números de fibonnacci durante 1 segundo y luego detenerse.

fibonnacci = [1,1]
stoptime = time.time() + 1 # set stop time to 1 second in the future
while time.time() < stoptime:
  fibonnacci.append(fibonnacci[-1]+fibonnacci[-2])

print "Generated %s numbers, the last one was %s." % (len(fibonnacci),fibonnacci[-1])

No estoy seguro de cuán eficiente es llamar a time.time () en cada ciclo, dependiendo de lo que esté haciendo dentro del ciclo, podría terminar eliminando gran parte del rendimiento.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top