1

I am writing a program in python that accepts two inputs.

Once the user gives the first input, he gets 10 seconds to give the second input. If the user is able to provide the second value within those 10 seconds and presses the enter key, the timer stops and goes to the next part of the program.

Is there any functionality in python that allows me to provide an interrupt after the 10 seconds and stop accepting the second input. And if the second input is given, stop the timer.

3
  • 2
    You will need to use a multi threaded solution for this Commented May 26, 2019 at 16:23
  • 2
    You might be able to do this using timeout-decorator since this is a relatively simple requirement. Commented May 26, 2019 at 16:32
  • 1
    The python-idle tag is about the IDLE editor and shell, not 'doing nothing'. Anyway, you can easily do what you want with a simple tkinter program using an Entry and a .after callback. Commented May 26, 2019 at 20:19

1 Answer 1

2

You can create a custom Timer class and start it in a diffrent thread. Once the timeout occurs (after 10 seconds), you can send a SIGINT signal back to the parent thread, which will raise the KeyboardInterrupt exception that we catch in the main() function. Otherwise you can stop the Timer, after user enters the second input in the right time, which will then stop the Timer thread. Further, we can check if the KeyboardInterrupt happened due to timeout or user action.

Note: While we are sending the signal to the main process, we also need to check, on which platform we are running the programm. See signal.CTRL_C_EVENT and signal.SIGINT.

Demo: https://repl.it/repls/StandardBuoyantProtools

Solution:

import time
import threading
import os
import signal


class Timer(threading.Thread):
    _timeout = False
    _timer = 0
    _stopped = False

    def __init__(self, delay):
        super(Timer, self).__init__()
        self.restart(delay)

    def is_timeout(self):
        return self._timeout

    def stop(self):
        self._stopped = True

    def restart(self, delay):
        self._stopped = False
        self._timer = time.time() + delay

    def run(self):

        while not self._stopped:
            time.sleep(0.1)
            if time.time() >= self._timer:
                break
        if not self._stopped:
            self._timeout = True

            # check os name
            if os.name == 'nt':
                # we are on Windows
                os.kill(os.getpid(), signal.CTRL_C_EVENT)
            else:
                # we are on a Posix/Unix (or very unlikely on java) system
                os.kill(os.getpid(), signal.SIGINT)


def main():
    first_input = input('First input:')

    delay = 10
    timer = Timer(delay)
    timer.daemon = True

    try:
        print('\nStarting the timer for the second input %r second(s)' % delay)
        timer.start()

        second_input = input('Second input:')

        print('\nWell done. Stopping the timer!\n')
        timer.stop()

        print('Input values: %r %r\n' % (first_input, second_input))

        # do your stuff here...

    except KeyboardInterrupt:
        if timer.is_timeout():
            print("\nTimeout!")
        else:
            print("\nUser interrupted the input")


main()
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.