Re: using min and max with float

Ian Bicking <[email protected]> Tue, 13 May 2008 16:38:03 -0500
Newsgroups gmane.comp.python.formencode
Message-ID <[email protected]>
This has been applied, r3416

Shannon -jj Behrens wrote:
> On Fri, May 2, 2008 at 8:30 AM, Ian Bicking <[email protected]> wrote:
>> Re: Range -- perhaps that could be an abstract base class for Float and Int?
> 
> Yes, that's an excellent idea.  Duh ;)
> 
> My style is just slightly different than yours, but here's the code
> with doctests and all:
> 
> class RangeValidator(FancyValidator):
> 
>     """This is an abstract base class for Int and Number.
> 
>     It verifies that a value is within range.  It accepts min and max
>     values in the constructor.
> 
>     (Since this is an abstract base class, the tests are in Int and
>     Number.)
> 
>     """
> 
>     messages = {
>         'tooLow': _("Please enter a number that is %(min)s or greater"),
>         'tooHigh': _("Please enter a number that is %(max)s or smaller"),
>     }
> 
>     min = None
>     max = None
> 
>     def validate_python(self, value, state):
> 
>         # There's some duplicated code here, but it's a lot more
>         # readable than the alternative.
> 
>         if self.min is not None:
>             if value < self.min:
>                 msg = self.message("tooLow", state, min=self.min)
>                 raise Invalid(msg, value, state)
>         if self.max is not None:
>             if value > self.max:
>                 msg = self.message("tooHigh", state, max=self.max)
>                 raise Invalid(msg, value, state)
> 
> 
> class Int(RangeValidator):
> 
>     """Convert a value to an integer.
> 
>     Example::
> 
>         >>> Int.to_python('10')
>         10
>         >>> Int.to_python('ten')
>         Traceback (most recent call last):
>             ...
>         Invalid: Please enter an integer value
>         >>> Int(min=5).to_python('6')
>         6
>         >>> Int(max=10).to_python('11')
>         Traceback (most recent call last):
>             ...
>         Invalid: Please enter a number that is 10 or smaller
> 
>     """
> 
>     messages = {
>         'integer': _("Please enter an integer value")
>     }
> 
>     def _to_python(self, value, state):
>         try:
>             return int(value)
>         except (ValueError, TypeError):
>             raise Invalid(self.message('integer', state),
>                           value, state)
> 
>     _from_python = _to_python
> 
> 
> class Number(RangeValidator):
> 
>     """Convert a value to a float or integer.
> 
>     Tries to convert it to an integer if no information is lost.
> 
>     Example::
> 
>         >>> Number.to_python('10')
>         10
>         >>> Number.to_python('10.5')
>         10.5
>         >>> Number.to_python('ten')
>         Traceback (most recent call last):
>             ...
>         Invalid: Please enter a number
>         >>> Number(min=5).to_python('6.5')
>         6.5
>         >>> Number(max=10.5).to_python('11.5')
>         Traceback (most recent call last):
>             ...
>         Invalid: Please enter a number that is 10.5 or smaller
> 
>     """
> 
>     messages = {
>         'number': _("Please enter a number")
>     }
> 
>     def _to_python(self, value, state):
>         try:
>             value = float(value)
>             if value == int(value):
>                 return int(value)
>             return value
>         except ValueError:
>             raise Invalid(self.message('number', state),
>                           value, state)
> 
> Best Regards,
> -jj
> 


-- 
Ian Bicking : [email protected] : http://blog.ianbicking.org

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/