Implementing a circular counter using property / descriptors?

IloChab IloChab at yahoo.it
Sun Oct 8 06:25:10 EDT 2006


I'd like to implement an object that represents a circular counter, i.e.
an integer that returns to zero when it goes over it's maxVal.

This counter has a particular behavior in comparison: if I compare two of
them an they differ less than half of maxVal I want that, for example, 
0 > maxVal gives true. 
This is because my different counters  grew together and they never
differ a lot between them and so a value of 0 compared with an other of
maxVal means that the previous one just made its increment before the
other one.

The python problem that I give you it's about style. 
I'd like to write in my code something that looks almost like using an
integer object.  

I mean, I'd like to write:

cnt = CircularConter(maxVal=100, initialVal=10) 
cnt += 100     # cnt value is 9
print cnt      # prints 9
100 > cnt      # is false
cnt = 100      # cnt new value is 100 [NOT  rebind cnt with 100]

Until now I used this class:

class CircularConter:

    def __init__(self, maxVal, initialVal=0):
        self.maxVal = maxVal
        self.val = None
        self.set( initialVal )

    def __add__(self, increment):
        self.set( self.val + increment )
        return self

    def __cmp__(self, operand):
        return cmp(self.maxVal/2, abs(operand - self.val)) * cmp(self.val,
        operand)

    def __repr__(self):
        return str(self.val)
    def __str__(self):
        return str(self.val)

    def set(self, val):
        if val > self.maxVal:       self.val = val-self.maxVal-1 
        else:                       self.val = val


... and so my real writing was:

cnt = CircularConter(maxVal=100, initialVal=10) 
cnt += 100   
print cnt    
100 > cnt        # is false  
cnt.set(100)   

The fact is that I don't like to write cnt.set(100) or  
cnt = CircularConter(100, 100) instead of cnt = 100. 
So I thought that property or descriptors could be useful. 
I was even glad to write:

cnt = CircularConterWithProperty(maxVal=100, initialVal=10) 
cnt.val += 100
print cnt.val
100 > cnt.val      # is false
cnt.val = 100

just to give uniformity to counter accessing syntax. 
But I wasn't able to implement nothing working with my __cmp__ method.

I'll post one of mine NOT WORKING implementation.


class pro(object):

    def __init__(self, maxVal, val):
        self._maxVal = maxVal
        self._val = val
        
    def getval(self):
        return self._val
    
    def setval(self, val):
        if val > self._maxVal:       self._val = val-self._maxVal-1 
	else:                        self._val = val
    val = property(getval, setval)


class CircularConterWithProperty(pro):

    def __init__(self, maxVal, val=0):
        super(CircularConterWithProperty, self).__init__( maxVal, val)

    def __cmp__(self, operand):
        return cmp(self.maxVal/2, abs(operand - self.val)) * cmp(self.val,
        operand)



__ I know why this doesn't work. __

__ What I don't know __  is if there is a way to write a class that allows
my desire of uniform syntax or if IT IS JUST A NON SENSE.

I'll thank in advance for any answer.

Saluti a tutti
Licia



More information about the Python-list mailing list