#!/usr/bin/python
"""usage: gnome-points num-comments num-closed-bugs num-opened-bugs
Compute GNOME Bugzilla points and linear estimate of required activity
to go to the next point level."""
import sys, math
if len(sys.argv) != 4:
print >>sys.stderr, __doc__
sys.exit (1)
# We work with plus-oned stats, as that make all formulas much simpler
stats = []
for i in range (1, 4):
stats.append (1+int(sys.argv[i]))
activity_ratios = [x * 1. / stats[0] for x in stats]
bases = [10, 2, 2]
def bugzilla_points (comments, closed, opened):
"""Returns the GNOME Bugzilla points gathered, as a floating point."""
return sum ([math.log (x,y) for (x,y) in zip ([comments, closed, opened], bases)])
def points_derivative (comments, closed, opened):
"""Returns a tuple of partial derivatives of the bugzilla points to
each component. The returned values are what you will gain if you
contribute one more item of each kind."""
return [1./(x*math.log(y)) for (x,y) in zip ([comments, closed, opened], bases)]
def comments_adjusted (comments, closed, opened):
"""Adjusts the number of comments by subtracting from it the number
of closed and opened bugs, as they contribute a comment too."""
return [max(0, comments - closed - opened), closed, opened]
points = bugzilla_points (*stats)
print "Current points: %f" % points
# points required for the next level
target_points = math.ceil (points + .5) - .5
# linear interpolate
target_comments = 2**(math.log(10,200)*(target_points-sum([math.log(x,2) for x in activity_ratios])))
target_stats = [int(math.ceil (target_comments * ratio)) for ratio in activity_ratios]
diff_stats = [(x-y) for (x,y) in zip (target_stats, stats)]
print "Need %s more to go to the next level (%f)" % (comments_adjusted (*diff_stats), bugzilla_points (*target_stats))
# TODO: the linear interpolate is almost as good as you can get. however, it
# does overhit the target points because of the ceiling operations. it works
# good enough when you have quite a bunch of each kind of stats, but not when
# you have values (say) below 10. it should be changed to ceil one target at
# a time, and readjusting the rest, and this should be done from the stat with
# the highest derivated down to the lowest...
sys.exit()
# the following doesn't make any sense at this time, ignore
# min-effort estimate
point_derivs = points_derivative (*stats)
point_to_effort_derivs = [(x*y) for (x,y) in zip(point_derivs, activity_ratios)]
activity_ratios = [x / point_to_effort_derivs[0] for x in point_to_effort_derivs]
target_comments = 2**(math.log(10,200)*(target_points-sum([math.log(x,2) for x in activity_ratios])))
target_stats = [int(math.ceil (target_comments * ratio)) for ratio in activity_ratios]
diff_stats = [(x-y) for (x,y) in zip (target_stats, stats)]
print "Min-effort estimate (incorrect):", comments_adjusted (*diff_stats)