User:TakuyaMurata/vote.rb

From Wikipedia, the free encyclopedia
#!/usr/bin/ruby

$output = ""

class Entry
  attr_accessor (:score, :votes, :scales)
  
  def initialize (score, votes)
    @score = score
    @votes = votes
    @scales = {}
    @scales[1] = []
    @scales[2] = []
    @scales[3] = []
    @scales[4] = []
    @scales[5] = []
  end
  
  def mean
    @score.to_f / @votes
  end

  def to_s
    "#{mean} (points:#{score}; votes:#{votes})"
  end
  
  def scales_to_s
    s = ''
    for n in 1..5
      i = 6 - n
      s += ":#{i} (#{scales[i].size} votes) - #{@scales[i].join (', ')}\n"
    end
    s
  end
  
  def <=> (y)
    mean <=> y.mean
  end
end

$entries = {}

def vote (user, points, entry)
  $output += "#{user} votes #{points} for #{entry}\n"

  if $entries[entry] == nil then
    $entries[entry] = Entry.new (0, 0)
  end
  
  $entries[entry].score += points;
  $entries[entry].votes += 1;
  $entries[entry].scales[points].push (user)
end

def count_ballot (user)
  candidates = "1a|1b|2a|2b|2c|2d|2e|3a|3b|4a|4b|4c|4d|5a|5b|5c|5d|5e|6a|6b|6c|7a|7b|7c|7d|7e|8|9a|9b|9c|9d|9e|10|11|0"
  
  STDIN.each_line do |ln|
    ln = ln.chomp
    
    if ln =~ /Marked for invalidation/ && !(ln =~ /<strike>/) then
      STDERR.print "#{user}'s votes are marked for invalidation\n"
      return ln
    end
    
    if ln =~ /^\*/ then 
      if ln =~ /^\* *(#{candidates})(?:[:. ]| )+([12345])/ then
        vote (user, $2.to_i, $1)
      else
        STDERR.print "#{user}'s invalid: " + ln + "\n"
      end
    elsif ln =~ /==|---/ then
      return ln
    end
  end
  
  return ''
end

STDIN.each_line do |ln|
  ln = ln.chomp
  if ln =~ /== *(\[\[.+\]\]).*==/ then 
    ln = count_ballot ($1)
    redo
  end
end

#print "\n"
#print "== Counted votes ==\n"
#print $output

$entries.sort {|a,b| b[1]<=>a[1]}.each do |entry|
  key = entry[0]
  print "*#{key}: #{entry[1]}\n"
  print entry[1].scales_to_s
end