Using the ranker library with a "open-ended" contest

125 views
Skip to first unread message

victor noagbodji

unread,
Nov 20, 2012, 2:23:00 AM11/20/12
to google-app-en...@googlegroups.com
Hi,

We are using the ranker library in our application and ties are an issue for us. I haven't found a good penalty time for breaking ties because our ranking is not done on a fixed time interval. Our users can perpetually submit new scores. As long as the application is up and running.

Users would submit a series of number of punches gathered by a specialized device, which then the application turn into "scores" after various operations like average punches, punch force, etc... I am hands-tied with the details. But basically those are the scores we feed into the rankers. Scoreboards for all entries and ranks for individual entries are displayed on the front-end.

It works well but for ties. And I was wondering if anyone has encountered this situation before and what could help. As mentioned about, penalty time isn't really applicable here.

Please advise,

Bartholomew Furrow

unread,
Nov 20, 2012, 10:45:30 PM11/20/12
to google-app-en...@googlegroups.com
Can you give me some idea of the range of scores you're using?

As for ties, what is the actual problem?  Presumably the ranker is doing OK at saying "these 5 people are tied for 10th place".  Is the problem with displaying a large number of tied people?

In Code Jam, we occasionally get ties of 2-3 people.  We show pages of 20 people at a time, and if there's a tie for position 20, we choose who gets displayed first based on the user_id() of the user.  This works fine for small ties, but if you're going to have giant ties then you might need to engineer something more sophisticated.  I've got some ideas, but I'm not sure if you need them.

Best,
Bartholomew



--
You received this message because you are subscribed to the Google Groups "Google App Engine Ranklist" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-app-engine-ranklist/-/2YbLfEIQtm0J.
To post to this group, send email to google-app-en...@googlegroups.com.
To unsubscribe from this group, send email to google-app-engine-r...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-app-engine-ranklist?hl=en.

victor noagbodji

unread,
Nov 21, 2012, 9:54:42 PM11/21/12
to google-app-en...@googlegroups.com
Thanks for the reply Bartholomew,

Here's the function returning the ranges:

def get_range(ranker_name):
    # ranges are [inclusive, exclusive)
    return {
        'punch_force':     [1, 2001],
        'most_punches':    [1,  301],
        'pound_for_pound': [0,  151]
    }[ranker_name]

Yes the ties are correct. But we are displaying too many of them. We ideally wants less ties by a tie-breaking mechanism. I would be more than glad to hear your ideas.

As example for the test data I generated for the pound for pound ranker, we got only 3 distinct values for 100 test users. The values were just 2, 1 and 0 (I should definitely improve the test data generator too) With these values we got on the leader board (the rank list) a series of 1st (rank 0) followed by a series of 7th and finally a series of 44th (rank 6 and 43rd respectively.)

Again I appreciate your advice on this issue.

Thanks
To unsubscribe from this group, send email to google-app-engine-ranklist+unsub...@googlegroups.com.

Bartholomew Furrow

unread,
Dec 13, 2012, 5:02:26 PM12/13/12
to google-app-en...@googlegroups.com
Victor,

I'm very sorry for my slow response; I started composing a reply last month, but never sent it.

A traditional way of breaking this sort of tie is simply by time.  Bill and Bob both lifted 100, but Bill did it first, so he's in first place.  You could bucket it by day, and just make it work for the next 1000 years by making punch_force [1, 2001, 0, 400000].  Then store score[0] * 10**9 + score[1] and query based on that.

Another thing you could do: modify the ranker library so that instead of returning one overall rank, it returns a different rank for each score type.  So if there are 500 people who punch more than 100, and I was the 200th person to punch 100, then for me it would return (500, 200), whereas it currently returns 700.  You can then decide what to do with that: treat it as 700th place, or treat it as a tie for 500th place.

Does that help?
Bartholomew



To post to this group, send email to google-app-en...@googlegroups.com.
To unsubscribe from this group, send email to google-app-engine-r...@googlegroups.com.

victor noagbodji

unread,
Dec 15, 2012, 11:00:37 AM12/15/12
to google-app-en...@googlegroups.com
no worries Bartholomew, as a developer i can understand.

i will go over your suggestion this evening and i get back to you.

To unsubscribe from this group, send email to google-app-engine-ranklist+unsubsc...@googlegroups.com.

victor noagbodji

unread,
Feb 16, 2013, 1:16:18 AM2/16/13
to google-app-en...@googlegroups.com
Hi Bartholomew, that was a pretty long evening. I apologize for that.

I decided to go with the first solution and incorporated the changes a few days ago. I also decided to use minutes instead of days. Tested with the development server, it seems to have the correct behavior. I am puzzled with this though "Then store score[0] * 10**9 + score[1] and query based on that."

Can you elaborate more on that ? Right now I just store the value (that's score[0]) and the timestamp (that's score[1]) in different model properties. When querying, I get the entries sorted by values and retrieve their ranks for display. The ranker seems to be doing the right thing.

Thanks again for helping.


On Thursday, December 13, 2012 5:02:26 PM UTC-5, Bartholomew wrote:

To unsubscribe from this group, send email to google-app-engine-ranklist+unsubsc...@googlegroups.com.

Bartholomew Furrow

unread,
Feb 16, 2013, 1:46:22 PM2/16/13
to google-app-en...@googlegroups.com

The 10**9 thing is about how you can retrieve the scorers themselves. Can you do a query that's sorted based on property a, but sorts based on property b in case of ties? If so, great. At one point that definitely wasn't true, and our method of doing that was to create property c=1000000000*a+b.

To unsubscribe from this group and stop receiving emails from it, send an email to google-app-engine-r...@googlegroups.com.

To post to this group, send email to google-app-en...@googlegroups.com.

victor noagbodji

unread,
Feb 18, 2013, 6:36:39 AM2/18/13
to google-app-en...@googlegroups.com
That seems to be the case. When multiple order()'s are added to a query they are chained: https://developers.google.com/appengine/docs/python/datastore/queryclass#Query_order

But I will keep this solution in mind. Thanks again.
To unsubscribe from this group and stop receiving emails from it, send an email to google-app-engine-ranklist+unsub...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages