93 lines
3.4 KiB
Python
93 lines
3.4 KiB
Python
|
# coding: utf-8
|
||
|
|
||
|
from django.conf import settings
|
||
|
import random
|
||
|
|
||
|
class Algorithm(object):
|
||
|
|
||
|
shows = None
|
||
|
ranks = None
|
||
|
origranks = None
|
||
|
double = None
|
||
|
|
||
|
def __init__(self, shows, members):
|
||
|
"""Initialisation :
|
||
|
- on aggrège toutes les demandes pour chaque spectacle dans
|
||
|
show.requests
|
||
|
- on crée des tables de demandes pour chaque personne, afin de
|
||
|
pouvoir modifier les rankings"""
|
||
|
self.shows = []
|
||
|
showdict = {}
|
||
|
for show in shows:
|
||
|
showdict[show] = show
|
||
|
show.requests = []
|
||
|
self.shows.append(show)
|
||
|
self.ranks = {}
|
||
|
self.origranks = {}
|
||
|
self.double = {}
|
||
|
for member in members:
|
||
|
ranks = {}
|
||
|
double = {}
|
||
|
for i in range(1, settings.NUM_CHOICES + 1):
|
||
|
choice = getattr(member, "choice%d" % i)
|
||
|
if not choice:
|
||
|
continue
|
||
|
# Noter les doubles demandes
|
||
|
if choice in double:
|
||
|
double[choice] = True
|
||
|
else:
|
||
|
showdict[choice].requests.append(member)
|
||
|
ranks[choice] = i
|
||
|
double[choice] = False
|
||
|
self.ranks[member] = ranks
|
||
|
self.double[member] = double
|
||
|
self.origranks[member] = dict(ranks)
|
||
|
|
||
|
def IncrementRanks(self, member, currank, increment = 1):
|
||
|
for show in self.ranks[member]:
|
||
|
if self.ranks[member][show] > currank:
|
||
|
self.ranks[member][show] -= increment
|
||
|
|
||
|
def appendResult(self, l, member, show):
|
||
|
l.append((member,
|
||
|
self.ranks[member][show],
|
||
|
self.origranks[member][show],
|
||
|
self.double[member][show]))
|
||
|
|
||
|
def __call__(self, seed):
|
||
|
random.seed(seed)
|
||
|
results = []
|
||
|
for show in self.shows:
|
||
|
# On regroupe tous les gens ayant le même rang
|
||
|
groups = {}
|
||
|
for i in range(1, settings.NUM_CHOICES + 1):
|
||
|
groups[i] = []
|
||
|
for member in show.requests:
|
||
|
groups[self.ranks[member][show]].append(member)
|
||
|
# On passe à l'attribution
|
||
|
winners = []
|
||
|
losers = []
|
||
|
for i in range(1, settings.NUM_CHOICES + 1):
|
||
|
group = list(groups[i])
|
||
|
random.shuffle(group)
|
||
|
for member in group:
|
||
|
if self.double[member][show]: # double
|
||
|
if len(winners) + 1 < show.slots:
|
||
|
self.appendResult(winners, member, show)
|
||
|
self.appendResult(winners, member, show)
|
||
|
elif not member.autoquit and len(winners) < show.slots:
|
||
|
self.appendResult(winners, member, show)
|
||
|
self.appendResult(losers, member, show)
|
||
|
else:
|
||
|
self.appendResult(losers, member, show)
|
||
|
self.appendResult(losers, member, show)
|
||
|
self.IncrementRanks(member, i, 2)
|
||
|
else: # simple
|
||
|
if len(winners) < show.slots:
|
||
|
self.appendResult(winners, member, show)
|
||
|
else:
|
||
|
self.appendResult(losers, member, show)
|
||
|
self.IncrementRanks(member, i)
|
||
|
results.append((show,winners,losers))
|
||
|
return results
|