def __cmp__(self, other): if isinstance(other, (str, string_types, tuple, list)): other = SmartVersion(other) elif isinstance(other, SmartVersion): pass elif isinstance(other, Version): other = SmartVersion(other.vstring) else: raise ValueError("Do not know how to treat version %s" % str(other)) if sys.version >= '3': def cmp(a, b): """Compatibility with Python3 -- regular (deprecated in 3) cmp operation should be sufficient for our needs""" return (a > b) - (a < b) else: # having above cmp overloads builtin cmp for this function so we # need manually rebind it or just resort to above cmp in general # (why not?) from __builtin__ import cmp # Do ad-hoc comparison of strings i = 0 s, o = self.version, other.version regex_prerelease = re.compile( '~|-?dev|-?rc|-?svn|-?pre|-?beta|-?alpha', re.I) for i in range(max(len(s), len(o))): if i < len(s): si = s[i] else: si = None if i < len(o): oi = o[i] else: oi = None if si == oi: continue for x, y, mult in ((si, oi, 1), (oi, si, -1)): if x is None: if isinstance(y, int): return -mult # we got '.1' suffix if isinstance(y, str): if (regex_prerelease.match(y)): return mult # so we got something to signal # pre-release, so first one won else: # otherwise the other one wins return -mult else: raise RuntimeError("Should not have got here with %s" \ % y) elif isinstance(x, int): if not isinstance(y, int): return mult return mult * cmp(x, y) # both are ints elif isinstance(x, str): if isinstance(y, str): return mult * cmp(x, y) return 0
def __cmp__(self, other): if isinstance(other, (str, string_types, tuple, list)): other = SmartVersion(other) elif isinstance(other, SmartVersion): pass elif isinstance(other, Version): other = SmartVersion(other.vstring) else: raise ValueError("Do not know how to treat version %s" % str(other)) if sys.version >= '3': def cmp(a, b): """Compatibility with Python3 -- regular (deprecated in 3) cmp operation should be sufficient for our needs""" return (a > b) - (a < b) else: # having above cmp overloads builtin cmp for this function so we # need manually rebind it or just resort to above cmp in general # (why not?) from __builtin__ import cmp # Do ad-hoc comparison of strings i = 0 s, o = self.version, other.version regex_prerelease = re.compile('~|-?dev|-?rc|-?svn|-?pre|-?beta|-?alpha', re.I) for i in range(max(len(s), len(o))): if i < len(s): si = s[i] else: si = None if i < len(o): oi = o[i] else: oi = None if si == oi: continue for x,y,mult in ((si, oi, 1), (oi, si, -1)): if x is None: if isinstance(y, int): return -mult # we got '.1' suffix if isinstance(y, str): if (regex_prerelease.match(y)): return mult # so we got something to signal # pre-release, so first one won else: # otherwise the other one wins return -mult else: raise RuntimeError("Should not have got here with %s" \ % y) elif isinstance(x, int): if not isinstance(y, int): return mult return mult*cmp(x, y) # both are ints elif isinstance(x, str): if isinstance(y, str): return mult*cmp(x,y) return 0
def cmp(x, y): """Return -1 if x < y, 0 if x == y, +1 if x > y.""" type_x = type(x) try: cmp = object.__getattribute__(type_x, '__cmp__') except AttributeError: cmp = _no_cmp cmp = cmp(x, y) if cmp is not NotImplemented: if cmp == 0: return 0 if cmp < 0: return -1 if cmp > 0: return 1 type_y = type(y) try: cmp = object.__getattribute__(type_y, '__cmp__') except AttributeError: cmp = _no_cmp cmp = cmp(y, x) if cmp is not NotImplemented: if cmp == 0: return 0 if cmp < 0: return 1 if cmp > 0: return -1 gt = x > y lt = x < y eq = x == y if gt and not lt and not eq: return 1 if lt and not gt and not eq: return -1 if eq and not gt and not lt: return 0 if isinstance(x, (set, frozenset)): raise TypeError('cannot compare sets using cmp()') if type_x is type_y: raise TypeError('Cannot compare {} objects with cmp()'.format( type_x.__name__ )) raise TypeError( 'cannot compare objects of types {} and {} with cmp()'.format( type_x.__name__, type_y.__name__ ) )
def sort(aggr, cmp=None, key=None, reverse=False): """ Sorts the aggregate. Using selection sort, the data is sorted in O(n^2). The data aggregate is assumed to be iterable. If a key is passed, it is called on each element. Finally, if a cmp is passed, it will be used when comparing two elements. :param obj data: aggregate to be sorted :param func cmp: function used to compare two elements :param func key: function called on each element before it is compared :returns: sorted data """ aggr = list(aggr) for i, element in enumerate(aggr): # Get the next element to swap with swap_index = i for j in xrange(i+1, len(aggr)): # Get the data to be compared if key: data = key(aggr[j]) swap_data = key(aggr[swap_index]) else: data = aggr[j] swap_data = aggr[swap_index] # Get the result of the compare if cmp and reverse is False: result = cmp(data, swap_data) elif cmp and reverse is True: result = cmp(swap_data, data) if reverse is False: result = __builtin__.cmp(data, swap_data) else: result = __builtin__.cmp(swap_data, data) if result < 0: swap_index = j # Swap if necessary if swap_index != i: aggr[i] = aggr[swap_index] aggr[swap_index] = element return aggr
def sort(aggr, cmp=None, key=None, reverse=False): """ Sorts the aggregate. Using insertion sort, the data is sorted in O(n^2). The data aggregate is assumed to be iterable. If a key is passed, it is called on each data1. Finally, if a cmp is passed, it will be used when comparing two data1s. :param obj data: aggregate to be sorted :param func cmp: function used to compare two data1s :param func key: function called on each data1 before it is compared :returns: sorted data """ aggr = list(aggr) for i in xrange(1, len(aggr)): for j in xrange(i, 0, -1): # Get the data to be compared if key: data = key(aggr[j]) data1 = key(aggr[j-1]) else: data = aggr[j] data1 = aggr[j-1] # Get the result of the compare if cmp and reverse is False: result = cmp(data, data1) elif cmp and reverse is True: result = cmp(data1, data) if reverse is False: result = __builtin__.cmp(data, data1) else: result = __builtin__.cmp(data1, data) if result < 0: temp = aggr[j] aggr[j] = aggr[j-1] aggr[j-1] = temp else: break return aggr
def __cmp__(self, other): if self.__is_evaluated and other.__is_evaluated: return cmp(self.__head, other.__head) elif len(self.__head) >= len(other.__head): # check the evaluated heads heads = zip(self.__head[:len(other.__head)], other.__head) heads_comp = ((cmp(h1, h2) for h1, h2 in heads)) for comp in heads_comp: if comp != 0: return comp # evaluate the shorter-headed list until it is the same size while len(self.__head) > len(other.__head): if other.__is_evaluated: return 1 other.__next() comp = cmp(self.__head[len(other.__head) - 1], other.__head[-1]) if comp != 0: return comp # evaluate the tails, checking each time while not self.__is_evaluated or not other.__is_evaluated: if not self.__is_evaluated: self.__next() if not other.__is_evaluated: other.__next() len_comp = cmp(len(self.__head), len(other.__head)) if len_comp != 0: return len_comp if len(self.__head) > 0: value_comp = cmp(self.__head[-1], other.__head[-1]) if value_comp != 0: return value_comp elif len(other.__head) > len(self.__head): return -other.__cmp__(self) return 0
def __cmp__(self, other): """Оператор сравнения. - Если ранги индексов не равны, то меньшим является индекс с бОльльшим рангом. - Корневые индексы равны, независимо от того. - Если ранги равны, то индексы считаются равными, если равны все уровни иерархии. Если хотя бы один уровень, начиная с нулевого и до значения собственного индекса, меньше, чем соответствующий уровень другого индекса, то индекс считается меньшим. Например: <br> 1.1.2 == 1.1.2 ==> True 1.1.2.1 < 1.1.2 ==> True, т.к. ранг 1.1.2.1 больше ранга 1.1.2 (4 > 3) 1.2.1 > 1.1.2 ==> True, т.к. 1.2.\<...> > 1.1.\<...> @return (int) * -1, если индекс меньше *other* * 0, если равен * 1, если больше """ if self.rank() != other.rank(): return cmp(other.rank(), self.rank()) if self.isRoot() and other.isRoot(): return 0 for t in izip(self.__index, other.__index): cmpRes = cmp(*t) if cmpRes != 0: return cmpRes return 0 # if __name__ == "__main__": # # i1 = TreeIndex() # # flag = (not i1.isRoot()) # flag = (not i1.isValid()) # # i1.depthInc() # # flag = i1.isRoot() # flag = i1.isValid() # # print i1 # # print i1.depthInc() # print i1.widthInc() # print i1.widthInc() # print i1.depthInc().widthInc() # # print i1.getParent() # # print i1.depthNext().widthInc(), '\t', i1 # print i1.widthDec() # # i2 = TreeIndex() # i2.copy(i1) # # print i1 == i2 # i3 = i2.depthNext() # # print i3 > i2 # print i3 < i2 # /**Оператор сравнения. # * # * Равными считаются индексы, совпадающие с точностью до иерархии и собственного индекса. # * # * Например: 0.1.2.1 = 0.1.2.1 и 0.1.2.2 != 0.1.2.1 и 0.1.2.2. != 0.1.2.2.1 # */ # public boolean equals(TreeIndex obj) { # return this.index.equals(obj.index); # } # # /**Выполняет сравнение индексов поэлементно. # * # * Индекс считается меньше индекса inOther, если: # * - ранг inOther меньше или # * - если ранги одинаковые, то индекс одного из родителей больше inOther или # * - если один родитель, то собственный индекс меньше собственного индекса inOther # */ # public boolean lt(final TreeIndex inOther) { # if (inOther.rank() != rank()) # return inOther.rank() < rank(); # # if (inOther.isRoot() && isRoot()) # return false; # # for (int i = 0; i < inOther.index.size(); i++) # if (inOther.index.get(i) > this.index.get(i)) # return true; # # return false; # } # # public boolean gt(final TreeIndex obj) { # return !this.equals(obj) && !this.lt(obj); # } # # @Override # protected TreeIndex clone() throws CloneNotSupportedException { # // TODO Auto-generated method stub # return new TreeIndex(this); # # } # # };