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 :

Débuggage de code


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de thierrybatlle
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2005
    Messages
    621
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2005
    Messages : 621
    Par défaut Débuggage de code
    Bonjour à tous,
    Cela fait plusieurs année que je ne code plus et je me suis lancé dans un petit programme en python, que je découvre, qui doit me permettre de saisir une valeur décimale, la convertir en binaire. Une fois converti j'ai un octet représenté par des LED qui vont être verte si la valeur est 1.

    Mon problème :
    Je n'arrive plus à débugger mon programme. J'ai les led qui ne s'affiche pas.
    J'ai 3 fichiers :
    - Un fichier "main.py" qui lance l'application.
    - Un fichier "ihm.py" qui contient mon IHM.
    - Un fichier "fonctions.py" qui contient des fonctions utilitaires.

    Voici mon code :
    Main.py
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    # coding : utf-8
     
    from ihm import *
     
    window = ihm()
    window.maFenetre.mainloop()
    ihm.py
    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
     
    # coding : utf-8
     
    import tkinter as tk
    import fonctions as fc
     
     
    class ihm :
     
        def __init__(self):
            # Création de la fenêtre
            self.maFenetre = tk.Tk()
            self.maFenetre.title("BINAIRE")
            self.maFenetre.geometry("800x300")
            self.maFenetre.minsize(480, 300)
            self.maFenetre.iconbitmap("images/binaire.ico")
     
            # Création d'un frame
            self.frame = tk.Frame(self.maFenetre)
     
            self.led(self)
            self.labelInfo(self)
            self.saiDecimal(self)
            self.labelResult(self)
            self.btn(self)
     
            self.affichage(self)
     
        def led(self, arg):
            # Ajout de ma led
            largeur = 60  # Largeur de la led
            hauteur = 60  # Hauteur de la led
            nbLed = 8  # Nombre de led
     
            # Initialisation du tableau de led
            elem = tuple({} for i in range(nbLed))
     
            # Création des leds
            for i in range(nbLed):
                elem[i]["led"] = tk.PhotoImage(file="images/led_green.png")
                elem[i]["canvas"] = tk.Canvas(self.frame, width=largeur, height=hauteur)
                elem[i]["canvas"].create_image(largeur / 2, hauteur / 2, image=elem[i]["led"])
                elem[i]["canvas"].grid(row=0, column=i)
            # for
     
        def labelInfo(self,arg):
            # Création d'un label
            labelDeci = tk.Label(self.frame, text="Votre valeur décimale : ")
            labelDeci.grid(row=2, column=0, columnspan=2)
     
        def saiDecimal(self,arg):
            # Création d'un champ de saisie
            valDeci = tk.Entry(self.frame)
            valDeci.grid(row=2, column=2, columnspan=2)
     
        def labelResult(self,arg):
            result = tk.Label(self.frame)
            result.grid(row=2, column=6)
     
        def btn(self,arg):
            # Création d'un bouton pour la convertion
            btnConvert = tk.Button(self.frame, text="Convertir", command=lambda: fc.controle(self.valDeci.get(), self.result))
            btnConvert.grid(row=2, column=4)
     
            # Création d'un bouton close
            btnClose = tk.Button(self.frame, text="Fermer", command=self.maFenetre.destroy)
            btnClose.grid(row=6, column=0)
     
        def affichage(self,arg):
            # Affichage de la frame
            print("Affichage")
            self.frame.pack()
            #self.mainloop()
    fonctions.py
    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
     
    # coding : utf-8
     
    class fonctions :
        def dec2bin(d,nb=0):
            """dec2bin(d,nb=0): conversion nombre entier positif ou nul -> chaîne binaire (si nb>0, complète à gauche par des zéros)"""
            if d == 0:
                b = "0"
            else:
                b = ""
                while d != 0:
                    # d&1 correspondant à d%2 ou d modulo 2 (= reste de la division entière par 2)
                    # "01"[0] donne "0"
                    # "01"[1] donne "1"
                    b = "01"[d & 1]+b
                    # d>>1 correspond à d//2 (= division entière par 2)
                    d = d >> 1
                    # b.zfill(nb) complète b de 0 à gauche afin d'avoir la chaîne à la longueur demandée
                return b.zfill(nb)
     
     
        def convertir(nb, sai_result):
            print(nb)
            try:
                binaire = fonctions.dec2bin(int(nb), 8)
                print(binaire)
                sai_result['text'] = binaire
                for i in range(8):
                    if int(binaire[i]) == 1:
                        print("Led verte")
                    else:
                        print("led rouge")
            except ValueError:
                print("La valeur saisie n'est pas convertible")
     
     
        def controle(nb, sai_result):
            if nb == "":
                print("Veuillez saisir une valeur")
            elif int(nb) > 255:
                print("Veuillez saisir une valeur entre 0 et 255")
            else:
                fonctions.convertir(nb, sai_result)

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    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 741
    Par défaut
    Salut,

    Pour trouver la cause d'un problème, il faut commencer par réduire le code. Ce qui commence par supprimer tout ce qui est sans rapport avec le problème.
    Le code réduit va vous permettre de mieux visualiser ce qu'il se passe vs. ce que vous attendiez qu'il se passe et vous poser des questions plus précises.

    Ceci dit, en lisant votre code en diagonale, il est probable que vous ayez omis de garder une référence à la liste elem.
    Ligne 36 écrivez:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            self.elem = elem = tuple({} for i in range(nbLed))
    çà devrait arranger des choses.

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

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

    J'ai essayé ton code mais il me manque le contenu du dossier "images"...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre éclairé Avatar de thierrybatlle
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2005
    Messages
    621
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2005
    Messages : 621
    Par défaut
    Bonjour,
    Voici un lien pour télécharger les images :

    https://drive.google.com/open?id=14r...FW5QfTBl2bilqI

    Merci.

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    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 832
    Billets dans le blog
    1
    Par défaut
    Ok, mis à part "binaire.ico" qui n'est pas reconnu, ça marche. J'ai donc commenté la ligne qui l'appelle.

    Bon, ton code ne s'exécute pas. Or quand tu dis "j'ai des leds qui ne s'allument pas" ça sous-entend une exécution. Alors erreur de version ou autre ?

    Donc comme l'a dit wiztricks, tous tes attributs de "ihm" n'en sont pas. Si par exemple dans la méthode "btn()" (ligne 59) tu utilises "self.result", il te faut alors créer ce "self.result" quelque part. Très certainement dans "labelResult()" 3 lignes plus haut.
    Parce que si, dans "labelResult()", tu remplis juste "result", alors cette variable locale est perdue quand la méthode se termine. Et ensuite quand la méthode "btn()" est appelée, le programme plante en tentant de traiter un attribut "self.result" inexistant.
    Et pareil pour "self.valDeci"

    Ensuite ton module "fonctions.py" pour regrouper les fonctions de travail c'est bien mais pourquoi les sous-regrouper dans un "objet" fonction ???
    Le souci c'est qu'avec ton import import fonctions as fc alors tu n'as pas accès aux méthodes "dec2bin()", "convertir()" etc. car tu ne vois que l'objet de premier niveau "fonctions". Ce qui t'oblige alors passer par "fonctions.dec2bin()", "fonctions.convertir()" etc. pour appeler ces méthodes.
    Donc si tu veux importer l'objet "fonctions" du module "fonctions.py" tu dois l'écrire ainsi: from fonctions import fonctions as fc.

    Mais le second souci c'est que ces méthodes "dec2bin()", "convertir()" etc étant des méthodes d'instance, tu dois instancier un objet "fonctions" pour pouvoir les appeler depuis cet objet. Et elles doivent toutes déclarer un premier paramètre "self".
    Ou alors tu leur rajoutes à toutes le sucre @staticmethod juste au dessus de la définition (sur la ligne juste au dessus) pour en faire des méthodes statiques (donc appelables sans instance).

    Ou alors tu simplifies tout et tu sors ces méthodes de cet objet idiot qui peut alors disparaitre. Tes méthodes "dec2bin()", "convertir()" etc deviennent alors de simples fonctions écrites telles quelles dans le module "fonctions.py" que tu peux ensuite importer pour les utiliser comme de simples fonctions et non plus comme des méthodes. Dans ce cas ton premier import est bon et tu n'as pas à leur rajouter @staticmethod au dessus.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    En plus de tout ce qu'on peut faire comme actions de mise au point basées sur l'exécution, on peut utiliser un "analyseur de code" comme pylint. Celui-ci analyse le code et peut détecter même des erreurs qui n'empêche pas l'exécution mais qui empêche que le programme fasse ce qu'il doit faire.

    Pour l'installer: https://pypi.org/project/pylint/

    Sa doc: http://pylint.pycqa.org/en/latest/. Pour avoir les options principales en console: "pylint --help". Pour en avoir plus: "pylint --full-documentation".

    Il a aussi l'avantage de signaler les anomalies de codage par rapport aux "bonnes pratiques" (https://www.python.org/dev/peps/pep-0008/)

    On peut lui faire analyser un fichier Python seul, mais aussi un package composé de plusieurs fichiers en citant son répertoire (avec les "__init__.py" même vides à chaque niveau).

    Pour analyser un fichier en se concentrant sur les alertes et erreurs (donc sans les "bonnes pratiques"):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pylint --disable=R,C monfichier.py
    Il y a beaucoup de possibilités de paramétrage. Avec un peu de pratique, on arrive à la liste d'options qui va bien par rapport à ce qu'on cherche. On peut gérer un fichier de configuration (sous Windows: "C:\Users\utilisateur\.pylintgui\pylintrc") et l'appeler pour éviter de ré-écrire à chaque appel toutes les options qu'on veut.

    pylint peut faire gagner beaucoup de temps dans la mise au point d'un programme.

Discussions similaires

  1. Réponses: 1
    Dernier message: 12/10/2015, 11h40
  2. débuggage de code pour validation de formulaire
    Par Cassandra Nova dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 11/05/2010, 03h16
  3. De la rapidité du code
    Par jfloviou dans le forum Contribuez
    Réponses: 233
    Dernier message: 29/05/2009, 02h17
  4. Explorateur de code C
    Par Zero dans le forum C
    Réponses: 14
    Dernier message: 06/06/2002, 09h41
  5. OmniORB : code sous Windows et Linux
    Par debug dans le forum CORBA
    Réponses: 2
    Dernier message: 30/04/2002, 17h45

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