def set_values():
loopCtrl = 1
while loopCtrl == 1:
loopCtrl = 2
juvenilePopulation = int(input("Enter the population of the juvenile greenfly (1000s) > "))
if not isinstance(juvenilePopulation, int): loopCtrl = 1
juvenileSurvivalRate = float(input("Enter the survival rate of juvenile greenfly (decimal) > "))
if not isinstance(juvenileSurvivalRate, float): loopCtrl = 1
adultPopulation = int(input("Enter the population of the adult greenfly (1000s) > "))
if not isinstance(adultPopulation, int): loopCtrl = 1
adultSurvivalRate = float(input("Enter the survival rate of adult greenfly (decimal) > "))
if not isinstance(adultSurvivalRate, float): loopCtrl = 1
senilePopulation = int(input("Enter the population of the senile greenfly (1000s) > "))
if not isinstance(senilePopulation, int): loopCtrl = 1
senileSurvivalRate = float(input("Enter the survival rate of senile greenfly (decimal) > "))
if not isinstance(senileSurvivalRate, float): loopCtrl = 1
birthRate = float(input("Enter the birthrate of the greenfly > "))
if not isinstance(birthRate, float): loopCtrl = 1
I have this admittedly ugly chunk of code, that currently just asks for a bunch of inputs, assigns it to variables, and then checks the type of the variable, before looping back around to the top. What I really want to achieve is for the code to loop back to the input statement that had the incorrect input rather than the beginning, but in a way that is more pythonistic than a ton of while loops.
CodePudding user response:
Replace your calls to input
with a function like this:
def get_value(prompt, validator):
while True:
try:
return validator(input(prompt))
except ValueError as err:
print(f" Invalid value, please try again: {err}")
You would call it like this:
juvenilePopulation = get_value("Enter the population of the juvenile greenfly (1000s) > ", int)
juvenileSurvivalRate = get_value("Enter the survival rate of juvenile greenfly (decimal) > ", float)
Running the above code looks something like this:
Enter the population of the juvenile greenfly (1000s) > foo
Invalid value, please try again: invalid literal for int() with base 10: 'foo'
Enter the population of the juvenile greenfly (1000s) > 1.1
Invalid value, please try again: invalid literal for int() with base 10: '1.1'
Enter the population of the juvenile greenfly (1000s) > 12
Enter the survival rate of juvenile greenfly (decimal) > bar
Invalid value, please try again: could not convert string to float: 'bar'
Enter the survival rate of juvenile greenfly (decimal) > 0.1
Note that in this example we're using basic types like int
and float
for validation, but you could just as easily pass in a custom function. For example, if the survival rate needs to be between 0 and 1, you could write:
def validateSurvivalRate(v):
v = float(v)
if not 0 < v < 1:
raise ValueError("surival rate must be between 0 and 1")
return v
juvenileSurvivalRate = get_value("Enter the survival rate of juvenile greenfly (decimal) > ", validateSurvivalRate)
Which would look like:
Enter the survival rate of juvenile greenfly (decimal) > foo
Invalid value, please try again: could not convert string to float: 'foo'
Enter the survival rate of juvenile greenfly (decimal) > 1.1
Invalid value, please try again: surival rate must be between 0 and 1
Enter the survival rate of juvenile greenfly (decimal) > -4
Invalid value, please try again: surival rate must be between 0 and 1
Enter the survival rate of juvenile greenfly (decimal) > 0.4
CodePudding user response:
Try like this. I'm not sure this is the best practice but you reuse code this code. you can add extra datatypes also
def process_values(input_string, input_values, data_type):
try:
if not isinstance(eval(input_values), data_type):
input_values = input(input_string)
process_values(input_string, input_values, data_type)
except NameError:
print('Invalid input')
input_values = input(input_string)
process_values(input_string, input_values, data_type)
input_strings = ['Enter the population of the juvenile greenfly (1000s) > ',
'Enter the survival rate of juvenile greenfly (decimal) > ',
'Enter the population of the adult greenfly (1000s) > ',
'Enter the survival rate of adult greenfly (decimal) > ',
'Enter the population of the senile greenfly (1000s) > ',
'Enter the survival rate of senile greenfly (decimal) >'
'Enter the birthrate of the greenfly > '
]
data_types = [int, float, int, float, int, float, float]
for input_string, data_type in zip(input_strings, data_types):
input_values = input(input_string)
process_values(input_string, input_values, data_type)
here i have handled errors also. if you need more exceptions condition you can add it there.