Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Première requête stockée dans le pointeur "classement_aleatoire_efe" #12

Open
khena opened this issue Oct 18, 2016 · 23 comments
Open
Labels

Comments

@khena
Copy link
Collaborator

khena commented Oct 18, 2016

Déjà, ça commence bien, la requête qui va de la ligne 48 à la ligne à la ligne 96 me gène un peu, elle semble contraire aux commentaires écrits dans le fichier. Son résultat est stocké dans le pointeur de parcours classement_aleatoire_efe

Elle prend tous les candidats de type bac EFE qui ont "fait des voeux",
elle joint ce résultat à la liste des candidats de bac EFE qui n'ont pas fait de voeux (le mot clé UNION) en dédoublonnant les résultats (si un dev de base Oracle pouvait me confirmer que UNION et UNION ALL se comportent bien de cette façon avec Oracle)

Première remarque : ça semble complètement stupide de dédoublonner les résultats, car d'un coté nous avons les utilisateurs qui ont fait un voeu : la jointure dans le where (tssss) sur la table a_voe et dans l'autre partie du UNION, nous avons l'espèce d'horreur ligne 95 :
AND NOT EXISTS (SELECT 1 FROM a_voe v WHERE c.g_cn_cod=v.g_cn_cod AND r.g_ta_cod=v.g_ta_cod)

Donc à priori, il ne peut pas y avoir de doublons. Mais bref.

Plus gênant, le commentaire indique :

les candidats EFE qui n'ont au final pas classé la formation dans leur liste ordonnée. Ils sont classé, mais en dernier.

Hors, si je ne m'abuse
Premier SELECT va retourner le résultat suivant (exemple) :
Identifiant du candidat | Ordre du voeu avec voeux groupés relatifs licence | Ordre du voeu avec voeux | groupé relatif licence et tous les autres voeux | Ordre du sous-voeu dans le voeu groupé | Valeur aléatoire pour gérer les égalités | i.i_ep_cod

avec pour valeur
XYZ | 2 | 3 | 5 | 65745 | 1

UNION

Le deuxième SELECT qui va retourner le même nombre de colonnes, mais avec "en dur" les voeux à 0
ABC | 0 | 0 | 0 | 41674 | 1

Résultat avant le tri :
XYZ | 2 | 3 | 5 | 65745 | 1
ABC | 0 | 0 | 0 | 41674 | 1

Maintenant, observons le ORDER BY 2, 3, 4, 5; ( qui indique qu'il faut trier les colonnes 2 par ordre croissant, 3 par ordre croissant , etc.)

Résultat après le tri :
ABC | 0 | 0 | 0 | 41674 | 1
XYZ | 2 | 3 | 5 | 65745 | 1

Le candidat sans voeux arrive avant le candidat qui a fait des voeux

Donc il me semble que clairement, les candidats qui n'ont pas fait de voeux sont classés avant. Notez que ça d'ailleurs été corrigé dans la requête suivante, ligne 149, la présence d'un tri décroissant.

Qu'en pensez vous ?

@jeantil
Copy link
Owner

jeantil commented Oct 19, 2016

bonjour @khena

si un dev de base Oracle pouvait me confirmer que UNION et UNION ALL se comportent bien de cette façon avec Oracle

la doc officielle qui confirme ce que tu dis :)

nous avons l'espèce d'horreur ligne 95 :

Perso ça ne me choque pas le where not exists avec une sous requête qui renvoie 1 est une forme classique en SQL.
Je ne suis pas certain qu'on puisse vraiment faire mieux les features custom d'oracle pour factoriser les sous query ne marcheraient pas a cause des références croisées (si je me souviens bien, c'est vieux tout ça pour moi)

Ta remarque sur le order by est tout a fait judicieuse, ça me parait tellement énorme comme erreur que je me dis qu'on dois rater quelque chose. Pourtant la seule utilisation faite du curseur est dans le bloc x:=61 et qu'elle le parcourt séquentiellement. Il faudrait la définition de c_can_grp pour vérifier si les 0 peuvent lever une erreur sur la contrainte d'unicité mais ce serait surprenant.

Après ça ne concerne que les étudiants qui étudient en français à l'étranger mais c'est quand même louche.

@khena
Copy link
Collaborator Author

khena commented Oct 19, 2016

Pour le select dans le where, rien ne me surprend vraiment, mais il me semble bien qu'Oracle est tout à fait capable de faire des jointures non ? Un LEFT OUTER avec un = null dans le WHERE aurait très bien fait l'affaire. Enfin bref, vu que la totalité du code doit datée de 1992 ;) car il n'y a aucune jointure, c'est vraiment peu ou pas important. C'est juste illisible et obsolète. Bon, on fera avec :)

Je viens de relire l'algo, et mis à part que le cas ne soit JAMAIS géré (par exemple, que l'interface oblige les étudiants à faire des voeux), j'ai bien peur que ce soit effectivement une erreur (ça reste dans tous les cas en complète contradiction avec le commentaire).

@IBG2016
Copy link

IBG2016 commented Oct 19, 2016

Effectivement, il me semble (souvenir de mon fils qui a passé son bac en 2013) que il y avait une date butoir pour classer les voeux avec un commentaire du genre "Tout voeu non classé sera supprimé". dans la doc actuelle, il y a "Un vœu non classé ne pourra jamais vous être proposé".
Je suppose que si quelqu'un avait hérité d'un voeu non classé, on en aurait entendu parler comme d'un dysfonctionnement.
Il ne me semble pas que le Decode(l_six_voe, 1, Six_voeu_l1(c.g_cn_cod, g_aa_cod_bac_int, g_cn_flg_int_aca, o_g_tg_cod), o),
même en ordre descendant corrige vraiment le problème.
Les ordres suivants sont pareils (avec des 0 sur une des branches de l'union)

et " Permet de récupérer Ies AC ", vouc comprenez ?

Par contre, il semble que les candidats AEFE (candidats de l'étranger) soient prioritaires ?
ce n'est pas dit sur le
http://cache.media.education.gouv.fr/file/05__mai/30/9/Algorithme_APB_capacites_d_accueil_limitees_586309.pdf

C'est quand même incroyable de mettre des priorités sans les annoncer.

@khena
Copy link
Collaborator Author

khena commented Oct 19, 2016

Merci pour votre précision, je suis assez d'accord avec vous sur le decode, ça ne semble pas résoudre le problème. Pour les AC, je viens de trouver (enfin je crois) par déduction. J'ai fait une PR à ce sujet : https://github.com/jeantil/admission_post_bac/pull/16/files

mais bon je ne suis vraiment pas sûr . AC = A classer, code 6 / NC = non classé code 4

@mister-good-deal
Copy link

@IBG2016

Par contre, il semble que les candidats AEFE (candidats de l'étranger) soient prioritaires ?

Oui ils le sont, de l'époque où j'étais en terminale aux États-Unis (2011), le choix d'une université était obligatoirement validée sur APB. Ce n'était en revanche pas vrais pour les écoles types INSA, pour les prépas je crois que ça suivait le même schéma que les facs.

Franchement faire les règles de gestions des admissions en SQL et pas côté applicatif sur un serveur type PHP ou même JAVA EE c'est vraiment relou... Oui je sais l'intérêt de le faire côté BDD c'est que l'on peut brancher le dev avec n'importe quelle implémentation derrière mais je ne crois pas que APB soit distribué sur autre chose qu'un portail web.

Des vérifs SQL avec des triggers oui, toute la logique de classement attribution non.

@Hantlowt
Copy link

Hantlowt commented Oct 19, 2016

Je suis assez d'accord en effet, c'est vraiment crade ce qu'ils ont fait. Aussi, Ce qui serait pas mal, c'est que l'on ait accès à l'intégralité du code source, car là franchement, ça pue.

Je connais pas grand chose en SQL, néanmoins, et je sais pas si cela a déjà été stipulé, il faudrait pas une init avec une seed pour utiliser DBMS_RANDOM ? (https://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_random.htm#i998925)

@jeantil
Copy link
Owner

jeantil commented Oct 19, 2016

pour la seed il y a eu une réponse sur mon gist initial

DBMS_RANDOM can be explicitly initialized, but does not need to be initialized before calling the random number generator. It will automatically initialize with the date, userid, and process id if no explicit initialization is performed.

@jeantil
Copy link
Owner

jeantil commented Oct 19, 2016

par ailleurs nous manquons clairement de contexte et hors contexte du code peut facilement sembler inintelligible. imagine devoir analyser ce code hors context par exemple :

int             key(int keycode, void *param)
{
    t_fractol   *f;

    f = (t_fractol*)param;
    if (keycode == 124)
        move_f(f, 0.2, 0.0);
    if (keycode == 123)
        move_f(f, -0.2, 0.0);
    if (keycode == 126)
        move_f(f, 0.0, -0.2);
    if (keycode == 125)
        move_f(f, 0.0, 0.2);
    if (keycode == 16)
        zoom_f(f, 0.3);
    if (keycode == 4)
        zoom_f(f, -0.3);
    if (keycode == 15)
        f->ecolor = 16;
    if (keycode == 9)
        f->ecolor = 8;
    if (keycode == 11)
        f->ecolor = 0;
    if (keycode == 53)
        exit(0);
    f->draw(f);
    return (0);
}

;)

@GuillaumeTara
Copy link
Collaborator

Pour les voeux qui ont la valeur 0, il me semble aussi qu'ils remontent dans la liste, ce qui est plus qu'inquiétant. Après comme le candidat ne l'a pas classé peut-être qu'une autre fonction finale se charge de ne pas le montrer au candidat et de mettre à jour la liste, mais c'est plus qu'inquiétant.

Pour les candidats des lycées français de l'étranger, ils ne sont pas censés être prioritaires puisque dans les textes officiels il est dit qu'ils doivent être "considérés comme des candidats de l'académie". En toute rigueur il faudrait qu'ils soient dans la même liste que les autres candidats et subissent le même tirage au sort aléatoire.

Or, ici tous les candidats de l'étranger quel que soit leur voeu sont placés avant le reste des autres candidats. Du coup si un candidat de Londres a placé une licence dans l'académie de Versailles en voeu 12, dans tous les cas il apparaîtra avant un candidat de cette académie qui l'a placé en voeu 1. ça me semble être un manquement assez grave puisque normalement le candidat londonien devrait être traité comme un candidat de l'académie et, donc, apparaître en dessous dans la liste...

@AxelVoitier
Copy link

AxelVoitier commented Oct 19, 2016

Pour le order by, ca pourrait marchait si les voeux sont en fait codes en valeures negatives.
Ca serait pas vraiment naturel, mais bon, au point ou on en est ...

@GuillaumeTara
Copy link
Collaborator

A priori non puisque pour récupérer ces vœux non-classés la requête utilise la valeur 0 pour les différents paramètres de vœu. Il semblerait donc que la convention soit vœu non classé = 0...

@GuillaumeTara
Copy link
Collaborator

Attention, contrairement à ce que vous avez indiqué dans le premier message, le bug n'est pas réglé à la ligne suivante. Le tri décroissant se fait, en effet sur la 2ème valeur du Select qui n'est pas un voeu mais qui correspond à la variable issue de la fonction mystère six_voeu_L1. Donc il y a le même problème pour les candidats français.

@Sboulahia
Copy link

Sboulahia commented Oct 20, 2016

Les candidats français qui n'ont pas classé leurs vœux sont aussi prioritaires sur les candidats français pour qui six_voeu_L1 renvoie 0 (à priori, ceux qui ne sont pas franciliens).

Donc les provinciaux qui veulent faire une licence en IDF, ne classez pas vos vœux et rappelez à vos camarades de ne pas oublier de les classer 😬

@Skrol29
Copy link
Collaborator

Skrol29 commented Oct 20, 2016

Notez que si un rang de grande valeur est prioritaire sur un rang de petit valeur, alors l'algorithme revient à faire passer en priorité les Non EFE avant les EFE, et les « avec-vœux » avant « les sans-vœux ».

Par ailleurs, voici un petit synopsis de l'algo :

Il y a quelques traitements de cas particuliers mais je les ignores pour l'instant.

  • La fonction prend en argument une formation et un groupe donné.
  • Pour la formation et le groupe donné, la fonction va attribuer à chaque candidat inscrit un numéro de rang différent. Le numéro de rang correspond au numéro d'ordre de traitement du candidat, en commençant par 1.
  • Les candidat EFE sont traités d'abord, ils auront donc les numéro de rang les plus petits.
  • Les candidat EFE sont traités par ordre de vœux croissant (sachant qu'un vœu absent équivaut à un ordre de vœux égale à zéro), puis par ordre aléatoire en cas de vœux identiques.
  • Les autres candidats sont traités en suite.
  • Si le groupe passé en argument est issu d'IDF (pour faire court) alors les candidats sont classés d'abord par la fonction six_voeu_L1() décroissante.
  • Si le groupe n'est pas issu d'IDF , alors le classement six_voeu_L1() est annulé.
  • Pour un même résultat de six_voeu_L1(), les candidats sont ensuite traités comme les EFE :
    par ordre de vœux croissant (sachant qu'un vœu absent équivaut à zéro), puis par ordre aléatoire en cas de vœux identiques.

Remarques :

  • la fonction six_voeu_L1() est totalement inconnue
  • on ne sait pas si les ordre de voeux sont négatifs ou positifs (négatifs serait quand même très particulier)

@GuillaumeTara
Copy link
Collaborator

Je partage à peu près tous les éléments de votre analyse mais il y a un point qui me pose toujours question :
"Si le groupe n'est pas issu d'IDF , alors le classement six_voeu_L1() est annulé."

j'imagine que ça correspond à la partie du Decode. Mais je drais que si le candidat n'est pas d'IDF, alors on lui affecte la valeur 0 et donc, si le résultat de six_voeu_L1 est positif, il sera toujours en dessous des candidats d'IDF.

Or, cet algo est censé fonctionner pour toutes les académies et pas seulement l'IDF, donc ce passage semble vraiment poser problème...

@Skrol29
Copy link
Collaborator

Skrol29 commented Oct 20, 2016

@GuillaumeTara : j'imagine que ça correspond à la partie du Decode. Mais je drais que si le candidat n'est pas d'IDF, alors on lui affecte la valeur 0 et donc, si le résultat de six_voeu_L1 est positif, il sera toujours en dessous des candidats d'IDF.

La variable l_six_voe ne dépend que du groupe et pas du tout du candidat. Donc concernant les candidats français (non EFE) : soit on invoque six_voeu_L1() pour tous, soit on applique zéro pour tous ce qui revient à annuler ce tri. C'est le DECODE() qui fait cet aiguillage.

Cette fonction six_voeu_L1() retourne un ordre de priorité principal en fonction du candidats et le code source n'est pas fourni. Donc un partie significative de l'algorithme est encore caché tant qu'on a pas le source de cette fonction et de ses éventuelles dépendances.

@jferard
Copy link
Collaborator

jferard commented Oct 20, 2016

Deux points :

  • il est raisonnable de supposer que les ordres de voeux sont des valeurs négatives, -1 étant le dernier voeu, et -N le premier. O représente l'absence de voeu, et permet de classer un candidat après tous ceux qui ont fait des voeux ;
  • il est raisonnable de supposer que la fonction six_voeu_L1() renvoie un résultat positif, puisque si "le groupe est issu d''une formation de type IDF 2, 3, 5 ou 6 et s'il concerné par des néo d'IDF", les candidats (EFE exceptés) sont classés sur ce critère par ordre décroissant. Et avant les autres si la fonction renvoie une valeur > 0.

Cette fonction est effectivement une des clés de l'algorithme.

@khena
Copy link
Collaborator Author

khena commented Oct 20, 2016

Effectivement, si on a des valeurs négatices, tout s'explique, mais quel serait le fou-furieux qui classerait un ordre avec des valeurs négatives? Je n'y crois pas un instant. Laissons de côté cette requête, essayons d'avancer un peu sur la suite de l'algo de façon détaillée.

@khena
Copy link
Collaborator Author

khena commented Oct 20, 2016

@jferard @GuillaumeTara @AxelVoitier cependant, si les valeurs sont négatives, comment expliquer le ORDER 2 DESC qui trie sur les mêmes champs que la première requête (et effectivement ça ne corrige pas le problème) ?

Donc si nous avons les mêmes champs (avec les mêmes types de valeurs j'espère, et qu'on trie un coup en DESC et un coup en ASC, il faut vraiment m'expliquer comment on obtient un tri comparable.

@AxelVoitier
Copy link

Dans la deuxieme requete le desc ne s'applique qu'a la colonne 2. Hors cette colonne 2 n'est pas la meme que celle de la premiere requete.
Dans la deuxieme requete, la deuxieme colonne est celle du cas particulier des 6 voeux pour les candidats et formations en IDF.

@jferard
Copy link
Collaborator

jferard commented Oct 20, 2016

@khena @AxelVoitier confirmé : le même tri sur les voeux, en ASC par défaut, pour les EFE et les autres. Il faut regarder ensuite ce qui se passe au moment de l'attribution du rang.

@khena
Copy link
Collaborator Author

khena commented Oct 25, 2016

Mise à jour suite aux déclarations du ministère : http://www.lemonde.fr/campus/article/2016/10/25/apb-les-questions-que-souleve-le-code-source_5020076_4401467.html

TL;DR

"oui mais non en fait, on fait un tri après et vous le voyez pas".

Avis personnel : pipeau !

@jferard
Copy link
Collaborator

jferard commented Oct 25, 2016

Voici comment ça pourrait marcher (rafistolage de code pour les nuls) :
abp v1. Je classe en fonction des voeux
Aïe, il y a des candidats qui n'ont fait aucun voeu !
abp v2. J'ajoute l'absence de voeu avec un 0 (zéro voeu : c'est logique).
Mais maintenant je me retrouve avec les candidats à 0 voeu devant les autres (si je fais un tri DESC, je fous tout en l'air). Ce n'est pas ce que je voulais. Par exemple, les zéro voeu de 1 à 153, et les autres de 154 à 1389.
abp v3. Je maintiens la v2, mais au moment de l'affectation, je fais un test (binaire) :

tant qu'il y a des places disponibles et des candidats :
       s'il y a des candidats ayant fait au moins un voeu : 
            c = le premier des candidats restants avec au moins un voeu
       sinon : 
            c = le premier des candidats restants avec zéro voeu
       mettre c à la première place disponible

On "consomme" ainsi les candidats ayant obtenu les rangs de 154 à 1389, puis ceux ayant les rangs de 1 à 153. Le "Ils sont classé, mais en dernier" (que nous avons tous mal compris) n'est pas une conséquence du 0 + tri ASC, mais un aide-mémoire pour ne pas oublier de tester après s'il y a ou non un voeu,

Je plaisante, mais à peine...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests