So... what is your StackOverflow score?

This is a simple one. Given the input of a number, return the name and reputation score of the Stack Overflow user with that given ID. Your program can assume that it is always given a valid and existent user ID.

For example: given the input 764357 (which is my userID on StackOverflow) the program would return LegoStormtroopr 3,088 (approximately) it might change.

You get the URL: "https://stackoverflow.com/users/" or "http://api.stackexchange.com/2.1/users/" for free, so your score is length of your program - 31 or 39, depending on which URL you use - but declare which it is. This prevents people from abusing URL shorteners.

edit: And no calling a custom made API that query Stack Overflow, and returns just the name and score. But if you know of an offical API, then that is totally legitimate.

edit2: If you need an example input: I've given my ID below, feel free to add your own ID, username and score below to help others out. Note again, this is for the main Stack Overflow site.

764357   returns   LegoStormtroopr 3,088

• hmm... if there are multiple users with that rep, should we pick one, or display all of them? What if there is no such user? Oct 3 '13 at 7:47
• uh... wait... of the user with that score, or of the user with that ID? Oct 3 '13 at 7:51
• @JanDvorak I've tried to clarify. The program should accept a user ID, and return the user with that ID, and that users Rep. Score.
– user8777
Oct 3 '13 at 11:16
• Should the url http://api.stackexchange.com/2.1/users/ also be "free" to avoid penalising users of the API? Oct 3 '13 at 20:10
• Could we get the site=stackoverflow part for free too? Oct 4 '13 at 13:18

Shell script: 64 51 characters

curl -sL http://stackoverflow.com/users/cat|grep -oPm2 'n">\K[0-9,]+|e">\K[^<]+'


Sample run:

bash-4.1$curl -sL http://stackoverflow.com/users/cat|grep -oPm2 'n">\K[0-9,]+|e">\K[^<]+' 662504 manatwork 834 bash-4.1$ curl -sL http://stackoverflow.com/users/cat|grep -oPm2 'n">\K[0-9,]+|e">\K[^<]+'
764357
Lego Stormtroopr
3,087


(Note that you have to press ^D after typing in the input interactively. Or just pipe it to the command.)

Ruby: 84 70 characters

s=open("http://stackoverflow.com/users/"+gets).read
puts s[/me">(.+)</,1],s[/n">([\d,]+)/,1]


Sample run:

bash-4.1$ruby -ropen-uri -e 's=open("http://stackoverflow.com/users/"+gets).read;puts s[/me">(.+)</,1],s[/n">([\d,]+)/,1]' <<< '662504' manatwork 834 bash-4.1$ ruby -ropen-uri -e 's=open("http://stackoverflow.com/users/"+gets).read;puts s[/me">(.+)</,1],s[/n">([\d,]+)/,1]' <<< '764357'
Lego Stormtroopr
3,087

• You don't need full words in the regex: s[/me">(.+)</,1],s[/ation".*?([\d,]+)/,1] seems to work Oct 3 '13 at 12:49
• Correct. They were just taken from my shell script answer. (grep would display more matches for just “ation"”.) Oct 3 '13 at 13:05
• @Doorknob, probably you omitted the -ropen-uri option. (It's mandatory and included in the character count.) Oct 4 '13 at 7:47
• @manatwork Ah, didn't notice that. Okay now it works.
– Doorknob
Oct 4 '13 at 12:02

Python 2.7 - 119

(150 - 31)

Without regex:

from urllib import*
p=str.split
print p(p(s,'r ')[1],' -')[0],p(p(s,'ore">')[1],'<')[0]


Python 3, 117

117 = 148 - 31

I don't think searching in plain HTML source code will lead to strong solution. For example, some weird stuff in one's profile may break your solutions. So I'd like to search using CSS selectors.

from lxml.html import*
C=parse('http://stackoverflow.com/users/'+input()).getroot().cssselect
print(C('[id^=u]')[0].text,C('[class$=ore]')[0].text)  Javascript 217 Heres a ungolfed Javascript Version using the official api with JSONP, to start with . Using the url would require XHR, which sould be quite verbose, if i find some time i'll try a more golfed version though. d=document;function f(a){y=a.items[0];alert(y.display_name+" "+y.reputation)}x=d.createElement("script");x.src="https://api.stackexchange.com/2.1/users/"+prompt()+"?site=stackoverflow&callback=f";d.body.appendChild(x)  Perl 5 (with Mojolicious), 87 - 31 = 56 bytes say/h1.*>(.*)</,$/,/core">(.*?)</ for g("http://stackoverflow.com/users/".pop)->dom


Sample run:

$perl -Mojo -E 'say/h1.*>(.*)</,$/,/core">(.*?)</ for g("http://stackoverflow.com/users/".pop)->dom' 764357
Lego Stormtroopr
3,103


Readable & clean: 128 - 31 = 97 bytes

say $_->at("#user-displayname")->text, ": ",$_->at(".reputation a")->text for g("http://stackoverflow.com/users/".pop)->dom


Sample run:

$perl -Mojo -E 'say$_->at("#user-displayname")->text, ": ", $_->at(".reputation a")->text for g("http://stackoverflow.com/users/$ARGV[0]")->dom' 764357
Lego Stormtroopr: 3,103

• Is -Mojo included in the count? That costs 4 characters. Oct 4 '13 at 9:20
• @manatwork: No, I did not include it in the count, because the Ruby answer did not include -ropen-uri. However, I am happy to include it if your comment gets a few up votes as indication that the community wants to count these. Oct 4 '13 at 9:40
• Count again. It includes. pastebin.com/qZp1QgKa Oct 4 '13 at 9:48
• Well, I wish we have an exact documentation of the counting rule, but as I know, there is none. One thing is sure: perl's -p option is usually counted +1. Based on that I count -Mojo +4. Oct 4 '13 at 10:02
• Here's one set of rules we've been using a few times.
– J B
Nov 10 '13 at 18:18

R: 150-31=119

f=function(i){S=function(x)strsplit(grep(x,scan(paste0("http://stackoverflow.com/users/",i),"",sep="\n"),v=T)[1],">|<")[[1]][3];cat(S("h1"),S("=re"))}


Quite simply picks the first lines containing h1 (for the name) and =re (for the score) using grep with argument value=TRUE (here v=T) and then split the string (using strsplit at characters > and <. Inconveniently it queries the page twice (hence the two "Read n items" warnings) but that was shorter.

>f(1451109)
plannapus 6,566


Tcl, (231 - 39) 192

not the shortest way, but using the official API

package r http
package r json
set d [lindex [dict get [json::json2dict [http::data [http::geturl http://api.stackexchange.com/2.1/users/$argv?site=stackoverflow]]] items] 0] puts [dict get$d display_name]\ [dict get $d reputation]  And in spirit of the original question: package r http package r json set c [dict get [json::json2dict [http::data [http::geturl http://api.stackexchange.com/2.1/users/?order=desc&sort=reputation&site=stackoverflow&min=$argv&max=$argv]]] items] foreach d$c {puts "[dict get $d display_name] [dict get$d reputation]"}


Finds users with that reputation

– user8777
Oct 3 '13 at 21:33
• @LegoStormtroopr: I wrote this answer when it was clear that you mean the userid, but I liked to show that the official API is able to solve the original question too. Oct 5 '13 at 12:32

Shorter CoffeeScript: 143 characters (182 - 39)

This relies on the API always returning the object keys in the same order, but shaves off 7 characters.

f=(r)->u=Object.keys(items[0]);alert u[3]+' '+u[5]
d=document
j=d.createElement('script')
j.src="//api.stackexchange.com/2.1/users/"+prompt()+'?site=diy&jsonp=f'
d.body.appendChild j


CoffeeScript: 150 characters (189 - 39)

f=(r)->u=r.items[0];alert u.display_name+' '+u.reputation
d=document
j=d.createElement('script')
j.src="//api.stackexchange.com/2.1/users/"+prompt()+'?site=diy&jsonp=f'
d.body.appendChild j


(Note that the program prompts you for "undefined" -- it's asking for the User ID.)

R - 84

84 = 115 - 31

sub(".*\\/(.*)\\?.*>(.*)<.*","\\1 \\2",grep("b=r",scan(paste0("http://stackoverflow.com/users/",scan(n=1)),""),v=T)[1])


Simulation:

> sub(".*\\/(.*)\\?.*>(.*)<.*","\\1 \\2",grep("b=r",scan(paste0("http://stackoverflow.com/users/",scan(n=1)),""),v=T)[1])
1: 1201032
[1] "flodel 31,093"

• +1 This is a very impressive use of regular expressions. Nov 17 '13 at 19:06

101 100 - CoffeeScript with jQuery

$.getJSON "http://api.stackexchange.com/2.1/users/#{prompt()}?site=stackoverflow",(d)->alert [d.items[0].reputation,d.items[0].display_name]  Here's a fiddle; just know that it prompts you when you first open the page, so have a ID ready, or press Run again. Or we can be super hacky to save a whole character! $.getJSON "http://api.stackexchange.com/2.1/users/#{prompt()}?site=stackoverflow",(d)->with(d.items[0])alert([reputation,display_name]);1


Python 2.7 - 112

112 = 143 - 31

A newer, short version that uses some of the ideas from Steven Rumbalski answer, while still using Regex.

import urllib,re
print r[0][0],r[2][1]


133 = 164 - 31

Here is a base version for people to work from, but I'm sure people can get even shorter.

import urllib,re
u=input()
r=re.findall('name.*?>(.*?)</h1|tion.?>(.*?)</a',s)
print r[0][0],r[1][1]

• this doesn't seem to work. http://stackoverflow.com/users/12340 is 404. Oct 3 '13 at 7:50
• @JanDvorak, try with 499214 instead of 12340 Oct 3 '13 at 8:14
• @PeterTaylor then the question is incorrect. Oct 3 '13 at 8:15
• @JanDvorak Obviously, the user with that ID doesn't exist.
– user8777
Oct 3 '13 at 11:18

GNU Awk: 217 characters

Just because GNU awk supports TCP natively: no module/library/external tool.

{RS="\r"
print h("/users/"$0,$0,"/",4),h($2,$2"\\?","<|>",3)}function h(p,m,r,f){d="stackoverflow.com"
g="/inet/tcp/0/"d"/80"
print"GET "p" HTTP/1.1\nHost:"d"\n"|&g
close(g,"to")
while(g|&getline)if($0~m){close(g,"from") split($0,a,r)
return a[f]}}


Sample run:

bash-4.1$awk '{RS="\r";print h("/users/"$0,$0,"/",4),h($2,$2"\\?","<|>",3)}function h(p,m,r,f){d="stackoverflow.com";g="/inet/tcp/0/"d"/80";print"GET "p" HTTP/1.1\nHost:"d"\n"|&g;close(g,"to");while(g|&getline)if($0~m){close(g,"from");split($0,a,r);return a[f]}}' <<< 662504 manatwork 854 bash-4.1$ awk '{RS="\r";print h("/users/"$0,$0,"/",4),h($2,$2"\\?","<|>",3)}function h(p,m,r,f){d="stackoverflow.com";g="/inet/tcp/0/"d"/80";print"GET "p" HTTP/1.1\nHost:"d"\n"|&g;close(g,"to");while(g|&getline)if($0~m){close(g,"from");split($0,a,r);return a[f]}}' <<< 764357
lego-stormtroopr 3,947