1. import csv
  2. import random
  3. import sys
  4.  
  5. Games = []
  6. Users = set()
  7.  
  8. class Game(object):
  9.     name = ""
  10.     stock = 0
  11.     winners = None
  12.    
  13.     def __init__(self, name="", stock=0):
  14.         self.name = name
  15.         self.stock = stock
  16.         self.winners = set()
  17.  
  18.     def __repr__(self):
  19.         return "%s (x%d)" % (self.name, self.stock)
  20.  
  21. class User(object):
  22.     name = ""
  23.     wants = None
  24.  
  25.     def prune(self):
  26.         global Users
  27.        
  28.         removes = []
  29.         for i in xrange(len(self.wants)):
  30.             if self.wants[i].stock <= 0:
  31.                 removes.append(i)
  32.  
  33.         removes.reverse()
  34.         for i in removes:
  35.             self.wants.pop(i)
  36.  
  37.         if len(self.wants) == 0:
  38.             print "Removing user %s" % self.name
  39.             return True
  40.         else:
  41.             return False
  42.  
  43.     def win(self):
  44.         global Users
  45.  
  46.         if len(self.wants) == 0:
  47.             raise ValueError("User %s doesn't want anything" % self.name)
  48.  
  49.         won = self.wants[0]
  50.         if won.stock <= 0:
  51.             raise ValueError("Oversold game %s" % str(won))
  52.  
  53.         print "%s wins %s" % (self.name, won.name)
  54.  
  55.         Users.remove(self)
  56.         won.winners.add(self)
  57.        
  58.         won.stock = won.stock - 1
  59.  
  60.         not_winners = set()
  61.         if won.stock == 0:
  62.             for user in Users:
  63.                 if user.prune():
  64.                     not_winners.add(user)
  65.  
  66.         for u in not_winners:
  67.             Users.remove(u)
  68.            
  69.     def __init__(self, line):
  70.         global Games
  71.        
  72.         self.name = line[0]
  73.         games = list(line[1:])
  74.  
  75.         self.wants = []
  76.         i = 1
  77.         while games.count(str(i)) > 0:
  78.             if games.count(str(i)) > 1:
  79.                 raise ValueError("User %s has multiple choice #%d" % (self.name, i))
  80.  
  81.             self.wants.append(Games[games.index(str(i))])
  82.  
  83.             i = i+1
  84.  
  85.         print "%s wants %s" % (self.name, ", ".join(x.name for x in self.wants))
  86.  
  87.     def __repr__(self):
  88.         return self.name
  89.  
  90. lines = csv.reader(open('drawing.csv', 'rb'))
  91. names = lines.next()
  92. Games = [Game(x) for x in names[1:]]
  93. stocks = lines.next()
  94. for i in xrange(len(Games)):
  95.     Games[i].stock = int(stocks[i+1])
  96.  
  97. # Skip user header
  98. lines.next()
  99.  
  100. # Load users
  101. Users.update(User(x) for x in lines if len(x) > 0 and x[0] != "")
  102.  
  103. print
  104. print '=================='
  105. print
  106.  
  107. # Draw winners
  108. while len(Users) > 0:
  109.     winner = random.sample(Users, 1)[0]
  110.     winner.win()
  111.  
  112. print
  113. print '=================='
  114. print
  115.  
  116. # Print results
  117. for game in Games:
  118.     print '***'
  119.     print
  120.     print '## %s' % game.name
  121.     print
  122.     print 'Winners: %s' % (', '.join('[%(name)s](/user/%(name)s)' % x for x in game.winners))
  123.     print
  124.     print 'Stock remaining: %d' % game.stock
  125.     print