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 :

Programme d'affectation d'horaires pour des cours


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2017
    Messages : 20
    Par défaut Programme d'affectation d'horaires pour des cours
    Bonjour,

    Ayant quelques bases de python on m'a demandé de voir s'il serait possible de faire un programme qui affecte des horaires à chaque professeur d'une petite école (10 enseignants environ) en fonction de leurs disponibilités, ayant de toute façon l'intention de me perfectionner en python j'ai donc décidé de me pencher sur la question mais le problème n'est pas simple. Voilà comment je pense procéder pour le moment; dans l'attente de suggestion, conseils...

    1) Tout d'abord chaque professeur donnera ses disponibilités qui seront enregistrées sous forme d'une liste de 1 et 0.
    2) Il donnera ensuite son nombre d'heures de cours à assurer sur une semaine.
    3) Le programme calcule alors le nombre d'heures totales disponibles de chaque professeur.
    4) Il soustrait pour chaque professeur le nombre d'heures de cours au nombre d'heures de cours disponibles.
    5) il prend alors la liste de disponibilité du professeur ayant eu le plus petit nombre d'heures à l'étape 4 (si plusieurs ont le mème résultat il en choisit un au hasard) et choisit une heure au hasard dans celles disponibles (un 1 dans la liste).
    6) Il ajoute ce prof à une liste finale à l'index de l'heure choisie (exemple 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0 => _,_,_,_,_,_,_,_,"mr michu",_,_,_,_,_,_,_,_ ).
    7) il retire alors cette heure de la liste de disponibilité de tous les profs (ici, la 9e heure est donc remplacée par un 0 chez tous les profs).
    8) Il recommence à l'étape 3 jusqu'à ce que la liste finale soit complète.

    ->je souhaiterai utiliser python 3.5 sur Ubuntu 16.04.
    ->les étapes en vert sont celles pour lesquelles je ne sais pas comment faire.
    ->je pense utiliser la POO (une classe matière avec une méthode pour les étapes 3 et 4 ) (je n'ai pas encore de démarche précise pour les étapes 5,6 et 7 donc je ne sait pas pour ce étapes) mais je ne sais pas si je me complique la vie.

    voilà, je pense avoir expliqué le problème, je vous ferai part de l'avancée du travail.
    Si vous avez de meilleures suggestions quand à la démarche à suivre je suis preneur et si vous pouviez m'éclairer sur les étapes 4 et 6 cela m'aiderait beaucoup.
    Si je n'ai pas été assez clair dites le moi, je m'efforcerai de préciser.
    Si vous désirez des précisions, demandez.
    Si vous pensez que je vais dans le mur dites le

    Cordialement, dans l'attente de vos réponses
    Lisiof.

  2. #2
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 078
    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 : 4 078
    Par défaut
    J'ai regardé rapidement, mais pour la question 5, si on connaît les dispos de chacun, on peut trier par horaire et ressortir tous les enseignants avec dispos minimum. Par exemple,

    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
    from random import choice
     
    dispos = (
        ('tartanpion', 15),
        ('bisounours', 5),
        ('nadal', 5),
        ('bechamel', 8)
    )
     
    def get_min_disp(profs):
        """profs -> iterable object"""
        sorting_profs = sorted(dispos, key=lambda disp:disp[1])
        prof_disp = sorting_profs[0]
        res = []
        res.append(prof_disp)
        for prof, hour in sorting_profs[1:]:
            if hour != prof_disp[1]:
                break
            res.append((prof, hour))
        return choice(res)
     
    print(get_min_disp(dispos)) # return nadal or bisounours
    Pas le temps de regarder la suite... désolé !

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Je n'ai pas trop bien compris la partie 6 "on ajoute ce prof à une liste finale et l'heure choisie pour ce prof passe à 0 chez tous les autres". Cela sous-entend donc qu'il n'y a qu'une seule classe et que les profs s'y succèdent ???

    Sinon en partant sur cet algo d'énumération tu as des risques de tomber sur un phénomène de blocage. Exemple M. Michu a été choisi (parmi plusieurs) pour le lundi 8h. Or il y a aussi un besoin de prof pour mercredi 8h et M. Michu est le seul qui avait ce créneau de libre et là il ne l'a plus car son créneau a été bouffé le lundi (alors que d'autres auraient pu assurer ce créneau)...

    Comme pour tout il y a beaucoup de façons de faire, beaucoup de bonnes et aussi beaucoup de mauvaises. Mais j'ai l'intuition que le point de départ c'est la classe. Commencer par énumérer, pour chaque heure de cours de la classe, le nombre de profs disponibles à cette heure. Et trier alors cette liste d'heures de cours par le nombre de profs pouvant les assurer (l'heure la plus critique en premier). Ensuite prendre ces heures une à une et choisir, parmis les profs dispos, celui qui a le moins de disponibilités autres (il est alors moins disponible pour les autres heures donc autant qu'il soit utile là où il peut). C'est paradoxal (celui qui bosse déjà beaucoup et qui a donc le moins de dispos bossera encore plus) mais c'est la meilleure façon de faire du point de vue algo (et de toute façon c'est bosser plus pour gagner plus !!!).

    Ca n'empêchera pas les blocages (M. Michu pourrait être le seul à pouvoir assurer le lundi et le mercredi et il n'a qu'une heure dispo) mais ça aidera à éviter autant que possible.

    Ensuite pour le 5 (choisir un min ou un max) tu as à ta disposition une fonction min(iterable) et max(iterable). Et pour placer la "xième" heure de tous les profs à 0, ben en partant d'un truc comme ça
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    prof=[
        {"nom" : "michu", "dispo" : [0, 1, 0, 1, 0, 1, 0, 1]},
        {"nom" : "tristus", "dispo" : [0, 0, 0, 0, 1, 1, 0, 1]},
        {"nom" : "bistus", "dispo" : [1, 1, 0, 0, 1, 1, 0, 1]},
    ]
     
    for p in prof:
        p["dispo"][4]=0   # Mettre la 5° heure à 0
    # for
    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]

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2017
    Messages : 20
    Par défaut
    Pour la 5 l'étape sur laquelle je bloque est le fait de choisir aléatoirement un des créneaux disponibles dans la liste de disponibilités et pas de choisir un min ou un max mais voir le programme dans l'autre sens en partant des horaires directement au lieu des disponibilités me parait une option à creuser ce que je vais faire.
    mon problème pour la 5 est par exemple:
    disponibilités de mr michu:1,1,1,0,0,1,1,0,0,1,0,1,0
    il faut que le programme ne lui affecte pas nécessairement les trois premières heures libres mais les choisisse aléatoirement afin que si les horaires ne conviennent pas pour X raison il suffise de refaire tourner le bébé avec les mèmes paramètres pour qu'il ressorte un résultat différent et cela autant de fois que l'on veut.
    j'ai oublié de préciser que je fais cet algo pour une seule classe ou les heures se succédent pour le moment, et en le faisant tourner plusieurs fois on fera les autres classes en tenant compte des résultats de la classe précédente.

  5. #5
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Tu peux te faire une fonction qui va tirer non pas un '1' au hasard, mais une position occupée par un '1'

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import random
     
    dispo_michu=[1,1,1,0,0,1,1,0,0,1,0,1,0]
     
    def RandomAccordingToAvailability(dispo):
         free_hours=[ pos for pos,dispo in enumerate(dispo) ]
         return random.choice(free_hours)
     
    for i in range(10):
         print(RandomAccordingToAvailability(dispo_michu))

    A titre indicatif, pour cet exemple free_hours vaut [0,1,2,5,6,9,11].
    La fonction te retourne la position du créneau que tu peux attribuer à M. Michu.

    A noter : - Si tu fais plusieurs appel à cette fonction dans le même code (comme ici dans la boucle for), tu auras des résultats différents d'un appel à l'autre (ce qui est à priori l'effet recherché)
    - Mais attention, si tu exécute plusieurs fois ce bout de code, la série des 10 chiffres imprimés à l'écran sera toujours la même ! La faute au fait que les générateurs de nombre aléatoire sont pseudo random. Il dépendent d'une graine, et cette graine fixe toute la série générée par le random. L'astuce pour avoir qqch qui change aussi en fonction des éxécutions (si tel est ton besoin) c'est de spécifier une graine, qui va dépendre de l'heure à laquelle on lance le programme par exemple comme ci dessous.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    import time
    import random
     
    random.seed(int(time.time()))
    Et là tu pourras éxécuter plein de fois ton code et tu auras des résultats toujours différents.

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2017
    Messages : 20
    Par défaut
    Grâce a votre aide dont je vous remercie sincèrement, j'ai réussi à finir un premier programme qui fait cela pour 4 profs et 10 créneaux horaires.
    comme il faut compter 10 profs et 29 créneaux horaires le travail ne me parait pas monstrueux pour l'adapter mais comme il est susceptible de resservir j'aimerai savoir comment je pourrais faire pour rendre le programme plus adaptable sans toutefois une saisie des dispos à répétition (while: input()) mais plutôt une lecture de fichier ou autre.
    voici donc le code, j'espère qu'il est assez clair.
    ->dans le second dictionnaire "indexX" ne sert pas pour le moment mais pourrait servir à s'y retrouver en cas de modification donc je le laisse

    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
     
    #essai avec des dictionnaire
    import time
    import random
     
    random.seed(int(time.time()))
     
     
    def choix(dispo):
        free_hours = [pos for pos, dispo in enumerate(dispo)]
        return random.choice(free_hours)
     
    a,b,c,d=3,3,2,2
     
    profs=[
        {"nom" : "mich","dispo" : [1,0,1,0,0,1,0,0,1,1],"temps" : a},
        {"nom" : "juju","dispo" : [1,1,0,1,1,0,0,0,1,0],"temps" : b},
        {"nom" : "dédé","dispo" : [1,0,0,0,1,1,0,1,0,0],"temps" : c},
        {"nom" : "gégé","dispo" : [0,0,1,0,1,1,1,0,1,1],"temps" : d},
    ]
     
     
    i=1#variable pour le bouclage
    liste=[]#liste intermédiaire pour la réorganisation.
    for i in range (0,10):
        for p in profs:
            liste.append(p["dispo"][i])
     
     
     
     
    #dictionnaire qui contient toutes les heures et les disponibilités par profs
    heures=[
        {"indexX": "1","dispos":liste[0:4],"somme":sum(liste[0:4])},
        {"indexX": "2","dispos":liste[4:8],"somme":sum(liste[4:8])},
        {"indexX": "3","dispos":liste[8:12],"somme":sum(liste[8:12])},
        {"indexX": "4","dispos":liste[12:16],"somme":sum(liste[12:16])},
        {"indexX": "5","dispos":liste[16:20],"somme":sum(liste[16:20])},
        {"indexX": "6","dispos":liste[20:24],"somme":sum(liste[20:24])},
        {"indexX": "7","dispos":liste[24:28],"somme":sum(liste[24:28])},
        {"indexX": "8","dispos":liste[28:32],"somme":sum(liste[28:32])},
        {"indexX": "9","dispos":liste[32:36],"somme":sum(liste[32:36])},
        {"indexX": "10","dispos":liste[36:40],"somme":sum(liste[36:40])},
    ]#réorganisation de la grande liste en 10 petites correspondantes à chaque heure.
     
    listfinal=[0,0,0,0,0,0,0,0,0,0]
    index=0
    for p in heures:#première boucle ou on affecte les heures ou on n'a pas le choix
        if p["somme"] == 1 :
            numero=p["dispos"].index(1)
            profs[numero]["temps"] -= 1
            listfinal[index]=numero
        index += 1
    index=0
     
    for p in heures:#deuxième boucle pour les heures n'ayant pas été casées par la première
        if p["somme"] != 1:
            i=1
            while i == 1:
                ch=choix(p["dispos"])#choix d'un prof dispo, ch est son index
     
                if profs[ch]["temps"] > 0:#si il a du temps libre
                    listfinal[index] = ch #ajouter le numéro du prof à la liste finale
                    profs[ch]["temps"] -= 1
                    i=2
                else:
                    i=1
     
        index+=1
     
     
     
     
     
     
    #vérification du nombre d'heures
    print (listfinal.count(0))
    print (listfinal.count(1))
    print (listfinal.count(2))
    print (listfinal.count(3))
     
    #affichage final
    print ("mich=0, juju=1, dédé=2, gégé=3")
    print (listfinal)

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lisiof Voir le message
    j'aimerai savoir comment je pourrais faire pour rendre le programme plus adaptable sans toutefois une saisie des dispos à répétition (while: input()) mais plutôt une lecture de fichier ou autre.
    Pourquoi ne pas passer par une structure de fichier ".ini" comme on en voit assez souvent ??? Avec ConfigParser ça passe comme une lettre à la poste
    Exemple de fichier "fic.ini"
    Code fic.ini : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    [chapitre1]
    classe = 10
    prof = 25
     
    [chapitre2]
    classe = 12
    prof = 17

    Et voici comment on peut le lire
    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
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
     
    import ConfigParser
     
    config=ConfigParser.ConfigParser()
     
    config.read("fic.ini")
     
    for i in xrange(1, 3):
    	chapitre="chapitre%d" % i
    	if config.has_section(chapitre):
    		print "classe=", config.get(chapitre, "classe")
    		print "prof=", config.get(chapitre, "prof")
    	# if
    # for
    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]

Discussions similaires

  1. besoin d'aide pour des cours en programmation débutant
    Par xxjijoxx dans le forum Autres langages
    Réponses: 3
    Dernier message: 22/05/2016, 22h16
  2. Combien demander pour des cours de progra + quel statut
    Par Anne1969 dans le forum Structure
    Réponses: 3
    Dernier message: 27/07/2006, 13h08

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