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 :

Une boucle sans fin ?


Sujet :

Python

  1. #1
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut Une boucle sans fin ?
    Bonjour ,

    Un petit problème de boucle qui ne finit pas....et j'ignore pourquoi.

    Je ne vais pas vous mettre tout le code, juste les def qui sont concernées (pour info, c'est l'histoire d'un robot symbolisé par un "X" qui doit apparaître aléatoirement sur ma carte, qui est dans un fichier txt et que je charge dans ma variable self.labyrinthe) :
    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
    def robot(self) :
            """Place le robot sur la carte, de manière aléatoire"""
            if len(self.labyrinthe) > 1 :
                limit_maxi = len(self.labyrinthe)-1
                x_aleat = randint(1,limit_maxi)
                y_aleat = randint(1,limit_maxi)
                position_aleat = self.labyrinthe[x_aleat][y_aleat]
     
                while "X" not in self.labyrinthe :
                    if position_aleat == " " :
                        position_aleat = "X"
                    else :
                        x_aleat = randint(1,limit_maxi)
                        y_aleat = randint(1,limit_maxi)
     
     
        def chargement(self) :
            """Récupère la carte choisie par l'utilisateur, et la transfère dans
    une liste des lignes de la carte"""
            with open(self.path +'/'+ self.nom,'r') as fichier :
                self.labyrinthe = []
                while 1 :
                    ligne = fichier.readline()
                    if ligne == '' :
                        break
                    else :
                        ligne = list(ligne)                                 
                    self.labyrinthe.append(ligne)
     
            # j'ajoute le robot :
            self.robot()
     
     
        def generation_aleatoire(self) :
            """Génère automatiquement des cartes aléatoires, sans garantir que le
    labyrinthe sera 'faisable'"""
            elts_laby = [' ','O','.',' ']
            self.labyrinthe = []
     
            # création de 15 listes de symboles aléatoires   
            for _ in range(15):
                line = []
                for _ in range(15):
                    line.append(choice(elts_laby))
                self.labyrinthe.append(line)
     
            for ligne in self.labyrinthe :
                ligne.append('\n')
     
            # ensuite remplacement des symboles entourant le labyrinthe par
            # des 'o' pour qu'il soit "fermé"
            self.labyrinthe[0] = ['O']*15
            self.labyrinthe[0].append('\n')
     
            self.labyrinthe[14] = ['O']*15
            self.labyrinthe[14].append('\n')
     
            i = 0
            while i <= 14 :
                self.labyrinthe[i][14] = 'O'
                self.labyrinthe[i][0] = 'O'
                i += 1
     
            # + la sortie + le robot : 
            self.labyrinthe[12][14] = 'U'
            self.robot()
    Faites pas gaffe si c'est moche, c'est un code qui a quelques...jours au moins (peut-être même quelques semaines)

    Le problème c'est que je ne sais pas où est le truc qui cloche, celui qui boucle à l’infini. Je suppose que c'est dans mon self.robot() mais je suis même pas sûre, et si oui je me demande bien pourquoi.

    Vos idées (et votre patience pour comprendre le code ) sont les bienvenus

  2. #2
    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
    Salut,

    Citation Envoyé par RowanMayfair Voir le message
    Je suppose que c'est dans mon self.robot() mais je suis même pas sûre, et si oui je me demande bien pourquoi.
    Chaque fois que vous écrivez une boucle while, vous devez vous poser la question de savoir à quelle condition çà va bien pouvoir se terminer.

    Et quand vous lisez:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
                while "X" not in self.labyrinthe :
                    if position_aleat == " " :
                        position_aleat = "X"
                    else :
                        x_aleat = randint(1,limit_maxi)
                        y_aleat = randint(1,limit_maxi)
    il est clair çà ne sort que si "X" not in self.labyrinthe devient vraie.
    Pour çà, il faudrait que l'objet self.labyrinthe soit mis à jour à l'intérieur de la boucle...

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

  3. #3
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    je ne sais pas comment mettre à jour l'objet à l'intérieur de ma boucle.
    Enfin déjà je sais où est le problème, c'est déjà ça.
    Donc si on part sur un truc plus simple (pour m'éviter d'exécuter mon programme toutes les 2 minutes ), le problème est là en effet :
    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
    liste = [[1,2,5],[5,9,4],[4,5,3]]
     
     
     
    while 1 :
        for ligne in liste :
            if liste[1][0] == 5 :
                liste[1][0] = 10
                print(liste)
                break
            elif liste[1][0] == 10 :
                print(liste)
                break
            else :
                print("GRRRRRRRR")
                print(liste)
    Même en mettant des break partout, ça ne fonctionne pas
    J'en ait rêvé cette nuit de cette histoire

  4. #4
    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
    Salut,

    Citation Envoyé par RowanMayfair Voir le message
    je ne sais pas comment mettre à jour l'objet à l'intérieur de ma boucle.
    Si vous ne comprenez plus le code que vous avez écrit, il faut revenir au pourquoi vous l'avez écrit.

    Je ne sais pas trop quelle était votre intention de départ mais quand je lis "Place le robot sur la carte, de manière aléatoire"... J'imagine (peut être à tord) qu'on va chercher une case (i, j) libre pour y placer un 'X' représentant le robot.

    Donc les itérations devraient se faire sur le tirage aléatoire de (i, j) et la condition de sortie de la boucle pourrait être case(i, j) libre pour sortir de la boucle et placer le 'X' dans cette case.

    Puisétant "rigoureux", je me poserai la question de savoir s'il y a assez de cases libres pour qu'on puisse en trouver une rapidement de cette façon là: plus de case libre, çà va encore boucler.

    Pour éviter çà, il faut "borner" le nombre de tirages (essayer au plus N fois ou sortir en erreur) ou trouver les indices de toutes les cases libres (histoire de savoir qu'il en existe) et en choisir une au hasard.

    Tout çà pour dire qu'il faut un peu réfléchir à ce qu'on veut faire avant de coder et anticiper un peu les conséquences de ses choix dans des cas particuliers. Puis si çà ne fonctionne pas, il faut réfléchir encore car si ce n'est pas une faute de frappe, c'est qu'on est passé à côté de... i.e. faire travailler son cerveau avant de coder.

    Citation Envoyé par RowanMayfair Voir le message
    Même en mettant des break partout, ça ne fonctionne pas
    J'en ait rêvé cette nuit de cette histoire
    Si l'intention est de remplacer la valeur de la case (1, 0) par 10 si elle vaut 5... je ne vois pas l'intérêt de faire une boucle "for" en encore moins de l'encapsuler dans un "while True".

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

  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
    Bonjour

    Citation Envoyé par RowanMayfair Voir le message
    Donc si on part sur un truc plus simple (pour m'éviter d'exécuter mon programme toutes les 2 minutes ), le problème est là en effet :
    D'autant plus que d'écrire for ligne in liste puis faire tout un traitement qui n'utilise absolument pas la variable "ligne" revient un petit peu à la même remarque à propos du while(condition) avec tout un traitement qui ne modifie jamais ladite condition...

    Citation Envoyé par RowanMayfair Voir le message
    Même en mettant des break partout, ça ne fonctionne pas
    Ben là encore c'est presque pareil: une boucle où tous les différents traitements internes finissent tous par un break n'a alors aucune raison d'exister.

    Citation Envoyé par RowanMayfair Voir le message
    je ne sais pas comment mettre à jour l'objet à l'intérieur de ma boucle.
    A mon avis, ça devrait fortement ressembler à un truc du genre self.labyrinthe[x_aleat][y_aleat]="X". La vraie question c'est surtout "pourquoi faire une boucle". On veut placer un "X" on le place point. On n'écrit pas tant que "X" non placé parce qu'étant placé à la première itération, la boucle ne bouclera plus.
    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
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    Normalement, il y a toujours des cases libres. En tout cas dans les cartes déjà enregistrées, et celles qui se créent aléatoirement ce serait bien extraordinaire s'il n'y avait pas d'espaces (elles sont créées à partir d'une liste dont la moitié des éléments sont des espaces). Mais je devrait quand même prévoir le cas.

    Bref je vais donc essayer de faire l'inverse en effet, je n'y avait pas pensé : parcourir le labyrinthe, en créant des listes avec les indices des endroits où se trouvent les espaces. Je vais tenter comme ça, ce sera en effet déjà un peu moins lourd.

    Edit : pour vous donner une idée, voici une carte générée aléatoirement :
    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
    OOOOOOOOOOOOOOO
    O..O O OO  O.OO
    O   ..OO .O OOO
    O  ..OO O    OO
    O... OO.OO  . O
    OO. ..O  O. OOO
    O .. .. O.   .O
    O O.    O.   .O
    O .  ..   . ..O
    O  . OO .O . OO
    O   O . OO  . O
    O    OO.  O OOO
    O O    .      U
    O     OO  O.O.O
    OOOOOOOOOOOOOOO

  7. #7
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    Une question : est-ce qu'il est possible d'utiliser random.choice (ou une autre méthode du module random) sur les clés d'un dictionnaire ?

    Parce que, par exemple, ce lien me dit que oui : https://www.science-emergence.com/Ar...e-sous-python/
    Mais mon Python à moi, il s'obstine à me dire que non, parce que, je le cite :
    TypeError: 'dict_keys' object is not subscriptable
    Qui a raison ?
    Le lien que j'ai trouvé semble plutôt récent (2017) mais est-ce vraiment du Python 3 ? (c'est pénible ça....les gens précisent rarement )

  8. #8
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    je vous mets ma solution (qui fonctionne !!! ) :
    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
    libre = {}
     
            for ligne in self.labyrinthe :
                for idx,elt in enumerate(ligne) :
                    if elt == ' ' :
                        cle = self.labyrinthe.index(ligne)
                        libre.setdefault(cle,[]).append(idx)
     
            x = randrange(1,len(libre)-1)
     
            while x not in libre.keys() :
                x = randrange(1,len(libre)-1)
     
            y = choice(libre[x])
     
            self.labyrinthe[x][y] = "X"
    donc finalement j'ai stocké mes espaces libres dans un dictionnaire. J'ai pas vraiment trouvé mieux. Mais du coup faire de l'aléatoire sur les clés dudit dictionnaire, c'est pas si simple. Enfin dans ce cas, ça nécessite une boucle pour vérifier si le nombre tiré au hasard par randrange est bien une clé, c'est à dire l'indice d'une ligne qui contient un/des espaces.

    Bref.
    Si vous voulez critiquer, que vous pensez qu'il y avait mieux, plus efficace, plus court, toussa.....n'hésitez pas

    Edit : le setdefault(), j'ai pas oublié il est imprimé dans mon petit cerveau

  9. #9
    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 RowanMayfair Voir le message
    Qui a raison ?
    Le lien que j'ai trouvé semble plutôt récent (2017) mais est-ce vraiment du Python 3 ? (c'est pénible ça....les gens précisent rarement )
    Ta doc est probablement du Python2. Et à l'époque P2, dict.keys() retournait une liste qui était alors utilisable dans random.choice() (précisément parce qu'une liste est indiçable et que c'est la base du choix).

    Aujourd'hui, dict.keys() de P3 retourne un type appelé "dict_keys()" qui est "tout comme une liste" sauf que ce n'est pas indiçable (pas possible de demander par exemple dict.keys()[3]) donc non, tu ne peux plus passer dict.keys() à random.choice() (tout comme tu ne peux pas lui passer un ensemble, un générateur ou autres trucs exotiques non indiçables).

    Toutefois rien ne t'interdit de transformer un "dict_keys" en truc indiçable (comme une liste ou un tuple) puis de passer ce truc à random.choice() => random.choice(tuple(dict.keys()))...

    Citation Envoyé par RowanMayfair Voir le message
    Si vous voulez critiquer, que vous pensez qu'il y avait mieux, plus efficace, plus court, toussa.....n'hésitez pas
    Ben déjà juste question "groupement" j'aurais écrit
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
            x = randrange(1,len(libre)-1)
            while x not in libre.keys() :
                x = randrange(1,len(libre)-1)
    sans ligne vide (j'ai l'habitude d'écrire ensemble les trucs qui forment un "tout" logique"). Donc l'initialisation, le test et la réinitialisation si le test ne convient pas forment pour moi un "tout" qui est "trouver un espace libre".

    Mais comme en plus je n'aime pas répéter deux fois des instructions qui ne font qu'une action, moi j'aurais alors écrit ça de cette façon
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
            while True:
                x = randrange(1,len(libre)-1)
                if x in libre.keys() : break
    Pour le reste il faudrait mieux regarder...
    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]

  10. #10
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    on a posté en même temps

    mais oui c'est beau avec un tuple.
    donc finalement ça donne ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    libre = {}
     
            for ligne in self.labyrinthe :
                for idx,elt in enumerate(ligne) :
                    if elt == ' ' :
                        cle = self.labyrinthe.index(ligne)
                        libre.setdefault(cle,[]).append(idx)
     
            x = choice(tuple(libre.keys()))
     
            y = choice(libre[x])
     
            self.labyrinthe[x][y] = "X"

  11. #11
    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
    Salut,

    Citation Envoyé par RowanMayfair Voir le message
    Si vous voulez critiquer, que vous pensez qu'il y avait mieux, plus efficace, plus court, toussa.....n'hésitez pas
    Je ne comprends par trop l'intérêt de passer par un dictionnaire et une liste pour stocker la liste des index des cases vides.
    Plus simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    length = len(self.labyrinthe)
    cases_vides = []
    for i in range(length) 
          for j in range(length) 
               if self.labyrinthe[i][j] == ' ':
                   cases_vides.append((i, j))
    puis on choisi un (i, j):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    i, j = random.choice(cases_vides)
    et on le rend occupé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.labyrinthe[i][j] = 'X'
    note: et on a pris la peine de s'assurer que random.choice d'une liste vide plante.

    Après si on est a peu près sûr que le tableau est rempli à moitié de cases vides, on peut essayer un nombre de fois "petit":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    length = len(self.labyrinthe)
    for _ in range(length):
        i, j = random.randint(1, length), random.randint(1, length)
        if self.labyrinthe[i][j] == '  ':
             break
    else:
        raise Exception('fatal, pas de case vides')
    self.labyrinthe[i][j] = 'X'
    histoire de réviser un peu la construction for...else... bien utile parfois.

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

  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 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Je ne comprends par trop l'intérêt de passer par un dictionnaire
    A mon avis, il voulait absolument placer un setdefault()

    Citation Envoyé par wiztricks Voir le message
    Plus simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    length = len(self.labyrinthe)
    cases_vides = []
    for i in range(length) 
          for j in range(length) 
               if self.labyrinthe[i][j] == ' ':
                   cases_vides.append((i, j))
    Et si on veut réviser un peu les listes en intension: cases_vides=tuple((i, j) for i in range(length) for j in range(length) if self.labyrinthe[i][j] == ' ').

    On peut alors passer l'étape "cases_vides=" et écrire directement (i, j)=random.choice(tuple((i, j) for i in range(length) for j in range(length) if self.labyrinthe[i][j] == ' ')) (j'ai aussi essayé de passer l'étape "(i, j)=" mais je n'y suis pas arrivé )

    Citation Envoyé par RowanMayfair Voir le message
    Si vous voulez critiquer, que vous pensez qu'il y avait mieux, plus efficace, plus court, toussa.....n'hésitez pas
    Ben tu pourrais ne plus te caler sur "ce qui s'affiche" mais sur "ce qui est géré en interne".
    Explications: tu utilises des éléments d'affichage ("X", cases vides) pour gérer tes actions (une case vide c'est une case qui contient " "). Mais ce sont justement des éléments d'affichage, pas des éléments de calculs. Et si demain tu veux remplacer "X" par "x" parce que ça fait plus joli ?
    Tu pourrais utiliser des booléens (True/False) pour gérer tes cases vides/remplies ce qui serait plus rapide (il est plus rapide de tester un booléen qu'une chaine). Ou alors des nombres (0=vide, 1=robot, 2=joueur, etc).
    Ca te permettrait alors de rendre ton jeu plus modulable (offrir au joueur la possibilité de choisir la forme de ses pions) sans rien changer aux calculs. Et toi, tu adaptes juste les valeurs internes aux pions du joueur lors de l'affichage écran.

    C'est une façon de faire qui se rapproche de la notion de MVC (Modèle, Vue, Controleur).
    Ca permet de dissocier dans de gros projets tout ce qui est datas (modèle), saisie/affichage (vue) et calculs (Contrôleur). Ainsi on peut passer assez facilement d'une vue X à une vue Y (on change la librairie graphique) sans toucher aux calculs. De même on peut stocker les données dans des fichiers aujourd'hui et dans une bdd demain sans toucher au reste.
    Bref c'est un bon exercice...
    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 é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 Sve@r Voir le message
    Ben tu pourrais ne plus te caler sur "ce qui s'affiche" mais sur "ce qui est géré en interne".
    Explications: tu utilises des éléments d'affichage ("X", cases vides) pour gérer tes actions (une case vide c'est une case qui contient " "). Mais ce sont justement des éléments d'affichage, pas des éléments de calculs.
    Le PO a posté a quoi ressemble un fichier labyrinthe dans cette réponse.
    L'utilisateur peut visualiser le labyrinthe avec more ou cat et le modifier avec un simple éditeur. Et si cette chose là est une exigence fonctionnelle, coder ces informations en 1234 ou encore la compresser ne permettra plus cela.

    Citation Envoyé par Sve@r Voir le message
    Ca te permettrait alors de rendre ton jeu plus modulable (offrir au joueur la possibilité de choisir la forme de ses pions) sans rien changer aux calculs. Et toi, tu adaptes juste les valeurs internes aux pions du joueur lors de l'affichage écran.
    Que le pion soit codé X ou 4 dans le fichier n'empêche pas de l'afficher comme on veut.

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

  14. #14
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,



    Je ne comprends par trop l'intérêt de passer par un dictionnaire et une liste pour stocker la liste des index des cases vides.
    Plus simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    length = len(self.labyrinthe)
    cases_vides = []
    for i in range(length) 
          for j in range(length) 
               if self.labyrinthe[i][j] == ' ':
                   cases_vides.append((i, j))
    (...)
    - W
    Oui mais là, dans la liste cases_vides, j'ai.....des ' '. Alors que je cherche les index de ces cases. Le n° de ligne associé à mon n° de case.
    Et je n'ai pas trouvé comment obtenir ça avec des listes dans des listes. Parce que je connais la méthode liste.index(), mais ça me renvoie uniquement le 1er index trouvé sur la ligne, pas tous les index. Bref, c'est peut-être possible, mais je ne sais pas comment.
    Alors que je sais qu'avec un dictionnaire, je peux stocker en clé l'index de la ligne, et en valeurs les index de toutes les cases vides sur cette ligne.

    Citation Envoyé par Sve@r
    A mon avis, il voulait absolument placer un setdefault()
    En fait, c'est elle.
    Je sais. Une femme (plus toute jeune en +), qui a la prétention de vouloir utiliser son cerveau, c'est stupéfiant .
    Je vais prendre 5 minutes pour aller trouver et mettre un avatar qui évitera les confusions.

  15. #15
    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
    Salut,

    Citation Envoyé par RowanMayfair Voir le message
    Oui mais là, dans la liste cases_vides, j'ai.....des ' '. Alors que je cherche les index de ces cases. Le n° de ligne associé à mon n° de case.
    Si cases_vides démarre à liste vide et qu'on y ajoute des tuples (i, j), impossible d'y retrouver des ' ' et ce juste à cause de cases_vides.append((i, j))...

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

  16. #16
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    Ah mais oui
    En effet, j'ai pas pensé à cette solution pourtant simple...je vais tester ça, dans une liste il est plus facile d'utiliser random.

  17. #17
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,



    Si cases_vides démarre à liste vide et qu'on y ajoute des tuples (i, j), impossible d'y retrouver des ' ' et ce juste à cause de cases_vides.append((i, j))...

    - W
    ah ah
    en le faisant je me souviens que j'avais essayé, un peu désespérément, de faire comme ça au départ.
    Mais j'avais fait un truc du genre cases_vides.append(i,j)
    donc, fatalement, Python m'a envoyé boulée avec ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TypeError: append() takes exactly one argument (2 given)
    Du coup j'ai fait un dictionnaire.
    Alors qu'il suffisait, en effet, de mettre 2 parenthèses autour de (i,j) pour qu'il accepte de le prendre comme un seul argument

    Je me coucherai encore moins bête ce soir

    Merci

  18. #18
    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 wiztricks Voir le message
    Le PO a posté a quoi ressemble un fichier labyrinthe dans cette réponse.
    L'utilisateur peut visualiser le labyrinthe avec more ou cat et le modifier avec un simple éditeur. Et si cette chose là est une exigence fonctionnelle, coder ces informations en 1234 ou encore la compresser ne permettra plus cela.
    Le MVC peut s'appliquer aussi bien pour des données sortantes que des données entrantes. Aujourd'hui son fichier c'est "OOOOOOOOO" pour les murs mais peut-être que le truc pourrait s'adapter à un fichier qui contiendrait "-----------". Et en interne ce serait toujours codé de la même façon.
    Et puis c'est un programme qui a quand-même un arrière goût de TP ça. Et c'est bien justement les TP. Ca permet de s'entrainer à des technologies pas forcément nécessaires ici mais qui pourraient l'être plus tard. J'ai quand-même précisé "c'est un bon exercice" dans mon post...

    Citation Envoyé par wiztricks Voir le message
    Que le pion soit codé X ou 4 dans le fichier n'empêche pas de l'afficher comme on veut.
    Oui. Mais je ne parlais pas du pion codé dans le fichier mais codé en interne (dans la partie "Controleur" donc). J'ai pas fait de tests avec timeit() mais intuitivement, et vu comment j'imagine ce que donnera la traduction Python en code machine, j'ai l'impression que comparer un truc avec int(4) sera plus rapide que le comparer avec str("X")...

    Citation Envoyé par RowanMayfair Voir le message
    Alors qu'il suffisait, en effet, de mettre 2 parenthèses autour de (i,j) pour qu'il accepte de le prendre comme un seul argument
    En fait c'est dû à la façon qu'a Python d'identifier un tuple.
    A la base, un tuple c'est plusieurs items ("plusieurs" pouvant tout de même aller jusqu'à 0) séparés par une virgule => ex tp=1, 2, 3. Il faut bien noter que c'est la virgule qui fait le tuple et non les parenthèses (même si l'affichage d'un tuple se fait avec des parenthèses). Ainsi tp=1, sera un tuple avec un seul élément tandis que tp=(1) sera un simple int. Mais tp=() sera un tuple vide (vas t'y retrouver avec ça !!!)

    Le souci se pose quand on veut passer un tuple à une fonction. Si on lui passe le tuple dans sa plus simple expression (ex fct(1, 2, 3) on tombe dans l'écriture classique d'un appel de fonction avec 3 arguments. Et si la fonction n'est prévue que pour en recevoir qu'un seul, Python ne s'y retrouve plus et lève une exception.
    Donc il conviendra d'encadrer le tuple de parenthèses pour bien signifier "un truc". Et comme la fonction a aussi des parenthèses, on se retrouve avec un doublé => fct((1, 2, 3)).

    Donc quand on manipule des tuples, parfois les parenthèses ne sont pas nécessaires, parfois elles le sont. Pour ma part j'ai donc fait le choix de toujours les mettre => tp=(1, 2, 3).

    A noter que ce souci se pose aussi avec les listes mais d'un autre point de vue. Une liste c'est un truc entre crochets. Ainsi tp=(1) sera un simple int mais li=[1] sera une liste. Donc là c'est un peu pareil, la virgule est parfois obligatoire (tp=(1,)) et parfois ne l'est pas (li=[1]). J'ai donc là aussi fait le choix de toujours la mettre => tp=(1,); li[1,]. Ce qui me permet si nécessaire de reprendre assez facilement un code si j'ai utilisé une liste là où un simple tuple aurait suffit (et inversement).
    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]

  19. #19
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    Oh merci pour toutes ces explications ! en effet, j'avais cru m'apercevoir que selon les circonstances, on est pas obligés de rédiger un tuple de la même façon. Et c'est pas évident parfois !

    Et, en effet il s'agit d'un TP.
    Je l'ai fait il y a quelques semaines, à ce moment là j'avais déjà été un petit peu plus loin que ce qui était demandé puisque j'offre la possibilité à l'utilisateur de générer une carte aléatoire. Histoire que le joueur ait un peu de variété sans avoir à s'embêter de créer lui-même un labyrinthe.

    Or là c'est un autre TP, ou il faut améliorer le 1er.
    Et les améliorations demandées sont déjà très compliquées (là j'ai fait le plus facile ), je ne suis déjà pas certaine de réussir à aller au bout cette fois.
    Donc là tout de suite, je vais me contenter d'essayer de fournir ce qui est demandé. Ensuite....on verra.

    Edit : en plus je débute (vraiment) donc là les temps "machine"...euh...c'est pas encore mon problème

Discussions similaires

  1. Réponses: 4
    Dernier message: 02/11/2009, 16h22
  2. [Débutant]Boucle sans fin : Wend non reconnu
    Par SebHoule dans le forum IHM
    Réponses: 5
    Dernier message: 12/06/2006, 16h49
  3. C : utilisation de getopt - il boucle sans fin...
    Par moussmouss dans le forum C
    Réponses: 14
    Dernier message: 21/12/2005, 11h35
  4. Boucle sans fin : danger pour le serveur ?
    Par Rémiz dans le forum Langage
    Réponses: 4
    Dernier message: 09/12/2005, 16h52
  5. [SQL SERVER 2000] Fonction utilisateur : boucle sans fin
    Par galinijay dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 30/09/2005, 16h03

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