1

A straightforward application of:

  • Prompt for user input.
  • Start countdown (or count up) timer.
  • Wait on user input (as timer counts down/up).
  • If user inputs a correct response, conditional statement 1
  • Else, conditional statement 2
  • If user exceeds a preset time, timer expires and user is directed accordingly.

I've tried some of the solutions offered on this web site. However, in all cases, the count up/down timer seems to stop once the user input prompt is generated. In other words, the timer does not seem to run as a separate (background) thread.

import threading
import time

class TimerClass(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.event = threading.Event()
        self.count = 10

    def run(self):
        while self.count > 0 and not self.event.is_set():
            print (self.count)
            int_answer = (int(input('Enter your age: '), base = 10)
            str_answer = str(int_answer)
            while str_answer == '':
                self.count -= 1
                self.event.wait(10)
                if (int_answer > 50) :
                    <do something>
                else:
                    <do somethingelse>

    def stop(self):
        self.event.set()

tmr = TimerClass()
tmr.start()

time.sleep(1)

tmr.stop()

The program should go to condition 1 if a response of > 50 is provided; else, go to condition 2 if a response of <= 50 is entered. The timer should expire after a period of 10 secs. if the user has not provided a response (with user notification).

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • 3
    `input()` blocks the current thread. Don't use `input()` in the counter thread if you don't want it to be blocked when waiting for user input. – Martijn Pieters Aug 10 '19 at 18:47
  • What should work however is creating a separate Thread Class i.e. User, that prompts and returns the user input into a User.response attribute. This User class can be called from inside TimerClass and the User.response attribute can be monitored from a while loop inside TimerClass. Alternatively User Class returns a callback. – lmielke Aug 10 '19 at 19:45

1 Answers1

0

I've adapted the code from this answer to your needs:

import threading
import queue
import time

def read_kbd_input(inputQueue):
    print('Ready for keyboard input:')
    while (True):
        input_str = input()
        inputQueue.put(input_str)

def main():
    inputQueue = queue.Queue()

    inputThread = threading.Thread(target=read_kbd_input, args=(inputQueue,), daemon=True)
    inputThread.start()

    start_time = time.time()
    while True:
        if (inputQueue.qsize() > 0):
            input_str = inputQueue.get()
            # Insert your code here to do whatever you want with the input_str.
            print("input_str = {}".format(input_str))
            break

        time.sleep(0.1)  # poll each 100ms
        if time.time() - start_time > 2: # timeout after 2 sec
            break
    print("End.")

if (__name__ == '__main__'): 
    main()
Nickolay
  • 31,095
  • 13
  • 107
  • 185