I am trying to perform something that has certainly been asked several times before (specifically Asking the user for input until they give a valid response, but I'm either trying to do something too complex or not thinking about my loops the correct way.
In the code below, I am trying to do a few things:
- Ask the user for a list of integers, could be one or several (in this case,
loan_ids
) - If the integer fails, reject the input loudly
- if an integer, append to a running list
- Convert all results to tuples to they can be used in a SQL query
In the second func, I am trying to combine the first one and then also ask the user to confirm the loan_ids
before cutting out:
- If the user enters
y
, then end the loop - If the user enters
n
, go back to the first function and ask again - If anything else is entered, ask the user to resubmit the answer
I'm trying not to violate the Don't Repeat Yourself principle, but for the life of me I can't figure out the placement of the loops. I'm also relatively new to python and programming structure, so open to idiomatic comments on the design as well
def get_unique_loans_from_user():
"""Get list of loan_ids from user
This function is mean to capture raw loan_ids a user wishes to look up.
Returns tuple of unique loan_ids
"""
loan_ids = []
while True:
loan_id = raw_input('> Loan Id: ')
# If nothing entered, exit
if len(loan_id)==0:
break
# Make sure an integer was entered
else:
try:
int(loan_id)
except ValueError:
print loan_id + " is not a real integer, so likely not a valid loan id"
continue
# if an integer was entered, append to running list as an integer and continue
# We only need to return the unique list of loan ids
else:
loan_ids.append(int(loan_id))
# Convert unique list of loans to tuple to use in SQL
loans = tuple(np.unique(loan_ids))
# Return the tuple of loans
return loans
And the second piece - the way it's currently written forces the same result when a user enters anything but y
- I'm trying to cause different behavior depending on whether the use has invalid input vs. actually confirms the loan_ids
are incorrect. I also have used an extra break statement at the end, which I'm fairly sure is not best practice
def confirm_loan_ids():
""" Confirm the list of loan ids is what the user wanted"""
while True:
# Get loan ids from user through raw input
ids = get_unique_loans_from_user()
# Print out the ids to the user
print "Printing loan ids. There are {0} ids".format(len(ids))
print ids
# Confirm with user these are the correct ids
answer = raw_input('> Are these the loan ids you expected? [y/n] ')
# If user confirms correct, and continue
if answer == 'y':
print "\nExcellent - moving on\n"
print "Here are your loan ids:"
print ids
break
# If the answer is n, repeat the question
elif answer == 'n':
print "\n-------------> Let\'s try again\n"
continue
# If answer is not no or yes, ask again
elif (len(answer) == 0) or (answer not in ('y','n')):
print "Please enter only y or n"
continue
else:
print "This is only a test"
# The If loop only breaks when the answer is 'y'
break
return ids