Mashumaro
Mashumaro

Reputation: 11

While loop that asks for input and breaks once time is up

I want to create a while loop that is able to keep on receiving inputs but will break once a timer countdown to 0. How am I able to do it?

while True: x = raw_input("Enter Stuff here:")

This loop will end once timer reaches zero, regardless if the user has anything inputted or not. However, i do not know how to implement such timer

Upvotes: 1

Views: 202

Answers (3)

meTchaikovsky
meTchaikovsky

Reputation: 7666

You can do it by using multiprocessing.Process

from time import sleep
from os.path import isfile
from os import remove

def timeout():
    t_start = time()
    while True:
        if time() - t_start > 3:
            with open('spy', 'w') as source:
                source.write('emm')
            break
        else:
            sleep(1.)
p1 = Process(target=timeout, daemon=True)
p1.start()

while True:
    if not isfile('spy'):
        a = input('input something:')
    else:
        remove('spy')
        p1.join()
        break

However, as you can see from the script, one problem is this script won't exit unless a user types something to invoke if not isfile('spy').

Upvotes: 0

sunpip
sunpip

Reputation: 1

import sys
import threading
import time
import queue

def add_input(input_queue):
    while True:
        input_queue.put(sys.stdin.read(1))


def timed_input():
    s = ""
    input_queue = queue.Queue()
    input_thread = threading.Thread(target=add_input, args=(input_queue,))
    input_thread.daemon = True
    input_thread.start()

    last_update = time.time()

    print("Enter stuff here and confirm with enter:")

    while True:
        # Do while countdown of 5 seconds
        if time.time()-last_update > 5:
            print("\nTime is up")
            s = s.replace("\n", "")
            if s != "":
                print(s, " entered.")
            break

        if not input_queue.empty():
            s += input_queue.get()

timed_input()

Upvotes: 0

fixatd
fixatd

Reputation: 1404

I've done something similar previously, where I use signal to trigger an error when the time I've allotted has run out, basically a TimeOutError. I have it as a function wrapper which I can conveniently use it as @timeout(seconds=<number_of_seconds>). See the code below:

import signal
from functools import wraps


class TimeOutError(Exception):
    pass


def timeout(seconds):
    def decorator(func):
        def _handle_timeout(signum, frame):
            raise TimeOutError()

        def wrapper(*args, **kwargs):
            signal.signal(signal.SIGALRM, _handle_timeout)
            signal.alarm(seconds)
            try:
                result = func(*args, **kwargs)
            finally:
                signal.alarm(0)
            return result

        return wraps(func)(wrapper)

    return decorator

# Using it as a function wrapper    
@timeout(seconds=10)
def run():
    while True: x = raw_input("Enter Stuff here:")


# Then calling it as such
try:
    run()
except TimeOutError:
    print("You have exceeded the allotted time!")

Upvotes: 2

Related Questions