Get user input to stop a while loop - python

I need a way to stop a loop by getting user input without blocking the loop itself which works cross-platform.
Things I have tried:
processes (closes stdin so I can't use input())
threads (can't kill a thread if the while loop terminates and I no longer need the input())
FLAG = False
def break_main_loop(): # how do I get this to execute?
global FLAG
user_in = input()
if user_in == 'stop':
FLAG = True
return
else:
break_main_loop()
def stuff():
pass
def main():
# do stuff, e.g. getting other user input()
while True:
stuff()
if FLAG:
break
return # if I return here, I need to cancel break_main_loop's input()
main()

This will work for you and simple to use. Replace main function with this
def main():
# do stuff, e.g. getting other user input()
try:
while True:
stuff()
except KeyboardInterrupt:
print("Press 1 to quit")
return # if I return here, I need to cancel break_main_loop's input()
main()

I'd love to answer your question. You see, once you are in the main-loop, you don't necessarily need to use a FLAG variable, rather, I'd suggest doing something like this :
def break_main_loop(): # how do I get this to execute?
user_in = input()
if user_in == 'stop':
return True # Returning integer 1 also works just fine
else:
return False # Returning integer 0 also works just fine
def stuff():
pass
def main():
# do stuff, e.g. getting other user input()
while True:
stuff()
if break_main_loop(): # If the user inputs stop, the loop stops via the return statement automatically
return
main()
If you wish to get out of the loop without returning anything else and keep the main() function running for doing stuff:
def break_main_loop(): # how do I get this to execute?
user_in = input()
if user_in == 'stop':
return True # Returning integer 1 also works just fine
else:
return False # Returning integer 0 also works just fine
def stuff():
pass
def main():
# do stuff, e.g. getting other user input()
while True:
stuff()
if break_main_loop():
break
#continue doing stuff
main()
Now, there's a better way to break out of the loop without using the helper function break_main_loop(), and that's done like so:
def stuff():
pass
def main():
# do stuff, e.g. getting other user input()
while True:
stuff()
if str(input("Do you wish to continue:[y/n]")) == 'n':
break
#continue doing stuff
main()
This lets you get rid of the helper function completely.
I hope this answer was helpful. :D

try this:
class new_game:
start_game = True
# end_game = False
def break_main_loop(self): # how do I get this to execute?
print("game is ending!")
def stuff(self):
print("this is stuff happening....now...game is: ", self.start_game)
def game_loop(self):
user_in = int(input("enter '2' to end game or '1' to keep playing:" ))
if user_in == 1:
self.stuff()
self.game_loop()
else:
return self.break_main_loop()
Test_game = new_game()
Test_game.game_loop()

Related

Try and except block not running the exception

The code works fine except for the exceptions i.e., when I input something like cat/dog or 1/0 or for the case 3/2, instead of re-prompting, the terminal just goes into blank infinite mode that I have to manually stop with cmd+c. Please help identify what I'm doing wrong. Thanks!
def main():
fuel=input("Fuel: ")
c=convert(fuel)
print(f"{convert(fuel)}%")
gauge(c)
def convert(fraction):
while True:
try:
X,Y=fraction.split("/")
x=int(X)
y=int(Y)
f=x/y
z=int((x/y)*100)
if f<=1:
return z
except (ValueError, ZeroDivisionError):
pass
def gauge(percentage):
if percentage<=1:
print("E")
elif percentage>=99:
print("F")
else:
print("Z%")
if __name__ == "__main__":
main()
Well, you never re-ask the question. To solve it, move the input("Fuel: ") call inside the while loop:
def main():
c = convert()
print(f"{c}%")
gauge(c)
def convert():
while True:
fraction = input("Fuel:")
try: # Rest can be the same

Calling a method from farther down the stack

Ok I have a code that's basically this....
def create():
#long list of print statements
m_commands()
def get_desc():
#print statement
m_commands()
def m_commands():
while close != True:
input = input(str(">>>"))
If inp == "close" or "quit":
close = True
If inp == "create":
create()
If inp == "describe":
get_desc()
m_commands()
I need to call m_commands() in create() and get_desc() to continue continuity. Is this possible. Sorry in advance, I don't know how to put code in a spoiler thingy. Thanks!
def create():
#long list of print statements
print("hello")
m_commands()
def get_desc():
#print statement
print("world")
m_commands()
def m_commands():
close=False
while close != True:
inp = input(str(">>>"))
if inp == "close" or "quit":
close = True
if inp == "create":
create()
if inp == "describe":
get_desc()
m_commands()
This is working for me though.

What is best way to repeatedly execute a function in python and stop it based on some condition?

I want to execute a function repeatedly every 5 seconds and at the same time take input from the user and based on the input stop the execution?
Ex:
def printit():
t=threading.Timer(3.0,printit)
t.start()
n=str(input())
if(n=='rajesh'):
t.cancel()
else:
#I want to continue the execution here
This Should Help
import time
#use a While loop
While True:
#request said user input
x= input("Please Press 1 to continue Or 2 to Exit")
#then an if statement
if x==1:
#call your function
printit()
time.sleep(5)
else:break
This should Do the trick
If you really want to use threading, then this should work:
import threading
import time
def worker():
while True:
user_input = input("Enter text:")
if user_input == 'rajesh':
break
else:
time.sleep(5)
thread = threading.Thread(target=worker, daemon=True)
thread.start()
thread.join()
This Should Help
#request said user input
x= input("Please Press 1 to continue Or 2 to Exit")
#use a While loop
While True:
#then an if statement
if x==1:
#call your function
printit()
else:break
This should Do the trick

Python 3.4.2:My infinite function while loop is not working

My infinite while loop is not working as I expected it:
def main():
print("Type 1 to create a file")
print("Type 2 to read a file")
print("Type 3 to append a file")
print("Type 4 to calculate total of file")
print("Type 5 to end the program")
choice=input("Select a number:")
if choice == '1':
file_create(filename)
elif choice == '2':
read_file(filename)
elif choice == '3':
append_file(filename)
elif choice == '4':
add_numbers(filename)
filename=input("Give a name to your file:")
while main():
# ...
This executes the main once, but it does not loop.
Mr.Anyoneoutthere, Sylvain is absolutely correct. Since you don't understand it, I'll explain.
A loop needs a conditon:- True OR False.
So when you say:-
while True:
print('World')
is the same as:-
a = 100
while a == 100:
print('poop')
Since a == 100 would evaluate to 'True', and start a loop because you let the value remain constant, and start an infinite loop. But you can directly put the evaluation, i.e., 'True', so as to directly start an infinite loop.
As you have put:-
while main():
print('World')
So now think... while main()... main() what?... the compiler does not get any code to evaluate something into 'True' or 'False' and the loop never starts!
So your required correct code is:-
while True:
main()
def main():
# ...
# <- no return statement
while main():
# Something
The while loop loops as long as the condition is true. Here, as your main() function does not have a return statement, it doesn't return anything explicitly. So Python behave as if it were returning None. None is not true. So the condition is false and you don't execute the body even once.
What about something like that (assuming you need to execute main() until the user wants to quit):
def main():
# ...
print("Type 9 to quit")
choice=input("Select a number:")
if choice == '9':
return False
# Handle other cases
if choice == '1':
file_create(filename)
elif choice == '2':
# ...
return True
On the other hand, as suggested by #thiruvenkadam in a comment below, you could keep your main as it was written in your question, but really write an infinite loop:
while True:
main()
But that way, if you want to terminate your program gracefully , you will have to rely on some other mechanism like using exceptions...

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