stats.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import sys, traceback
  2. import sqlite3 as sql
  3. import math
  4. import argparse
  5. def get_median(sorted_data):
  6. n = len(sorted_data)
  7. # floor division
  8. if n % 2 == 1: # If odd
  9. median = sorted_data[n // 2]
  10. else: # If even
  11. mid1 = sorted_data[n // 2 - 1]
  12. mid2 = sorted_data[n // 2]
  13. median = (mid1 + mid2) // 2
  14. return median
  15. def calculate(rows):
  16. n = len(rows)
  17. if n < 2:
  18. return
  19. # (9, '^xfff[^xf00NoLove^xeee]^xddd idle^7', 9722)
  20. times = [row[2] for row in rows]
  21. mean = sum(times) // n
  22. if n > 2:
  23. median = get_median(times)
  24. else:
  25. median = mean
  26. stdev = int()
  27. variance = int()
  28. for time in times:
  29. variance = (time - mean) ** 2
  30. variance = variance/n
  31. stdev = round(math.sqrt(variance))
  32. # print(times, file=sys.stderr)
  33. # print(mean, file=sys.stderr)
  34. # print(median, file=sys.stderr)
  35. # print(stdev, file=sys.stderr)
  36. return n, mean/100, median/100, (mean-median)/100, stdev/100
  37. def main_loop(database, map_list):
  38. if map_list == []:
  39. return
  40. query = str();
  41. with open("queries/mleaderboard-ojoin.sql", 'r') as f:
  42. query = f.read()
  43. if query == str():
  44. return
  45. data = []
  46. # with open("test.html", 'w') as output:
  47. for game_map in map_list:
  48. result = []
  49. with sql.connect(database) as con:
  50. cursor = con.cursor()
  51. try:
  52. cursor.execute(query, game_map)
  53. result = cursor.fetchall()
  54. except sql.Error:
  55. traceback.print_exc()
  56. print("\n\t", game_map)
  57. try:
  58. # select Cts_ranks.mapid, max(trank), min(tvalue), alias
  59. if len(result) > 1:
  60. data.append ( [game_map[0], *calculate(result)] )
  61. # test output without spamming console
  62. # if game_map[0] == "zeel-omnitek":
  63. # print(result, file=sys.stderr)
  64. except TypeError:
  65. traceback.print_exc()
  66. print("\n\t occurred given map ", game_map[0])
  67. return data
  68. def to_html(data, footnotes=[str(),str()], ahref = str()):
  69. # print(data)
  70. table = list()
  71. header = """<table class='leaderboard'>
  72. <th colspan='6'> <h3><br/>Map List</H3> </th>
  73. <tr>
  74. <th>Name</th>
  75. <th>Records</th>
  76. <th>Mean</th>
  77. <th>Median</th>
  78. <th>Δ {explain1}</th>
  79. <th>σ {explain2}</th>
  80. </tr>"""
  81. table.append(
  82. header.format(
  83. explain1=footnotes[0], explain2=footnotes[1]
  84. )
  85. )
  86. for d in data:
  87. if ahref != str():
  88. d[0] = "<a href=\"%s%s\">%s</a>" % (ahref, d[0],d[0])
  89. row = ["<td>%s</s>" % elem for elem in d]
  90. table.append("\t<tr>%s</tr>\n" % "".join(row))
  91. table.append("</table>")
  92. return table
  93. def generate_page(html_template, data):
  94. template = str()
  95. with open(html_template,'r') as f:
  96. template = f.read()
  97. with open("test.html", 'w') as output:
  98. output.write(template % "".join(data))
  99. return len(data)
  100. # get maps in same order asother pages
  101. def get_map_list(db):
  102. map_list = []
  103. query = str()
  104. result = []
  105. with open("queries/mranks.sql", 'r') as f:
  106. query = f.read()
  107. with sql.connect(db) as con:
  108. try:
  109. cursor = con.cursor()
  110. cursor.execute(query)
  111. result = cursor.fetchall()
  112. except sql.Error:
  113. pass
  114. return [ (row[0],) for row in result]
  115. def main(p1, p2, p3, p4):
  116. database = p1 or "db/cts.db"
  117. template = p2 or "templates/overview.html"
  118. url = p3 or "/xdf/maps/"
  119. notes = p4
  120. maps = get_map_list(database)
  121. line_count = generate_page(
  122. template,
  123. to_html(main_loop(database, maps), footnotes=notes, ahref=url)
  124. )
  125. print("wrote %i lines to template %s" \
  126. % (line_count, template))
  127. return
  128. if __name__ == "__main__":
  129. parser = argparse.ArgumentParser()
  130. parser.add_argument(
  131. '-d','--db',
  132. help="database that is queried by the script"
  133. )
  134. parser.add_argument(
  135. '-t', '--tpl',
  136. help="the html template to generate the page from"
  137. )
  138. parser.add_argument(
  139. '-l', '--link',
  140. help="folder or link, creates anchor tags on map names"
  141. )
  142. parser.add_argument(
  143. '-f1', '--footnote1',
  144. help="insert html (a footnote or tooltip) into <th> of delta"
  145. )
  146. parser.add_argument(
  147. '-f2', '--footnote2',
  148. help="insert html (a footnote or tooltip) into <th> of sigma"
  149. )
  150. # parser.add_argument(
  151. #
  152. # )
  153. a = parser.parse_args()
  154. f1 = a.footnote1 or str()
  155. f2 = a.footnote2 or str()
  156. args = [a.db, a.tpl, a.link, [f1,f2] ]
  157. main(*args)