Is there a better way to evaluate user inputs without a 'for' loop and changing a checker from False to True?
Very new to python and have been, as an exercise, doing a text-based version of a board game (I'm an avid board gamer).
There are obviously lots of places for the user to input something, and naturally I need to evaluate those inputs and make sure they are valid.
I learned about using a True/False check and for loops from this site (thanks!) and now that I've done them so much I was wondering if there was a better way - they get a little crazy if they are nested and I want to to my best to adhere to those Zen-like Python rules.
Here is what I mean, in a simple example, using generic code so it makes sense (not all of you may know the rules of this board game!)
The goal is to make sure the code loops until a color or "none" is given. I know this accomplishes that, i'm just wondering if there is a more streamlined way that I haven't learned yet.
colors = ["red", "green", "white", "blue", "yellow"]
for color in colors:
print(f"You can choose {color}.")
choice = input("Which color would you choose? (input a color or 'none' : ")
checker = False
while not checker:
if choice not in colors:
choice = input("That's not one of your options. Choose again: ")
elif choice == "none":
print("You don't want a color. That's fine.")
checker = True
else:
print("You chose {color}! Have fun!")
checker = True
python python-3.x
add a comment |
Very new to python and have been, as an exercise, doing a text-based version of a board game (I'm an avid board gamer).
There are obviously lots of places for the user to input something, and naturally I need to evaluate those inputs and make sure they are valid.
I learned about using a True/False check and for loops from this site (thanks!) and now that I've done them so much I was wondering if there was a better way - they get a little crazy if they are nested and I want to to my best to adhere to those Zen-like Python rules.
Here is what I mean, in a simple example, using generic code so it makes sense (not all of you may know the rules of this board game!)
The goal is to make sure the code loops until a color or "none" is given. I know this accomplishes that, i'm just wondering if there is a more streamlined way that I haven't learned yet.
colors = ["red", "green", "white", "blue", "yellow"]
for color in colors:
print(f"You can choose {color}.")
choice = input("Which color would you choose? (input a color or 'none' : ")
checker = False
while not checker:
if choice not in colors:
choice = input("That's not one of your options. Choose again: ")
elif choice == "none":
print("You don't want a color. That's fine.")
checker = True
else:
print("You chose {color}! Have fun!")
checker = True
python python-3.x
3
this looks reasonable ...
– Joran Beasley
Nov 20 '18 at 0:40
Think about a full-blown argument parser likeargparse
orclick
- they don't need to be used on the program's command-line argument. Even if you don't actually use one of them, the mindset may be useful.
– o11c
Nov 20 '18 at 0:48
add a comment |
Very new to python and have been, as an exercise, doing a text-based version of a board game (I'm an avid board gamer).
There are obviously lots of places for the user to input something, and naturally I need to evaluate those inputs and make sure they are valid.
I learned about using a True/False check and for loops from this site (thanks!) and now that I've done them so much I was wondering if there was a better way - they get a little crazy if they are nested and I want to to my best to adhere to those Zen-like Python rules.
Here is what I mean, in a simple example, using generic code so it makes sense (not all of you may know the rules of this board game!)
The goal is to make sure the code loops until a color or "none" is given. I know this accomplishes that, i'm just wondering if there is a more streamlined way that I haven't learned yet.
colors = ["red", "green", "white", "blue", "yellow"]
for color in colors:
print(f"You can choose {color}.")
choice = input("Which color would you choose? (input a color or 'none' : ")
checker = False
while not checker:
if choice not in colors:
choice = input("That's not one of your options. Choose again: ")
elif choice == "none":
print("You don't want a color. That's fine.")
checker = True
else:
print("You chose {color}! Have fun!")
checker = True
python python-3.x
Very new to python and have been, as an exercise, doing a text-based version of a board game (I'm an avid board gamer).
There are obviously lots of places for the user to input something, and naturally I need to evaluate those inputs and make sure they are valid.
I learned about using a True/False check and for loops from this site (thanks!) and now that I've done them so much I was wondering if there was a better way - they get a little crazy if they are nested and I want to to my best to adhere to those Zen-like Python rules.
Here is what I mean, in a simple example, using generic code so it makes sense (not all of you may know the rules of this board game!)
The goal is to make sure the code loops until a color or "none" is given. I know this accomplishes that, i'm just wondering if there is a more streamlined way that I haven't learned yet.
colors = ["red", "green", "white", "blue", "yellow"]
for color in colors:
print(f"You can choose {color}.")
choice = input("Which color would you choose? (input a color or 'none' : ")
checker = False
while not checker:
if choice not in colors:
choice = input("That's not one of your options. Choose again: ")
elif choice == "none":
print("You don't want a color. That's fine.")
checker = True
else:
print("You chose {color}! Have fun!")
checker = True
python python-3.x
python python-3.x
edited Nov 20 '18 at 0:39
cricket_007
80k1142110
80k1142110
asked Nov 20 '18 at 0:37
JonathanJonathan
314
314
3
this looks reasonable ...
– Joran Beasley
Nov 20 '18 at 0:40
Think about a full-blown argument parser likeargparse
orclick
- they don't need to be used on the program's command-line argument. Even if you don't actually use one of them, the mindset may be useful.
– o11c
Nov 20 '18 at 0:48
add a comment |
3
this looks reasonable ...
– Joran Beasley
Nov 20 '18 at 0:40
Think about a full-blown argument parser likeargparse
orclick
- they don't need to be used on the program's command-line argument. Even if you don't actually use one of them, the mindset may be useful.
– o11c
Nov 20 '18 at 0:48
3
3
this looks reasonable ...
– Joran Beasley
Nov 20 '18 at 0:40
this looks reasonable ...
– Joran Beasley
Nov 20 '18 at 0:40
Think about a full-blown argument parser like
argparse
or click
- they don't need to be used on the program's command-line argument. Even if you don't actually use one of them, the mindset may be useful.– o11c
Nov 20 '18 at 0:48
Think about a full-blown argument parser like
argparse
or click
- they don't need to be used on the program's command-line argument. Even if you don't actually use one of them, the mindset may be useful.– o11c
Nov 20 '18 at 0:48
add a comment |
3 Answers
3
active
oldest
votes
You could define a generic function if you find yourself repeating the same things
def prompt_for_valid_input(options):
while True:
print(f"You can choose one of {options}.")
choice = input("Which would you choose? (or 'none' : ")
if choice == "none" and "none" not in options:
print("You didn't pick anything. That's fine.")
return None
elif choice in options:
return choice
else:
print("That's not one of your options. Choose again. ")
colors = ["red", "green", "white", "blue", "yellow"]
color = prompt_for_valid_input(colors)
if color is not None:
print(f"You chose {color}! Have fun!")
numbers = [1, 10, 100]
num = prompt_for_valid_input(numbers)
if num is not None:
print(f"You chose {num}! Have fun!")
So "without a while/for loop", not really. Without a sentinel variable, yes, if the conditions are simple enough.
Thanks for this, I like this idea. In my code, often times entering a certain input launches a function which itself might have more input validators. I like this idea and can probably implement it wisely in the right spots.
– Jonathan
Nov 20 '18 at 0:54
add a comment |
you can abstract it out to a generic validated input method
def validated_input(prompt,validation_method,error_message):
while True:
result = input(prompt)
if validation_method(result):
return result
print(error_message)
choices = ['red','green','blue','none']
validator = lambda test:test.lower().strip() in choices
prompt = "Enter A Color(one of Red, Green, Blue, or None):"
error_message = "Please enter a valid color or None!"
print(validated_input(prompt,validator,error_message))
its arguable whether this is "better"
Thanks Jordan. I see now how a function like this can actually help me a lot. Often my validations lead to a function, and sometimes those have more validations. I'll play with these kind of constructions and see if i can improve the code!
– Jonathan
Nov 20 '18 at 0:56
*Joran! want to get your name right.
– Jonathan
Nov 20 '18 at 1:12
add a comment |
Usually how you wrote your code is considered pretty "normal" and straightforward which is good. The issue is that you would want the looping part of your code to repeat till it has met its expectation. So a conditional looping event is necessary. If you really want you can simplify it a little by making a break statement for example:
x = 0
while True:
if x == 12:
break;
else:
x = x + 1
print(x)
This will create a infinite loop until the condition you are looking for is met and then it will break out of the loop. Make sure you have your escape condition though.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53384614%2fis-there-a-better-way-to-evaluate-user-inputs-without-a-for-loop-and-changing%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
You could define a generic function if you find yourself repeating the same things
def prompt_for_valid_input(options):
while True:
print(f"You can choose one of {options}.")
choice = input("Which would you choose? (or 'none' : ")
if choice == "none" and "none" not in options:
print("You didn't pick anything. That's fine.")
return None
elif choice in options:
return choice
else:
print("That's not one of your options. Choose again. ")
colors = ["red", "green", "white", "blue", "yellow"]
color = prompt_for_valid_input(colors)
if color is not None:
print(f"You chose {color}! Have fun!")
numbers = [1, 10, 100]
num = prompt_for_valid_input(numbers)
if num is not None:
print(f"You chose {num}! Have fun!")
So "without a while/for loop", not really. Without a sentinel variable, yes, if the conditions are simple enough.
Thanks for this, I like this idea. In my code, often times entering a certain input launches a function which itself might have more input validators. I like this idea and can probably implement it wisely in the right spots.
– Jonathan
Nov 20 '18 at 0:54
add a comment |
You could define a generic function if you find yourself repeating the same things
def prompt_for_valid_input(options):
while True:
print(f"You can choose one of {options}.")
choice = input("Which would you choose? (or 'none' : ")
if choice == "none" and "none" not in options:
print("You didn't pick anything. That's fine.")
return None
elif choice in options:
return choice
else:
print("That's not one of your options. Choose again. ")
colors = ["red", "green", "white", "blue", "yellow"]
color = prompt_for_valid_input(colors)
if color is not None:
print(f"You chose {color}! Have fun!")
numbers = [1, 10, 100]
num = prompt_for_valid_input(numbers)
if num is not None:
print(f"You chose {num}! Have fun!")
So "without a while/for loop", not really. Without a sentinel variable, yes, if the conditions are simple enough.
Thanks for this, I like this idea. In my code, often times entering a certain input launches a function which itself might have more input validators. I like this idea and can probably implement it wisely in the right spots.
– Jonathan
Nov 20 '18 at 0:54
add a comment |
You could define a generic function if you find yourself repeating the same things
def prompt_for_valid_input(options):
while True:
print(f"You can choose one of {options}.")
choice = input("Which would you choose? (or 'none' : ")
if choice == "none" and "none" not in options:
print("You didn't pick anything. That's fine.")
return None
elif choice in options:
return choice
else:
print("That's not one of your options. Choose again. ")
colors = ["red", "green", "white", "blue", "yellow"]
color = prompt_for_valid_input(colors)
if color is not None:
print(f"You chose {color}! Have fun!")
numbers = [1, 10, 100]
num = prompt_for_valid_input(numbers)
if num is not None:
print(f"You chose {num}! Have fun!")
So "without a while/for loop", not really. Without a sentinel variable, yes, if the conditions are simple enough.
You could define a generic function if you find yourself repeating the same things
def prompt_for_valid_input(options):
while True:
print(f"You can choose one of {options}.")
choice = input("Which would you choose? (or 'none' : ")
if choice == "none" and "none" not in options:
print("You didn't pick anything. That's fine.")
return None
elif choice in options:
return choice
else:
print("That's not one of your options. Choose again. ")
colors = ["red", "green", "white", "blue", "yellow"]
color = prompt_for_valid_input(colors)
if color is not None:
print(f"You chose {color}! Have fun!")
numbers = [1, 10, 100]
num = prompt_for_valid_input(numbers)
if num is not None:
print(f"You chose {num}! Have fun!")
So "without a while/for loop", not really. Without a sentinel variable, yes, if the conditions are simple enough.
answered Nov 20 '18 at 0:45
cricket_007cricket_007
80k1142110
80k1142110
Thanks for this, I like this idea. In my code, often times entering a certain input launches a function which itself might have more input validators. I like this idea and can probably implement it wisely in the right spots.
– Jonathan
Nov 20 '18 at 0:54
add a comment |
Thanks for this, I like this idea. In my code, often times entering a certain input launches a function which itself might have more input validators. I like this idea and can probably implement it wisely in the right spots.
– Jonathan
Nov 20 '18 at 0:54
Thanks for this, I like this idea. In my code, often times entering a certain input launches a function which itself might have more input validators. I like this idea and can probably implement it wisely in the right spots.
– Jonathan
Nov 20 '18 at 0:54
Thanks for this, I like this idea. In my code, often times entering a certain input launches a function which itself might have more input validators. I like this idea and can probably implement it wisely in the right spots.
– Jonathan
Nov 20 '18 at 0:54
add a comment |
you can abstract it out to a generic validated input method
def validated_input(prompt,validation_method,error_message):
while True:
result = input(prompt)
if validation_method(result):
return result
print(error_message)
choices = ['red','green','blue','none']
validator = lambda test:test.lower().strip() in choices
prompt = "Enter A Color(one of Red, Green, Blue, or None):"
error_message = "Please enter a valid color or None!"
print(validated_input(prompt,validator,error_message))
its arguable whether this is "better"
Thanks Jordan. I see now how a function like this can actually help me a lot. Often my validations lead to a function, and sometimes those have more validations. I'll play with these kind of constructions and see if i can improve the code!
– Jonathan
Nov 20 '18 at 0:56
*Joran! want to get your name right.
– Jonathan
Nov 20 '18 at 1:12
add a comment |
you can abstract it out to a generic validated input method
def validated_input(prompt,validation_method,error_message):
while True:
result = input(prompt)
if validation_method(result):
return result
print(error_message)
choices = ['red','green','blue','none']
validator = lambda test:test.lower().strip() in choices
prompt = "Enter A Color(one of Red, Green, Blue, or None):"
error_message = "Please enter a valid color or None!"
print(validated_input(prompt,validator,error_message))
its arguable whether this is "better"
Thanks Jordan. I see now how a function like this can actually help me a lot. Often my validations lead to a function, and sometimes those have more validations. I'll play with these kind of constructions and see if i can improve the code!
– Jonathan
Nov 20 '18 at 0:56
*Joran! want to get your name right.
– Jonathan
Nov 20 '18 at 1:12
add a comment |
you can abstract it out to a generic validated input method
def validated_input(prompt,validation_method,error_message):
while True:
result = input(prompt)
if validation_method(result):
return result
print(error_message)
choices = ['red','green','blue','none']
validator = lambda test:test.lower().strip() in choices
prompt = "Enter A Color(one of Red, Green, Blue, or None):"
error_message = "Please enter a valid color or None!"
print(validated_input(prompt,validator,error_message))
its arguable whether this is "better"
you can abstract it out to a generic validated input method
def validated_input(prompt,validation_method,error_message):
while True:
result = input(prompt)
if validation_method(result):
return result
print(error_message)
choices = ['red','green','blue','none']
validator = lambda test:test.lower().strip() in choices
prompt = "Enter A Color(one of Red, Green, Blue, or None):"
error_message = "Please enter a valid color or None!"
print(validated_input(prompt,validator,error_message))
its arguable whether this is "better"
answered Nov 20 '18 at 0:45
Joran BeasleyJoran Beasley
72.5k678118
72.5k678118
Thanks Jordan. I see now how a function like this can actually help me a lot. Often my validations lead to a function, and sometimes those have more validations. I'll play with these kind of constructions and see if i can improve the code!
– Jonathan
Nov 20 '18 at 0:56
*Joran! want to get your name right.
– Jonathan
Nov 20 '18 at 1:12
add a comment |
Thanks Jordan. I see now how a function like this can actually help me a lot. Often my validations lead to a function, and sometimes those have more validations. I'll play with these kind of constructions and see if i can improve the code!
– Jonathan
Nov 20 '18 at 0:56
*Joran! want to get your name right.
– Jonathan
Nov 20 '18 at 1:12
Thanks Jordan. I see now how a function like this can actually help me a lot. Often my validations lead to a function, and sometimes those have more validations. I'll play with these kind of constructions and see if i can improve the code!
– Jonathan
Nov 20 '18 at 0:56
Thanks Jordan. I see now how a function like this can actually help me a lot. Often my validations lead to a function, and sometimes those have more validations. I'll play with these kind of constructions and see if i can improve the code!
– Jonathan
Nov 20 '18 at 0:56
*Joran! want to get your name right.
– Jonathan
Nov 20 '18 at 1:12
*Joran! want to get your name right.
– Jonathan
Nov 20 '18 at 1:12
add a comment |
Usually how you wrote your code is considered pretty "normal" and straightforward which is good. The issue is that you would want the looping part of your code to repeat till it has met its expectation. So a conditional looping event is necessary. If you really want you can simplify it a little by making a break statement for example:
x = 0
while True:
if x == 12:
break;
else:
x = x + 1
print(x)
This will create a infinite loop until the condition you are looking for is met and then it will break out of the loop. Make sure you have your escape condition though.
add a comment |
Usually how you wrote your code is considered pretty "normal" and straightforward which is good. The issue is that you would want the looping part of your code to repeat till it has met its expectation. So a conditional looping event is necessary. If you really want you can simplify it a little by making a break statement for example:
x = 0
while True:
if x == 12:
break;
else:
x = x + 1
print(x)
This will create a infinite loop until the condition you are looking for is met and then it will break out of the loop. Make sure you have your escape condition though.
add a comment |
Usually how you wrote your code is considered pretty "normal" and straightforward which is good. The issue is that you would want the looping part of your code to repeat till it has met its expectation. So a conditional looping event is necessary. If you really want you can simplify it a little by making a break statement for example:
x = 0
while True:
if x == 12:
break;
else:
x = x + 1
print(x)
This will create a infinite loop until the condition you are looking for is met and then it will break out of the loop. Make sure you have your escape condition though.
Usually how you wrote your code is considered pretty "normal" and straightforward which is good. The issue is that you would want the looping part of your code to repeat till it has met its expectation. So a conditional looping event is necessary. If you really want you can simplify it a little by making a break statement for example:
x = 0
while True:
if x == 12:
break;
else:
x = x + 1
print(x)
This will create a infinite loop until the condition you are looking for is met and then it will break out of the loop. Make sure you have your escape condition though.
answered Nov 20 '18 at 1:24
Jay PatelJay Patel
261
261
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53384614%2fis-there-a-better-way-to-evaluate-user-inputs-without-a-for-loop-and-changing%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
this looks reasonable ...
– Joran Beasley
Nov 20 '18 at 0:40
Think about a full-blown argument parser like
argparse
orclick
- they don't need to be used on the program's command-line argument. Even if you don't actually use one of them, the mindset may be useful.– o11c
Nov 20 '18 at 0:48