How to Let a Raw_Input Repeat Until I Want to Quit

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



Leave a reply



Submit