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
 
     
    