added minor unit test
finished implementation of xmlrate.rb
This commit is contained in:
1 parent
1d7fe55032
commit
f88f2d020b
2 files changed
+107
-62
No files matched your search
@@ -22,6 +22,12 @@ class TestGlicko2 < Test::Unit::TestCase
|
|||||||
|
|
||||||
assert_in_delta(1464.05,a.rating,0.01)
|
assert_in_delta(1464.05,a.rating,0.01)
|
||||||
assert_in_delta(151.516,a.deviation,0.01)
|
assert_in_delta(151.516,a.deviation,0.01)
|
||||||
|
|
||||||
|
a.update()
|
||||||
|
|
||||||
|
assert_in_delta(1464.05,a.rating,0.01)
|
||||||
|
assert_in_delta(151.516,a.deviation,0.01)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
+101
-62
@@ -1,68 +1,107 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
require "rexml/document"
|
require "rexml/document"
|
||||||
require "glicko2"
|
require "glicko2"
|
||||||
|
|
||||||
file = File.new( "../py/data/hockey-2005.xml" )
|
# sort & output the player array
|
||||||
|
def output_players(playerhash,title="")
|
||||||
doc = REXML::Document.new(file)
|
puts title
|
||||||
|
sorted_players = playerhash.sort { |a,b| a[1] <=> b[1] }
|
||||||
# each rating doc
|
i = 0
|
||||||
doc.elements.each("ratingdoc") do |root|
|
sorted_players.reverse.each { |k,v| puts sprintf("%3d%30s: %6.1f +/- %5.1f %0.05f\n",i += 1,k,v.rating,v.deviation,v.volatility) }
|
||||||
|
puts
|
||||||
players = Hash.new
|
|
||||||
|
|
||||||
# each player
|
|
||||||
root.elements.each("player") do |player|
|
|
||||||
|
|
||||||
name = player.elements["name"].text
|
|
||||||
rating = 1500.0
|
|
||||||
deviation = 350.0
|
|
||||||
variance = 0.06
|
|
||||||
|
|
||||||
# TODO: find better "Ruby-esqe" way of doing these
|
|
||||||
if player.elements["rating"]
|
|
||||||
rating = player.elements["rating"].text
|
|
||||||
end
|
|
||||||
if player.elements["deviation"]
|
|
||||||
deviation = player.elements["deviation"].text
|
|
||||||
end
|
|
||||||
if player.elements["variance"]
|
|
||||||
variance = player.elements["variance"].text
|
|
||||||
end
|
|
||||||
|
|
||||||
players[name] = Glicko2.new(rating.to_f,deviation.to_f,variance.to_f)
|
|
||||||
puts name,rating,deviation,variance
|
|
||||||
puts
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# each rating period
|
|
||||||
root.elements.each("period") do |period|
|
|
||||||
|
|
||||||
# each regular game
|
|
||||||
period.elements.each("game") do |game|
|
|
||||||
|
|
||||||
home = game.elements["home"].text
|
|
||||||
away = game.elements["away"].text
|
|
||||||
result = game.elements["result"].text
|
|
||||||
|
|
||||||
players[home].add_result( players[away], result.to_f )
|
|
||||||
players[away].add_result( players[home], 1.0 - result.to_f )
|
|
||||||
end
|
|
||||||
|
|
||||||
# each race
|
|
||||||
period.elements.each("race") do |race|
|
|
||||||
race.elements.each("competitor") do |c|
|
|
||||||
puts c.text
|
|
||||||
end
|
|
||||||
puts
|
|
||||||
end
|
|
||||||
|
|
||||||
# update all players
|
|
||||||
players.each_value { |p| p.update }
|
|
||||||
players.each { |p,r| puts p,r.rating }
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# handle one file
|
||||||
|
def parse_file(filename)
|
||||||
|
|
||||||
|
# load & parse XML
|
||||||
|
file = File.new(filename)
|
||||||
|
doc = REXML::Document.new(file)
|
||||||
|
|
||||||
|
# each rating doc
|
||||||
|
doc.elements.each("ratingdoc") do |root|
|
||||||
|
|
||||||
|
# new/empty player hash
|
||||||
|
players = Hash.new
|
||||||
|
|
||||||
|
# each player
|
||||||
|
root.elements.each("player") do |player|
|
||||||
|
|
||||||
|
# setup defaults
|
||||||
|
name = player.elements["name"].text
|
||||||
|
rating = 1500.0
|
||||||
|
deviation = 350.0
|
||||||
|
variance = 0.06
|
||||||
|
|
||||||
|
# TODO: find better "Ruby-esqe" way of doing these
|
||||||
|
if player.elements["rating"]
|
||||||
|
rating = player.elements["rating"].text
|
||||||
|
end
|
||||||
|
if player.elements["deviation"]
|
||||||
|
deviation = player.elements["deviation"].text
|
||||||
|
end
|
||||||
|
if player.elements["variance"]
|
||||||
|
variance = player.elements["variance"].text
|
||||||
|
end
|
||||||
|
|
||||||
|
# create player + glicko2 object
|
||||||
|
players[name] = Glicko2.new(rating.to_f,deviation.to_f,variance.to_f)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# dump initial player ratings
|
||||||
|
output_players(players,"initial ratings")
|
||||||
|
|
||||||
|
# each rating period
|
||||||
|
period_id = 0
|
||||||
|
root.elements.each("period") do |period|
|
||||||
|
|
||||||
|
# each regular game
|
||||||
|
period.elements.each("game") do |game|
|
||||||
|
|
||||||
|
home = game.elements["home"].text
|
||||||
|
away = game.elements["away"].text
|
||||||
|
result = game.elements["result"].text
|
||||||
|
|
||||||
|
result_val = Glicko2::WIN if result == "win"
|
||||||
|
result_val = Glicko2::LOSS if result == "loss"
|
||||||
|
result_val = Glicko2::DRAW if result == "draw"
|
||||||
|
|
||||||
|
players[home].add_result( players[away], result_val )
|
||||||
|
players[away].add_result( players[home], 1.0 - result_val )
|
||||||
|
end
|
||||||
|
|
||||||
|
# each race
|
||||||
|
racelist = []
|
||||||
|
period.elements.each("race") do |race|
|
||||||
|
race.elements.each("competitor") do |c|
|
||||||
|
|
||||||
|
# make this competitor lose to everyone already in our list
|
||||||
|
racelist.each do |otherc|
|
||||||
|
players[otherc].add_win(players[c.text])
|
||||||
|
players[c.text].add_loss(players[otherc])
|
||||||
|
end
|
||||||
|
|
||||||
|
# add this competitor to our list
|
||||||
|
racelist.push(c.text)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# update all players
|
||||||
|
players.each_value { |p| p.update }
|
||||||
|
|
||||||
|
# output players
|
||||||
|
output_players(players,sprintf("after rating period %d",period_id += 1))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# main program
|
||||||
|
ARGV.each { |a| parse_file(a) }
|
||||||
|
|
||||||
|
|
||||||
Reference in new issue
Block a user