Attention ! Gitlab fournissant maintenant nativement des certificats Let’s Encrypt aux domaines personnalisés des Gitlab Pages, nous avons coupé notre service qui le faisait automatiquement pour vous.

Il est impératif, pour que votre domaine personnalisé continue à avoir un certificat Let’s Encrypt à jour, d’activer la fonctionnalité native dans les paramètres de votre projet. Cette activation remplacera votre certificat actuel par un nouveau certificat Let’s Encrypt géré par Gitlab.

Voir les détails sur https://docs.framasoft.org/fr/gitlab/gitlab-pages-le.html

Commit 1fbf5356 authored by Loïc's avatar Loïc

Fix #10 : System.out -> JUL

parent 7febb178
/* Copyright 2018, 2018 Hugo Gimbert (hugo.gimbert@enseignementsup.gouv.fr)
/* Copyright 2018, 2018 Hugo Gimbert (hugo.gimbert@enseignementsup.gouv.fr)
This file is part of Algorithmes-de-parcoursup.
......@@ -19,18 +19,21 @@
*/
package parcoursup.ordreappel.donnees;
import static java.util.stream.Collectors.joining;
import parcoursup.ordreappel.algo.AlgoOrdreAppelEntree;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import oracle.jdbc.OracleDriver;
import oracle.jdbc.pool.OracleDataSource;
import parcoursup.ordreappel.algo.AlgoOrdreAppelSortie;
......@@ -40,8 +43,10 @@ import parcoursup.ordreappel.algo.VoeuClasse;
public class ConnecteurDonneesAppelOracle implements ConnecteurDonneesAppel {
private static final Logger LOGGER = Logger.getLogger(ConnecteurDonneesAppelOracle.class.getName());
/* connexion à la base de données */
Connection conn = null;
private final Connection conn;
public ConnecteurDonneesAppelOracle(String url, String user, String password) throws SQLException {
if (url == null || url.isEmpty()) {
......@@ -65,9 +70,9 @@ public class ConnecteurDonneesAppelOracle implements ConnecteurDonneesAppel {
try (Statement stmt = conn.createStatement()) {
/* récupère la liste des groupes et les taux minimum de boursiers
/* récupère la liste des groupes et les taux minimum de boursiers
et de résidents depuis la base de données */
log("Récupération des groupes");
LOGGER.info("Récupération des groupes");
stmt.setFetchSize(1000000);
String sql
......@@ -99,7 +104,7 @@ public class ConnecteurDonneesAppelOracle implements ConnecteurDonneesAppel {
+ " AND ti.g_ti_eta_cla=2 "
+ " AND NVL(g.c_gp_flg_pas_cla, 0)!=1";
log(sql);
LOGGER.info(sql);
try (ResultSet result = stmt.executeQuery(sql)) {
......@@ -140,7 +145,7 @@ public class ConnecteurDonneesAppelOracle implements ConnecteurDonneesAppel {
Set<Integer> groupesManquants = new HashSet<>();
/* récupère la liste des voeux depuis la base de données */
log("Récupération des voeux");
LOGGER.info("Récupération des voeux");
stmt.setFetchSize(1000000);
String sql = "SELECT "
//id du groupe de classement
......@@ -151,7 +156,7 @@ public class ConnecteurDonneesAppelOracle implements ConnecteurDonneesAppel {
+ "NVL(C_CG_RAN,0), "
//le candidat a-t'il déclaré être boursier? non 0 lycée 1 dusup 2
+ "g_cn_brs, "
//cette déclaration a-t'elle été confirmée
//cette déclaration a-t'elle été confirmée
//via les remontées de base SIECLE (1)
//ou directement par le chef d'établissement (2)
+ "g_cn_flg_brs_cer,"
......@@ -176,11 +181,11 @@ public class ConnecteurDonneesAppelOracle implements ConnecteurDonneesAppel {
//seulement les formations qui classent
+ " AND NVL(gp.c_gp_flg_pas_cla, 0)!=1";
log(sql);
LOGGER.info(sql);
try (ResultSet result = stmt.executeQuery(sql)) {
/* Remarque: le rang est à null / 0 pour celles des formations
/* Remarque: le rang est à null / 0 pour celles des formations
non-sélectives qui ne réalisent pas de classement. */
while (result.next()) {
......@@ -215,12 +220,11 @@ public class ConnecteurDonneesAppelOracle implements ConnecteurDonneesAppel {
stmt.close();
if (!groupesManquants.isEmpty()) {
log(groupesManquants.size() + " groupes manquants.");
System.out.print("(");
for (int c_gp_cod : groupesManquants) {
System.out.print(c_gp_cod + ",");
}
System.out.println(")");
LOGGER.log(Level.SEVERE, "{0} groupes manquants.", groupesManquants.size());
String list = groupesManquants.stream()
.map(String::valueOf)
.collect(joining(",", "(", ")"));
LOGGER.severe(list);
//throw new RuntimeException(groupesManquants.size() + " groupes manquants.");
}
......@@ -241,7 +245,7 @@ public class ConnecteurDonneesAppelOracle implements ConnecteurDonneesAppel {
try {
log("Début de l'exportation");
LOGGER.info("Début de l'exportation");
preparerExport();
......@@ -264,10 +268,10 @@ public class ConnecteurDonneesAppelOracle implements ConnecteurDonneesAppel {
ps.setInt(3, rang++);
ps.addBatch();
if (++count % 500000 == 0) {
log("Exportation des ordres d'appel des voeux " + (count - 499999) + " a " + count);
LOGGER.log(Level.INFO, "Exportation des ordres d''appel des voeux {0} a {1}", new Object[]{count - 499999, count});
ps.executeBatch();
ps.clearBatch();
log("Fait");
LOGGER.info("Fait");
}
}
......@@ -276,16 +280,16 @@ public class ConnecteurDonneesAppelOracle implements ConnecteurDonneesAppel {
}
conn.commit();
log("Mise à jour de la table C_CAN_GRP");
LOGGER.info("Mise à jour de la table C_CAN_GRP");
conn.createStatement().execute("UPDATE "
+ "(SELECT a.C_CG_ORD_APP cible, b.C_CG_ORD_APP source FROM C_CAN_GRP a,"
+ "J_ORD_APPEL_TMP b WHERE a.G_CN_COD=b.G_CN_COD AND a.C_GP_COD=b.C_GP_COD)"
+ "SET cible=source");
/* exportation des statistiques mesurant l'écart entre l'ordre d'appel
et le classement initial.
et le classement initial.
*/
log("Exportation des coefficients de divergence");
LOGGER.info("Exportation des coefficients de divergence");
try (PreparedStatement ps = conn.prepareStatement(
"INSERT INTO C_CAN_ORD_APPEL_DIV (C_GP_COD,COEF_DIV) VALUES (?,?)")) {
for (Entry<Integer, OrdreAppel> paire
......@@ -298,13 +302,13 @@ public class ConnecteurDonneesAppelOracle implements ConnecteurDonneesAppel {
ps.executeBatch();
}
log("Application des changements");
LOGGER.info("Application des changements");
conn.commit();
log("Fin de l'exportation");
LOGGER.info("Fin de l'exportation");
} catch (SQLException ex) {
log("Erreur d'exportation des données");
LOGGER.severe("Erreur d'exportation des données");
throw new RuntimeException("Erreur d'exportation des données", ex);
}
}
......@@ -321,7 +325,7 @@ public class ConnecteurDonneesAppelOracle implements ConnecteurDonneesAppel {
conn.createStatement().execute("DROP TABLE J_ORD_APPEL_TMP");
} catch (SQLException e) {
/* peut arriver si la table n'existait pas */
};
}
conn.createStatement().execute(
"CREATE GLOBAL TEMPORARY TABLE J_ORD_APPEL_TMP ("
......@@ -337,7 +341,7 @@ public class ConnecteurDonneesAppelOracle implements ConnecteurDonneesAppel {
conn.createStatement().execute("DROP TABLE C_CAN_ORD_APPEL_DIV");
} catch (SQLException e) {
/* peut arriver si la table n'existait pas */
};
}
conn.createStatement().execute(
"CREATE TABLE C_CAN_ORD_APPEL_DIV ("
......@@ -349,8 +353,4 @@ public class ConnecteurDonneesAppelOracle implements ConnecteurDonneesAppel {
}
private void log(String message) {
System.out.println(LocalDateTime.now().toLocalTime() + ": " + message);
}
}
......@@ -18,7 +18,7 @@
*/
package parcoursup.propositions;
import java.time.LocalDateTime;
import java.util.logging.Logger;
import parcoursup.propositions.algo.AlgoPropositions;
import parcoursup.propositions.algo.AlgoPropositionsEntree;
......@@ -30,6 +30,8 @@ Ce code est exécuté de manière quotidienne.
*/
public class EnvoiPropositions {
private static final Logger LOGGER = Logger.getLogger(EnvoiPropositions.class.getName());
private final ConnecteurDonneesPropositions acces;
public EnvoiPropositions(ConnecteurDonneesPropositions acces) {
......@@ -38,24 +40,20 @@ public class EnvoiPropositions {
public void execute() throws Exception {
log("Récupération des données");
LOGGER.info("Récupération des données");
AlgoPropositionsEntree entree = acces.recupererDonnees();
log("Sauvegarde locale de l'entrée");
LOGGER.info("Sauvegarde locale de l'entrée");
entree.serialiser(null);
log("Calcul des propositions");
LOGGER.info("Calcul des propositions");
AlgoPropositionsSortie sortie = AlgoPropositions.calculePropositions(entree);
log("Sauvegarde locale de la sortie");
LOGGER.info("Sauvegarde locale de la sortie");
sortie.serialiser(null);
log("Export des données");
LOGGER.info("Export des données");
acces.exporterDonnees(sortie);
}
static void log(String msg) {
System.out.println(LocalDateTime.now().toLocalTime() + ": " + msg);
}
}
/* Copyright 2018, 2018 Hugo Gimbert (hugo.gimbert@enseignementsup.gouv.fr)
/* Copyright 2018, 2018 Hugo Gimbert (hugo.gimbert@enseignementsup.gouv.fr)
This file is part of Algorithmes-de-parcoursup.
......@@ -19,21 +19,24 @@
*/
package parcoursup.propositions.algo;
import java.time.LocalDateTime;
import java.util.HashMap;
import parcoursup.propositions.test.VerificationsResultats;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
public class AlgoPropositions {
private static final Logger LOGGER = Logger.getLogger(AlgoPropositions.class.getName());
/* la boucle principale du calcul des propositions à envoyer */
public static AlgoPropositionsSortie calculePropositions(AlgoPropositionsEntree entree) {
entree.verifierIntegrite();
log("Début calcul propositions");
LOGGER.info("Début calcul propositions");
/* groupes à mettre à jour */
Set<GroupeAffectation> groupesAMettreAJour
......@@ -48,42 +51,42 @@ public class AlgoPropositions {
int compteurBoucle = 0;
while (groupesAMettreAJour.size() > 0) {
/* calcul des propositions à effectuer,
/* calcul des propositions à effectuer,
étant données les positions actuelles d'admissions aux internats */
for (GroupeAffectation gc : groupesAMettreAJour) {
gc.mettreAJourPropositions();
}
/* Test de surcapacité des internats, avec
/* Test de surcapacité des internats, avec
mise à jour de la position d'admission si nécessaire.
Baisser la position d'admission d'un internat ne diminue
pas le nombre de candidats dans les autres internats, voire augmente ces nombres,
car les formations devront potentiellement descendre plus bas dans l'ordre d'appel.
Par conséquent, on peut mettre à jour toutes les positions d'admission
de tous les internats sans mettre à jour systématiquement les propositions:
si un internat est détecté en surcapacité avant la mise
à jour des propositions, il l'aurait été également après la mise à jour des propositions.
(Mais la réciproque est fausse en général).
De cette manière, on reste bien dans l'ensemble E des vecteurs de positions
d'admission supérieurs sur chaque composante au vecteur de positions d'admission
le plus permissif possible parmi tous ceux respectant les contraintes
de capacité des internats et situés en deçà des positions maximales
d'admission.
Ce vecteur est égal, sur chaque composante, à la valeur minimum de cette
composante parmi les éléments de E.
La boucle termine quand les contraintes de capacité des internats
sont satisfaites, c'est-à-dire quand ce minimum global est atteint.
Une propriété de symétrie i.e. d'équité intéressante:
le résultat ne dépend pas de l'ordre dans lequel on itère sur les internats et
les formations.
*/
groupesAMettreAJour.clear();
for (GroupeInternat internat : entree.internats) {
......@@ -95,11 +98,10 @@ public class AlgoPropositions {
compteurBoucle++;
}
log("Calcul terminé après " + compteurBoucle + " itération(s).");
LOGGER.log(Level.INFO, "Calcul terminé après {0} itération(s).", compteurBoucle);
log("Vérification des propriétés attendues des propositions pour un des "
+ entree.groupesAffectations.size()
+ " groupes d'affectation");
LOGGER.log(Level.INFO, "Vérification des propriétés attendues des propositions pour un des {0} groupes d''affectation",
entree.groupesAffectations.size());
int step = Integer.max(1, entree.groupesAffectations.size() / 100);
int count = 0;
......@@ -119,8 +121,8 @@ public class AlgoPropositions {
}
System.out.println();
log("Vérification des propriétés attendues des propositions d'un des "
+ entree.internats.size() + " internats");
LOGGER.log(Level.INFO, "Vérification des propriétés attendues des propositions d''un des {0} internats",
entree.internats.size());
step = Integer.max(1, entree.internats.size() / 100);
count = 0;
......@@ -153,9 +155,9 @@ public class AlgoPropositions {
}
System.out.println();
log("Vérification ok");
LOGGER.info("Vérification ok");
log("Préparation données de sortie");
LOGGER.info("Préparation données de sortie");
AlgoPropositionsSortie sortie = new AlgoPropositionsSortie();
......@@ -175,10 +177,6 @@ public class AlgoPropositions {
}
private static void log(String msg) {
System.out.println(LocalDateTime.now().toLocalTime() + ": " + msg);
}
private static void afficherJauge() {
for (int i = 0; i < 100; i++) {
System.out.print("-");
......
/* Copyright 2018, 2018 Hugo Gimbert (hugo.gimbert@enseignementsup.gouv.fr)
/* Copyright 2018, 2018 Hugo Gimbert (hugo.gimbert@enseignementsup.gouv.fr)
This file is part of Algorithmes-de-parcoursup.
......@@ -28,6 +28,8 @@ import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import parcoursup.propositions.algo.AlgoPropositionsEntree;
......@@ -39,6 +41,8 @@ import parcoursup.propositions.algo.VoeuEnAttente;
public class ExempleAleatoire extends ExemplePropositions {
private static final Logger LOGGER = Logger.getLogger(ExempleAleatoire.class.getName());
@Override
String nom() {
return "ExempleAleatoire";// + dateCreation;
......@@ -64,7 +68,7 @@ public class ExempleAleatoire extends ExemplePropositions {
final int maxNbGroupesParFormation = 5;
List<Etablissement> etablissements = new LinkedList<>();
private final List<Etablissement> etablissements = new LinkedList<>();
int last_G_TI_COD = 1;
int last_G_TA_COD = 1;
......@@ -248,7 +252,7 @@ public class ExempleAleatoire extends ExemplePropositions {
}
} else {
int rangInternat = juryInternat.ajouterCandidat(candidat);
if ((rang <= cl.plusHautRangAffecte && rangInternat <= juryInternat.plusHautRangAffecte)) {
ga.ajouterCandidatAffecte(candidat.G_CN_COD);
internat.ajouterCandidatAffecte(candidat.G_CN_COD);
......@@ -289,7 +293,7 @@ public class ExempleAleatoire extends ExemplePropositions {
/* le rang le plus haut dans l'ordre d'appel d'un candidat recruté */
int plusHautRangAffecte = random.nextInt(nbEtudiants / 4);
GroupeClassement() {
this.C_G_COD = last_C_GP_COD++;
}
......@@ -329,9 +333,7 @@ public class ExempleAleatoire extends ExemplePropositions {
public ExempleAleatoire(int nbEtudiants) {
if(nbEtudiants < 100)
nbEtudiants = 100;
this.nbEtudiants = nbEtudiants;
this.nbEtudiants = Math.max(100, nbEtudiants);
}
......@@ -341,16 +343,16 @@ public class ExempleAleatoire extends ExemplePropositions {
int capacite_totale = 0;
GroupeInternat.nbJoursCampagne = 1 + random.nextInt(70);
log("Jours de campagne: " + GroupeInternat.nbJoursCampagne);
LOGGER.log(Level.INFO, "Jours de campagne: {0}", GroupeInternat.nbJoursCampagne);
log("Génération aléatoire des établissements et formations");
LOGGER.info("Génération aléatoire des établissements et formations");
while (capacite_totale < nbEtudiants) {
Etablissement e = new Etablissement();
etablissements.add(e);
capacite_totale += e.capacite();
}
log("Génération aléatoire des voeux et classements");
LOGGER.info("Génération aléatoire des voeux et classements");
for (int i = 0; i < nbEtudiants; i++) {
Candidat c = new Candidat();
int nbVoeux = (int) (Math.random() * maxNbVoeuxParCandidat);
......@@ -360,11 +362,11 @@ public class ExempleAleatoire extends ExemplePropositions {
nbVoeux -= e.ajouterVoeux(c);
}
if ((i + 1) % 100000 == 0) {
log((1 + i) + " étudiants générés ...");
LOGGER.log(Level.INFO, "{0}{1} étudiants générés ...", new Object[]{1, i});
}
}
log("Génération données entrée algorithme");
LOGGER.info("Génération données entrée algorithme");
AlgoPropositionsEntree entree = new AlgoPropositionsEntree();
......@@ -386,12 +388,8 @@ public class ExempleAleatoire extends ExemplePropositions {
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(entree, new File(nom() + "_entree.xml"));
return entree;
}
return entree;
void log(String msg) {
System.out.println(LocalDateTime.now().toLocalTime() + ": " + msg);
}
}
/*
Copyright 2018, 2018 Hugo Gimbert (hugo.gimbert@enseignementsup.gouv.fr)
/*
Copyright 2018, 2018 Hugo Gimbert (hugo.gimbert@enseignementsup.gouv.fr)
This file is part of Algorithmes-de-parcoursup.
Algorithmes-de-parcoursup is free software: you can redistribute it and/or modify
......@@ -22,6 +22,8 @@ package parcoursup.propositions.test;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import parcoursup.propositions.algo.GroupeAffectation;
import parcoursup.propositions.algo.GroupeInternat;
import parcoursup.propositions.algo.VoeuEnAttente;
......@@ -30,11 +32,13 @@ import parcoursup.propositions.algo.VoeuEnAttente;
des sorties de l'algorithme.
Sans garantir la correction du code,
cela garantit que les résultats produits satisfont les principales propriétés
énoncées dans le document.
énoncées dans le document.
Des tests complémentaires sont effectués en base par des scripts PL/SQL.
*/
public class VerificationsResultats {
private static final Logger LOGGER = Logger.getLogger(VerificationsResultats.class.getName());
/*
P1 (respect ordre appel pour les voeux sans internat)
......@@ -59,7 +63,7 @@ public class VerificationsResultats {
/*
P2 (respect ordre appel et classement internat pour les voeux avec internat)
Si un candidat C1 précède un candidat C2
Si un candidat C1 précède un candidat C2
à la fois dans l'ordre d'appel d'une formation F
et dans un classement d'internat I
et si C1 a un voeu en attente pour F avec internat I
......@@ -87,7 +91,7 @@ public class VerificationsResultats {
P3 (respect classement internat pour les candidats avec une proposition sans internat)
Si un candidat C1 a un voeu en attente pour une formation F avec demande d'internat I
et une proposition acceptée ou en attente de réponse de sa part pour la formation F
et une proposition acceptée ou en attente de réponse de sa part pour la formation F
sans demande d'internat,
et si C2 est un candidat moins bien classé que C1 à l'internat I
et si une des nouvelles propositions du jour offre l'internat I à C2
......@@ -114,7 +118,7 @@ public class VerificationsResultats {
P4 (remplissage maximal des formations dans le respect des positions d'admission à l'internat)
Le nombre de propositions doit être inférieur au nombre de places vacantes.
Si le nombre de nouvelles propositions dans une formation est strictement inférieur
au nombre de places vacantes dans cette formation, alors tous les voeux en attente
pour cette formation sont des voeux avec internat,
......@@ -179,8 +183,8 @@ public class VerificationsResultats {
Si le nombre de nouvelles propositions dans un internat I est strictement inférieur
au nombre de places vacantes dans I, alors tous les voeux en attente
pour une formation F et demande d'internat I sont
soit effectués par des candidats
pour une formation F et demande d'internat I sont
soit effectués par des candidats
dont le classement à l'internat I est strictement supérieur
à la position d'admission dans I ou bien situés plus bas dans l'ordre d'appel de F
que tous les candidats ayant reçu une estAProposer de F ce jour là.
......@@ -189,8 +193,8 @@ public class VerificationsResultats {
GroupeInternat internat,
Map<GroupeAffectation,Integer> rangDernierAppeles
) {
/* un même candidat peut avoir plusieurs
/* un même candidat peut avoir plusieurs
propositions pour le même internat,
émanant de différentes formations */
Set<Integer> candidatsProposes = new HashSet<>();
......@@ -200,7 +204,7 @@ public class VerificationsResultats {
candidatsProposes.add(v.id.G_CN_COD);
}
}
int nbNouveauxArrivants = candidatsProposes.size();
alerterSi(nbNouveauxArrivants > 0
......@@ -214,9 +218,9 @@ public class VerificationsResultats {
alerterSi(!internat.groupesConcernes.contains(formation), "formation inconnue (?)");
alerterSi(
(v.internatDejaObtenu()
(v.internatDejaObtenu()
|| v.rangInternat <= internat.positionAdmission)
&& (v.formationDejaObtenue()
&& (v.formationDejaObtenue()
|| v.ordreAppel <= rangDernierAppeles.get(v.groupe)),
"souscapacité internat compensable par un voeu"
+ "classé sous la position d'admission internat"
......@@ -226,16 +230,16 @@ public class VerificationsResultats {
}
}
/*
P6 (maximalité des positions d'admission)
P6 (maximalité des positions d'admission)
Pour tout internat, la position d'admission est inférieure ou égale à la position maximale d'admission.
Dans le cas où elle est strictement inférieure, augmenter d'une unité la position d'admission
entrainerait une surcapacité d'un des internats.
Non-implémenté.
*/
private static void alerterSi(boolean prop, String message) {
if (prop) {
......@@ -245,7 +249,7 @@ public class VerificationsResultats {
private static void prevenirSi(boolean prop, String message) {
if (prop) {
System.out.println("Attention: " + message);
LOGGER.log(Level.WARNING, "Attention: {0}", message);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment