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.)

share|improve this question
    
I think I still got awhile before Troggy goes epic! –  Troggy Dec 7 '09 at 1:36
    
Voting to close. This references the old reputation profile page, and was obsoleted some time ago by the /reputation page anyhow. –  Pops Mar 21 '12 at 22:20
add comment

8 Answers

up vote 12 down vote accepted

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

Voyeurism is fun

// ==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        http://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.

share|improve this answer
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 '09 at 16:44
    
Very nice - thanks! –  RichieHindle Dec 7 '09 at 18:03
    
@Shog9, it's not working for me, see meta.stackoverflow.com/questions/32687/… –  C. Ross Dec 11 '09 at 13:59
add comment

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.

share|improve this answer
1  
I said Python, not Perl. :-) –  RichieHindle Dec 7 '09 at 0:07
    
Functional Python is still Python! –  Greg Hewgill Dec 7 '09 at 0:33
3  
Nah, Perl would be print scalar grep { $_ >= 200 } map { $d[$_][-1] - $d[$_-1][-1] } (1..$#d); –  ベレアー アダム Dec 7 '09 at 1:33
6  
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 '09 at 4:28
    
@Amarghosh: Funny, I thought the same thing reading Greg's Python snippet. To each his own, I guess. –  ベレアー アダム Dec 7 '09 at 14:49
    
@Adam Bellaire: Out of curiosity, do you feel the same reading the simple-syntax-only Python script in my question? –  RichieHindle Dec 7 '09 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 '09 at 15:20
    
How about print sum(200<=y[1]-x[1] for x,y in zip(d,d[1:])) –  gnibbler Dec 7 '09 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. –  Greg Hewgill Dec 8 '09 at 1:27
    
@Greg: Oh you'll like Ruby then ;) –  gnibbler Dec 8 '09 at 1:49
add comment

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

share|improve this answer
add comment

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.

share|improve this answer
4  
+1 for a version that doesn't require me to install anything. –  mmyers Dec 7 '09 at 15:41
add comment

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>
share|improve this answer
    
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 '09 at 12:56
    
cletus: does that include weekends? –  Joel Coehoorn Dec 7 '09 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 '09 at 15:55
    
No, but 11 months of weekdays is fewer days than 11 full months - only ~240 days instead of ~335. –  Joel Coehoorn Dec 7 '09 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 '09 at 16:06
add comment

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;
}
share|improve this answer
    
FAIL, way too long of an entry for code golf, sorry. :-P –  Chris Jester-Young Mar 25 '10 at 1:36
add comment

I'm more interested to know how far am I from the Fanatic badge

share|improve this answer
add comment

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
share|improve this answer
add comment

You must log in to answer this question.

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