IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Trier des individus selon une parité sexuelle


Sujet :

Python

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    terminale
    Inscrit en
    Février 2024
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : terminale

    Informations forums :
    Inscription : Février 2024
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Trier des individus selon une parité sexuelle
    Salutations,

    Avec quelques camarades, nous travaillons depuis quelques mois sur un projet.

    Dans celui-ci, il nous faut trier une liste d’élèves d’une école dans des classes selon certaines contraintes.

    Celle qui me pose problème est la contrainte de la parité de sexe, où, chaque classe doit contenir un nombre équivalent de garçons et de filles, et qui tolère un écart maximal de 4 filles ou garçons en plus.

    Pour rendre plus simple les tests, j’avais créé un bout de code fictif qui contenait une liste de listes pour chaque élève avec le prénom de chaque élève et son sexe ci-dessous :

    liste=[(‘Jean´, ‘M’), (‘Enzo´, ‘M’), (‘Juliette´, ‘F’), (‘Blanche´, ‘F’), (‘Aurore´, ‘F’), (‘Gabriel ´, ‘M’), (‘Marc´, ‘M’), (‘Manon´, ‘F’), (‘Emma´, ‘F’), (‘Ulysse´, ‘M’), (‘Kevin´, ‘M’), (‘Iris´, ‘F’), (‘Jeremy´, ‘M’), (‘Michel´, ‘M’), (‘Noemie´, ‘F’), (‘Axel´, ‘M’), (‘Yanis´, ‘M’), (‘Solene´, ‘F’), (‘Alice´, ‘F’), (‘Valerie´, ‘F’)]

    Le but est de trier les élèves dans 2 classes différentes représentées par des listes qui sont situés dans un dictionnaire.

    classes={´Classes’: {´1’: [], ‘2’: []}}

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    from math import *
    liste=[('BLANCHE', 'F'),('JEAN', 'M'),('CAMILLE', 'F'),('MARC', 'M'),('MANON', 'F'),('TOM', 'M'),('ALICE', 'F'),('ADRIEN', 'F'),('JOSIE', 'F'),('ARTHUR', 'M'),('EMMA', 'F'),('TEO', 'M'),('AURORE', 'F'),('JULIETTE', 'F')]
     
    def parite_homme_femme(liste):
        compteur_m=0
        compteur_f=0
        for i in range(len(liste)):
            if liste[i][1]=='M':
                compteur_m+=1
            else:
                compteur_f+=1
        classes={'Classe': {'1': [], '2': []}}
        nb_eleves=ceil(len(liste)/2)
        difference=0
        if compteur_m>compteur_f:
            difference=compteur_m-compteur_f
        else:
            difference=compteur_f-compteur_m
        difference=ceil(difference/2)
        for j in liste:
            if len(classes['Classe'][1])<nb_eleves
    J'avais déjà essayé avec un petit bout de code au dessus, mais je me retrouve bloqué, et ne voulant pas utiliser d'IA, j'aimerais vous demander votre aide.
    Merci d'avance !

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par mrsogravity Voir le message
    et ne voulant pas utiliser d'IA
    Très bonne mentalité

    Citation Envoyé par mrsogravity Voir le message
    et qui tolère un écart maximal de 4 filles ou garçons en plus.
    Et que se passe-t-il si l'écart dépasse ?

    Citation Envoyé par mrsogravity Voir le message
    Le but est de trier les élèves dans 2 classes différentes représentées par des listes qui sont situés dans un dictionnaire.
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    liste=(
    	('Jean', 'M'),
    	('Enzo', 'M'),
    	('Juliette', 'F'),
    	('Blanche', 'F'),
    	('Aurore', 'F'),
    	('Gabriel ', 'M'),
    	('Marc', 'M'),
    	('Manon', 'F'),
    	('Emma', 'F'),
    	('Ulysse', 'M'),
    	('Kevin', 'M'),
    	('Iris', 'F'),
    	('Jeremy', 'M'),
    	('Michel', 'M'),
    	('Noemie', 'F'),
    	('Axel', 'M'),
    	('Yanis', 'M'),
    	('Solene', 'F'),
    	('Alice', 'F'),
    	('Valerie', 'F'),
    )		# Pas besoin de liste quand un tuple suffit...
     
    classes={
    	'Classes': {
    		'M': tuple(x[0] for x in liste if x[1] == 'M'),
    		'F': tuple(x[0] for x in liste if x[1] == 'F'),
    	}
    }
    print(classes)
    On peut même mettre "MF" en intension mais ça alourdirait la lecture.

    Après suffit de compter classes["Classes"]["M"] par rapport à classes["Classes"]["F"] et si l'écart dépasse 4 ben à toi de gérer...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre expérimenté
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    870
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 870
    Points : 1 522
    Points
    1 522
    Billets dans le blog
    4
    Par défaut
    Bonjour,
    qui tolère un écart maximal de 4 filles ou garçons en plus.
    ... ce qui sous entend qu'il peut y avoir un total de 8 garçons ou filles en plus à répartir dans les 2 classes...
    #Rien de nouveau sous le soleil, tout est vanité comme courir après le vent!
    Developpement pour Android avec Python3/Kivy/Buildozer

  4. #4
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 824
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 824
    Points : 7 120
    Points
    7 120
    Par défaut
    Bonjour,

    Sve@r,

    C'est un peu plus complexe que cela niveau algorithme

    Ce que veut le PO, c'est une manière d'équilibrer les deux classes avant d'ajouter un nouvel élève et ça ce n'est pas simple, déjà parce-que le PO ne donne pas de règle sur la manière dont doit être réparti les élèves dans chaque classe.
    Par ex :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Classe 1: 12 élèves, 5 garçons, 7 filles
    Classe 2: 2 élèves, 0 garçons, 2 filles
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Classe 1: 8 élèves, 3 garçons, 5 filles
    Classe 2: 6 élèves, 2 garçons, 4 filles
    ou

    ...



    mrsogravity,

    Le but est de trier les élèves dans 2 classes différentes représentées par des listes qui sont situés dans un dictionnaire.
    C'est cette partie qui est complexe ! Quel devrait être selon vous le nombre de garçons et filles dans la classe 1 et dans la classe 2

    Car des "bonnes" répartitions possibles, il y en a beaucoup pouvant recevoir une différence entre nombre de garçons et filles dans chaque classe.
    Définissez vous le nombre maximum d'élèves dans une classe ?

    Si vous avez beaucoup plus d'élève dans votre liste d'élèves, le nombre de classe peut augmenter dynamiquement plutôt que de les créer manuellement.
    Es-ce que plus de 2 classes est possible ?
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Ce que veut le PO, c'est une manière d'équilibrer les deux classes avant d'ajouter un nouvel élève
    Compris. Mais ça reste quand-même flou parce que expliqué de cette façon, on peut parfaitement monter à 5000 élèves dans une classe tant que la différence garçon/fille ne dépasse pas 4...

    Ceci dit, j'ai pondu un petit quelque chose...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    liste=(
    	('Jean', 'M'),
    	('Enzo', 'M'),
    	('Juliette', 'F'),
    	('Blanche', 'F'),
    	('Aurore', 'F'),
    	('Gabriel ', 'M'),
    	('Marc', 'M'),
    	('Manon', 'F'),
    	('Emma', 'F'),
    	('Ulysse', 'M'),
    	('Kevin', 'M'),
    	('Iris', 'F'),
    	('Jeremy', 'M'),
    	('Michel', 'M'),
    	('Noemie', 'F'),
    	('Axel', 'M'),
    	('Yanis', 'M'),
    	('Solene', 'F'),
    	('Alice', 'F'),
    	('Valerie', 'F'),
    )		# Pas besoin de liste quand un tuple suffit...
     
    classes={}
     
    import math
    def ajoute_eleve(eleve, classes, *, ecart=4, limit=math.inf):
    	for (i, c) in enumerate(classes, 1):
    		key="classe_%d" % i
    		match eleve[1]:
    			case "M": parite="F"
    			case "F": parite="M"
    			case _: raise KeyError("Eleve [%s] genre [%s] incohérent" % (eleve[0], eleve[1]))
    		# match
    		if math.fabs(len(classes[key][eleve[1]]) - len(classes[key][parite])) < ecart\
    		and len(classes[key][eleve[1]]) + len(classes[key][parite]) < limit:
    			break
    	else:
    		# Toutes classes pleines (ou pas encore de classe): nouvelle classe...
    		key="classe_%d" % (len(classes) + 1)
    		classes[key]={"M" : list(), "F" : list()}
    	# for
     
    	# Choipeaumagique
    	classes[key][eleve[1]].append(eleve[0])
    # ajoute_eleve()
     
    for e in liste: ajoute_eleve(e, classes)
     
    for (k, v) in classes.items():
    	print(k, v, len(v["M"]), len(v["F"]))

    Plus ou moins bancal je l'admets, surtout que la répartition des élèves dépend pour beaucoup de leur ordre d'arrivée...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 824
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 824
    Points : 7 120
    Points
    7 120
    Par défaut
    Sve@r,

    Mais ça reste quand-même flou parce que expliqué de cette façon, on peut parfaitement monter à 5000 élèves dans une classe tant que la différence garçon/fille ne dépasse pas 4...
    Voilà ! tu as compris où je voulais en venir, en plus son exemple permettrait d'avoir

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Classe 1: 20 élèves, 10 garçons, 10 filles
    À mon sens, la problématique est mal exprimé, car le PO sait ce qu'il veut mais ne sait pas poser le problème.

    On pourrait écrire le problème de cette manière,

    J'ai une école avec 92 élèves pour plusieurs classes de 3ème, voici les critères :
    • Élèves max par classe : 30
    • Différence max entre nombre de filles et garçons dans une classe : 4


    Générer l'ensemble des classes de 3ème.

    EDIT: 92 est bien choisi, car considérant qu'une classe est extrêmement coûteux, on pourrait exceptionnellement dépasser le nombre maximum d'élèves dans une classe de un ou deux élèves sans prendre en considération le critère de mixité (je vais un peu loin, mais ayant été enseignant dans ma vie pendant plusieurs années, le plus concret est cet exemple) donc deux classes de 31 élèves et une classe de 30 élèves.

    Par exemple à l'exécution du code, voici mes critères,

    max par classe : 5
    diff entre nombre de filles et garçons dans une classe : 4

    Résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    Classe 1: 5 élèves (Filles: 3, Garçons: 2)
     - Jean (M)
     - Enzo (M)
     - Juliette (F)
     - Blanche (F)
     - Aurore (F)
     
     
    Classe 2: 5 élèves (Filles: 2, Garçons: 3)
     - Gabriel  (M)
     - Marc (M)
     - Manon (F)
     - Emma (F)
     - Ulysse (M)
     
     
    Classe 3: 5 élèves (Filles: 2, Garçons: 3)
     - Kevin (M)
     - Iris (F)
     - Jeremy (M)
     - Michel (M)
     - Noemie (F)
     
     
    Classe 4: 5 élèves (Filles: 3, Garçons: 2)
     - Axel (M)
     - Yanis (M)
     - Solene (F)
     - Alice (F)
     - Valerie (F)
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  7. #7
    Membre expérimenté
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    870
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 870
    Points : 1 522
    Points
    1 522
    Billets dans le blog
    4
    Par défaut
    A l'arrache:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    liste=[('Pierre', 'M'), ('Jean', 'M'), ('Enzo', 'M'), ('Juliette', 'F'), ('Blanche', 'F'), ('Aurore', 'F'), ('Gabriel', 'M'), ('Marc', 'M'), ('Manon', 'F'), ('Emma', 'F'), ('Ulysse', 'M'), ('Kevin', 'M'), ('Iris', 'F'), ('Jeremy', 'M'), ('Michel', 'M'), ('Noemie', 'F'), ('Axel', 'M'), ('Yanis', 'M'), ('Solene', 'F'), ('Alice', 'F'), ('Valerie', 'F')]
     
    classes={'Classes': {'1': [], '2': []}}
     
    females = [student for student in liste if student[1] == 'F']
    males = [student for student in liste if student[1] == 'M']
     
    liste1 = []
    liste2 = []
    if abs(len(females) - len(males)) > 8:
        print('mission impossible')
        quit()
    if len(females) > len(males):
        liste_laplusCourte = males[:]
        liste_laplusLongue = females
    else:
        liste_laplusCourte = females[:]
        liste_laplusLongue = males
     
    m = males[:]
    f = females[:]
     
    for i in range(len(liste_laplusCourte)-1):  
        fille=f[i][0]
        garçon=m[i][0]
        females.pop(0)
        males.pop(0)
        if i%2 == 0:
            liste1.append(fille)
            liste1.append(garçon)
        else:
            liste2.append(fille)
            liste2.append(garçon)
     
    for i,étudiant in enumerate(liste_laplusLongue):
        if liste_laplusCourte == females:
            if i%2 == 0:
                liste1.append(étudiant[0])
            else:
                liste1.append(étudiant[0])
        else:
            if i%2 == 0:
                liste2.append(étudiant[0])
            else:
                liste2.append(étudiant[0])
    print(liste1)
    print(liste2)
    Pas très joli (pas le temps), mais ça semble fonctionner avec la demande telle que je l'ai comprise.
    #Rien de nouveau sous le soleil, tout est vanité comme courir après le vent!
    Developpement pour Android avec Python3/Kivy/Buildozer

  8. #8
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 824
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 824
    Points : 7 120
    Points
    7 120
    Par défaut
    @MPython,

    Pas très joli (pas le temps), mais ça semble fonctionner avec la demande telle que je l'ai comprise.
    Pas sûr que se soit juste, j'ai ce résultat,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ['Juliette', 'Pierre', 'Aurore', 'Enzo', 'Emma', 'Marc', 'Noemie', 'Kevin', 'Alice', 'Michel', 'A']
    ['Blanche', 'Jean', 'Manon', 'Gabriel', 'Iris', 'Ulysse', 'Solene', 'Jeremy', 'M']
    Que représente les caractères A et M en fin de listes ?

    et si j'ai besoin de répartir sur plusieurs classes dont le maximum d'élèves par classe est 5 ?

    EDIT : Si la mixité n'est pas possible, alors on ne crée pas nos classes ?
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  9. #9
    Membre expérimenté
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    870
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 870
    Points : 1 522
    Points
    1 522
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par fred1599

    Que représente les caractères A et M en fin de listes ?
    un cafouillage ... j'ai rectifié


    Citation Envoyé par fred1599

    et si j'ai besoin de répartir sur plusieurs classes dont le maximum d'élèves par classe est 5 ?
    Faudra modifier le code ..., c'est juste une approche que je montre, pas plus.
    Bon cette fois-ci j'y vais. J'ai du béton à faire qui m'attend*
    #Rien de nouveau sous le soleil, tout est vanité comme courir après le vent!
    Developpement pour Android avec Python3/Kivy/Buildozer

  10. #10
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 104
    Points : 4 454
    Points
    4 454
    Par défaut
    bonjour
    Citation Envoyé par fred1599 Voir le message
    EDIT : Si la mixité n'est pas possible, alors on
    C'est la question que je me pose, s'il n'est pas possible de suivre la règle de "4" de différence maxi, que fait-on du "reste" ? si on suit cette règle, alors Il est préférable de créer à la fin une classe non mixe ???

    Puisqu'il y a déjà proposition de codes, ma contribution :
    - génération aléatoire d'une liste d'élèves (pour pouvoir jouer plusieurs scénarios)
    - un simple tri de cette liste par "couple" : il suffit alors de piocher (par couple) dans cette liste pour remplir les classes

    Note : ici la règle des "4" n'est aucunement respectée ! c'est juste un mélange le plus équitable possible. (comment respecter cette règle si on a deux fois plus de filles???)
    Note: ici je me retrouve avec des classes de 20 et quelques et non de 30, donc à revoir cette répartition (déjà demandé plus haut #6 comment gérer cela). Une solution ? re-générer les classes mais avec une en moins depuis la même liste d'élèves...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    #!/usr/bin/env python
    import math
    import random
    from collections import defaultdict
    from collections import Counter
     
    def generer(size: int, maxi: int = 28):
        TEMPLATE = [
            ("BLANCHE", "F"),
            ("JEAN", "M"),
            ("CAMILLE", "F"),
            ("MARC", "M"),
            ("MANON", "F"),
            ("TOM", "M"),
            ("ALICE", "F"),
            ("ADRIEN", "F"),
            ("JOSIE", "F"),
            ("ARTHUR", "M"),
            ("EMMA", "F"),
            ("TEO", "M"),
            ("AURORE", "F"),
            ("JULIETTE", "F"),
        ]
        items = []
        for i in range(size):
            item = random.choice(TEMPLATE)
            item = f"{item[0]} {i}", item[1]
            items.append(item)
        return items, math.ceil(len(items) / maxi)
     
     
    def melanger_trier(eleves):
        # pas de mélange ici car déjà fait avec ramdom
        hommes = [e for e in eleves if e[1] == "M"]
        femmes = [e for e in eleves if e[1] == "F"]
        ret = []
        while True:
            try:
                ret.append(hommes.pop())
                ret.append(femmes.pop())
            except IndexError:
                # plus de parité ou fin de liste
                break
        return ret + hommes + femmes  # parité + les éventuels restes
     
     
    eleves, classes_count = generer(63, 30)
    print(len(eleves), "élèves,", classes_count, "classes", len(eleves) // classes_count, "élèves par classe environ")
    print(eleves)
     
     
    print()
    print("*" * 24)
    # mélanger les eleves
    eleves = melanger_trier(eleves)
    print(eleves)
    print(len([True for e in eleves if e[1] == "M"]), "Masculin")
    print(len([True for e in eleves if e[1] == "F"]), "Féminin")
     
    print("*" * 24)
    classes = defaultdict(list)
    while len(eleves) > 0:
        # repartir dans les classes
        for classe in range(classes_count):
            try:
                classes[classe].append(eleves.pop(0))
                classes[classe].append(eleves.pop(0))
            except IndexError:
                break
     
    print("Chaque classe avec ces élèves")
    for _, classe in classes.items():
        print()
        print(len(classe), "élèves :")
        print(*classe)
        print(*[e[1] for e in classe])
        ret = Counter(e[1] for e in classe)
        print(f"F: {ret['F']:02} M: {ret['M']:02}\tDécalage de : {abs(ret['F'] - ret['M'])}")
    $moi= ( !== ) ? : ;

  11. #11
    Membre expérimenté
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    870
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 870
    Points : 1 522
    Points
    1 522
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par fred1599 Voir le message

    EDIT : Si la mixité n'est pas possible, alors on ne crée pas nos classes ?
    Si, le code prend bien en charge une non mixité de 4 élèves par classe s'il y a plus de filles ou de garçons.

    J'ai édité mon code pour commencer la répartition des élèves restants dans la classe où il y a moins d'élèves (condition nécessaire pour une répartition plus équitable).
    La demande :
    Le but est de trier les élèves dans 2 classes différentes représentées par des listes .
    et
    qui tolère un écart maximal de 4 filles ou garçons en plus.
    me semble satisfaite.
    #Rien de nouveau sous le soleil, tout est vanité comme courir après le vent!
    Developpement pour Android avec Python3/Kivy/Buildozer

  12. #12
    Membre expérimenté
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    870
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 870
    Points : 1 522
    Points
    1 522
    Billets dans le blog
    4
    Par défaut
    J'ai posé la question à chatgpt par curiosité. La première étape du code, celle qui ne traite que les éléments qui trouvent une parité est quand même bien plus simple que la mienne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        garcons = [eleve for eleve in liste if eleve[1] == 'M']
        filles = [eleve for eleve in liste if eleve[1] == 'F']
     
     
        # Initialisation des classes
        classe1 = []
        classe2 = []
     
        # Distribuer les élèves dans les classes
        while garcons and filles:
            classe1.append(garcons.pop(0))
            classe2.append(filles.pop(0))
    j'aime bien le while garcons and filles: . Par contre pour ce qui du deuxième traitement(je ne l'ai pas joint) : soit distribuer les élèves restant dans les deux classes (en veillant qu'ils ne dépassent pas 4 par classe) il est à la ramasse.
    #Rien de nouveau sous le soleil, tout est vanité comme courir après le vent!
    Developpement pour Android avec Python3/Kivy/Buildozer

  13. #13
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par MPython Alaplancha Voir le message
    j'aime bien le while garcons and filles: .
    Pas moi. Déjà c'est détruire inutilement les listes en cours. On peut par exemple utiliser zip() ou tout autre solution pour avoir les listes égales...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    classe1 = [eleve[0] for eleve in liste if eleve[1] == 'M']
    classe2 = [eleve[0] for eleve in liste if eleve[1] == 'F']
    m=min(len(classe1), len(classe2))
    classe1=classe1[0:m]
    classe2=classe2[0:m]
    ...et puis surtout ça crée juste deux classes composées pour la première de garçons et pour la seconde de filles (ce qui n'a plus rien à voir avec le sujet initial)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  14. #14
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 049
    Points : 1 380
    Points
    1 380
    Par défaut
    Dans mon code, les élèves en trop ne sont pas répartis, il n'y a que 2 classes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    liste=[('Jean', 'M'), ('Enzo', 'M'), ('Juliette', 'F'), ('Blanche', 'F'), ('Aurore', 'F'), ('Gabriel ', 'M'), ('Marc', 'M'), ('Manon', 'F'), ('Emma', 'F'), ('Ulysse', 'M'), ('Kevin', 'M'), ('Iris', 'F'), ('Jeremy', 'M'), ('Michel', 'M'), ('Noemie', 'F'), ('Axel', 'M'), ('Yanis', 'M'), ('Solene', 'F'), ('Alice', 'F'), ('Valerie', 'F')]
     
    # tri de eleves
    garcons = []
    filles = [(nom,sex) for  nom,sex in liste if sex=='F' or garcons.append((nom,sex))]
     
    # limite le nombre
    filles = filles[:len(garcons)+8]
    garcons = garcons[:len(filles)+8]
     
    # isole le plus petit groupe
    grp1,grp2 = sorted((filles,garcons),key=len)
     
    # repartition des classes
    eleves = filles+garcons
    classe1 = eleves[::2]
    classe2 = eleves[1::2]
     
    # ajuste la repartiton
    if len(grp1) & 1 and len(grp2)-len(grp1)==8:
    	classe1.append(classe2.pop())
     
    print(classe1)
    print(classe2)

  15. #15
    Membre expérimenté
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    870
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 870
    Points : 1 522
    Points
    1 522
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    ...et puis surtout ça crée juste deux classes composées pour la première de garçons et pour la seconde de filles (ce qui n'a plus rien à voir avec le sujet initial)...
    oh Tu as raison toutes mes excuses.. . 1 point pour l'Homme , 0 pour la machine!

    @josmily:
    J'aime
    #Rien de nouveau sous le soleil, tout est vanité comme courir après le vent!
    Developpement pour Android avec Python3/Kivy/Buildozer

  16. #16
    Nouveau Candidat au Club
    Homme Profil pro
    terminale
    Inscrit en
    Février 2024
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : terminale

    Informations forums :
    Inscription : Février 2024
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Réponse
    Salut à tous, merci pour vos réponses très précieuses !

    Je vais faire le tour dès maintenant,
    Pour répondre à certains,


    Citation Envoyé par Sve@r Voir le message
    Et que se passe-t-il si l'écart dépasse ?
    @Sve@r L'écart de 4 est pour le moment qu'un teste, on peut accepter un écart plus grand si besoin est.

    Citation Envoyé par MPython Alaplancha Voir le message
    ... ce qui sous entend qu'il peut y avoir un total de 8 garçons ou filles en plus à répartir dans les 2 classes...
    @MPython Alaplancha C'est à peu près ça, pour le coup on accepte qu'il y a ait 4 filles en plus que le nombre de garçons ou vice-versa. Mais toujours, le 4 est une valeur de test.


    Le contexte de base est la création de classes d'écoles, la liste que j'ai fournie est juste une sorte de test, à la base on parle d'une liste de plus d'une centaine d'élèves à répartir dans 4 classes différentes, et on essaie d'avoir un nombre relativement équivalent entre chaque classe. On part du principe que chaque classe doit avoir le même nombre d'élèves à 1 ou 2 élèves près.@

  17. #17
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Si la contrainte est simplement "même nombre d'élèves +-epsilon par classe" ça sera toujours faisable. Mais la contrainte "même nombre de filles que de garçons" pourra potentiellement amener à une impasse (sur un nombre de classes fixes je veux dire). Imaginons que tu aies 75 filles et 25 garçons tu ne pourras jamais les dispatcher sur 4 classes avec autant de filles que de garçons...

    Citation Envoyé par mrsogravity Voir le message
    @Sve@r L'écart de 4 est pour le moment qu'un teste, on peut accepter un écart plus grand si besoin est.
    Si tu regardes bien ma fonction, le cas est prévu (paramètre "ecart" qu'on peut spécifier). Mais bien entendu ma fonction n'a pas été prévue pour un nombre de classes limite. Elle prend les élèves au compte-gouttes et si le nouveau ne trouve pas de place dans les classes déjà existantes, elle crée alors une nouvelle classe pour lui.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  18. #18
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 824
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 824
    Points : 7 120
    Points
    7 120
    Par défaut
    Bonjour,

    mrsogravity,

    Pour répondre à certains,
    Peux-tu faire un effort supplémentaire et répondre aux miennes aussi ?

    L'écart de 4 est pour le moment qu'un teste, on peut accepter un écart plus grand si besoin est.
    La seule chose que je comprend dans cette phrase c'est que l'écart est paramétrable, mais ça on s'en doutait, c'est un peu le but que paramétrer et automatiser dans le développement informatique.
    Sauf que la réflexion va un peu plus loin que juste paramétrer, il faut prévoir certains cas déjà indiquer dans nos précédents messages.

    à la base on parle d'une liste de plus d'une centaine d'élèves à répartir dans 4 classes différentes, et on essaie d'avoir un nombre relativement équivalent entre chaque classe. On part du principe que chaque classe doit avoir le même nombre d'élèves à 1 ou 2 élèves près.
    Là on a une problématique mieux posée, mais c'est loin d'être aussi simple pour résoudre... Il y a une complexité dans le sujet que tu ne vois pas, comprend pas à mon sens.
    Comme c'est un projet, je suppose que c'est un travail sur un temps assez long, on attend donc de toi pas seulement des lignes de code, mais une réflexion sur comment résoudre ton problème.
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  19. #19
    Nouveau Candidat au Club
    Homme Profil pro
    terminale
    Inscrit en
    Février 2024
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : terminale

    Informations forums :
    Inscription : Février 2024
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Détails
    Salut et re,

    Tout à l'heure je n'ai pas eu le temps de lire tous vos messages.

    Je viens donc éclairer un peu la lanterne de tout le monde quant à mon soucis.


    Avec mes amis, nous devons créer une fonction qui va répartir les classes d'un collège pour "automatiser" le côté technique de la répartition des classes afin de peut-être par la suite créer un logiciel permettant de remplacer nos chers professeurs lors de la création des classes en tout cas pour le côté technique de la chose...
    Nous avons déjà codé la majorité de ce dont nous avons besoin selon les contraintes posées par notre lycée. Ce qu'il nous manque donc est une fonction/méthode qui nous permettrait d'agir sur une parité de sexe dans les classes afin de créer une mixité car actuellement, tel notre programme est façonné, nous nous retrouvons avec des classes de 20 garçons pour 7 filles... Bref sachant que la mixité est une chose importante lors de la répartition des classes surtout pour un collège, c'est relativement fondamental d'ajouter cette fonction à notre programme.


    Les contraintes sont telles que nous avons une liste d'à peu près 120 élèves et qu'il nous faut les répartir dans 4 classes. Comme c'est surtout pour tester et que par la suite j'ajouterais le bout de code à notre programme, ici nous avons juste besoin de repartir les élèves dans 4 classes différentes, l'ordre importe peu, donc on peut le faire dans l'ordre de la liste donnée. L'objectif est surtout de créer des classes ayant une certaine parité de sexe et en l'occurrence avec une parité qui peut être changée, j'ai dit 4 au début mais c'était juste pour les tests, dans la vraie vie certaines classes peuvent même se retrouver avec 10 filles de plus que de garçons etc... Et si jamais il n'est pas possible de créer une classe avec une parité maximale de 4, la parité sera donc augmentée.

  20. #20
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 824
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 824
    Points : 7 120
    Points
    7 120
    Par défaut
    Les contraintes sont bien plus importantes, mais bref, vous n'avez sans doute pas prévu tous les cas de figure pour vous limiter à elles seules.

    Après plusieurs tests, mais loin de les avoir tous fait, j'ai modélisé le problème (entités). Voici le code que je propose,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    class Classroom:    
        def __init__(self, max_students, max_diff):
            self.students = []
            self.max_students = max_students
            self.max_diff = max_diff
     
        def can_accommodate(self, student):
            girls = len([s for s in self.students if s[1] == 'F'])
            boys = len([s for s in self.students if s[1] == 'M'])
            if len(self.students) < self.max_students:
                diff_after_adding = abs(girls - boys + (1 if student[1] == 'F' else -1))
                return diff_after_adding <= self.max_diff
            return False
     
        def add_student(self, student):
            if self.can_accommodate(student):
                self.students.append(student)
                return True
            return False
     
    class School:
        def __init__(self, max_per_class, max_diff):
            self.classrooms: list[Classroom] = []
            self.max_per_class = max_per_class
            self.max_diff = max_diff
     
        def distribute_students(self, students):
            for student in students:
                placed = False
                for classroom in self.classrooms:
                    if classroom.add_student(student):
                        placed = True
                        break
                if not placed:
                    new_classroom = Classroom(self.max_per_class, self.max_diff)
                    new_classroom.add_student(student)
                    self.classrooms.append(new_classroom)
     
        def redistribute_students(self, min_students):
            subminimal_students = []
            for classroom in self.classrooms:
                if len(classroom.students) < min_students:
                    subminimal_students.extend(classroom.students)
            self.classrooms = [classroom for classroom in self.classrooms if len(classroom.students) >= min_students]
            for student in subminimal_students:
                placed = False
                for classroom in self.classrooms:
                    if classroom.add_student(student):
                        placed = True
                        break
                if not placed:
                    pass
            self.classrooms = [c for c in self.classrooms if c.students]
     
        def print_classrooms(self):
            for i, classroom in enumerate(self.classrooms, 1):
                num_girls = len([s for s in classroom.students if s[1] == 'F'])
                num_boys = len([s for s in classroom.students if s[1] == 'M'])
                print(f"Classe {i}: {len(classroom.students)} élèves (Filles: {num_girls}, Garçons: {num_boys})")
                for student in classroom.students:
                    print(f" - {student[0]} ({student[1]})")
     
     
    students_list = (
        ("Jean", "M"),
        ("Enzo", "M"),
        ("Juliette", "F"),
        ("Blanche", "F"),
        ("Aurore", "F"),
        ("Gabriel ", "M"),
        ("Marc", "M"),
        ("Manon", "F"),
        ("Emma", "F"),
        ("Ulysse", "M"),
        ("Kevin", "M"),
        ("Iris", "F"),
        ("Jeremy", "M"),
        ("Michel", "M"),
        ("Noemie", "F"),
        ("Axel", "M"),
        ("Yanis", "M"),
        ("Solene", "F"),
        ("Alice", "F"),
        ("Valerie", "F"),
    )
     
     
    school = School(max_per_class=10, max_diff=4)
    school.distribute_students(students_list)
    school.redistribute_students(min_students=4)
    school.print_classrooms()
    ça envoi une sortie comme,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    Classe 1: 10 élèves (Filles: 5, Garçons: 5)
     - Jean (M)
     - Enzo (M)
     - Juliette (F)
     - Blanche (F)
     - Aurore (F)
     - Gabriel  (M)
     - Marc (M)
     - Manon (F)
     - Emma (F)
     - Ulysse (M)
    Classe 2: 10 élèves (Filles: 5, Garçons: 5)
     - Kevin (M)
     - Iris (F)
     - Jeremy (M)
     - Michel (M)
     - Noemie (F)
     - Axel (M)
     - Yanis (M)
     - Solene (F)
     - Alice (F)
     - Valerie (F)
    ça passe pas mal de tests, mais sans doute pas tous, pas eu le temps de les écrire complètement...
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

Discussions similaires

  1. [9][logiciel]Restriction des données selon une période
    Par hondavtec77 dans le forum SAP Crystal Reports
    Réponses: 3
    Dernier message: 14/09/2007, 11h42
  2. Grouper des données selon une date
    Par gids01 dans le forum iReport
    Réponses: 2
    Dernier message: 30/07/2007, 16h03
  3. [MySQL] Afficher des évènements selon une année précise
    Par gotenks dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 11/01/2006, 13h43
  4. Boucle en Dos pour lister des fichiers selon une date
    Par Corben dans le forum Autres Logiciels
    Réponses: 1
    Dernier message: 17/12/2005, 12h17
  5. Trigger vidant des informations selon une contrainte de temp
    Par jlassira dans le forum Développement
    Réponses: 1
    Dernier message: 16/11/2005, 15h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo