Input stopping threads from running - python

I want to run a program that can ask for input and run threads at the same time.
For example:
import threading
def get_input():
while True:
var = input('prompt> ')
do_stuff
#main loop
while True:
input_thread = threading.Thread(target=get_input)
input_thread.start()
do_stuff_that_doesn't_work
So the problem above would be that it asks for input(prompt>) and while it's asking for input, do_stuff_that_doesn't_work won't work.
I've seen people get by this before but I don't know how to do it.

You shouldn't be creating a thread inside your while loop. Try this code...
import threading
import time
run = True
def get_input():
global run
while run:
var = input('prompt> ') #python 3 only
print('Input was ', var)
if 'q' == var:
run = False
input_thread = threading.Thread(target=get_input)
input_thread.start()
print('Type q to exit')
ctr = 0
while run:
ctr += 1
time.sleep(0.1)
print('Exiting with ctr: ', ctr)

Related

Mimic user input (press enter) to escape from the block of input() in multithread scanrio

I have a thread keeps asking user's input, how can I escape the block of input() in the main thread?
from threading import Thread
import time
flag = True
def keep_ask_input():
print('thread start')
while flag:
user_input = input('type something: ')
print(f"user_input = {user_input}")
print('stop asking input')
if __name__ == '__main__':
t = Thread(target=keep_ask_input)
t.start()
time.sleep(.5)
flag = False
''' do something to mimic user input or escape from input() '''

Run a loop while waiting for a user input

I want to run a loop in my script while the user has not input anything. But when they have input something I want the loop to break.
The issue I am currently having is that when using the input() function, the script will stop and wait for an input, but I want to run another part of the script while waiting for the user input.
I have tried using try: with a raw_input():
while True:
try:
print('SCAN BARCODE')
userInput= raw_input()
#doing something with input
except:
#run this while there is no input
With this, I find that whatever is in the except: will always run, but it will not run try: even when there is a user input. If I change raw_input() to input() the script just waits at input() and doesn't run anything in the except:.
How do I achieve what I am after?
you can use python threads:
from threading import Thread
import time
thread_running = True
def my_forever_while():
global thread_running
start_time = time.time()
# run this while there is no input
while thread_running:
time.sleep(0.1)
if time.time() - start_time >= 5:
start_time = time.time()
print('Another 5 seconds has passed')
def take_input():
user_input = input('Type user input: ')
# doing something with the input
print('The user input is: ', user_input)
if __name__ == '__main__':
t1 = Thread(target=my_forever_while)
t2 = Thread(target=take_input)
t1.start()
t2.start()
t2.join() # interpreter will wait until your process get completed or terminated
thread_running = False
print('The end')
In my example you have 2 threads, the first thread is up and executes code until you have some input from the user, thread 2 is waiting for some input from the user. After you got the user input thread 1 and 2 will stop.
It simple bro u use flag boolean values
Flag = True
while Flag:
try:
Print('scan bar code')
User_inp = input()
if User_inp != '':
Flag = False
Except:
Print('except part')
I suggest you to look for select
it allow you to check if a file descriptor is ready for read/write/expect operation

Python pause loop on user input

Hey I am trying to have a loop be pausable from user input like having a input box in the terminal that if you type pause it will pause the loop and then if you type start it will start again.
while True:
#Do something
pause = input('Pause or play:')
if pause == 'Pause':
#Paused
Something like this but having the #Do something continually happening without waiting for the input to be sent.
Ok I get it now, here is a solution with Threads:
from threading import Thread
import time
paused = "play"
def loop():
global paused
while not (paused == "pause"):
print("do some")
time.sleep(3)
def interrupt():
global paused
paused = input('pause or play:')
if __name__ == "__main__":
thread2 = Thread(target = interrupt, args = [])
thread = Thread(target = loop, args = [])
thread.start()
thread2.start()
You can't directly, as input blocks everything until it returns.
The _thread module, though, can help you with that:
import _thread
def input_thread(checker):
while True:
text = input()
if text == 'Pause':
checker.append(True)
break
else:
print('Unknown input: "{}"'.format(text))
def do_stuff():
checker = []
_thread.start_new_thread(input_thread, (checker,))
counter = 0
while not checker:
counter += 1
return counter
print(do_stuff())

RuntimeError: threads can only be started once for a beginner

This is for my first program. I am trying to put this loading animation in a while loop, but it gives this error after the second "f.start()". As I don't understand much about threads, the "help" I could find on Google was not helpful at all, which involved long codes with class creation and everything. Can somebody help me understand what I could do here?
I copied the animation code from here: Python how to make simple animated loading while process is running
import itertools
import threading
import time
import sys
#here is the animation
def animate():
for c in itertools.cycle(['|', '/', '-', '\\']):
if done:
break
sys.stdout.write('\rloading ' + c)
sys.stdout.flush()
time.sleep(0.25)
sys.stdout.write('\rDone! ')
t = threading.Thread(target=animate)
while True:
done = False
user_input = input('Press "E" to exit.\n Press"S" to stay.')
if user_input is "E":
break
elif user_input is "S":
# Long process here
t.start()
time.sleep(5)
done = True
time.sleep(1)
print("\nThis will crash in 3 seconds!")
time.sleep(3)
break
# Another long process here
t.start()
time.sleep(5)
done = True
As the error says, a thread can only be started once. So, create a new thread instead. Notice also that I use join to wait for the old thread to stop.
import itertools
import threading
import time
import sys
#here is the animation
def animate():
for c in itertools.cycle(['|', '/', '-', '\\']):
if done:
break
sys.stdout.write('\rloading ' + c)
sys.stdout.flush()
time.sleep(0.25)
sys.stdout.write('\rDone! ')
t = threading.Thread(target=animate)
while True:
done = False
user_input = input('Press "E" to exit.\n Press"S" to stay.')
if user_input is "E":
break
elif user_input is "S":
# Long process here
t.start()
time.sleep(5)
done = True
t.join()
print("\nThis will crash in 3 seconds!")
time.sleep(3)
break
# Another long process here
done = False
t = threading.Thread(target=animate)
t.start()
time.sleep(5)
done = True

Pause and resume a running script in Python 3.42 in Windows

I'm new to Python and have been googling for a couple of days and read all I can find on this forum. Might be that I don't understand it all but I haven't found a solution to my problem yet. Ask for forgiveness already if there's an answer already to my problem, then I haven't understood it.
I want to make a Pause function for my program Tennismatch. The program will when it's being run print the score of a tennis match like this: "15-0, 15-15 etc ongoing till the match ends. It will print the score line by line.
I want the user to be able to pause after x number of balls, games, etc. So I don't know when the user wants to pause and after the user has paused I want the user to be able to resume the tennismatch where it was.
Have seen the time.sleep() but as I have understood it you must know when you want to pause to use this and it also ain't an indefinetie pause like I want. With input() it's the same.
Am going to make a GUI later on when the code is finished. Happy for anything that leads me to solving my problem.
I use Windows and Python 3.42 and run the program in Shell.
A piece of the code (haven't written it all yet, it's more of a general situation when something is being printed line after line for some time and want to be able do pause in the CIL:
#self.__points = [0,0]
def playGame(self):
if self.server == True: #self.server is either True or False when someone calls playGame()
server = self.player_1.get_win_serve() #self.player_1 = an object of a class Player():
else:
server = self.player_2.get_win_serve() #get_win_serve() method returns the probability to win his serv (1-0)
while (0 < self.__points[0] - self.__points[1] >= 2 or 0 < self.__points[1] - self.__points[0] >= 2) and (self.__points[1] >= 4 or self.__points[0] >= 4):
x = random.uniform(0,1)
if x > 0 and x < server:
self.__points[0] += 1
else:
self.__points[1] += 1
# print('The score, by calling a score() function that I haven't written yet')
For dealing with events in main loop you need to make a separated thread which capture input or any other event.
import sys
from sys import stdin
from time import sleep
from threading import Thread
from Queue import Queue, Empty
def do_something():
sleep(1)
print 42
def enqueue_output(queue):
while True:
# reading line from stdin and pushing to shared queue
input = stdin.readline()
print "got input ", input
queue.put(input)
queue = Queue()
t = Thread(target=enqueue_output, args=(queue,))
t.daemon = True
t.start()
pause = False
try:
while True:
try:
command = queue.get_nowait().strip()
print 'got from queue ', command
except Empty:
print "queue is empty"
command = None
if command:
if command == 'p':
pause = True
if command == 'u':
pause = False
if not pause:
print pause
do_something()
except KeyboardInterrupt:
sys.exit(0)
I came up with the following.
while True:
try:
## Keep doing something here
## your regular code
print '.',
except KeyboardInterrupt:
## write or call pause function which could be time.sleep()
print '\nPausing... (Hit ENTER to continue, type quit to exit.)'
try:
response = raw_input()
if response.lower() == 'quit':
break
print 'Quitting...'
except KeyboardInterrupt:
print 'Resuming...'
continue
The Event loop might as well be the code I wrote with.
I don't see any user input so I assume that x emulates it. To pause the game if x < 0.1 and to unpause(/resume) it if x > 0.9, you could:
while your_condition(self.__points):
x = random.random()
if x < 0.1: # pause
self.pause()
elif x > 0.9: # resume
self.resume()
if self.is_paused:
continue # do nothing else only wait for input (`x`)
# assume your_condition() has no side-effects
# here's what the resumed version does:
print("...")
# change self.__points, etc
where pause(), resume(), is_paused() methods could be implemented as:
def __init__(self):
self.is_paused = False
def pause(self):
self.is_paused = True
def resume(self):
self.is_paused = False
as you can see the implementation is very simple.

Categories