Hmm... I'd try something like this: print 13 % 12 . . . yields 1.
print -1 % 12 . . . yields 11. print 11 % 12 > 1 % 12 . . . asks if 11 is left of 1 and returns True. print ( 315 + 360 ) % 360 . . . yields 315 print 666 % 12 . . . yields 6... :o 2009/2/22 Daniel Jo <[email protected]>: > 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 > -- ____________________ Jussi Toivola
