title: User input - validation and confirmation -
body: <p>I am trying to perform something that has certainly been asked several times before (specifically <a href="https://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response">Asking the user for input until they give a valid response</a>, but I'm either trying to do something too complex or not thinking about my loops the correct way. </p>
  
  <p>In the code below, I am trying to do a few things:</p>
  
  <ul>
  <li>Ask the user for a list of integers, could be one or several (in this case, <code>loan_ids</code>)</li>
  <li>If the integer fails, reject the input loudly</li>
  <li>if an integer, append to a running list</li>
  <li>Convert all results to tuples to they can be used in a SQL query</li>
  </ul>
  
  <p>In the second func, I am trying to combine the first one and then also ask the user to confirm the <code>loan_ids</code> before cutting out:</p>
  
  <ul>
  <li>If the user enters <code>y</code>, then end the loop</li>
  <li>If the user enters <code>n</code>, go back to the first function and ask again</li>
  <li>If anything else is entered, ask the user to resubmit the answer</li>
  </ul>
  
  <p>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</p>
  
  <pre><code>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('&gt; 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
  </code></pre>
  
  <p>And the second piece - the way it's currently written forces the same result when a user enters anything but <code>y</code> - I'm trying to cause different behavior depending on whether the use has invalid input vs. actually confirms the <code>loan_ids</code> are incorrect. I also have used an extra break statement at the end, which I'm fairly sure is not best practice</p>
  
  <pre><code>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('&gt; 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-------------&gt; 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
  </code></pre>