Storing value with limits in object

Lie Lie.1296 at gmail.com
Mon Jun 23 17:28:29 EDT 2008


On Jun 23, 1:24 am, "Josip" <i... at i.i> wrote:
> > Why not make it a function?
>
> > function assignLimited(value, vmin, vmax):
> >     value = max(vmin, value)
> >     value = min(vmax, value)
> >     return value
>
> > a = assignLimited(7, 0, 10)
>
> > Seems like it solves your problem relatively cleanly.
> > Note: I also removed min/max variables because they would mask the
> > built-in min/max functions.
>
> > -Larry
>

> Still, I'm going for object
> oriented solution because I want the value and it's limits to be kept
> together as I'll have many such values with different limits.

In that case, "overriding assignment" makes no sense since if an
operation is done on two values that have two different limits, what
would happen? Take the first's or second's limits, or interpolate the
new limit by some magic function? A much better solution would be for
operation to always return plain vanilla int, and we set limits
explicitly.

> Storing all
> the limits in caller namespace is not really an option.

You want to store limits in the object too?

Try this: (_LimitedInt inherits from int, so operator overloading is
unnecessary)

###
#!/usr/bin/env python

class _LimitedInt(int):
    class InvalidLimitsError(Exception): pass

    def __init__(self, value, base = 10):
        int.__init__(value, base)

    def setlimits(self, lim):
        ''' Set the limits and if value is not within limit,
            raise ValueError

            The lim argument accepts:
            - A _LimitedInt instance, from which to copy the limits
            - A two-tuple, which specifies the limits i.e. (min, max)

            If lim isn't those or lim[0] > lim[1], raise
InvalidLimitsError

            Accepting _LimitedInt instance is just for convenience
        '''

        if isinstance(lim, _LimitedInt):
            lim = lim.limits

        try:
            self.min, self.max = [int(x) for x in lim]
            if self.min > self.max: raise ValueError
        except (ValueError, TypeError):
            raise self.InvalidLimitsError, ('limit = %s' % str(lim))

        if not (self.min < self < self.max):
            raise ValueError, \
                  ('val = %s, min = %s, max = %s' % \
                  (self, self.min, self.max))

    def getlimits(self):
        return (self.min, self.max)

    limits = property(getlimits, setlimits)

def lint(value, limits, base = 10):
    if base != 10:
        ret = _LimitedInt(value, base)
    else:
        ret = _LimitedInt(value)

    ret.limits = limits
    return ret

###         END OF REAL CODE        ###
### THE REST ARE JUST TESTING CODES ###

if __name__ == '__main__':
    print 'Instantiating lint...'
    a = lint(50, (0, 200))  # Limit explicitly specified
    b = lint(150, a)        # Copy the limits of a
    c = lint(a, (0, 1000))  # Value = a, Limit = (0, 1000)
    d = lint(a, c)          # Value = a, Limit = c
    print

    print 'Printing the value and the limits...'
    print a, a.limits
    print b, b.limits
    print c, c.limits
    print d, d.limits
    print

    print 'Changing limits'
    print 'Note: lint is partially immutable,'
    print '      its limits is mutable,'
    print '      while its value is immutable'
    a.limits = (0, 300)
    b.limits = a
    print a, a.limits
    print b, b.limits
    print

    print '"Changing" values'
    a = lint(b, a)
    print a, a.limits
    print

    print 'Operations...'
    e = lint(a + b - c * d + 100, (-10000, 1000))
    f = a + b - c * d              ## Operation returns plain integer
    g = lint(f, (-100000, 100000)) ## Always recast result of operator
    print e, e.limits, type(e)     ## This is an int, not lint
    print f, type(f)               ## BEWARE: f is integer, it has no
limits
    print g, g.limits, type(g)

    ## INVALIDS
    # a = lint(100, (1000, 100000))
    # a = lint(100, 'ab')
    # a = lint(100, (10000, 0))
    # a = lint(100, 10)
    # a = lint(100, (10, 1000, 10000))###



More information about the Python-list mailing list