Mercurial > hg > rlgallery-misc
view py/stats2.py @ 55:e421ea2519ec
dgamelaunch: define user/group by name instead of UID/GID.
The user and group might not be created with the UID and GID expected,
so it is better to use names. They can be changed to numeric values
after installation.
author | John "Elwin" Edwards |
---|---|
date | Sun, 11 May 2014 08:32:31 -0700 |
parents | 0f4163dbbafc |
children | 5cf88bd4e556 |
line wrap: on
line source
#!/usr/bin/python3 import psycopg2 import rlgall from datetime import datetime sitename = "rlgallery.org" svgpath = rlgall.webdir timestr = datetime.utcnow().strftime("%Y-%m-%d %H:%M") dochead = """<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="900" height="600"> """ stylesheet = """<style type="text/css"> rect.frame {{ fill:#ffffff; fill-opacity:1; stroke:#000000; stroke-width:2; stroke-opacity:1; }} rect.bar {{ fill:#{0}; fill-opacity:1; stroke:#000000; stroke-width:2; stroke-opacity:1; }} </style> """ framerect = '<rect width="750" height="500" x="100" y="50" class="frame"/>\n' barstr = '<rect width="{0}" height="{1}" x="{2}" y="{3}" class="bar"/>\n' xllabel = '<text x="{0}" y="570" font-size="15" text-anchor="middle">{1}</text>\n' ylabel = '<text x="90" y="{0}" font-size="16" text-anchor="end">{1}</text>\n' xlabelf = '<text x="475" y="590" font-size="15" text-anchor="middle">{0}</text>\n' ltitle = '<text x="100" y="35" font-size="16" text-anchor="start">{0}</text>\n' ctitle = '<text x="475" y="34" font-size="18" text-anchor="middle">{0}</text>\n' rtitle = '<text x="850" y="35" font-size="16" text-anchor="end">{0}</text>\n' ylabelf = """<g transform="translate(100, 300)"> <g transform="rotate(-90)"> <text x="0" y="-60" font-size="16" text-anchor="middle">{0}</text> </g> </g> """ class SVGChart(): def __init__(self, filename): self.of = open(filename, "w", encoding="utf-8") self.of.write(dochead) def style(self, barcolor): self.of.write(stylesheet.format(barcolor)) def write(self, obj): self.of.write(obj) def close(self): self.of.write('</svg>\n') self.of.close() def ylimits(x): ll = [2, 3, 4, 5, 6, 8, 10, 15] m = 1 size = 0 while True: for i in ll: if i * m > x: size = i lim = i * m break if size: break else: m *= 10 if size in [3, 6]: if lim == 3: divs = 3 else: divs = 6 elif size in [4, 8]: divs = 4 else: if lim == 2: divs = 2 else: divs = 5 return divs, lim def titles(l, c, r): return ltitle.format(l) + ctitle.format(c) + rtitle.format(r) def mkxlgraph(game, xldata): xlgraph = SVGChart("{0}/xl-{1}.svg".format(svgpath, game.uname)) xlgraph.style("0000ff") xlgraph.write(framerect) xldivs, xlmax = ylimits(max([ pt[1] for pt in xldata ])) scale = 500 / xlmax for xl, count in xldata: barx = xl * 50 + 60 barh = round(scale * count) bary = 550 - barh xlgraph.write(barstr.format(30, barh, barx, bary)) xlgraph.write(xllabel.format(barx + 15, xl)) for yl in range(xldivs + 1): labeln = int(xlmax * yl / xldivs) labelh = 550 + 8 - 500 * yl / xldivs xlgraph.write(ylabel.format(labelh, labeln)) xlgraph.write(xlabelf.format("Experience level")) xlgraph.write(ylabelf.format("# of games")) xlgraph.write(titles(sitename, game.name, timestr)) xlgraph.close() return def mkscoregraph(game, scoredata): if isinstance(game, rlgall.ARogueGame): scorewidth = 1500 else: scorewidth = 1000 scoregraph = SVGChart("{0}/score-{1}.svg".format(svgpath, game.uname)) scoregraph.style("ffff00") scoregraph.write(framerect) scoredivs, scoremax = ylimits(max([ pt[1] for pt in scoredata ])) scale = 500 / scoremax for block, count in scoredata: n = block // scorewidth barx = n * 75 + 100 barh = round(scale * count) bary = 550 - barh scoregraph.write(barstr.format(75, barh, barx, bary)) scoregraph.write(xllabel.format(barx, block)) for yl in range(scoredivs + 1): labeln = int(scoremax * yl / scoredivs) labelh = 550 + 8 - 500 * yl / scoredivs scoregraph.write(ylabel.format(labelh, labeln)) scoregraph.write(xlabelf.format("Score")) scoregraph.write(ylabelf.format("# of games")) scoregraph.write(titles(sitename, game.name, timestr)) scoregraph.close() return def mkdeepgraph(game, deepdata): deepgraph = SVGChart("{0}/deep-{1}.svg".format(svgpath, game.uname)) deepgraph.style("808000") deepgraph.write(framerect) deepdivs, deepmax = ylimits(max([ pt[1] for pt in deepdata ])) scale = 500 / deepmax for lev, count in deepdata: barx = lev * 25 + 75 barh = round(scale * count) bary = 550 - barh deepgraph.write(barstr.format(25, barh, barx, bary)) if lev % 3 == 0: deepgraph.write(xllabel.format(barx + 12.5, lev)) for yl in range(deepdivs + 1): labeln = int(deepmax * yl / deepdivs) labelh = 550 + 8 - 500 * yl / deepdivs deepgraph.write(ylabel.format(labelh, labeln)) deepgraph.write(xlabelf.format("Deepest dungeon level")) deepgraph.write(ylabelf.format("# of games")) deepgraph.write(titles(sitename, game.name, timestr)) deepgraph.close() return for game in rlgall.gamelist: xldata = game.getXLCounts(15) deepdata = game.getDepthCounts(30) if isinstance(game, rlgall.ARogueGame): scorewidth = 1500 else: scorewidth = 1000 scoredata = game.getScoreCounts(10, scorewidth) mkxlgraph(game, xldata) mkscoregraph(game, scoredata) mkdeepgraph(game, deepdata) exit()