diff --git a/parcoursup/propositions/GroupeInternat.py b/parcoursup/propositions/GroupeInternat.py index a28cfeb..2ad74ea 100644 --- a/parcoursup/propositions/GroupeInternat.py +++ b/parcoursup/propositions/GroupeInternat.py @@ -87,16 +87,8 @@ def estAffecte(self, G_CN_CODE: int) -> bool: """ Vérifie si le candidat est affecté.""" return G_CN_CODE in self.candidatsAffectes - def initialiserPositionAdmission(self) -> None: - """ Initialise la position d'admission à son maximum Bmax dans le document de référence.""" - # on calcule le nombre de candidats éligibles à une admission - # dans l'internat aujourd'hui, stocké dans la variable assietteAdmission. - # On colle aux notations du document de référence (pour les lettres M, L, t, p etc) - M = len(self.candidatsEnAttente) + len(self.candidatsAffectes) - L = self.capacite - t = self.nbJoursCampagne - p = self.pourcentageOuverture - + def calculeAssietteAdmission(self, M: int, L: int, t: int, p: int) -> int: + """ Calcule l'assiette d'admission Bmax comme décrit dans l'algorithme.""" assietteAdmission = -1 if M <= L: @@ -117,6 +109,19 @@ def initialiserPositionAdmission(self) -> None: assietteAdmission = M self.contingentAdmission = max(0, assietteAdmission - len(self.candidatsAffectes)) + return assietteAdmission + + def initialiserPositionAdmission(self) -> None: + """ Initialise la position d'admission à son maximum Bmax dans le document de référence.""" + # on calcule le nombre de candidats éligibles à une admission + # dans l'internat aujourd'hui, stocké dans la variable assietteAdmission. + # On colle aux notations du document de référence (pour les lettres M, L, t, p etc) + M = len(self.candidatsEnAttente) + len(self.candidatsAffectes) + L = self.capacite + t = self.nbJoursCampagne + p = self.pourcentageOuverture + + assietteAdmission = self.calculeAssietteAdmission(M, L, t, p) if t <= 0 or t > 120 or p < 0 or p > 100 or L < 0 or assietteAdmission > M or self.contingentAdmission > len(self.candidatsEnAttente) or self.contingentAdmission < 0: raise RuntimeError("Problème de calcul du contingent d'admission, veuillez vérifier les données.") diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..d3eddb3 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,22 @@ +# Tests basés sur le BDD +## Avec [behave](https://behave.readthedocs.io/) + +- Ces fichiers de tests (fichiers `*.features`) viennent de [ce dépôt](https://github.com/JosePaumard/tests-pour-parcoursup). +- Les fichiers en Python utilisent [l'implémentation de ParcourSup.py](../parcoursup). + +## Comment lancer ces tests ? +- Il faut installer le module `behave` : + ```bash + $ sudo pip3 install behave + ``` +- Et ensuite vous pouvez utiliser le [`Makefile`](Makefile) fournit : + ```bash + $ make tests + ``` + qui va lancer tous les tests. + +## Exemples +TODO + +## À propos +- Merci à [José Paumard](https://github.com/JosePaumard/) pour cette belle initiative. diff --git a/tests/features/propositions-5-1-bmax.feature b/tests/features/propositions-5-1-bmax.feature new file mode 100644 index 0000000..eaf8d60 --- /dev/null +++ b/tests/features/propositions-5-1-bmax.feature @@ -0,0 +1,166 @@ +# Copyright (C) 2018 José Paumard +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +@Bmax +Feature: Algorithme de calcul de la position max d'admission d'un internat + Algorithme de calcul de la position maximum d’admission Bmax + + Scenario Template: Calcul de Bmax + Given un internat disposant de 300 places + And une liste de 1500 candidats + And un taux d'ouverture de 100 + When l'appel est lancé le jour + Then sont appelés + Examples: + | jour | candidats | + | 1 | 300 | + | 2 | 340 | + | 15 | 860 | + | 30 | 1460 | + | 31 | 1500 | + | 45 | 1500 | + | 60 | 1500 | + | 61 | 1500 | + | 65 | 1500 | + + Scenario Template: Calcul de Bmax + Given un internat disposant de 300 places + And une liste de 1500 candidats + And un taux d'ouverture de 70 + When l'appel est lancé le jour + Then sont appelés + Examples: + | jour | candidats | + | 1 | 300 | + | 2 | 328 | + | 15 | 692 | + | 30 | 1112 | + | 31 | 1140 | + | 45 | 1140 | + | 60 | 1500 | + | 61 | 1500 | + | 65 | 1500 | + + + Scenario Template: Calcul de Bmax + Given un internat disposant de 300 places + And une liste de 300 candidats + And un taux d'ouverture de 100 + When l'appel est lancé le jour + Then sont appelés + Examples: + | jour | candidats | + | 1 | 300 | + | 2 | 300 | + | 15 | 300 | + | 30 | 300 | + | 31 | 300 | + | 45 | 300 | + | 60 | 300 | + | 61 | 300 | + | 65 | 300 | + + + Scenario Template: Calcul de Bmax + Given un internat disposant de 300 places + And une liste de 300 candidats + And un taux d'ouverture de 70 + When l'appel est lancé le jour + Then sont appelés + Examples: + | jour | candidats | + | 1 | 300 | + | 2 | 300 | + | 15 | 300 | + | 30 | 300 | + | 31 | 300 | + | 45 | 300 | + | 60 | 300 | + | 61 | 300 | + | 65 | 300 | + + Scenario Template: Calcul de Bmax + Given un internat disposant de 300 places + And une liste de 40 candidats + And un taux d'ouverture de 100 + When l'appel est lancé le jour + Then sont appelés + Examples: + | jour | candidats | + | 1 | 40 | + | 2 | 40 | + | 15 | 40 | + | 30 | 40 | + | 31 | 40 | + | 45 | 40 | + | 60 | 40 | + | 61 | 40 | + | 65 | 40 | + + + Scenario Template: Calcul de Bmax + Given un internat disposant de 300 places + And une liste de 40 candidats + And un taux d'ouverture de 70 + When l'appel est lancé le jour + Then sont appelés + Examples: + | jour | candidats | + | 1 | 40 | + | 2 | 40 | + | 15 | 40 | + | 30 | 40 | + | 31 | 40 | + | 45 | 40 | + | 60 | 40 | + | 61 | 40 | + | 65 | 40 | + + Scenario Template: Calcul de Bmax + Given un internat disposant de 300 places + And une liste de 299 candidats + And un taux d'ouverture de 100 + When l'appel est lancé le jour + Then sont appelés + Examples: + | jour | candidats | + | 1 | 299 | + | 2 | 299 | + | 15 | 299 | + | 30 | 299 | + | 31 | 299 | + | 45 | 299 | + | 60 | 299 | + | 61 | 299 | + | 65 | 299 | + + + Scenario Template: Calcul de Bmax + Given un internat disposant de 300 places + And une liste de 299 candidats + And un taux d'ouverture de 70 + When l'appel est lancé le jour + Then sont appelés + Examples: + | jour | candidats | + | 1 | 299 | + | 2 | 299 | + | 15 | 299 | + | 30 | 299 | + | 31 | 299 | + | 45 | 299 | + | 60 | 299 | + | 61 | 299 | + | 65 | 299 | + diff --git a/tests/features/steps/propositions_steps.py b/tests/features/steps/propositions_steps.py new file mode 100644 index 0000000..d2b9044 --- /dev/null +++ b/tests/features/steps/propositions_steps.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +# -*- coding: utf8 -*- +""" Fichier Python qui définit les étapes permettant le test du module ordreappel avec Cucumber et le module behave. +""" + +# --------------------- +# Import des dépendances +from behave import * + +import sys +import os.path +sys.path.insert(0, os.path.join('..', '..')) + +# On importe parcoursup +from parcoursup.ordreappel.VoeuClasse import VoeuClasse + +from parcoursup.propositions.AlgoPropositions import AlgoPropositions +from parcoursup.propositions.GroupeAffectation import GroupeAffectation +from parcoursup.propositions.GroupeAffectationUID import GroupeAffectationUID +from parcoursup.propositions.GroupeInternat import GroupeInternat +from parcoursup.propositions.GroupeInternatUID import GroupeInternatUID +from parcoursup.propositions.VoeuEnAttente import VoeuEnAttente +from parcoursup.propositions.Candidat import Candidat +from parcoursup.propositions.Etablissement import Etablissement + + +# --------------------- +# On définit les fonctions utilitaires + +from ordreappel_steps import candidat2VoeuClasse, VoeuClasse2candidat + + +# --------------------- +# On définit les étapes + +@given("un internat disposant de {L:d} places") +def step_impl(context, L): + context.L = L + +@given("une liste de {M:d} candidats") +def step_impl(context, M): + context.M = M + +@given("un taux d'ouverture de {ouverture:d}") +def step_impl(context, ouverture): + context.ouverture = ouverture + +@when("l'appel est lancé le jour {jour:d}") +def step_impl(context, jour): + context.jour = jour + groupeInternatUID = GroupeInternatUID(1, 1) + groupeInternat = GroupeInternat(groupeInternatUID, context.L, context.ouverture) + bmax = groupeInternat.calculeAssietteAdmission(context.M, context.L, context.jour, context.ouverture) + context.bmax = bmax + +@then("{candidats:d} sont appelés") +def step_impl(context, candidats): + assert context.bmax == candidats