Skip to content

Instantly share code, notes, and snippets.

@diafygi
Created June 21, 2012 07:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save diafygi/2964356 to your computer and use it in GitHub Desktop.
Save diafygi/2964356 to your computer and use it in GitHub Desktop.
HardcoreSMP Death Stats Example
# Written by diafygi: diafygi<at symbol>gmail<dot>com
# Released under the GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
#
# This script downloads the HardcoreSMP death list and parses it to create stats for the month.
import urllib2
import re
from datetime import datetime, timedelta
#grab hcsmp death log
req = urllib2.Request("http://hcsmp.com/players/deaths")
full_page = "".join(urllib2.urlopen(req).readlines())
#parse death log
#[<rebirth>, <cause>, <user>, <join_time>, <death_time>, <total_time>, <summary>, <killer>, <witness>, <last_words>]
deaths_raw = re.findall('<tr class="(.*?)"><td><i class="(.+?)"></i>(.+?)</td><td>(.+?)</td><td>(.+?)</td><td>(.+?)</td><td>(.+?)</td><td>(.+?)</td><td>(.+?)</td><td><pre class="lastWords">(.*?)</pre></td></tr>', full_page)
deaths = []
for d in deaths_raw:
deaths.append({
"rebirth": "revived" if d[0] else "final" if d[0] else None,
"cause": d[1],
"user": d[2],
"join_time": datetime.strptime(d[3] + " 2012", "%b %d, %I:%M %p %Y"),
"death_time": datetime.strptime(d[4] + " 2012", "%b %d, %I:%M %p %Y"),
"total_time": timedelta(hours=int(d[5].split(" ")[0])) if "hour" in d[5] \
else timedelta(minutes=int(d[5].split(" ")[0])) if "minute" in d[5] \
else timedelta(seconds=int(d[5].split(" ")[0])),
"summary": "Slain By Player" if "Killed By" in d[6] else d[6].strip(),
"killer": d[7] if d[7] != "-" else re.findall("Killed By (.+)", d[6])[0].strip() if re.findall("Killed By (.+)", d[6]) else None,
"witness": d[8] if d[8] != "-" else None,
"last_words": d[9],
})
#define stats
ways_to_die = {
"overall": {},
"0-2 hours": {},
"2-30 hours": {},
"30+ hours": {},
}
killers_dict = {}
witnesses_dict = {}
#calculate stats
for d in deaths:
#overall
ways_to_die['overall'][d['summary']] = ways_to_die['overall'].get(d['summary'], 0) + 1
#noobs
if d['total_time'] < timedelta(hours=2):
ways_to_die['0-2 hours'][d['summary']] = ways_to_die['0-2 hours'].get(d['summary'], 0) + 1
#moderates
elif d['total_time'] < timedelta(hours=30):
ways_to_die['2-30 hours'][d['summary']] = ways_to_die['2-30 hours'].get(d['summary'], 0) + 1
#experienced
else:
ways_to_die['30+ hours'][d['summary']] = ways_to_die['30+ hours'].get(d['summary'], 0) + 1
#killers
if d['killer']:
killers_dict[d['killer']] = killers_dict.get(d['killer'], 0) + 1
#witnesses
if d['witness']:
witnesses_dict[d['witness']] = witnesses_dict.get(d['witness'], 0) + 1
killers = sorted([{"user":u, "killed":k} for u, k in killers_dict.items()], key=lambda u: u['killed'], reverse=True)
witnesses = sorted([{"user":u, "witnessed":k} for u, k in witnesses_dict.items()], key=lambda u: u['witnessed'], reverse=True)
#format for html charts and tables
ways_to_die_tuple = {}
for w in ways_to_die.keys():
ways_to_die_tuple[w] = sorted([(d, c) for d, c in ways_to_die[w].items()], key=lambda u: u[1], reverse=True)
ways_to_die_html = {
"overall": {
"labels": "|".join(["{} ({})".format(i[0], i[1]) for i in ways_to_die_tuple['overall']]),
"numbers": ",".join([str(i[1]) for i in ways_to_die_tuple['overall']]),
},
"0-2 hours": {
"labels": "|".join(["{} ({})".format(i[0], i[1]) for i in ways_to_die_tuple['0-2 hours']]),
"numbers": ",".join([str(i[1]) for i in ways_to_die_tuple['0-2 hours']]),
},
"2-30 hours": {
"labels": "|".join(["{} ({})".format(i[0], i[1]) for i in ways_to_die_tuple['2-30 hours']]),
"numbers": ",".join([str(i[1]) for i in ways_to_die_tuple['2-30 hours']]),
},
"30+ hours": {
"labels": "|".join(["{} ({})".format(i[0], i[1]) for i in ways_to_die_tuple['30+ hours']]),
"numbers": ",".join([str(i[1]) for i in ways_to_die_tuple['30+ hours']]),
},
}
killers_html = "</tr><tr>".join(['<td>{}</td><td>{}</td>'.format(x['user'], x['killed']) for i, x in enumerate(killers) if i < 10])
witnesses_html = "</tr><tr>".join(['<td>{}</td><td>{}</td>'.format(x['user'], x['witnessed']) for i, x in enumerate(witnesses) if i < 10])
#print html page
print """
<html>
<head><title>HCSMP Stats</title></head>
<body>
<h1>Top Killers</h1>
<table>
<tr><td>Player</td><td>Kills</td></tr>
<tr>{}</tr>
</table>
<h1>Top Witnesses</h1>
<table>
<tr><td>Player</td><td>Deaths Witnessed</td></tr>
<tr>{}</tr>
</table>
<h1>Ways to Die</h1>
<h3>Overall</h3>
<img src="https://chart.googleapis.com/chart?cht=p&chds=a&chs=700x300&chd=t:{}&chl={}" />
<h3>Noobs (0-2 hours)</h3>
<img src="https://chart.googleapis.com/chart?cht=p&chds=a&chs=700x300&chd=t:{}&chl={}" />
<h3>Moderates (2-30 hours)</h3>
<img src="https://chart.googleapis.com/chart?cht=p&chds=a&chs=700x300&chd=t:{}&chl={}" />
<h3>Experienced (30+ hours)</h3>
<img src="https://chart.googleapis.com/chart?cht=p&chds=a&chs=700x300&chd=t:{}&chl={}" />
</body>
</html>
""".format(
killers_html,
witnesses_html,
ways_to_die_html['overall']['numbers'],
ways_to_die_html['overall']['labels'],
ways_to_die_html['0-2 hours']['numbers'],
ways_to_die_html['0-2 hours']['labels'],
ways_to_die_html['2-30 hours']['numbers'],
ways_to_die_html['2-30 hours']['labels'],
ways_to_die_html['30+ hours']['numbers'],
ways_to_die_html['30+ hours']['labels'],
)
<html>
<head><title>HCSMP Stats</title></head>
<body>
<h1>Top Killers</h1>
<table>
<tr><td>Player</td><td>Kills</td></tr>
<tr><td>cliffnerd5</td><td>43</td></tr><tr><td>Scatcycle</td><td>16</td></tr><tr><td>rupturedKidney</td><td>13</td></tr><tr><td>jaycow</td><td>12</td></tr><tr><td>xHippo</td><td>11</td></tr><tr><td>Byron_Tryhard</td><td>11</td></tr><tr><td>xMopx</td><td>9</td></tr><tr><td>PapaLuigi121</td><td>8</td></tr><tr><td>justintb97</td><td>8</td></tr><tr><td>FatherSouth</td><td>7</td></tr>
</table>
<h1>Top Witnesses</h1>
<table>
<tr><td>Player</td><td>Deaths Witnessed</td></tr>
<tr><td>cliffnerd5</td><td>9</td></tr><tr><td>Kibbles93</td><td>6</td></tr><tr><td>xCoyote18</td><td>5</td></tr><tr><td>xHippo</td><td>5</td></tr><tr><td>edmundishere</td><td>5</td></tr><tr><td>FatherSouth</td><td>5</td></tr><tr><td>robpm88</td><td>5</td></tr><tr><td>Four_Down</td><td>4</td></tr><tr><td>stormhawk49</td><td>4</td></tr><tr><td>Emmzy_pop</td><td>4</td></tr>
</table>
<h1>Ways to Die</h1>
<h3>Overall</h3>
<img src="https://chart.googleapis.com/chart?cht=p&chds=a&chs=700x300&chd=t:910,463,460,210,173,151,136,99,97,66,54,46,34,32,23,16,15,2,1&chl=Starved To Death (910)|Hit The Ground Too Hard (463)|Slain By Player (460)|Tried To Swim In Lava (210)|Blew Up (173)|Drowned (151)|Shot By Skeleton (136)|Died (99)|Burned To Death (97)|Slain By Zombie (66)|Slain By Spider (54)|Went Up In Flames (46)|Slain By Zombie Pigman (34)|Suffocated In A Wall (32)|Slain By Cave Spider (23)|Slain By Enderman (16)|Pricked To Death (15)|Slain By Wolf (2)|Slain By Giant (1)" />
<h3>Noobs (0-2 hours)</h3>
<img src="https://chart.googleapis.com/chart?cht=p&chds=a&chs=700x300&chd=t:877,332,175,147,133,123,97,49,49,49,30,30,25,19,13,11,8,2,1&chl=Starved To Death (877)|Hit The Ground Too Hard (332)|Slain By Player (175)|Blew Up (147)|Tried To Swim In Lava (133)|Shot By Skeleton (123)|Drowned (97)|Slain By Spider (49)|Burned To Death (49)|Slain By Zombie (49)|Slain By Zombie Pigman (30)|Went Up In Flames (30)|Suffocated In A Wall (25)|Died (19)|Pricked To Death (13)|Slain By Enderman (11)|Slain By Cave Spider (8)|Slain By Wolf (2)|Slain By Giant (1)" />
<h3>Moderates (2-30 hours)</h3>
<img src="https://chart.googleapis.com/chart?cht=p&chds=a&chs=700x300&chd=t:225,114,69,66,44,40,28,23,15,15,12,10,7,4,4,3,2&chl=Slain By Player (225)|Hit The Ground Too Hard (114)|Tried To Swim In Lava (69)|Died (66)|Drowned (44)|Burned To Death (40)|Starved To Death (28)|Blew Up (23)|Went Up In Flames (15)|Slain By Zombie (15)|Slain By Cave Spider (12)|Shot By Skeleton (10)|Suffocated In A Wall (7)|Slain By Enderman (4)|Slain By Spider (4)|Slain By Zombie Pigman (3)|Pricked To Death (2)" />
<h3>Experienced (30+ hours)</h3>
<img src="https://chart.googleapis.com/chart?cht=p&chds=a&chs=700x300&chd=t:60,17,14,10,8,8,5,3,3,3,2,1,1,1,1&chl=Slain By Player (60)|Hit The Ground Too Hard (17)|Died (14)|Drowned (10)|Tried To Swim In Lava (8)|Burned To Death (8)|Starved To Death (5)|Shot By Skeleton (3)|Slain By Cave Spider (3)|Blew Up (3)|Slain By Zombie (2)|Slain By Enderman (1)|Slain By Zombie Pigman (1)|Slain By Spider (1)|Went Up In Flames (1)" />
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment