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 :

non compréhension de l'évolution des valeurs d'une liste par un novice


Sujet :

Python

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Septembre 2023
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Septembre 2023
    Messages : 5
    Points : 1
    Points
    1
    Par défaut non compréhension de l'évolution des valeurs d'une liste par un novice
    Je suis en train de programmer un jeu avec la console de python pour m'entrainer et je faisais une partie du programme sur la construction des bâtiments à part pour faciliter sa conception.

    Mon problème est que je dois faire évoluer puis supprimer les valeurs dans des listes, et c'est cette évolution que je ne comprends pas :
    mon programme devrait en théorie enlever 0.5 à la liste "projet_batiment_temps_construction" (visible plus bas dans le message), et supprimer la valeur quand elle arrive à zéro, et supprimer les valeurs/mots de même index dans deux autres listes. Et quand je teste le programme certaines valeurs n'évoluent pas pendant plusieurs "tour" (un tour correspond à un appel de la fonction), si bien qu'au lieu de traiter et supprimer les valeurs de la liste (et d'incrémenter les variables des bâtiments construits (et non de ceux en construction)) en 6 "tours", il lui en faut 7, d'autant plus que les derniers à être traités sont ceux qui devrait l'être en 2 "tours".
    Et malgré que j'ai regardé plusieurs fois le programme et changé ce qui semblait poser problème, soit rien n'a changé, soit ça a très partiellement amélioré la situation (me rendant d'autant plus confus que je pensais qu'il s'agissait d'un problème simple).

    Il est très probable que le code ne soit pas optimisé, mais je suis ouvert aux conseils.

    voici le code :

    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
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    # Les bâtiments construits sont stockés dans ces variables
    maison_niv_1 = 0
    maison_niv_2 = 0
    maison_niv_3 = 0
    entrepot_niv_1 = 0
    entrepot_niv_2 = 0
    entrepot_niv_3 = 0
    total_batiment = 0
     
    # Les projets de bâtiments en cours sont stockés dans ces listes,
    # la première pour leurs noms/types, la deuxième pour leurs niveaux 1, 2 ou 3 et la dernière pour le temps de construction
    projet_batiment_nom = []
    projet_batiment_niv = []
    projet_batiment_temps_construction = []
     
    # ce groupe de 6 variables ne sert qu'à déterminer (plus loin dans le code) la vitesse de construction et à constater les coûts de construction
    batisseur = 1
     
    bois = 10000
    pierre = 10000
     
    surface_construite = 0.0
    surface_constructible = 10000
     
    nombre_heure_travaille = 8
     
    # Cette fonction permet de completer les listes précédemment établies (je l'ai implémentée dans ce code car elle est nécessaire, mais je l'avais programmée avant)
    def projet_construction(nombre, niv, type):
        global projet_batiment_nom
        global projet_batiment_niv
        global projet_batiment_temps_construction
        global bois
        global pierre
        global surface_constructible
        global surface_construite
        if type == "maison" :
            if niv == 1:
                for quantité in range(nombre) :
                    projet_batiment_nom.append("maison")
                    projet_batiment_niv.append(1)
                    projet_batiment_temps_construction.append(2.0)
                    bois -= 5
                    pierre -= 4
                    surface_constructible -= 1
                    surface_construite += 1
     
            elif niv == 2:
                for quantité in range(nombre) :
                    projet_batiment_nom.append("maison")
                    projet_batiment_niv.append(2)
                    projet_batiment_temps_construction.append(3.0)
                    bois -= 6
                    pierre -= 7
                    surface_constructible -= 2.5
                    surface_construite += 2.5
     
            elif niv == 3:
                for quantité in range(nombre) :
                    projet_batiment_nom.append("maison")
                    projet_batiment_niv.append(2)
                    projet_batiment_temps_construction.append(4.0)
                    bois -= 8
                    pierre -= 11
                    surface_constructible -= 4.5
                    surface_construite += 4.5
     
            elif nombre == 0 :
                pass
            else :
                print("Vous avez du faire erreur dans votre demande de construction de maison...")
     
        if type == "entrepôt" :
            if niv == 1:
                for quantité in range(nombre) :
                    projet_batiment_nom.append("entrepôt")
                    projet_batiment_niv.append(1)
                    projet_batiment_temps_construction.append(1.0)
                    bois -= 10
                    pierre -= 1
                    surface_constructible -= 2
                    surface_construite += 2
     
            elif niv == 2:
                for quantité in range(nombre) :
                    projet_batiment_nom.append("entrepôt")
                    projet_batiment_niv.append(2)
                    projet_batiment_temps_construction.append(2.0)
                    bois -= 16
                    pierre -= 3
                    surface_constructible -= 5
                    surface_construite += 5
     
            elif niv == 3:
                for quantité in range(nombre) :
                    projet_batiment_nom.append("entrepôt")
                    projet_batiment_niv.append(3)
                    projet_batiment_temps_construction.append(3.0)
                    bois -= 23
                    pierre -= 5
                    surface_constructible -= 9
                    surface_construite += 9
     
            elif nombre == 0 :
                pass
            else :
                print("Vous avez du faire erreur dans votre demande de construction d'entrepôt...")
    """
    Cette fonction est celle que je suis en train de faire,
    elle doit permettre de faire évoluer les valeurs des listes de telle sorte que le temps de construction des bâtiments soit réduit de 0.5 à chaque utilisation 
    et une fois cette valeur à 0, elle doit suprimmer le bâtiment des 3 listes et incrémenter les 7 premières variables décrites au tout début du code en fonction du bâtiment construit
    """
    def avancement_construction():
        global projet_batiment_nom
        global projet_batiment_niv
        global projet_batiment_temps_construction
        global maison_niv_1
        global maison_niv_2
        global maison_niv_3
        global entrepot_niv_1
        global entrepot_niv_2
        global entrepot_niv_3
        global total_batiment
        global nombre_heure_travaille
     
        # Cette variable indique quel index des listes traite la fonction, on part du plus grand vers le plus petit (pour éviter que l'index soit décalé à chaque modification)
        index_avancement = len(projet_batiment_nom)-1
     
        for quantiter in range(len(projet_batiment_nom)) :
     
            # vitesse de construction (0.5 par tour en tout)
            projet_batiment_temps_construction[index_avancement] -= batisseur * 0.0625 * nombre_heure_travaille
     
            if projet_batiment_temps_construction[index_avancement] <= 0 :# si le bâtiment a fini d'être construit ou non
                if projet_batiment_nom[index_avancement] == "maison": # vérification du type de bâtiment
                    if projet_batiment_niv[index_avancement] == 1 : # vérification du niveau du bâtiment
                        maison_niv_1 += 1
                        total_batiment += 1
                        # supression des données des trois listes
                        del projet_batiment_nom[index_avancement]
                        del projet_batiment_niv[index_avancement]
                        del projet_batiment_temps_construction[index_avancement]
     
                    # même principe pour la suite, mais pour les niveaux 2 et 3 de ce type de bâtiment. Puis, plus loin, le type suivant
                    elif projet_batiment_niv[index_avancement] == 2 :
                        maison_niv_2 += 1
                        total_batiment += 1
                        del projet_batiment_nom[index_avancement]
                        del projet_batiment_niv[index_avancement]
                        del projet_batiment_temps_construction[index_avancement]
     
                    elif projet_batiment_niv[index_avancement] == 3 :
                        maison_niv_3 += 1
                        total_batiment += 1
                        del projet_batiment_nom[index_avancement]
                        del projet_batiment_niv[index_avancement]
                        del projet_batiment_temps_construction[index_avancement]
                    index_avancement -= 1 # changement d'index une fois l'action effectuée
     
                elif projet_batiment_nom[index_avancement] == "entrepôt" :
     
                    if projet_batiment_niv[index_avancement] == 1 :
                        entrepot_niv_1 += 1
                        total_batiment += 1
                        del projet_batiment_nom[index_avancement]
                        del projet_batiment_niv[index_avancement]
                        del projet_batiment_temps_construction[index_avancement]
     
                    elif projet_batiment_niv[index_avancement] == 2 :
                        entrepot_niv_2 += 1
                        total_batiment += 1
                        del projet_batiment_nom[index_avancement]
                        del projet_batiment_niv[index_avancement]
                        del projet_batiment_temps_construction[index_avancement]
     
                    elif projet_batiment_niv[index_avancement] == 3 :
                        entrepot_niv_3 += 1
                        total_batiment += 1
                        del projet_batiment_nom[index_avancement]
                        del projet_batiment_niv[index_avancement]
                        del projet_batiment_temps_construction[index_avancement]
                    index_avancement -= 1
     
    #les listes sont remplies via la fonction "projet_construction"
    projet_construction(3, 1, "entrepôt")
    projet_construction(5, 2, "maison")
    projet_construction(3, 1, "maison")
    projet_construction(2, 2, "entrepôt")
     
    # fonction donnant les informations sur l'évolution des variables
    def print_test() :
        print(projet_batiment_nom)
        print(projet_batiment_niv)
        print(projet_batiment_temps_construction)
        print(maison_niv_1)
        print(maison_niv_2)
        print(maison_niv_3)
        print(entrepot_niv_1)
        print(entrepot_niv_2)
        print(entrepot_niv_3)
        print(total_batiment)
        print("")
        avancement_construction()
     
    print_test()
    print_test()
    print_test()
    print_test()
    print_test()
    print_test()
    print_test()

  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 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Ton programme est trop "lourd". Tu n'as rien factorisé et de fait difficilement assimilable par une lecture simple. Le seul fait d'avoir créé des variables "entrepot_niv1" et "entrepot_niv2" puis devoir écrire "si niveau = 1 je traite niv1 puis si niveau = 2 je traite niv2" en est le résultat (en plus tout ça réécrit aussi pour maison). Ca aurait été tellement plus simple de créer une liste "construction" puis d'écrire simplement traitement construction["entrepot"][niveau]...

    Et donc je ne trouve pas la logique de ton algo ni le souci qui en résulte. Ce que je peux dire, c'est que le souci se situe probablement aux del projet_batiment_temps_construction[index_avancement]. Parce que deleter un élément d'une liste décale tous les éléments suivants (deleter element[3] fait que [4] devient [3], [5] devient [4] et etc). Mais si tu deletes et qu'en même temps "index_avancement" augmente, tu te retrouves à sauter des éléments (voire même tomber sur IndexError si "index_avancement" arrive à une valeur n qui était permise au début mais qui ne l'est plus du fait de ces décalages).

    Bref on ne modifie jamais une liste sur laquelle on boucle (directement ou indirectement) dessus. Si on veut pouvoir le faire alors il faut boucler sur une copie de la liste ; ou alors mémoriser les éléments à supprimer et les supprimer ensuite une fois la boucle terminée.

    Et refais ton programme. Dans l'absolu constuire une maison ou un entrepot c'est juste "construire truc". Donc tu écris un algo général et tu lui passes "truc" en paramètre. Tu as à ta disposition des milliers d'outils pour te faciliter la programmation (liste, dictionnaires, liste de dictionnaires, dictionnaires pouvant contenir des listes, classes, classes de dictionnaires, classes de listes, listes de classes, etc etc etc) alors utilises-les. N'oublie pas le principe qui doit être la base de tout programme : un programme est dix fois plus lu qu'écrit.
    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
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Dindalas12 Voir le message
    Je suis en train de programmer un jeu avec la console de python pour m'entrainer et je faisais une partie du programme sur la construction des bâtiments à part pour faciliter sa conception.
    Dès que vous partez à écrire plus de 20 lignes de code, vous devez maîtriser les structures et les constructions du langage, histoire de pouvoir facilement reformuler votre besoin avec les outils qu'offre le langage.
    Là vous partez à utiliser des listes parce que vous ne connaissez que çà... c'est un bon exercice mais un exercice sur les listes qui fait plus de 200 lignes, c'est un mauvais exercice sur les listes (et plutôt qu'inventer vos propres exercices, essayez de faire ceux proposés par votre tuto préféré: ils ont été un minimum réfléchis pour coller au chapitre correspondant du cours).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Septembre 2023
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Septembre 2023
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    D'accord, je vais simplifier le code pour le rendre plus lisible et efficace.

    Par contre, pour se qui est de l'index qui change à chaque modification de la liste, j'y avait pensé et j'ai fait en sorte que les listes soit édités en partant de la fin vers le début.
    Je pense que ça à résolue ce problème, mais il se peut que je me trompe.
    merci de la réponse.

  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 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Dindalas12 Voir le message
    Je pense que ça à résolue ce problème, mais il se peut que je me trompe.
    En effet partir de la fin et remonter vers le début c'est une solution possible qui fonctionne. Mais la toute première question est de te demander si tu as vraiment besoin de supprimer des éléments du tableau.
    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
    Nouveau Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Septembre 2023
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Septembre 2023
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    J'ai optimisé le code, j'ai réussi à enlevé 90 ligne de ce dernier, il devrait être plus lisible :

    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
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    # Les bâtiments construits sont stockés dans ce dictionnaire
    Batiment_construit = {"maison_niv_1" : 0, "maison_niv_2" : 0, "maison_niv_3" : 0, "entrepôt_niv_1" : 0, "entrepôt_niv_2" : 0, "entrepôt_niv_3" : 0}
     
    # Les projets de bâtiments en cours sont stockés dans ces listes,
    # la première pour leurs noms/types, la deuxième pour leurs niveaux 1, 2 ou 3 et la dernière pour le temps de construction
    projet_batiment_nom = []
    projet_batiment_niv = []
    projet_batiment_temps_construction = []
     
    # ce groupe de 6 variables ne sert qu'à déterminer (plus loin dans le code) la vitesse de construction et à constater les coûts de construction
    batisseur = 1
     
    ressource ={"bois" : 10000.0, "pierre" : 10000.0}
    surface = {"surface_construite" : 0.0, "surface_constructible" : 10000.0}
     
    nombre_heure_travaille = 8
     
    # Cette fonction permet de completer les listes précédemment établies (je l'ai implémentée dans ce code car elle est nécessaire, mais je l'avais programmée avant)
    def projet_construction(nombre, niv, type):
        global projet_batiment_nom
        global projet_batiment_niv
        global projet_batiment_temps_construction
        global ressource
        global surface
     
        if nombre > 0 :
            for quantité in range(nombre) :
                projet_batiment_nom.append(type)
                projet_batiment_niv.append(niv)
                calcul_temps_construction = niv
                calcul_temps_construction = float(calcul_temps_construction)
                projet_batiment_temps_construction.append(calcul_temps_construction)
                ressource["bois"] -= 5
                ressource["pierre"] -= 4
                surface["surface_constructible"] -= 1
                surface["surface_construite"] += 1
     
        elif nombre == 0 :
            pass
        else :
            print("Vous avez du faire erreur dans votre demande de construction de maison...")
     
    """
    Cette fonction est celle que je suis en train de faire,
    elle doit permettre de faire évoluer les valeurs des listes de telle sorte que le temps de construction des bâtiments soit réduit de 0.5 à chaque utilisation 
    et une fois cette valeur à 0, elle doit suprimmer le bâtiment des 3 listes et incrémenter les 7 premières variables décrites au tout début du code en fonction du bâtiment construit
    """
     
    def vitesse_construction():
        global batisseur
        global nombre_heure_travaille
     
        # vitesse de construction (0.5 par tour en tout)
        projet_batiment_temps_construction[index_avancement] -= batisseur * 0.0625 * nombre_heure_travaille
        # la variable "index_avancement" est décrite dans la fonction "avancement construction" un peu plus bas
     
    def fin_construction_batiment():
        global Batiment_construit
     
        if projet_batiment_temps_construction[index_avancement] <= 0 :# si le bâtiment a fini d'être construit ou non
     
            # incrémentation du dictionaire "batiments_construits" avec les batiments dont le temps de construction est arrivé à zéro
            if projet_batiment_nom[index_avancement] == "maison" and projet_batiment_niv[index_avancement] == 1 :
                    Batiment_construit["maison_niv_1"] += 1
     
            elif projet_batiment_nom[index_avancement] == "maison" and projet_batiment_niv[index_avancement] == 2 :
                Batiment_construit["maison_niv_2"] += 1
     
            elif projet_batiment_nom[index_avancement] == "maison" and projet_batiment_niv[index_avancement] == 3 :
                Batiment_construit["maison_niv_3"] += 1
     
            elif projet_batiment_nom[index_avancement] == "entrepôt" and projet_batiment_niv[index_avancement] == 1 :
                Batiment_construit["entrepôt_niv_1"] += 1
     
            elif projet_batiment_nom[index_avancement] == "entrepôt" and projet_batiment_niv[index_avancement] == 2 :
                Batiment_construit["entrepôt_niv_2"] += 1
     
            elif projet_batiment_nom[index_avancement] == "entrepôt" and projet_batiment_niv[index_avancement] == 3 :
                Batiment_construit["entrepôt_niv_3"] += 1
     
            # supression des données des trois listes
            del projet_batiment_nom[index_avancement]
            del projet_batiment_niv[index_avancement]
            del projet_batiment_temps_construction[index_avancement]
     
    def avancement_construction():
        global index_avancement
     
        # Cette variable indique quel index des listes traite les fonctions, on part du plus grand vers le plus petit (pour éviter que l'index soit décalé à chaque modification)
        index_avancement = len(projet_batiment_nom)-1
     
        for element in projet_batiment_nom :
            vitesse_construction()
            fin_construction_batiment()
            index_avancement -= 1
     
    #les listes sont remplies via la fonction "projet_construction"
    projet_construction(3, 1, "entrepôt")
    projet_construction(5, 3, "maison")
    projet_construction(3, 1, "maison")
    projet_construction(2, 2, "entrepôt")
     
    # fonction donnant les informations sur l'évolution des variables
    def print_test() :
     
        print("")
        print(projet_batiment_nom)
        print(projet_batiment_niv)
        print(projet_batiment_temps_construction)
        print(Batiment_construit)
        avancement_construction()
        print("")
     
    print_test()
    print_test()
    print_test()
    print_test()
    print_test()
    print_test()
    print_test()

  7. #7
    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 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Dindalas12 Voir le message
    J'ai optimisé le code, j'ai réussi à enlevé 90 ligne de ce dernier, il devrait être plus lisible :
    Si on peut dire... Je tique encore sur if nombre == 0: pass mais si ça te plait ainsi...
    En revanche je ne pige absolument pas le but initial du programme. Des bâtiments, des constructions, mais il doit faire quoi ??? Ce qui revient à dire que question lisibilité c'est pas encore ça. Et ce type de commentaire # je l'ai implémentée dans ce code car elle est nécessaire, mais je l'avais programmée avant n'apporte absolument rien. Le commentaire ne sert pas à dire que la fonction est nécessaire (on s'en doute qu'elle est nécessaire sinon on ne la met pas) ni quand a été écrite la fonction mais à quoi elle sert. Ceci dit je suis content que tu aies écrit correctement les accords de genre (vu le niveau actuel en orthographe c'est un truc à souligner).
    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]

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Dindalas12 Voir le message
    il devrait être plus lisible
    A partir du moment où vous n'arrivez pas à trouver l'erreur en relisant, c'est que ce n'est pas "lisible".

    Après il ne faut pas faire n'importe quoi: en lisant le code, on doit retrouver l'intention de celui qui l'a écrit.

    Lisez votre prose ligne 89:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    def avancement_construction():
        global index_avancement
     
        # Cette variable indique quel index des listes traite les fonctions, on part du plus grand vers le plus petit (pour éviter que l'index soit décalé à chaque modification)
        index_avancement = len(projet_batiment_nom)-1
     
        for element in projet_batiment_nom :
            vitesse_construction()
            fin_construction_batiment()
            index_avancement -= 1
    On a une boucle où element n'est pas utilisé dans la boucle et où on "bouge" index_avancement, variable globale.
    Ne serait-il pas plus direct de faire une boucle du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        for index_avancement in range(len(projet_batiment_nom)-1, -1, -1):
        ...
    et vous verrez que déjà ça marchera mieux.
    note: et si vous me dites, je ne sais pas utiliser range comme çà, je vous renvoie aux exercices proposés par les tutos que vous ne voulez pas faire!

    Après vous n'êtes pas supposé utiliser le mot clef "global" dans une fonction sans que ce soit nécessaire.
    Par exemple, dans cette fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def vitesse_construction():
        global batisseur
        global nombre_heure_travaille
     
        # vitesse de construction (0.5 par tour en tout)
        projet_batiment_temps_construction[index_avancement] -= batisseur * 0.0625 * nombre_heure_travaille
        # la variable "index_avancement" est décrite dans la fonction "avancement construction" un peu plus bas
    batisseur et nombre_heure_travaille ne sont pas utilisées... Et si vous me dites que c'est un oubli, je me demande si vous oubliez de vous habiller lorsque que vous allez acheter du pain.
    Et accessoirement, index_avancement aurait pu être passé en paramètre: la variable globale ne se justifie pas ici.

    L'un dans l'autre, c'est bien de vouloir faire des choses avec le Python que vous connaissez mais vous êtes dans la même situation qu'un gamin qui revient de la maternelle avec le beau dessin qu'il a trimer à faire: les parents sont hyper-contents mais le contenu artistique est assez nul car on voit la peine à tenir le crayon.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 106
    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 106
    Points : 4 462
    Points
    4 462
    Par défaut
    bonjour
    Citation Envoyé par Dindalas12 Voir le message
    J'ai optimisé le code, j'ai réussi à enlevé 90 ligne de ce dernier, il devrait être plus lisible :
    pas vraiment !
    pourquoi avoir encore projet_batiment_nom, projet_batiment_niv, projet_batiment_temps_construction ?
    Et en plus, l'utilisation de variables globales est une chose à proscrire !!!!!!!!!! sauf si on désire faire du gloubi-boulga à la place du code

    Je n'ai pas compris avec ton code, ton besoin, mais tu peux sans doute partir sur une base plus claire, du type
    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
    projet = {  # A titre de documentation
        "nom": "",
        "surface": {
            "constructible" : 1000,
            "construite" : 150,
        },
        "niveaux": 1,
        "heures": 450,
        "materiaux": {
            "bois": 40,
            "pierre" : 900,
        },
    }
     
    projets = [] # de projet
    # on va injecter les projets ...
     
    def is_fini_projet(projet):
        return projet["surface"]["construite"] >= projet["surface"]["constructible"]
     
    def is_fini(projets):
        for projet in projets:
            if not fini_projet(projet):
                return false
        return true
     
    def materiaux(projets):
        # TODO: même type de fonction si on désire le nombre d'heures totale de tous les projets
        total = {
            "bois": 0,
            "pierre" : 0,
        }
        for projet in projets:
            total["bois"] += projet["materiaux"]["bois"]
            total["pierre"] += projet["materiaux"]["pierre"]
        return total
     
    def une_journée_travail(projet, heures, surface):
        projet["heures"] += heures
        projet["surface"]["construite"] += surface
        return projet
     
     
    ###########
     
    for jour in range(1, 100):  #tout faire en 100 jours ?
        for projet in projets:
            if not is_fini_projet(projet):
                projet = une_journée_travail(projet, 80, 10) # 10 personnes vont "monter" 10m2
                print("fin de journée N°", jour, " : ", projet)
        if is_fini(projets):
            print("tout fini en", jour, "jours")
            exit(0)
    $moi= ( !== ) ? : ;

  10. #10
    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 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par papajoker Voir le message
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def is_fini(projets):
        for projet in projets:
            if not fini_projet(projet):
                return false
        return true
    def is_fini(projets): return all(map(lambda x: fini_projet(x), projets))
    Mais je te remercie, ton exemple m'a permis de mieux comprendre le but premier du PO
    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]

  11. #11
    Nouveau Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Septembre 2023
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Septembre 2023
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Je m'était peut être mal expliqué :
    le but est de diminuer les valeurs de la liste "projet_batiment_temps_construction" en fonction des variables "batisseur" et "nombre_heure_travaille" plus une valeur fixe (dans le cas présent cela abouti à -0.5).
    Et Quand une valeur de la liste "projet_batiment_temps_construction" arrive à zéro, on la supprime de la liste (et des listes liés) et ont la rajoute dans le dictionnaire "Batiment_construit" qui ressence (comme son nom l'indique, les bâtiment construit (et non ceux en construction)).

    Le code est un peut plus complexe pour permettre de l'intégrer dans le code complet du jeu.

    Mon problème est que la diminution de 0.5 ne se fait pas de façon homogène.

    J'espère m'être mieux expliqué.

  12. #12
    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 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Dindalas12 Voir le message
    Et Quand une valeur de la liste "projet_batiment_temps_construction" arrive à zéro, on la supprime de la liste (et des listes liés) et ont la rajoute dans le dictionnaire "Batiment_construit" qui ressence (comme son nom l'indique, les bâtiment construit (et non ceux en construction)).
    On ne crée pas des variables inutiles, ça alourdit le code. Si un batiment est construit, il n'est plus à construire. Donc la liste des bâtiments construits peut se déduire par la liste des bâtiments à construire et qui sont terminés.
    Inspire-toi du code de papajoker. Des fonctions simples qui font une chose et que l'on peut réutiliser dans différentes configurations.
    Et dommage pour le verbe "recenser". Certes tu as dédoublé le "s" pour ne pas qu'on lise "rezencer" mais bon c'était un "c" qu'il fallait mettre.
    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]

  13. #13
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 106
    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 106
    Points : 4 462
    Points
    4 462
    Par défaut
    Citation Envoyé par Dindalas12 Voir le message
    Quand une valeur de la liste "projet_batiment_temps_construction" arrive à zéro, on la supprime de la liste (et des listes liés) et ont la rajoute dans le dictionnaire "Batiment_construit" qui ressence (comme son nom l'indique, les bâtiment construit (et non ceux en construction)).
    Ici, c'est toi qui complexifies le truc

    Dans mon code on a une fonction is_fini_projet(), on a donc aucune raison lors du traitement d'avoir 2 listes et surtout de transférer des datas entre les 2 !
    Si on désire avoir ces 2 listes distinctes a la fin, c'est à nous de le coder (affiche ou on va créer ces 2 listes):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        for projet in projets:
            if not fini_projet(projet):
                 print(projet)
                 en_cours.append(projet) # ou
     
        for projet in projets:   # ceux fini
            if fini_projet(projet):
    ----------
    @Sve@r
    Vu le niveau débutant, je préfère être le plus basique possible (map , compréhension risque de le perdre ?)
    $moi= ( !== ) ? : ;

  14. #14
    Nouveau Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Septembre 2023
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Septembre 2023
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Si j'utilise "global", c'est par ce que je ne sait pas faire autrement :
    Je souhaite utiliser des variables à l'intérieur et à l'extérieur de fonctions : la solution que je connaisse à ce problème est d'utiliser "global".

    J'ai d'ailleurs diminué son utilisation en remaniant le code, mais je ne sais pas faire sans.

    Aussi en faisant ce poste je chercher plus à voir le problème que je n'arrivait et n'arrive toujours pas à comprendre et continuer de m'exercer, plutôt que l'on me donne un code entièrement remanier -qui, certes, semble bien meilleur-, mais que je ne comprend pas, c'est un peu comme si on essayer de faire comprendre le fonctionnement d'un ordinateur à un humain préhistorique.

    l'idée de se petit jeu en console c'était de m'exercer pour consolider les connaissance que j'avais déjà à travers un petit projet qui m'intéressais.

  15. #15
    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 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Dindalas12 Voir le message
    Si j'utilise "global", c'est par ce que je ne sait pas faire autrement :
    Je souhaite utiliser des variables à l'intérieur et à l'extérieur de fonctions : la solution que je connaisse à ce problème est d'utiliser "global".
    Parce que tes fonctions sont trop complexes, trop lourdes. Elles s'effondrent sur elles-même. Et aussi parce que tu n'as pas bien découpé ton problème.
    Si le problème c'est "construire n bâtiments", alors il devient "construire un bâtiment". Tu écris la fonction adéquate que tu appelleras pour tous les bâtiments.
    Si le problème "construire un bâtiment" se découpe en "travailler n jours" alors ça devient "travailler un jour". Tu écris la fonction adéquate que tu appelleras pour chaque jour de travail.
    Si le résultat de "travailler un jour" dépend du nombre de travailleurs, alors ce nombre devient paramètre de la fonction.

    Une fonction c'est comme un légo. Il y a des légos carrés, rectangulaires, en plaques. Puis avec tes plaques tes carrés et tes rectangles tu peux aussi bien construire une maison qu'une voiture...
    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]

  16. #16
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 106
    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 106
    Points : 4 462
    Points
    4 462
    Par défaut
    Citation Envoyé par Dindalas12 Voir le message
    Je souhaite utiliser des variables à l'intérieur et à l'extérieur de fonctions : la solution que je connaisse à ce problème est d'utiliser "global".
    mais je ne sais pas faire sans.
    tuto, ce petit exemple addition() est largement suffisant (et il ne faut pas une heure pour comprendre)

    à voir le problème que je n'arrivait et n'arrive toujours pas à comprendre
    Ton code n'a pas un problème particulier (à un endroit particulier) : il est juste très mal codé du début à la fin. Et même si le script fonctionnait, c'est juste un amalgame de ce qu'il ne faut pas faire (python et autres langages)
    note : "Mon problème est que la diminution de 0.5 ne se fait pas de façon homogène." c'est cette ligne (incompréhensible pour moi) : batisseur * 0.0625 * nombre_heure_travaille
    m'exercer pour consolider les connaissance que j'avais déjà à travers un petit projet
    Pour l'instant, tu n'as pas les connaissances pour faire un projet, même petit. Dans 8 jours ou un mois, cela devrait être beaucoup mieux...
    $moi= ( !== ) ? : ;

  17. #17
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Dindalas12 Voir le message
    Si j'utilise "global", c'est par ce que je ne sait pas faire autrement :
    Je souhaite utiliser des variables à l'intérieur et à l'extérieur de fonctions : la solution que je connaisse à ce problème est d'utiliser "global".
    "global" n'est utile que pour assigner un autre/nouvel objet à la variable.
    Par exemple ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def projet_construction(nombre, niv, type):
        global projet_batiment_nom
        global projet_batiment_niv
        global projet_batiment_temps_construction
        global ressource
        global surface
    "global" ne sert à rien.

    Après, vous avez 3 listes projet_* dont les éléments sont en relation... cette relation étant construite sur les qui ont le "même indice". Vous pourriez fabriquer une seule liste "projet" dont les items sont des listes à 3 éléments [ nom, niveau, temp_construction ].
    Cela vous simplifierait la vie... (et le nombre de lignes de code à écrire).

    Citation Envoyé par Dindalas12 Voir le message
    l'idée de se petit jeu en console c'était de m'exercer pour consolider les connaissance que j'avais déjà à travers un petit projet qui m'intéressais.
    C'est à ça que servent les exercices proposés dans les tutos. Là vous voulez faire vos propres exercices, alors que vous ne savez pas encore vous défaire de "global", utiliser "range",... c'est trop tôt.


    Citation Envoyé par Dindalas12 Voir le message
    Aussi en faisant ce poste je chercher plus à voir le problème que je n'arrivait et n'arrive toujours pas à comprendre et continuer de m'exercer, plutôt que l'on me donne un code entièrement remanier
    Si vous voulez comprendre, tracez l'état de la liste projet_batiment_nom qui sert à itérer et qui est mise à jour dans la fonction fin_construction_batiment appelée dans le corps de la boucle: ça ne marche pas. Et je vous ai proposé une solution qui itère sur index_avancement.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  18. #18
    Membre chevronné
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    721
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 721
    Points : 1 876
    Points
    1 876
    Par défaut
    Si j'ai un conseil à donner en plus du plus évident: apprendre les bases du langage, ce serait d'utiliser un bon environnement de développement, ça peut être Pycharm ou un éditeur comme Geany,VS code ou autre, avec des plugins adaptés au langage le cas échéant. Un bon IDE attirerait déjà l'attention sur des anomalies comme les variables non utilisées, et aussi le formatage. En Python, il y a des conventions de formatage comme PEP8, qu'on ne doit pas forcément respecter intégralement, mais qui apportent une certaine structure et prévisibilité dans le code.

    Ce code me donne l'impression d'avoir été rédigé sans analyse du besoin final. Donc, il y a beaucoup de code répétitif, ce code pourrait être plus succinct, et donc plus facile à appréhender.
    Je confirme que ce code est difficile à lire, et l'intention de tel ou tel bloc de code n'est pas toujours claire. (Il me rappelle le GW Basic...)
    Même si c'est plus ou moins clair pour vous aujourd'hui, ce sera moins clair dans 6 mois, si vous devrez reprendre ce code pour le faire évoluer.

    Supprimer des éléments d'une liste à la volée est quelque chose que l'on voit rarement en pratique, ce n'est pas parce que c'est possible qu'il faut le faire. Faire ça dans une boucle, c'est s'exposer à des problèmes de logique et des bugs. Au lieu de ça, on peut décider de sauter certains éléments lors de l'itération, ou générer une nouvelle liste filtrée => en Python les list comprehensions sont abondament utilisées.

    Je conseillerais aussi de rajouter de la traçabilité dans votre programme. Le module logging est très bien pour ça mais ce sera peut-être pour plus tard. En gros, l'idée serait de saupoudrer votre programme de prints pour afficher l'état des variables et vérifier que leurs valeurs évoluent bien comme vous l'attendez. C'est la méthode la plus primitive pour débugger, mais il ne faut pas s'en priver.

Discussions similaires

  1. choix des valeurs dans une liste deroulante
    Par Banzai74 dans le forum VBA Access
    Réponses: 2
    Dernier message: 12/06/2008, 11h03
  2. Modification des valeurs d'une liste déroulante
    Par edogawa dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 29/01/2008, 20h12
  3. masquer des valeurs dans une liste deroulante
    Par titeZ dans le forum IHM
    Réponses: 15
    Dernier message: 09/08/2007, 15h07
  4. Réponses: 1
    Dernier message: 23/05/2007, 11h49
  5. [SQL] Problème de récupération des valeurs d'une liste multiple en php
    Par BOLARD dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 01/05/2006, 00h29

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