Implementing a circular counter using property / descriptors?
Gerard Flanagan
grflanagan at yahoo.co.uk
Mon Oct 9 06:05:06 EDT 2006
IloChab wrote:
> 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]
>
[...]
> ... 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.
>
[...]
>
> __ 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
As Steven said, it's not possible to do what you want. I don't think
there's any way around either
cnt.val = 100
or
cnt.setval(100)
Here's an iterator version of your Counter class:
class Counter(object):
def __init__(self, maxval, initval=0):
self.maxval = maxval
self.val = initval
def __iter__(self):
return self
def next(self):
ret = self.val
self.__add__(1)
return ret
def __add__(self, increment):
self.val = (self.val + increment) % self.maxval
return self
def __sub__(self, decrement):
self.val = (self.val - decrement) % self.maxval
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)
cnt = Counter(10)
print cnt
cnt += 23
print cnt, cnt > 5
cnt.val = 7
print
print cnt, cnt > 5
cnt -= 65
print
print cnt, cnt > 5
print
print zip(cnt, ['a', 'b', 'c', 'd'])
-----------------------
Gerard
More information about the Python-list
mailing list