Major update

This commit is contained in:
root 2012-07-11 17:39:20 +02:00
parent 8e1bf7b705
commit 2479b0a24d
33 changed files with 1194 additions and 110 deletions

0
bda/__init__.py Normal file
View file

14
bda/admin.py Normal file
View file

@ -0,0 +1,14 @@
# coding: utf-8
from django.contrib import admin
from bda.models import Spectacle, Participant, ChoixSpectacle
class ChoixSpectacleInline(admin.TabularInline):
model = ChoixSpectacle
sortable_field_name = "priority"
class ParticipantAdmin(admin.ModelAdmin):
inlines = [ChoixSpectacleInline]
admin.site.register(Spectacle)
admin.site.register(Participant, ParticipantAdmin)

92
bda/algorithm.py Normal file
View file

@ -0,0 +1,92 @@
# 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

44
bda/models.py Normal file
View file

@ -0,0 +1,44 @@
# coding: utf-8
from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from django.db.models.signals import post_save
class Spectacle (models.Model):
title = models.CharField ("Titre", max_length = 300)
date = models.DateTimeField ("Date & heure")
location = models.CharField ("Lieu", max_length = 300,
blank = True, null = True)
description = models.TextField ("Description", blank = True)
slots_description = models.TextField ("Description des places", blank = True)
slots = models.IntegerField ("Places")
priority = models.IntegerField ("Priorité", default = 1000)
class Meta:
verbose_name = "Spectacle"
ordering = ("priority", "date","title",)
def __repr__ (self):
return u"[%s]" % self.__unicode__()
def __unicode__ (self):
return u"%s - %s @ %s" % (self.title, self.date, self.location)
class Participant (models.Model):
user = models.ForeignKey(User, unique = True)
choices = models.ManyToManyField(Spectacle, through = "ChoixSpectacle")
def __unicode__ (self):
return u"%s" % (self.user)
class ChoixSpectacle (models.Model):
participant = models.ForeignKey(Participant)
spectacle = models.ForeignKey(Spectacle, related_name = "participants")
priority = models.PositiveIntegerField("Priorité")
double = models.BooleanField("Deux places<sup>1</sup>")
autoquit = models.BooleanField("Abandon<sup>2</sup>")
class Meta:
ordering = ("priority",)
#unique_together = (("participant", "spectacle",),)
verbose_name = "voeu"

16
bda/tests.py Normal file
View file

@ -0,0 +1,16 @@
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
Replace this with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.assertEqual(1 + 1, 2)

40
bda/views.py Normal file
View file

@ -0,0 +1,40 @@
# coding: utf-8
from django.contrib.auth.decorators import login_required
from django import forms
from django.forms.models import inlineformset_factory, BaseInlineFormSet
from gestioncof.shared import render_page
from bda.models import Spectacle, Participant, ChoixSpectacle
class BaseBdaFormSet(BaseInlineFormSet):
def clean(self):
"""Checks that no two articles have the same title."""
if any(self.errors):
# Don't bother validating the formset unless each form is valid on its own
return
spectacles = []
for i in range(0, self.total_form_count()):
form = self.forms[i]
if not form.cleaned_data:
continue
spectacle = form.cleaned_data['spectacle']
delete = form.cleaned_data['DELETE']
if not delete and spectacle in spectacles:
raise forms.ValidationError("Vous ne pouvez pas vous inscrire deux fois pour le même spectacle.")
spectacles.append(spectacle)
@login_required
def inscription(request):
BdaFormSet = inlineformset_factory(Participant, ChoixSpectacle, fields = ("spectacle","double","autoquit","priority",), formset = BaseBdaFormSet)
participant, created = Participant.objects.get_or_create(user = request.user)
success = False
if request.method == "POST":
formset = BdaFormSet(request.POST, instance = participant)
if formset.is_valid():
formset.save()
success = True
formset = BdaFormSet(instance = participant)
else:
formset = BdaFormSet(instance = participant)
return render_page(request, {"formset": formset, "success": success}, "inscription-bda.html")