21

Here's how to find out (or see Shog9's answer if you use Greasemonkey). Go to your profile reputation page (the one with the chart on it), View Source, and find the line that looks like this:

var d = [[1238832000000, 10],[1240300800000, 20], ...

Paste that, without the var, into the top of this Python script:

d = [[1238832000000, 10],[1240300800000, 20], ...
qualifying_days = 0
previous_rep = 0
for _, rep in d:
    if rep - previous_rep >= 200:
        qualifying_days += 1
    previous_rep = rep
print qualifying_days

That will print the number of days you hit 200 points. (That probably isn't an exact match for how the badges are calculated, but it should be ballpark correct.)

3
  • I think I still got awhile before Troggy goes epic!
    – Troggy
    Dec 7, 2009 at 1:36
  • 1
    Voting to close. This references the old reputation profile page, and was obsoleted some time ago by the /reputation page anyhow.
    – Pops
    Mar 21, 2012 at 22:20
  • Close voter gone insane: how on Earth can a discussion be closed as "can no longer be reproduced"? Sheesh. Oct 19, 2014 at 11:08

7 Answers 7

12

JavaScript again, this time in easy-to-use Greasemonkey form:

Voyeurism is fun http://shog9.com/so_fake_badge_tracker.png

// ==UserScript==
// @name           Daily rep limit badge tracker
// @namespace      http://shog9.com/greasemonkey/scripts
// @description    Tracks days a user has hit or exceeded the daily rep limit
// @include        https://stackoverflow.com/users/*
// @include        http://meta.stackoverflow.com/users/*
// @include        http://serverfault.com/users/*
// @include        http://superuser.com/users/*
// ==/UserScript==


var output = document.getElementById("date-selection");
if ( output )
   var rep_data = eval(document.getElementById("source")
      .innerHTML.toString().match( /\s+var d = (\[.*]]);/ )[1]);

if ( rep_data ) 
{   
   var capped_days = 0;
   for (var i=0; i < rep_data.length; ++i) 
   {
      var today = rep_data[i];
      var yesterday = rep_data[i-1] || [0,0];
      if (today[1] - 200 >= yesterday[1]) 
         ++capped_days;
   }

   output.innerHTML += "<div>Hit the reputation cap on " 
      + capped_days + " days: "
      + format_badge_distance(150, "Legendary", 1) + ", "
      + format_badge_distance(50, "Epic", 2) + ", "
      + format_badge_distance(1, "Mortarboard", 3)
      + "</div>";
}

function format_badge_distance(caps_needed, title, rank)
{
   if ( capped_days < caps_needed )
      return caps_needed - capped_days 
        + " more to achieve " 
        + format_badge(title, rank);
   else if ( capped_days > caps_needed )
      return capped_days - caps_needed 
        + " past " 
        + format_badge(title, rank);
   return " at " + format_badge(title, rank);
}

function format_badge(title, rank)
{
   return '<span class="badge"><span class="badge'
     + rank
     + '">&#9679;</span>&nbsp;'
     + title
     + '</span>';
}

And yes, I think we can safely say that this technique doesn't work: Reed Copsey is placed at 148 days, but holds the Legendary badge... Whatever SO uses internally, this isn't it.

3
  • 1
    Likewise, Darin Dimitrov and karim79 have the Epic badge, but they currently need to hit the rep cap another 1 and 6 times, respectively.
    – Stephan202
    Dec 7, 2009 at 16:44
  • @Shog9, it's not working for me, see meta.stackexchange.com/questions/32687/…
    – C. Ross
    Dec 11, 2009 at 13:59
  • Interesting that the calculation for Epic and Legendary are still not working. How many "6-8 week" periods has it been since 2009? Aug 8, 2018 at 15:43
11

Bummer, this only lists me at 110, even though after playing with the query I used with this other question some more I can show I've hit the cap closer to 180 times. That means it's missing more than 1/3 of my hits.

Oh, and for those without a python interpreter handy, here's an html file you can paste your data into:

<html>
<head>
<script type="text/javascript">
function test() {

var d = [[1219737600000, 51],[1219824000000, 208],[1219910400000, 383],...];

var qualifying_days = 0;
var previous_rep = 0;
for (var i=0,il=d.length;i<il;i+=1) {
    if (d[i][1] - previous_rep >= 200) {
        qualifying_days += 1;
    }
    previous_rep = d[i][1];
}
document.getElementById('result').value = qualifying_days;
}
</script>
</head>
<body>
<input id="result" /><button onclick="test()">GO</button>
</body>
</html>
5
  • Thanks for that. That's more convenient than the Python or Perl versions. Apparently I'm at 208, which surprises me because I've been basically at the rep cap for 11 months or ~330 days. Now I haven't hit that 330 times I'm sure but I'm also sure I didn't "miss" 120 times, which supports your claim theres something wrong with the calculation.
    – cletus
    Dec 7, 2009 at 12:56
  • cletus: does that include weekends? Dec 7, 2009 at 15:21
  • I haven't factored weekends in but then again I haven't seen anywhere it's said only weekdays apply. Or did I miss something?
    – cletus
    Dec 7, 2009 at 15:55
  • No, but 11 months of weekdays is fewer days than 11 full months - only ~240 days instead of ~335. Dec 7, 2009 at 16:00
  • Weekends for me have a lower incidence of hitting the rep cap but it still happens sufficiently often to make me question the 208/330 number.
    – cletus
    Dec 7, 2009 at 16:06
8

Javascript version: http://jsbin.com/oyoka/edit

var d = [[1231660800000, 10],[1231747200000, 30],[1231833600000, 137]]; 

var counter = 0; 

for(i=1;i<d.length;i++) 
  if(d[i][1] - d[i-1][1] >= 200) 
    counter++; 

document.write(counter);

Only one day for me, btw.

1
  • 4
    +1 for a version that doesn't require me to install anything.
    – mmyers
    Dec 7, 2009 at 15:41
5

Really, really far.

And that's assuming it's not in a row, the wording is really awkward. It really ought to be "Hit the daily reputation cap X times (non-consecutive)" or something less ambiguous

4

C version: (this is code golf, right? :-)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{

   char d[] = "[[1235289600000, 10],[1235462400000, 20], ...";

   char *word, *last;
   int loc, qualifying_days = 0, rep = 0, previous_rep = 0;

   word = strtok(d, ",");

   while (word)
   {   

      last = strchr(word, ']');

      if (last)
      {   
         loc = last - word;
         word[loc] = '\0';

         rep = atoi((word+1));

         if ((rep - previous_rep) >= 200)
         {   
            qualifying_days += 1;
         }

         previous_rep = rep;

      }

      word = strtok(NULL, ",");
   }

   printf("%d\n", qualifying_days);
   return 0;
}
1
  • FAIL, way too long of an entry for code golf, sorry. :-P Mar 25, 2010 at 1:36
3

Or:

print len([x for x in [d[i+1][1]-d[i][1] for i in range(len(d)-1)] if x >= 200])

Update: On further reflection, this is better:

print len([1 for i in range(len(d)-1) if d[i+1][1]-d[i][1] >= 200])

No need for those nested list comprehensions.

Update again: I just got my Legendary badge a few minutes ago. The above query currently returns 134 days on which I'd reached the rep cap, so the actual badge calculation is using a somewhat different formula.

10
  • 1
    I said Python, not Perl. :-) Dec 7, 2009 at 0:07
  • Functional Python is still Python! Dec 7, 2009 at 0:33
  • 3
    Nah, Perl would be print scalar grep { $_ >= 200 } map { $d[$_][-1] - $d[$_-1][-1] } (1..$#d); Dec 7, 2009 at 1:33
  • 7
    In spite of being an atheist, I thank god every time I see some Perl snippet for not having to learn that language.
    – Amarghosh
    Dec 7, 2009 at 4:28
  • @Amarghosh: Funny, I thought the same thing reading Greg's Python snippet. To each his own, I guess. Dec 7, 2009 at 14:49
  • @Adam Bellaire: Out of curiosity, do you feel the same reading the simple-syntax-only Python script in my question? Dec 7, 2009 at 15:01
  • 2
    @RichieHindle: Actually, no, because that's how I expect Python to look. But, with all respect to Greg, if you want terse, use Perl. Right tool for the job and all of that. The terse Python hurts my brain. Dec 7, 2009 at 15:20
  • How about print sum(200<=y[1]-x[1] for x,y in zip(d,d[1:]))
    – gnibbler
    Dec 7, 2009 at 23:50
  • @gnibbler: That's a bit evil to treat boolean values as integers. I wouldn't even count on that to work in all future Python versions. Dec 8, 2009 at 1:27
  • @Greg: Oh you'll like Ruby then ;)
    – gnibbler
    Dec 8, 2009 at 1:49
0

Votes are anonymized, so it's impossible to deduct points for a user's downvotes.

I'm glad the data-dump XML is friendly!

#! /usr/bin/perl

use warnings;
use strict;

die "Usage: $0 id-num\n" unless @ARGV == 1;
my $id = shift;
my %postid;
@postid{
  map { /\bId="([^"]+)"/ ? $1 : die "$0: missing Id:\n$_" }
  `grep -w 'OwnerUserId="$id"' posts.xml`
} = ();

my %repmod = (
  1 => +15,
  2 => +10,
  3 =>  -2,
);

my %increase;
open my $votes, "<", "votes.xml" or die "$0: open: $!";
while (<$votes>) {
  next unless /<row\b/;
  my %attr = /\b(CreationDate|VoteTypeId|PostId)="([^"]+)"/g;
  next unless exists $postid{ $attr{PostId} };
  $increase{ $attr{CreationDate} } += $repmod{ $attr{VoteTypeId} } || 0;
}

my $i = 0;
foreach my $date (sort keys %increase) {
  next unless $increase{$date} >= 200;
  printf "%4d. $date - $increase{$date}\n", ++$i;
}

Example usage:

$ cd Stack\ Overflow\ Data\ Dump\ -\ Feb\ 10/Content/022010\ SO
$ legend 22656
[...]
 475. 2010-01-25 - 865
 476. 2010-01-26 - 828
 477. 2010-01-27 - 1486
 478. 2010-01-28 - 1110
 479. 2010-01-29 - 1228
 480. 2010-01-30 - 418
 481. 2010-01-31 - 325

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .