Rating with items sorted by value and accessed by key or rating index.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | #
# Rating class with mapping interface
# $Id: rating.py 41 2004-01-14 08:30:59Z hdima $
# Copyright (C) Dmitry Vasiliev <dima at hlabs.spb.ru> 2004
#
__all__ = ["Rating"]
from bisect import bisect_right, bisect_left, insort_left
class RatingItem(object):
"""Rating item
>>> i = RatingItem("bob", 10)
>>> i.key, i.value
('bob', 10)
>>> i2 = RatingItem("john", 10)
>>> i == i2, i < i2, i <= i2, i > i2, i >= i2
(True, False, True, False, True)
>>> i2 = RatingItem("paul", 20)
>>> i == i2, i < i2, i <= i2, i > i2, i >= i2
(False, True, True, False, False)
>>> i2 = RatingItem("tom", 0)
>>> i == i2, i < i2, i <= i2, i > i2, i >= i2
(False, False, False, True, True)
"""
__slots__ = ["key", "value"]
def __init__(self, key, value):
self.key = key
self.value = value
def __cmp__(self, other):
return cmp(self.value, other.value)
class Rating(object):
"""Rating class with mapping interface
>>> r = Rating({"bob": 30, "john": 30})
>>> len(r)
2
>>> r.has_key("paul"), "paul" in r
(False, False)
>>> r["john"] = 20
>>> r.update({"paul": 20, "tom": 10})
>>> len(r)
4
>>> r.has_key("paul"), "paul" in r
(True, True)
>>> [r[key] for key in ["bob", "john", "paul", "tom"]]
[30, 20, 20, 10]
>>> r.get("nobody"), r.get("nobody", 0)
(None, 0)
>>> [r.rating(key) for key in ["bob", "john", "paul", "tom"]]
[3, 2, 1, 0]
>>> [r.getValueByRating(rating) for rating in range(4)]
[10, 20, 20, 30]
>>> [r.getKeyByRating(rating) for rating in range(4)]
['tom', 'paul', 'john', 'bob']
>>> r.keys()
['tom', 'paul', 'john', 'bob']
>>> [key for key in r]
['tom', 'paul', 'john', 'bob']
>>> [key for key in r.iterkeys()]
['tom', 'paul', 'john', 'bob']
>>> r.values()
[10, 20, 20, 30]
>>> [value for value in r.itervalues()]
[10, 20, 20, 30]
>>> r.items()
[('tom', 10), ('paul', 20), ('john', 20), ('bob', 30)]
>>> [item for item in r.iteritems()]
[('tom', 10), ('paul', 20), ('john', 20), ('bob', 30)]
>>> r["tom"] = 100
>>> r.items()
[('paul', 20), ('john', 20), ('bob', 30), ('tom', 100)]
>>> del r["paul"]
>>> r.items()
[('john', 20), ('bob', 30), ('tom', 100)]
>>> r["paul"] = 25
>>> r.items()
[('john', 20), ('paul', 25), ('bob', 30), ('tom', 100)]
>>> r.clear()
>>> r.items()
[]
"""
__slots__ = ["__dict", "__rating"]
def __init__(self, mapping=None):
self.clear()
if mapping is not None:
self.update(mapping)
def update(self, mapping):
for key, value in mapping.iteritems():
self.__setitem__(key, value)
def __len__(self):
return len(self.__rating)
def clear(self):
self.__dict = {}
self.__rating = []
def __getitem__(self, key):
return self.__dict[key].value
def get(self, key, default=None):
return self.__dict.get(key, default)
def __contains__(self, key):
return key in self.__dict
has_key = __contains__
def keys(self):
return [item.key for item in self.__rating]
def __iter__(self):
for item in self.__rating:
yield item.key
iterkeys = __iter__
def values(self):
return [item.value for item in self.__rating]
def itervalues(self):
for item in self.__rating:
yield item.value
def items(self):
return [(item.key, item.value) for item in self.__rating]
def iteritems(self):
for item in self.__rating:
yield item.key, item.value
def getValueByRating(self, rating):
return self.__rating[rating].value
def rating(self, key):
return self.__getIndexByItem(self.__dict[key])
def __getIndexByItem(self, item):
i = bisect_left(self.__rating, item)
if item is self.__rating[i]:
return i
i2 = bisect_right(self.__rating, item) - 1
if item is self.__rating[i2]:
return i2
for i in xrange(i, i2 + 1):
if item is self.__rating[i]:
return i
raise AssertionError("item not found in rating")
def getKeyByRating(self, rating):
return self.__rating[rating].key
def __setitem__(self, key, value):
if key not in self.__dict:
item = RatingItem(key, value)
self.__dict[key] = item
else:
item = self.__dict[key]
del self.__rating[self.__getIndexByItem(item)]
item.value = value
insort_left(self.__rating, item)
def __delitem__(self, key):
del self.__rating[self.rating(key)], self.__dict[key]
def _test():
import doctest, rating
doctest.testmod(rating)
if __name__ == "__main__":
_test()
|
Class for rate items by value and access them by keys.
Tags: algorithms