TrickSpades
TrickSpades

Reputation: 62

Running one function without stopping another

How can I run a timer while asking for user input from the console? I was reading about multiprocessing, and I tried to use this answer: Python: Executing multiple functions simultaneously. When I tried to get it going, it gave me a bunch of framework errors.

Right now it runs start_timer(), but then stops it when it runs cut_wire().

Here's my start_timer function:

def start_timer():
    global timer
    timer = 10
    while timer > 0:
        time.sleep(1)
        timer -= 1
        sys.stdout.write ("There's only %i seconds left. Good luck. \r" % (timer))
        sys.stdout.flush()
        cut_wire()
    if timer == 0:
        print("Boom!")
        sys.exit()

and this is the cut_wire function:

def cut_wire():
    wire_choice = raw_input("\n> ")
    if wire_choice == "cut wire" or wire_choice == "Cut Wire":
        stop_timer()
    else:
        print("Boom!")
        sys.exit()

Upvotes: 3

Views: 184

Answers (3)

downhillFromHere
downhillFromHere

Reputation: 1977

Only addressing your concerns, here is a quick fix using threading :

import time
import sys  
import os 

def start_timer():
  global timer
  timer = 10 
  while timer > 0:
    time.sleep(1)
    timer -= 1
    sys.stdout.write ("There's only %i seconds left. Good luck. \r" % (timer))
    sys.stdout.flush()
    #cut_wire() ==> separate call is easier to handle
  if timer == 0:
  print("Boom!")
  os._exit(0)    #sys.exit() only exits thread

def cut_wire():
  wire_choice = raw_input("\n> ")
  if wire_choice == "cut wire" or wire_choice == "Cut Wire":
    stop_timer()
  else:
    print("Boom!")
    os._exit(0)    #same reason

if __name__ == '__main__':
  import threading
  looper = threading.Thread(target=start_timer)
  looper.start()
  cut_wire()

Upvotes: 1

Guy Goldenberg
Guy Goldenberg

Reputation: 819

Instead of using raw_input() use this function taken from here.

def readInput( caption, timeout = 1):
start_time = time.time()
sys.stdout.write('\n%s:'%(caption));
input = ''
while True:
    if msvcrt.kbhit():
        chr = msvcrt.getche()
        if ord(chr) == 13: # enter_key
            break
        elif ord(chr) >= 32: #space_char
            input += chr
    if len(input) == 0 and (time.time() - start_time) > timeout:
        break

print ''  # needed to move to next line
if len(input) > 0:
    return input
else:
    return ""

Thearding option

To make sure that both functions run completely simultaneously you can use this example of threading event:

import threading
event = threading.Event()
th = theading.Thread(target=start_timer, args=(event, ))
th1 = theading.Thread(target=cut_wire, args=(event, ))
th.start()
th1.start()
th.join()
th1.join()

In your function you can set an event using event.set(), check it using event.is_set() and clear it using event.clear().

Upvotes: 1

user2983378
user2983378

Reputation:

Of course it stops running when it plays the cut_wire function because "raw_input" command reads the text and wait for the user to put the text and press enter.

My suggestion is to check for they key press "Enter" and when then key was press, read the line. If the key wasn't press, just continue with your timer.

Regards.

Upvotes: 1

Related Questions