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 :

reduction d'un mur de "if"


Sujet :

Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2023
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Octobre 2023
    Messages : 25
    Points : 13
    Points
    13
    Par défaut reduction d'un mur de "if"
    Bonjour j'ai eu un projet a rendre dans le quel j'ai faire un long mur de if qui est très moche et étant encore débutant j'aimerais des conseils pour réduire cette horreur qui est obligatoirement (a moins de changer tout le programme) dans la fonction "choix_promo" qui ne prend en argument que "event" qui donne les coordonnées de la souris. Pour être bref dans la description ce ce morceau du code d'un jeu d'échecs sous tkinter, il recupere via les variables globales des noms d'images qui sont toutes supprimées lors du choix de la promotion du pion et les lignes "DraggalbleImage(...)" remplacent le pion qui a été promu par le pion qu'on a choisi.
    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
    def choix_promo(event):
        global choix_promotion, pion_promu, promo_dame_n, promo_fou_n, promo_cava_n, promo_tour_n, promo_dame_b, promo_fou_b, promo_cava_b, promo_tour_b
        if 560 < event.y <= 640:
            c_echecs.delete(promo_dame_n)
            c_echecs.delete(promo_fou_n)
            c_echecs.delete(promo_cava_n)
            c_echecs.delete(promo_tour_n)
            c_echecs.delete(pion_promu[0])
            DraggableImage(c_echecs, dame_n1, pion_promu[1], pion_promu[2], 80 + (pion_promu[2] * 80), 40 + (pion_promu[1] * 80), "dame", "noir")
            plateau[pion_promu[1]][pion_promu[2]] = "dame_n"
        elif 480 < event.y <= 560:
            c_echecs.delete(promo_dame_n)
            c_echecs.delete(promo_fou_n)
            c_echecs.delete(promo_cava_n)
            c_echecs.delete(promo_tour_n)
            c_echecs.delete(pion_promu[0])
            DraggableImage(c_echecs, fou_n1, pion_promu[1], pion_promu[2], 80 + (pion_promu[2] * 80), 40 + (pion_promu[1] * 80), "fou", "noir")
            plateau[pion_promu[1]][pion_promu[2]] = "fou_n"
        elif 400 < event.y <= 480:
            c_echecs.delete(promo_dame_n)
            c_echecs.delete(promo_fou_n)
            c_echecs.delete(promo_cava_n)
            c_echecs.delete(promo_tour_n)
            c_echecs.delete(pion_promu[0])
            DraggableImage(c_echecs, cava_n1, pion_promu[1], pion_promu[2], 80 + (pion_promu[2] * 80), 40 + (pion_promu[1] * 80), "cava", "noir")
            plateau[pion_promu[1]][pion_promu[2]] = "cava_n"
        elif 320 < event.y <= 400:
            c_echecs.delete(promo_dame_n)
            c_echecs.delete(promo_fou_n)
            c_echecs.delete(promo_cava_n)
            c_echecs.delete(promo_tour_n)
            c_echecs.delete(pion_promu[0])
            DraggableImage(c_echecs, tour_n1, pion_promu[1], pion_promu[2], 80 + (pion_promu[2] * 80), 40 + (pion_promu[1] * 80), "tour", "noir")
            plateau[pion_promu[1]][pion_promu[2]] -= "tour_n"
     
        elif 240 < event.y <= 320:
            c_echecs.delete(promo_dame_b)
            c_echecs.delete(promo_fou_b)
            c_echecs.delete(promo_cava_b)
            c_echecs.delete(promo_tour_b)
            c_echecs.delete(pion_promu[0])
            DraggableImage(c_echecs, tour_b1, pion_promu[1], pion_promu[2], 80 + (pion_promu[2] * 80), 40 + (pion_promu[1] * 80), "tour", "blanc")
            plateau[pion_promu[1]][pion_promu[2]] = "tour_b"
        elif 160 < event.y <= 240:
            c_echecs.delete(promo_dame_b)
            c_echecs.delete(promo_fou_b)
            c_echecs.delete(promo_cava_b)
            c_echecs.delete(promo_tour_b)
            c_echecs.delete(pion_promu[0])
            DraggableImage(c_echecs, cava_b1, pion_promu[1], pion_promu[2], 80 + (pion_promu[2] * 80), 40 + (pion_promu[1] * 80), "cava", "blanc")
            plateau[pion_promu[1]][pion_promu[2]] = "cava_b"
        elif 80 < event.y <= 160:
            c_echecs.delete(promo_dame_b)
            c_echecs.delete(promo_fou_b)
            c_echecs.delete(promo_cava_b)
            c_echecs.delete(promo_tour_b)
            c_echecs.delete(pion_promu[0])
            DraggableImage(c_echecs, fou_b1, pion_promu[1], pion_promu[2], 80 + (pion_promu[2] * 80), 40 + (pion_promu[1] * 80), "fou", "blanc")
            plateau[pion_promu[1]][pion_promu[2]] = "fou_b"
        elif event.y <= 80:
            c_echecs.delete(promo_dame_b)
            c_echecs.delete(promo_fou_b)
            c_echecs.delete(promo_cava_b)
            c_echecs.delete(promo_tour_b)
            c_echecs.delete(pion_promu[0])
            DraggableImage(c_echecs, dame_b1, pion_promu[1], pion_promu[2], 80 + (pion_promu[2] * 80), 40 + (pion_promu[1] * 80), "dame", "blanc")
            plateau[pion_promu[1]][pion_promu[2]] = "dame_b"

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

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

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 104
    Points : 4 454
    Points
    4 454
    Par défaut
    bonjour

    Ce ne sont pas les if qui me gêne mais les 7 lignes (identiques) qui suivent

    une façon de le réécrire pour éviter les répétitions pourrait être :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    BLANC, NOIR = "blanc", "noir"
    TOUR = "tour"    # et autres
     
    conditions = {    # ordre du + petit au + grand important
        80: {"dels":[promo_cava_n, promo_dame_n, a, b, c], "pion":TOUR, "color":BLANC},
        160: {"dels":[pion_promu[0], promo_fou_n, ], "pion":ROI, "color":NOIR},
        240: {"dels":[promo_fou_b, promo_dame_b, ], "pion":DAME, "color":BLANC},
    }
     
    valeurs = next(conditions[k] for k in conditions.keys() if event.y<= k)    # j'ai les valeurs suivant event.y
    for del in valeurs["dels"]:    # 5 trucs à supprimer
        c_echecs.delete(del)
    DraggableImage(..., valeurs["pion"], valeurs["color"])    #DraggableImage(..., "tour", "blanc")
    plateau[pion_promu[1]][pion_promu[2]] = valeurs["promu"]
    EDIT: Contrairement à Sve@r, je n'ai pas réfléchi au code (noms de variables) car je n'ai rien compris
    $moi= ( !== ) ? : ;

  3. #3
    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 Chipster_25 Voir le message
    et étant encore débutant j'aimerais des conseils pour réduire cette horreur
    C'est au début qu'il fallait demander des conseils sur comment partir. Ce long mur de "if" qui est effectivement ultra-moche c'est parce que tu as nommé tes variables "dame_n", "fou_b" et autres noms figé associé à leur contenu.
    Une variable doit représenter ce qu'elle gère, mais ne pas être du nom géré. Si par exemple je dois gérer le prix des prix des pommes, j'écrirai prix=10 mais sûrement pas pommes=10. Et si je dois gérer un élève prénommé "Hugo" j'écrirai eleve="Hugo" mais pas hugo="Hugo".

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    pieces={
    	"roi" : 20,
    	"dame" : 10,
    	"tour" : 5,
    	"cavalier" : 3,
    	"fou" : 3,
    	"pion" : 1,
    }
    Ainsi, tu peux gérer chaque pièce avec une simple chaine. Tu veux promouvoir un pion en cavalier tu écris case[x][y]="cavalier" et c'est fini.
    Et les couleurs blanches et noires c'est la même chose, une valeur 1/-1 ou ce que tu veux pourvu que ce soit utilisable directement. Le blanc joue => jeu=1. Le noir joue => jeu=-1. Mais le fonctionnement du jeu, lui, reste le même (la pièce [x] qui avance peut manger la pièce [-x]).

    Un code ça se construit sur des fondations. Si les fondations sont maladroites, tout le reste le sera.

    Citation Envoyé par Chipster_25 Voir le message
    il recupere via les variables globales des noms d'images qui sont toutes supprimées lors du choix de la promotion du pion
    C'est dans l'autre sens que ça marche. D'abord on gère le jeu de façon mathématique (chaque case est identifiée avec la pièce qu'elle contient, chaque mouvement de pièce modifie les valeurs des cases) et ensuite, quand tout est calculé, on affiche le dessin.

    Citation Envoyé par Chipster_25 Voir le message
    (a moins de changer tout le programme)
    Ce n'est pas forcément une mauvaise chose, et ça ne fait pas perdre autant de temps qu'on pourrait le croire.

    Citation Envoyé par papajoker Voir le message
    Ce ne sont pas les if qui me gêne mais les 7 lignes (identiques) qui suivent
    Moi aussi j'ai cru qu'elles étaient identiques mais en fait non. Sur l'une la variable c'est "dame_n", sur l'autre c'est "tour_n" et autres joyeusetés non factorisables.
    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
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 824
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

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

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

    Citation Envoyé par Chipster_25
    j'aimerais des conseils pour réduire cette horreur

    • Centraliser les informations relatives aux pièces et leurs conditions de promotion dans un dictionnaire, réduisant les redondances.
    • Créer une fonction supprimer_images_promotion() pour éviter la répétition du code de suppression des images de promotion.
    • Utiliser une boucle pour parcourir le dictionnaire des pièces et déterminer laquelle promouvoir en fonction de la position y de l'événement.


    Un exemple de début de dictionnaire,

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    type_pieces = {
        "dame_n": {"y_min": 560, "image": dame_n1, "type": "dame", "couleur": "noir"},
        "fou_n": {"y_min": 480, "image": fou_n1, "type": "fou", "couleur": "noir"},
        # suite ...

    Mais perso, je trouve que c'est un code qui reste très difficile à redresser... pas sûr qu'à votre niveau vous compreniez où l'on veut en venir mais on ne fera pas ce travail à votre place. Bon courage !
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  5. #5
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 057
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 057
    Points : 9 396
    Points
    9 396
    Par défaut
    Si on se limite à la question : comment éviter une succession de if ... elif ..., il y a la commande match case ( cf doc )

    Ici, pour notre valeur event.y ,on ne cherche pas à comparer à une liste de valeurs, mais à des intervalles. Galère.
    Je pensais à cette syntaxe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    match True :
       case 560 < event.y <= 640:
          ...
       case  480 < event.y <= 560: 
         ...
    Mais ça ne marche pas.
    Quelle est l'astuce pour ce type de cas ?
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 049
    Points : 1 380
    Points
    1 380
    Par défaut
    Un dictionnaire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    {expression : résultat, True:defaut}[valeur]

  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 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tbc92 Voir le message
    Mais ça ne marche pas.
    case if 560 < event.y <= 640...
    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 confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

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

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 104
    Points : 4 454
    Points
    4 454
    Par défaut
    remplacer 10 if par 10 case ne va rien changer

    Comme j'ai fait plus haut, dans ce cas il suffit de tester une seule borne du moment que l'on commence par la plus petite
    Cette stucture n'est clairement pas adaptée pour cela, mais si on désire vraiment un match/case pas génial :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    match y:
       case y if y <= 80:
           ...
       case y if y <= 120:
           ...
       case _:
           ...
    encore moins
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    match y:
       case y if y in range(0,80):
           ...
       case y if y in range(0,120):
           ...
       case _:
           ...
    A la limite (c'est ce que j'avais proposé : on boucle/cherche sur une structure ordonnée) :
    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
    def convert(y):
        return next(r[0] for r in (("gauche",80),("droite",120),("avant",sys.maxsize)) if y<=r[1])
        # ou intervalles non suivis
        return next(r[0] for r in (
            ("gauche",80,100),
            ("droite",120,160),
            ("error",-1,sys.maxsize)  # a la fin tous les cas possibles pour ne pas avoir d'Exception
        ) if r[1]<y<=r[2])
     
    match convert(y):
       case "droite":
           ...
       case "gauche":
           ...
       case _:
           ...
    $moi= ( !== ) ? : ;

  9. #9
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2023
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Octobre 2023
    Messages : 25
    Points : 13
    Points
    13
    Par défaut
    Merci pour tout vos retours, ils vont surement beaucoup m'aider même si j'ai plus trop le temps de les essayer pour l'instant je reviendrai surement la semaine prochaine si il me reste des questions.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Quote dans une requete...
    Par Isildur dans le forum Langage SQL
    Réponses: 6
    Dernier message: 20/06/2006, 10h57
  2. [xsl]simuler le mecanisme OO de "liaison dynamique"
    Par philemon_siclone dans le forum XSL/XSLT/XPATH
    Réponses: 10
    Dernier message: 19/12/2003, 11h34
  3. Problème de quote
    Par kennini dans le forum ASP
    Réponses: 4
    Dernier message: 20/11/2003, 09h40
  4. VARCHAR contenant une quote '
    Par tonyskn dans le forum Langage SQL
    Réponses: 2
    Dernier message: 29/05/2003, 19h21
  5. Quotes dans TFilenameEdit (RXLib)
    Par AnnSo dans le forum Composants VCL
    Réponses: 3
    Dernier message: 23/01/2003, 20h26

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