By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,994 Members | 1,166 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,994 IT Pros & Developers. It's quick & easy.

Implementing a circular counter using property / descriptors?

P: n/a
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
Oct 8 '06 #1
Share this Question
Share on Google+
2 Replies


P: n/a
On Sun, 08 Oct 2006 12:25:10 +0200, 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.
[snip]
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
All this is perfectly sensible.
cnt = 100 # cnt new value is 100 [NOT rebind cnt with 100]
This is not possible. Names like cnt are just labels, they don't have
behaviour. Objects have behaviour; but objects don't and can't know what
name or names they are assigned to.

[snip]
The fact is that I don't like to write cnt.set(100) or
cnt = CircularConter(100, 100) instead of cnt = 100.
How do you expect the Python compiler to know you want a CircularConter
instance if you just write 100?

(By the way, in English, the correct spelling is counter, not conter.)
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.
__cmp__ is for CoMParisons, not binding names to objects.
--
Steven.

Oct 8 '06 #2

P: n/a

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

Oct 9 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.