[Checkins] SVN: lovely.rating/trunk/src/lovely/rating/ added
support for timestamp based stats
Bernd Dorn
bernd.dorn at lovelysystems.com
Fri Feb 9 09:01:01 EST 2007
Log message for revision 72483:
added support for timestamp based stats
Changed:
U lovely.rating/trunk/src/lovely/rating/README.txt
U lovely.rating/trunk/src/lovely/rating/interfaces.py
U lovely.rating/trunk/src/lovely/rating/manager.py
-=-
Modified: lovely.rating/trunk/src/lovely/rating/README.txt
===================================================================
--- lovely.rating/trunk/src/lovely/rating/README.txt 2007-02-09 13:10:15 UTC (rev 72482)
+++ lovely.rating/trunk/src/lovely/rating/README.txt 2007-02-09 14:01:00 UTC (rev 72483)
@@ -102,6 +102,57 @@
>>> sorted([rating.__repr__() for rating in manager.getRatings('usability')])
["<Rating u'Okay' by u'kartnaller'>", "<Rating u'Okay' by u'srichter'>"]
+The getRatings method supports filtering the ratings by timestamp.
+
+ >>> from datetime import datetime, timedelta
+ >>> from pytz import UTC
+ >>> now = datetime.now(UTC)
+ >>> oneDay = timedelta(days=1)
+
+Since we have created all ratings in this test all should be within
+this day and before now.
+
+ >>> ratings = manager.getRatings('usability', dtMax=now, dtMin=now-oneDay)
+ >>> len(sorted(ratings))
+ 2
+
+The same result for an undefined dtMax or dtMin.
+
+ >>> ratings = manager.getRatings('usability', dtMin=now-oneDay)
+ >>> len(sorted(ratings))
+ 2
+ >>> ratings = manager.getRatings('usability', dtMax=now)
+ >>> len(sorted(ratings))
+ 2
+
+Let us set a timestamp on a rating just for testing (Note, this is
+private API)
+
+ >>> r = manager.getRatings('usability', dtMax=now)[0]
+ >>> r
+ <Rating u'Okay' by u'kartnaller'>
+ >>> r._timestamp = r._timestamp - oneDay
+ >>> twoDays = timedelta(days=2)
+ >>> threeHours = timedelta(hours=3)
+
+Get all ratings that are at most 3 hours old.
+
+ >>> ratings = manager.getRatings('usability', dtMin=now-threeHours)
+ >>> sorted(ratings)
+ [<Rating u'Okay' by u'srichter'>]
+
+Get all ratings that are at least 3 hours old.
+
+ >>> ratings = manager.getRatings('usability', dtMax=now-threeHours)
+ >>> sorted(ratings)
+ [<Rating u'Okay' by u'kartnaller'>]
+
+Get all ratings from the last two days.
+
+ >>> ratings = manager.getRatings('usability', dtMin=now-twoDays)
+ >>> sorted(ratings)
+ [<Rating u'Okay' by u'srichter'>, <Rating u'Okay' by u'kartnaller'>]
+
You can also ask for the rating of a particular user:
>>> manager.getRating('usability', u'srichter')
@@ -172,3 +223,6 @@
((u'Poor', Decimal("1")), 0),
((u'Crap', Decimal("0")), 0)]
+The computeAverage, countScores and countAmountRatings methods also
+support the dtMin and dtMax arguments as described in the getRatings
+method.
Modified: lovely.rating/trunk/src/lovely/rating/interfaces.py
===================================================================
--- lovely.rating/trunk/src/lovely/rating/interfaces.py 2007-02-09 13:10:15 UTC (rev 72482)
+++ lovely.rating/trunk/src/lovely/rating/interfaces.py 2007-02-09 14:01:00 UTC (rev 72483)
@@ -66,10 +66,13 @@
If no rating exists, do nothing and simply return.
"""
- def getRatings(id):
+ def getRatings(id, dtMin=None, dtMax=None):
"""Get all ratings for a particular definition.
The result will be a sequence of ``IRating`` objects.
+
+ The optional dtMin and dtMax arguments can be used to filter
+ the result based on their timestamps
"""
def getRating(id, user):
@@ -79,17 +82,17 @@
a ``ValueError``.
"""
- def computeAverage(id):
+ def computeAverage(id, dtMin=None, dtMax=None):
"""Compute the average rating value for the specified definition."""
- def countScores(id):
+ def countScores(id, dtMin=None, dtMax=None):
"""Count how many times each value was giving for a definition.
The result will be a list of tuples of the type ``(score,
amount)``. ``score`` is in turn a tuple of ``(name, value)``.
"""
- def countAmountRatings(id):
+ def countAmountRatings(id, dtMin=None, dtMax=None):
"""Counts the total amount of ratings for one definition"""
Modified: lovely.rating/trunk/src/lovely/rating/manager.py
===================================================================
--- lovely.rating/trunk/src/lovely/rating/manager.py 2007-02-09 13:10:15 UTC (rev 72482)
+++ lovely.rating/trunk/src/lovely/rating/manager.py 2007-02-09 14:01:00 UTC (rev 72483)
@@ -24,6 +24,7 @@
from zope.app.container import contained
from lovely.rating import IRatable, IRatingsManager, IRatingDefinition, rating
+import itertools
class RatingsManager(contained.Contained, persistent.Persistent):
zope.interface.implements(IRatingsManager)
@@ -71,28 +72,37 @@
del self._storage[id]
return True
- def getRatings(self, id):
+ def getRatings(self, id, dtMin=None, dtMax=None):
"""See interfaces.IRatingsManager"""
# Just get the definition to make sure it exists.
defn = self._getDefinition(id)
+ ratings = list(self._storage.get(id, {}).values())
+ f = None
+ if dtMin is not None:
+ if dtMax is not None:
+ f = lambda r: r.timestamp>=dtMin and r.timestamp<=dtMax
+ else:
+ f = lambda r: r.timestamp>=dtMin
+ elif dtMax is not None:
+ f = lambda r: r.timestamp<=dtMax
+ if f:
+ ratings = itertools.ifilter(f, ratings)
+ return list(ratings)
- return list(self._storage.get(id, {}).values())
-
def getRating(self, id, user):
"""See interfaces.IRatingsManager"""
# Just get the definition to make sure it exists.
defn = self._getDefinition(id)
-
if id not in self._storage or user not in self._storage[id]:
return
return self._storage[id][user]
- def computeAverage(self, id):
+ def computeAverage(self, id, dtMin=None, dtMax=None):
"""See interfaces.IRatingsManager"""
# Just get the definition to make sure it exists.
defn = self._getDefinition(id)
- ratings = self._storage.get(id, {}).values()
+ ratings = list(self.getRatings(id, dtMin, dtMax))
total = sum([defn.scoreSystem.getNumericalValue(rating.value)
for rating in ratings])
try:
@@ -100,21 +110,22 @@
except ZeroDivisionError:
return -1
- def countScores(self, id):
+ def countScores(self, id, dtMin=None, dtMax=None):
"""See interfaces.IRatingsManager"""
defn = self._getDefinition(id)
-
+ ratings = list(self._storage.get(id, {}).values())
value_count = {}
- for rating in self._storage.get(id, {}).values():
+ for rating in ratings:
value_count.setdefault(rating.value, 0)
value_count[rating.value] += 1
return [(score, value_count.get(score[0], 0))
for score in defn.scoreSystem.scores]
- def countAmountRatings(self, id):
+ def countAmountRatings(self, id, dtMin=None, dtMax=None):
"""See interfaces.IRatingManager"""
- return len(self._storage.get(id, {}))
+ ratings = list(self._storage.get(id, {}).values())
+ return len(ratings)
def __repr__(self):
More information about the Checkins
mailing list