Req: Error Trapping / Data Validation

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Dave067
    New Member
    • Sep 2010
    • 17

    Req: Error Trapping / Data Validation

    Hi!

    I'm a beginner using Python 2.5

    I'm trying to write a module which will peform the function of data entry and error trapping.

    If the user enters an integer outside of a pre-defined range or tries to enter an non-integer value, the module will ask to re-enter until a correct response is made.

    I want to call the module repeatedly with different sets of parameters for allowable data range from different points within the main program.

    I'm sure this is a very common problem, but can't find the exact solution that I'm looking for in any book or on line, and would be very grateful for your help & guidance.

    I've attached my latest (buggy, non-working) attempt to illustrate what I'm trying to achieve.

    Many thanks in anticipation

    Dave

    Code:
    def getdata(low_limit,high_limit):
        
    """Ask user to input integer between certain values
    If non-integer is entered, or integer is outside of defined range then
    Ask user to re-input until correct response is given"""
    
        try:
            n=int(input('Please enter integer between',low_limit,' and ',high_limit,' >'))
            return int(n)
        except (ValueError,TypeError, n<low_limit, n>high_limit):
            return "Error - please re-enter"
                 
    def main():
        getdata(0,10)
        print "done"
  • bvdet
    Recognized Expert Specialist
    • Oct 2006
    • 2851

    #2
    Instead of a try/except block, use a while True loop. Example:
    Code:
    >>> while True:
    ... 	ans = raw_input("Enter an integer between 1 and 10")
    ... 	if ans.isdigit():
    ... 		ans = int(ans)
    ... 		if 1 <= ans <= 10:
    ... 			print "You entered a valid number (%s)" % (ans)
    ... 			break
    ... 		else:
    ... 			print "You entered an INVALID number (%s). Try again." % (ans)
    ... 	else:
    ... 		"You entered a letter (%s). Try again." % (ans)
    ... 		
    You entered a letter (AA). Try again.
    You entered an INVALID number (13). Try again.
    You entered a valid number (5)
    >>>

    Comment

    • Dave067
      New Member
      • Sep 2010
      • 17

      #3
      Hi Bvdet

      Many thanks for your help - much appreciated

      3 further thoughts / queries:

      1)
      I was wondering if it is possible to go one step further, and make this module completely customisable for repeated use by somehow passing logical arguments (as strings) to define module parameters for error detection.

      e.g. so that I could call the module from one point in main() as:

      getdata(' 1 <= ans <= 10 ')

      ...to force the user to input a value which is not a letter and within the range 1-10
      ...then maybe later in the same main program, if I want the user to input another variable with different error parameters I could do something like e.g.

      getdata(' ans%3==0 and ans>0 ')

      ...to get the user to input a value which is not a letter but is greater than zero and divisible by 3

      I'm not sure if it is possible to convert strings to parameters that can be passed to a function, and then interpreted as booleans in this way, but it would keep the main() loop really clutter-free and be an elegant solution if it were possible.

      2)
      I attempted to add further variables and text characters to the "input" statement of the error trapping function to make it display the parameters when it was called.
      My pseudocode:
      n=int(input('Pl ease enter integer between',low_li mit,' and ',high_limit,' >'))

      - is obviously wrong.
      Is there a neat way to append variable values and further text strings within the same input statement as above? or do I have to do something like:

      explain = 'Please enter integer between' + str(low_limit)+ 'and ' str(high_limit) +' >'
      input (explain)

      3)
      Would Python 3.x instead of 2.x offer me more functionality to do this sort of task?

      Sorry to ask dumb questions, but hope I've managed to explain what I'm trying to achieve...
      Just not sure if it can be done or how to do it ;-)

      Kind regards

      Dave
      (UK)

      Comment

      • bvdet
        Recognized Expert Specialist
        • Oct 2006
        • 2851

        #4
        #1 - Something like these functions:
        Code:
        def getint(low, high):
            while True:
                ans = raw_input("Enter an integer between %s and %s" % (low, high))
                if ans.isdigit():
                    ans = int(ans)
                    if low <= ans <= high:
                        print "You entered a valid number (%s)." % (ans)
                        return ans
                    else:
                        print "You entered an INVALID number (%s). Try again." % (ans)
                else:
                    print "You entered an alpha character(s) (%s). Try again." % (ans)
        
        print getint(15, 125)
        
        
        def getint1(expression):
            while True:
                X = raw_input("Enter an integer 'X' such that %s" % (expression))
                if X.isdigit():
                    X = int(X)
                    if eval(expression):
                        print "You entered a valid number (%s)." % (X)
                        return X
                    else:
                        print "You entered an INVALID number (%s). Try again." % (X)
                else:
                    print "You entered an alpha character(s) (%s). Try again." % (X)
        
        print getint1('X%3==0 and X>0')
        #2 Use string formatting as shown above.
        #3 I don't know of anything in Python 3 that makes this task easier.

        Comment

        • Dave067
          New Member
          • Sep 2010
          • 17

          #5
          Many thanks Bvdet

          These routines do exactly what I needed.
          They also have taught me some very useful new techniques, so will study these for future reference.

          Best wishes

          Dave

          Comment

          • Dave067
            New Member
            • Sep 2010
            • 17

            #6
            Hi again!

            With the second routine, if a user enters a negative number or a non integer, the isdigit() command detects "." or "-" as non digit characters, and so returns the error message "You entered an alpha character..."

            I've tried converting the code to Python 3 and using the isnumeric() function, but this does not return "True" if the string contains "." or "-" either...

            Is there an easy way to modify the code to include detection and appropriate error messages if the user enters a negative number or non-integer?

            Thanks again!

            Dave

            Comment

            • bvdet
              Recognized Expert Specialist
              • Oct 2006
              • 2851

              #7
              To allow for a leading "-" character: if ans.lstrip("-").isdigit( ):

              To allow a float entry, the function needs to be modified.
              Code:
              def getfloat(low, high):
                  while True:
                      ans = raw_input("Enter a number between %s and %s" % (low, high))
                      try:
                          ans = float(ans)
                          if low <= ans <= high:
                              print "You entered a valid number (%s)." % (ans)
                              return ans
                          else:
                              print "You entered a number out of range (%s). Try again." % (ans)
                      except:
                          print "You entered an INVALID number (%s). Try again." % (ans)

              Comment

              • Dave067
                New Member
                • Sep 2010
                • 17

                #8
                Many thanks for this - much appreciated.

                Now you've explained how to do it, it seems obvious!

                Best wishes

                Dave

                Comment

                Working...