0

I'm getting back into programming, so I started a project that rolls a die based on the amount of side's a user inputs, and the amount of times the user wants the die to be rolled. I'm having trouble with a part of the program involving time. When the user doesn't input within ten seconds of being prompted, I want a message to be displayed. If nothing is entered in another ten seconds a message should be displayed, so on and so forth. I'm using python.

Right now most of the program is working, but time is only checked after an input is taken. Thus a user could sit on the input screen infinitely and not get prompted. I'm really stuck on how to simultaneously wait for an input, while checking the amount of time elapsed since being prompted for the input.

def roll(x, y):
    rvalues = []
    while(y > 0):
        y -= 1
        rvalues.append(random.randint(1, x))
    return rvalues

def waitingInput():
    # used to track the time it takes for user to input
    start = time.time()
    sides = int(input("How many sides does the die have? "))
    times = int(input("How many times should the die be rolled? "))
    tElapsed = time.time() - start
    if tElapsed <= 10:
        tElapsed = time.time() - start
        rInfo = roll(sides, times)
        print("Each side occurs the following number of times:")
        print(Counter(rInfo))
        waitingInput()
    else:
        print("I'm waiting...")
        waitingInput()

Any advice would be appreciated. I'm looking to improve my coding any way I can, so constructive criticism about unrelated code is welcome.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • Possible duplicate of [Keyboard input with timeout in Python](https://stackoverflow.com/questions/1335507/keyboard-input-with-timeout-in-python) – TrebledJ May 18 '19 at 04:01

1 Answers1

0

Situations like this call for a threaded timer class. The python standard library provides one:

import threading

...

def waitingInput():
    # create and start the timer before asking for user input
    timer = threading.Timer(10, print, ("I'm waiting...",))
    timer.start()

    sides = int(input("How many sides does the die have? "))
    times = int(input("How many times should the die be rolled? "))

    # once the user has provided input, stop the timer
    timer.cancel()  

    rInfo = roll(sides, times)
    print("Each side occurs the following number of times:")
    print(Counter(rInfo))
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Green Cloak Guy
  • 23,793
  • 4
  • 33
  • 53
  • Thanks, this helped a lot! I'm curious, why does there need to be a comma after print , and the string in : timer = threading.Timer(10, print, ("I'm waiting...",)). I see that without them, it prints I'm waiting without actually waiting ten seconds. – Solidswizzle May 18 '19 at 16:00
  • `threading.Timer()` takes three arguments: (1) interval, (2) Function to be executed, (3) arguments to give to that function, as a tuple. You have to present the function and the arguments separately here - if you remove the comma, you end up giving `print("I'm waiting...")` as the second argument - which returns None, so you end up with `threading.Timer(10, None)`. The comma in `("I'm waiting...",)` is how you designate a 1-tuple in python (putting just parentheses would be ambiguous) - `["I'm waiting..."]` would also work here. – Green Cloak Guy May 18 '19 at 17:05