def __init__(self, name, low, high, legalValues):
     self.name = name
     
     self.minimum = low
     self.maximum = high
     
     self.data = BTree()
class numericIndex(Persistent):
    '''
    Essentially an extension of durus.btree.BTree that accepts duplicate keys (via chaining)
    '''
    def __init__(self, name, low, high, legalValues):
        self.name = name
        
        self.minimum = low
        self.maximum = high
        
        self.data = BTree()
    
    def __getItem__(self, key):
        return self.data.get(key,[])
    
    def __setItem__(self, key, value):
        if self.minimum == None or key < self.minimum:
            self.minimum = key
        if self.maximum == None or key > self.maximum:
            self.maximum = key
        self.data[key] = value
    
    def count(self, low, high):
        return self.data.count_range(low,high,closed_start=True,closed_end=True)
    
    def has_key(self, key):
        return self.data.has_key(key)
    
    def findNaturalMinAndMax(self):
        if self.minimum == self.maximum:
            self.minimum = 0
            if self.maximum == 0:
                self.minimum = -1
                self.maximum = 1
                self._p_note_change()
                return
        elif self.minimum > self.maximum:
            temp = self.maximum
            self.maximum = self.minimum
            self.minimum = temp
        
        span = self.maximum - self.minimum
        
        if self.maximum > 0:
            nearestTenMax = 10**math.ceil(math.log10(self.maximum))
        elif self.maximum == 0:
            nearestTenMax = 0
        else:
            nearestTenMax = -10**math.floor(math.log10(-self.maximum))
        
        if self.minimum > 0:
            nearestTenMin = 10**math.floor(math.log10(self.minimum))
        elif self.minimum == 0:
            nearestTenMin = 0
        else:
            nearestTenMin = -10**math.ceil(math.log10(-self.minimum))
        
        # prefer nearestTenMax if the gap between it and self.maximum is less than 25% the span of the data
        if abs(nearestTenMax - self.maximum) < 0.25*span:
            self.maximum = nearestTenMax
        
        # prefer zero if the gap between it and self.minimum is less than 50% the span of the data, then 25% for nearestTenMin
        if self.minimum > 0 and self.minimum < 0.5*span:
            self.minimum = 0
        elif abs(self.minimum - nearestTenMin) < 0.25*span:
            self.minimum = nearestTenMin
        self._p_note_change()