Skip to content

Instantly share code, notes, and snippets.

@maxpert
Created June 15, 2014 17:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maxpert/b300beaa8c599f3668d6 to your computer and use it in GitHub Desktop.
Save maxpert/b300beaa8c599f3668d6 to your computer and use it in GitHub Desktop.
Decayed ranking basic implementation
import math
import operator
class DecayScore(object):
"""
Class for calculating basic decayable score over keys (items) and there score values.
It's not thread safe and not doesn't store anykind of timestamps against items stored.
The caller is responsible of keeping track of time.
"""
def __init__(me, init_score, half_life):
"""
Initializes the instance of decaying score class for set of items
:param init_score: The initial score assigned to new item.
:param half_life: The half life time of an item.
"""
me.__score = {}
me.__n0 = init_score
me.__lambda = math.log(2) / half_life
def decay(me, key, time_elapsed):
"""
Decays a given key (item identifier) with a given time elapsed.
The function does not store any kind of time stamp or last update value.
Caller is responsible for calculating and passing in correct delta.
:param key: A string or key value for dictionary of item. Usually this will be your item identifier.
:param time_elapsed: The amount of time elapsed. This must be in same units as half_life passed in constructor.
"""
s = me.__n0
if key in me.__score:
s = me.__score[key]
me.__score[key] = s - me.__lambda * time_elapsed
def update(me, key, score, time_elapsed = 0):
"""
Updates the score of an item (key) with given score and decays it if the time elapsed is passed in.
The function does not store any kind of time stamp or last update value.
Caller is responsible for calculating and passing in correct delta.
:param key: A string or key value for dictionary of item. Usually this will be your item identifier.
:param score: The amount of score to increment.
:param time_elapsed: The amount of time elapsed. This must be in same units as half_life passed in constructor.
"""
me.__score[key] = me.__score.get(key, me.__n0) - (me.__lambda * time_elapsed) + score
def get(me):
"""
Returns copy of the unsorted score dictionary.
"""
return me.__score.copy()
def get_ranked(me):
"""
Returns sorted set of tuples containing key and score of items
"""
x = me.__score
return sorted(x.iteritems(), key=operator.itemgetter(1))
if __name__ == "__main__":
x = DecayScore(math.log(10), 24)
for i in range(24):
x.decay('foo', 2)
x.decay('bar', 1)
print x.get_ranked()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment