def filtre(candidat, test = False): prefixe = '' commentaire = '' # Candidature validée ? if candidat.xpath('synoptique/établissement/candidature_validée')[0].text.lower() != 'oui': commentaire = 'Candidature non validée sur ParcoursSup' Fichier.set(candidat, 'Correction', 'NC') Fichier.set(candidat, 'Jury', 'Admin') else: # si validée, # on récupère la série serie = '' probs = candidat.xpath('bulletins/bulletin[classe="Terminale"]') for prob in probs: # fausse boucle (normalement) serie = prob.xpath('série')[0].text # Si série non valide, on exclut if serie in series_non_valides: commentaire = 'Série {}'.format(serie) Fichier.set(candidat, 'Correction', 'NC') Fichier.set(candidat, 'Jury', 'Admin') else: # sinon, on alerte Admin sur certaines anomalies rencontrées prefixe = '- Alerte :' # 1/ Série reconnue ? if not(serie in series_valides): commentaire += ' | Vérifier la série |' # 2/ Le dossier est-il complet (toutes les notes présentes + classe actuelle) if not(Fichier.is_complet(candidat)): commentaire += ' Dossier incomplet |' if commentaire != '': Fichier.set(candidat, 'Motifs', '{} {}'.format(prefixe, commentaire)) else: # si aucune remarque, on calcule le score brut Fichier.calcul_scoreb(candidat) # Fin des filtres; on retourne un candidat mis à jour return candidat
def generation_comm(self): """ Création des fichiers commission """ # Objectif : classer les candidats (fichier admin) par ordre de score brut décroissant et générer autant de # fichiers qu'il y a de jurys dans la filière concernées. Ces fichiers sont construits de façon à ce qu'ils # contiennent des candidatures également solides. # Récupération des fichiers admin list_fich = [Fichier(fich) for fich in glob.glob(os.path.join(os.curdir, "data", "admin_*.xml"))] # Pour chaque fichier "admin_*.xml" for fich in list_fich: # Tout d'abord, calculer (et renseigner le noeud) le score brut de chaque candidat for cand in fich: Fichier.calcul_scoreb(cand) # Classement par scoreb décroissant doss = fich.ordonne('score_b') # Calcul du rang de chaque candidat et renseignement du noeuds 'rang_brut' for cand in fich: Fichier.set(cand, 'Rang brut', str(Fichier.rang(cand, doss, 'Score brut'))) # Récupération de la filière et du nombre de jurys nbjury = int(nb_jurys[fich.filiere().lower()]) # Découpage en n listes de dossiers for j in range(nbjury): dossier = [] # deepcopy ligne suivante sinon les candidats sont retirés de doss à chaque append [dossier.append(copy.deepcopy(doss[i])) for i in range(len(doss)) if i%nbjury == j] # Sauvegarde dans un fichier comm_XXXX.xml res = etree.Element('candidats') [res.append(cand) for cand in dossier] nom = os.path.join(os.curdir, "data", "comm_{}{}.xml".format(fich.filiere().upper(), j+1)) with open(nom, 'wb') as fichier: fichier.write(etree.tostring(res, pretty_print=True, encoding='utf-8')) # Création fichier decompte : celui-ci contiendra en fin de commission le nombre de candidats traités pour # chacune des filières. Ici, il est créé et initialisé. Il contient un dictionnaire {'filière' : nb, ...} decompt = {} for fil in filieres: decompt['{}'.format(fil.upper())] = 0 with open(os.path.join(os.curdir, "data", "decomptes"), 'wb') as stat_fich: pickle.dump(decompt, stat_fich)
def traiter(self, **kwargs): """ Traiter un dossier """ # Fonction lancée par la fonction "traiter" du Serveur, elle même lancée par un clic sur 'Classé' ou 'NC' # On récupère le candidat courant cand = self.get_cand() # Ici, on va répercuter les complétions de l'administrateur dans tous les dossiers que le candidat a déposé. # Attention ! le traitement du fichier en cours est fait à part car deux objets 'Fichier' qui # auraient le même nom sont malgré tout différents !! On rajoute la bonne instance Fichier juste après. # Recherche de tous les fichiers existants (sauf fichier en cours) : list_fich_admin = [Fichier(fich) for fich in glob.glob(os.path.join(os.curdir, "data", "admin_*.xml"))\ if fich != self.fichier.nom] # On restreint la liste aux fichiers contenant le candidat en cours list_fich_cand = [fich for fich in list_fich_admin if cand in fich] # On rajoute le fichier suivi actuellement list_fich_cand.append(self.fichier) # list_fich_cand contient tous les fichiers dans lesquels le candidat courant se trouve. # ############### Admin a-t-il changé qqc ? Si oui, mise à jour. # Classe actuelle ? if Fichier.get(cand, 'Classe actuelle') != kwargs['Classe actuelle']: for fich in list_fich_cand: Fichier.set(fich.get_cand(cand), 'Classe actuelle', kwargs['Classe actuelle']) # Cas des notes matiere = ['Mathématiques', 'Physique/Chimie'] date = ['trimestre 1', 'trimestre 2', 'trimestre 3'] classe = ['Première', 'Terminale'] for cl in classe: for mat in matiere: for da in date: key = '{} {} {}'.format(mat, cl, da) if Fichier.get(cand, key) != kwargs[key]: # la note a-t-elle été modifiée ? for fich in list_fich_cand: Fichier.set(fich.get_cand(cand), key, kwargs[key]) # CPES et EAF #liste = ['Mathématiques CPES', 'Physique/Chimie CPES', 'Écrit EAF', 'Oral EAF'] # Seulement EAF depuis 2020 liste = ['Écrit EAF', 'Oral EAF'] for li in liste: if 'cpes' in li.lower(): if ('cpes' in Fichier.get(cand, 'Classe actuelle').lower()) and Fichier.get(cand, li) != kwargs[li]: for fich in list_fich_cand: Fichier.set(fich.get_cand(cand), li, kwargs[li]) else: if Fichier.get(cand, li) != kwargs[li]: for fich in list_fich_cand: Fichier.set(fich.get_cand(cand), li, kwargs[li]) # Commentaire éventuel admin + gestion des 'NC' # Les commentaires admin sont précédés de '- Admin :' c'est à cela qu'on les reconnaît. Et le jury les # verra sur fond rouge dans la liste de ses dossiers. # Par ailleurs, dossiers_jury.js exclut qu'un tel commentaire soit considéré comme une motivation de jury. motif = kwargs['motif'] if not('- Admin :' in motif or motif == '' or '- Alerte :' in motif): motif = '- Admin : {}'.format(motif) # Récupération de la correction. On en fait qqc seulement si elle est minimale (NC) cor = kwargs['correc'] # récupération de la correction et calcul du score final if float(cor) == float(min_correc): # L'admin a validé le formulaire avec la correction NC (le candidat ne passera pas en commission) # Pour ce cas là, on ne recopie pas dans toutes les filières. Admin peut exclure une candidature # dans une filière sans l'exclure des autres. Sécurité ! Fichier.set(cand, 'Correction', 'NC') # la fonction calcul_scoreb renverra 0 ! Fichier.set(cand, 'Jury', 'Admin') # Cette exclusion est un choix de l'admin (apparaît dans les tableaux) Fichier.set(cand, 'Motifs', motif) else: Fichier.set(cand, 'Correction', '0') # 2 lignes nécessaires si l'admin a NC un candidat, puis a changé d'avis. Fichier.set(cand, 'Jury', '') for fich in list_fich_cand: Fichier.set(fich.get_cand(cand), 'Motifs', motif) # On (re)calcule le score brut ! Fichier.calcul_scoreb(cand) # On sauvegarde tous les fichiers retouchés for fich in list_fich_cand: fich.sauvegarde()