On Sun, Feb 22, 2009 at 11:51 AM, Daniel Jo
<ostsol@xxxxxxxxx> wrote:
What I mean by "circular" is sort of like a clock, where passing the
upper limit takes one back to the start again. Two hours passed 11 on
a 12-hour clock is 1 o'clock. Similarily three hours before 2 is 11
o'clock. Another example is a compass. Forty-five degrees left of
north, 0 degrees, is 315 degrees, rather than -45.
My need for it is for the latter example. In such an example,
comparisons such as "less-than" and "greater-than" aren't so important
as "left-of" and "right-of", respectively. Anything in the range
[180,360) is left of 0 and anything in the range (0, 180] is right of
0. Similarily, anything in the range [270,360) and [0,90) is left of
0.
My implementation is more of a utility class than a data-type:
import math
class RingBase (object):
def __init__ (self, lower, upper):
self.lower = lower
self.upper = upper
self.span = upper - lower
def __call__ (self, value):
if value > self.upper:
loops = int (value / self.span)
return value - self.span * loops
if value < self.lower:
loops = int (abs (value) / self.span) + 1
return value + self.span * loops
return value
def _lo (self, v1, v2):
v1 = self (v1)
v2 = self (v2)
half = self.span * 0.5
left = v2 - half
if left < self.lower:
if v1 >= self.upper - (v2 - self.lower):
return True
elif v1 < v2:
return True
elif v1 < v2 and v1 > left:
return True
return False
def _ro (self, v1, v2):
v1 = self (v1)
v2 = self (v2)
half = self.span * 0.5
right = v2 + half
if right >= self.upper:
if v1 <= self.lower + (self.upper - v2):
return True
elif v1 > v2:
return True
elif v1 > v2 and v1 < right:
return True
return False
class Ring (RingBase):
def __init__ (self, lower, upper):
super (Ring, self).__init__ (lower, upper)
lo = RingBase._lo
ro = RingBase._ro
class Radian (RingBase):
def __init__ (self):
super (Radian, self).__init__ (0.0, 2.0 * math.pi)
lo = RingBase._ro
ro = RingBase._lo
An instance of Ring is callable and is used to clamp a value within
the Ring's limits. For example. . .
ring = Ring (0, 12)
print ring (13)
. . . yields 1.
print ring (-1)
. . . yields 11.
ring.lo (11, 1)
. . . asks if 11 is left of 1 and returns True.
So is there anything else like this out there?
-Daniel