Python: How to keep repeating a program until a specific input is obtained?
There are two ways to do this. First is like this:
while True: # Loop continuously
inp = raw_input() # Get the input
if inp == "": # If it is a blank line...
break # ...break the loop
The second is like this:
inp = raw_input() # Get the input
while inp != "": # Loop until it is a blank line
inp = raw_input() # Get the input again
Note that if you are on Python 3.x, you will need to replace raw_input
with input
.
Go back to start or repeat raw input a number of times
i = 0
def code_to_repeat():
# whatever is your code
print "I was repeated : " + str(i) +" times"
while(True):
print "Do you want to run the code (Y/N) : "
stri = raw_input()
print "\n"
if stri=="Y":
i += 1
code_to_repeat()
elif stri=="N"
print "exiting\n"
break;
else:
print "Please Answer Y/N only.\n"
Asking the user for input until they give a valid response
The simplest way to accomplish this is to put the input
method in a while loop. Use continue
when you get bad input, and break
out of the loop when you're satisfied.
When Your Input Might Raise an Exception
Use try
and except
to detect when the user enters data that can't be parsed.
while True:
try:
# Note: Python 2.x users should use raw_input, the equivalent of 3.x's input
age = int(input("Please enter your age: "))
except ValueError:
print("Sorry, I didn't understand that.")
#better try again... Return to the start of the loop
continue
else:
#age was successfully parsed!
#we're ready to exit the loop.
break
if age >= 18:
print("You are able to vote in the United States!")
else:
print("You are not able to vote in the United States.")
Implementing Your Own Validation Rules
If you want to reject values that Python can successfully parse, you can add your own validation logic.
while True:
data = input("Please enter a loud message (must be all caps): ")
if not data.isupper():
print("Sorry, your response was not loud enough.")
continue
else:
#we're happy with the value given.
#we're ready to exit the loop.
break
while True:
data = input("Pick an answer from A to D:")
if data.lower() not in ('a', 'b', 'c', 'd'):
print("Not an appropriate choice.")
else:
break
Combining Exception Handling and Custom Validation
Both of the above techniques can be combined into one loop.
while True:
try:
age = int(input("Please enter your age: "))
except ValueError:
print("Sorry, I didn't understand that.")
continue
if age < 0:
print("Sorry, your response must not be negative.")
continue
else:
#age was successfully parsed, and we're happy with its value.
#we're ready to exit the loop.
break
if age >= 18:
print("You are able to vote in the United States!")
else:
print("You are not able to vote in the United States.")
Encapsulating it All in a Function
If you need to ask your user for a lot of different values, it might be useful to put this code in a function, so you don't have to retype it every time.
def get_non_negative_int(prompt):
while True:
try:
value = int(input(prompt))
except ValueError:
print("Sorry, I didn't understand that.")
continue
if value < 0:
print("Sorry, your response must not be negative.")
continue
else:
break
return value
age = get_non_negative_int("Please enter your age: ")
kids = get_non_negative_int("Please enter the number of children you have: ")
salary = get_non_negative_int("Please enter your yearly earnings, in dollars: ")
Putting It All Together
You can extend this idea to make a very generic input function:
def sanitised_input(prompt, type_=None, min_=None, max_=None, range_=None):
if min_ is not None and max_ is not None and max_ < min_:
raise ValueError("min_ must be less than or equal to max_.")
while True:
ui = input(prompt)
if type_ is not None:
try:
ui = type_(ui)
except ValueError:
print("Input type must be {0}.".format(type_.__name__))
continue
if max_ is not None and ui > max_:
print("Input must be less than or equal to {0}.".format(max_))
elif min_ is not None and ui < min_:
print("Input must be greater than or equal to {0}.".format(min_))
elif range_ is not None and ui not in range_:
if isinstance(range_, range):
template = "Input must be between {0.start} and {0.stop}."
print(template.format(range_))
else:
template = "Input must be {0}."
if len(range_) == 1:
print(template.format(*range_))
else:
expected = " or ".join((
", ".join(str(x) for x in range_[:-1]),
str(range_[-1])
))
print(template.format(expected))
else:
return ui
With usage such as:
age = sanitised_input("Enter your age: ", int, 1, 101)
answer = sanitised_input("Enter your answer: ", str.lower, range_=('a', 'b', 'c', 'd'))
Common Pitfalls, and Why you Should Avoid Them
The Redundant Use of Redundant input
Statements
This method works but is generally considered poor style:
data = input("Please enter a loud message (must be all caps): ")
while not data.isupper():
print("Sorry, your response was not loud enough.")
data = input("Please enter a loud message (must be all caps): ")
It might look attractive initially because it's shorter than the while True
method, but it violates the Don't Repeat Yourself principle of software development. This increases the likelihood of bugs in your system. What if you want to backport to 2.7 by changing input
to raw_input
, but accidentally change only the first input
above? It's a SyntaxError
just waiting to happen.
Recursion Will Blow Your Stack
If you've just learned about recursion, you might be tempted to use it in get_non_negative_int
so you can dispose of the while loop.
def get_non_negative_int(prompt):
try:
value = int(input(prompt))
except ValueError:
print("Sorry, I didn't understand that.")
return get_non_negative_int(prompt)
if value < 0:
print("Sorry, your response must not be negative.")
return get_non_negative_int(prompt)
else:
return value
This appears to work fine most of the time, but if the user enters invalid data enough times, the script will terminate with a RuntimeError: maximum recursion depth exceeded
. You may think "no fool would make 1000 mistakes in a row", but you're underestimating the ingenuity of fools!
Does raw_input() stop an infinite while loop?
No. It's not stopping the loop; it's actively blocking for input. Once input is received, it will not be blocked anymore (and this is why you get infinite text from other selections); there is no blocking I/O in those branches.
The reason you're not getting a lot of text output from option 1 is due to the way it's being evaluated. Inside of the loop, question
never changes, so it's always going to evaluate to "good"
and will continually ask you the second question1.
1: This is if it is indeed while True
; if it's while state
, it will stop iteration due to state
being False
on a subsequent run.
Python - Infinite while loop, break on user input
I think you can do better with msvcrt:
import msvcrt, time
i = 0
while True:
i = i + 1
if msvcrt.kbhit():
if msvcrt.getwche() == '\r':
break
time.sleep(0.1)
print(i)
Sadly, still windows-specific.
How to break a loop when inputting unspecified raw_input?
You are getting an indent error because you do not have a closing double quote.
n = raw_input("'p' = pause, 'u' = unpause, 'p' = play 's' = stop, 'q' = quit")
If you want to have the while look break if there is any other value then put all of your conditions into elif statements, and an all includisve else at the end. Also I just put lower and strip onto the end of the raw_input statement.
while True:
n = raw_input("'p' = pause, 'u' = unpause, 'pl' = play 's' = stop, 'q' = quit").strip().lower()
if n == 'p':
mp3.pause()
elif n == 'u':
mp3.unpause()
elif n == 'pl':
mp3.play()
elif n == 's':
mp3.stop()
elif n == 'q':
break
else:
break
You could also put all of the valid answer options into a dictionary, but it looks like you should start with the simple solution to understand the flow. Also you used a p for both play and pause. You will want to use a unique value to differentiate so I added 'pl' for play.
Python 2.7.5 quit on user input
First of all, notice that you're doing int(raw_input())
everywhere. This means that when you try to enter quit as input, the program will raise a ValueError exception
and quit abnormally.
My suggestion is to modify a little bit the input loop:
while True:
i1 = raw_input("Enter in the value for red: ")
i2 = raw_input("Enter in the value for green: ")
i3 = raw_input("Enter in the value for blue: ")
if ((i1 == "quit") or (i2 == "quit") or (i3 == "quit")):
break
r = int(i1)
g = int(i2)
b = int(i3)
result = Brightness(r,g,b)
print result
result = Brightness(r,g,b)
Also I don't understand what the last line result = Brightness(r,g,b)
is for? It seems to me you're outputting the result in the last two lines in the loop.
Hope this helps!
Related Topics
Remove Non-Ascii Characters from Pandas Column
Finding a Substring Within a List in Python
Split String Based on a Regular Expression
How to Split/Partition a Dataset into Training and Test Datasets For, E.G., Cross Validation
Importerror: No Module Named Win32Api
Thread Local Storage in Python
Safest Way to Convert Float to Integer in Python
How to Get Md5 Sum of a String Using Python
How to Login to Django Using Tastypie
Fitting a Histogram with Python
Convert Year/Month/Day to Day of Year in Python
Zip with List Output Instead of Tuple
Activating Anaconda Environment in VScode
Python: Start New Command Prompt on Windows and Wait for It Finish/Exit