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 :

Optimisation du code pour définitions redondantes


Sujet :

Python

  1. #1
    Membre averti
    Homme Profil pro
    Astronome amateur
    Inscrit en
    Juillet 2016
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Astronome amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 63
    Par défaut Optimisation du code pour définitions redondantes
    Bonjour à tous

    J’ai une question concernant l’optimisation du code pour une petite application que j’ai développé en python.

    Cette application permet de piloter une carte relais connectée sur le port GPIO d’un Raspberry Pi. La physionomie de l’interface est évolutif en fonction du nombre de relais que comporte la carte connectée (4-8-12 ou 16). Il y a un bouton par relais et donc uniquement le nombre de boutons visibles en fonction de la carte utilisée.
    Chaque bouton peut avoir un libellé personnalisé via une fenêtre de paramètrage, dans laquelle on spécifie également la broche du port GPIO correspondant.

    Tous les paramètres sont sauvegardés dans un fichier pour être exploités à chaque utilisation de l’application.

    Tout fonctionne sans problème. Néanmoins, je trouve mon code assez basique et je souhaiterais l’améliorer, dans la mesure du possible.

    Dans l’interface, qui est construit via Tkinter, je positionne chaque bouton dans la fenêtre et je lui affecte une fonction qui va traiter le clic bouton.
    Vu que j’ai 16 boutons au maximum, j’appelle une définition par bouton :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Bout_Rel01 = Button(fenetre, text=Lib1[3:], width=Larg_Bouton, bg = Coul06, fg = Coul05, font=police, command = CommutRelais1)
    La définition appelée correspondante est la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    def CommutRelais1(): # Commutation du relais 1 - L'activation du relais s'effectue lorsque la broche GPIO est à l'état bas
    	EtatRelais = GPIO.input(GPIO_Rel01) # On teste l'état de la broche du GPIO alimentant le relais
    	if EtatRelais == 1: # Si la broche est à l'état haut (le relais n'est pas activé)
    		GPIO.output(GPIO_Rel01, 0) # On désactive la broche pour activer le relais
    		Bout_Rel01.configure(bg = Coul02, fg = Coul06) # On passe le fond de bouton en vert et le texte en gris foncé
    	else: # Si la broche est à l'état bas (désactivé)
    		GPIO.output(GPIO_Rel01, 1) # On active la broche pour désactiver le relais
    		Bout_Rel01.configure(bg = Coul06, fg = Coul05) # on passe le fond de bouton en gris foncé et le texte en gris clair
    J’ai donc 16 définitions, de CommutRelais1 à CommutRelais16 qui contiennent chacune les variables GPIO_Rel01 à GPIO_Rel016, Bout_Rel01 à Bout_Rel016.

    Comme dit plus haut, ça fonctionne, mais 16 définitions comme ça, je trouve que ce n'est pas terrible et je pense qu’il doit être possible d’optimiser ce code.

    Ma question est la suivante : y’a t’il une possibilité d’appeler une définition unique (ex : CommutRelais) pour l’ensemble des 16 boutons, et dans cette définition, de détecter quel est le bouton déclencheur de l’événement, puis de lancer les actions inhérentes à chaque bouton/relais ?

    Merci par avance pour vos propositions

    Jean-Pierre

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

    En fait, vous avez un tas de Button qui activent la même fonction modulo un paramètre à lui passer en fonction du Button.
    Un solution s'appelle fermeture/closure et est bien exposé dans ce tuto..

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

  3. #3
    Membre averti
    Homme Profil pro
    Astronome amateur
    Inscrit en
    Juillet 2016
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Astronome amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 63
    Par défaut
    Salut Wiztricks

    Merci pour la réponse. j'ai étudié ce auto qui répond en partie à mon besoin (la définition unique et identification de l'événement déclencheur). La première chose que je constate qu'il est possible de passer une variable par le biais d'un appel de fonction, y compris (c'est là, la nouveauté pour moi) dans la définition d'un bouton.

    Maintenant, il faut que je trouve comment programmer les actions induites.

    Pour la variable GPIO_Rel01 à GPIO_Rel16, je peux basculer sur un tableau GPIO_Rel(Num_Rel). Num_Rel étant le numéro du bouton identifié dans la nouvelle définition.

    Par contre, pour modifier l'état visuel du bouton concerné (Bout_Rel01.configure(bg = Coul02, fg = Coul06)), comment puis-je définir le nom du bouton ?

    Est-il possible de créer le nom du bouton comme étant la concaténation de 2 paramètres (ex : 'Bout_Rel' + str(Num_Rel) ? Et comment utiliser ce genre d'argument ?

    JP

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

    Citation Envoyé par Discret68 Voir le message
    Par contre, pour modifier l'état visuel du bouton concerné (Bout_Rel01.configure(bg = Coul02, fg = Coul06)), comment puis-je définir le nom du bouton ?

    Est-il possible de créer le nom du bouton comme étant la concaténation de 2 paramètres (ex : 'Bout_Rel' + str(Num_Rel) ? Et comment utiliser ce genre d'argument ?
    Pourquoi ne pas faire comme pour GPIO_Rel i.e. avoir une liste de Button?

    Faites aussi attention aux mots employés: une liste Python n'est pas vraiment un tableau et ce que vous appelez nom du Button n'est qu'une variable associée à un objet instance de Button.

    Pareil pour CoulXX... et de manière générale, remplacer un tas de variables V0, V1, ...Vn par une liste V allant de 0 à n-1 sera plus simple.

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

  5. #5
    Membre averti
    Homme Profil pro
    Astronome amateur
    Inscrit en
    Juillet 2016
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Astronome amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 63
    Par défaut
    Bonjour Wiztricks

    J’ai eu un peu de mal à comprendre le sens de tes suggestions, mais en me triturant un peu le cerveau, j’ai fini par en trouver (enfin je crois) la déclinaison pratique. En tout cas, ce que j’ai mis en oeuvre fonctionne.
    D’un autre coté, ça fait 2 mois que je pratique le python en autodidacte et il faut que j’y aille progressivement pour ne pas trop m’embourber.

    J’ai donc commencé par convertir une partie de mes variables en liste (Bout_Rel, Coul; …) pour réduire le risque de bugs. Voila ce que donne la définition précédemment évoquée (en 16 exemplaires) qui se retrouve en un seule. Ce qui au passage, "génère" une économie d’environ 150 lignes de programme.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Coul=['#11FF11','#44FF44’,’#FF0000','#444444','#CCCCCC','#333333']
    Bout_Rel=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
     
    def CommutRelais(Num_Bouton): # Commutation du relais - L'activation du relais s'effectue lorsque la broche GPIO est à l'état bas
    	def Traitement():
    		Num_Relais = Num_Bouton+19 # Pour le moment le numéro de port GPIO est figé
    		EtatRelais = GPIO.input(Num_Relais) # On teste l'état de la broche du GPIO alimentant le relais
    		if EtatRelais == 1: # Si la broche est à l'état haut (le relais n'est pas activé)
    			GPIO.output(Num_Relais, 0) # On désactive la broche pour activer le relais
    			Bout_Rel[Num_Bouton].configure(bg = Coul[1], fg = Coul[5]) # On passe le fond de bouton en vert et le texte en gris foncé
    		else: # Si la broche est à l'état bas (désactivé)
    			GPIO.output(Num_Relais, 1) # On active la broche pour désactiver le relais
    			Bout_Rel[Num_Bouton].configure(bg = Coul[5], fg = Coul[4]) # on passe le fond de bouton en gris foncé et le texte en gris clair
    	return Traitement
    Concernant la formulation pour la définition et le positionnement des boutons, vu que je procède à la modification de la physionomie des boutons par ailleurs, je pense que je n’ai pas d’autre choix que de les définir en tant que variable.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	Bout_Rel[1] = Button(fenetre, text=Lib1[3:], width=Larg_Bouton, bg = Coul[5], fg = Coul[4], font=police, command = CommutRelais(1))
    	Bout_Rel[1].place(x=80, y=Bout_Y2)
    	Bout_Rel[2] = Button(fenetre, text=Lib2[3:], width=Larg_Bouton, bg = Coul[5], fg = Coul[4], font=police, command = CommutRelais(2))
    	Bout_Rel[2].place(x=80, y=Bout_Y2+40)
    Suite à ce que je viens de mettre en oeuvre, j'imagine aisément quelques évolutions du code actuel :
    • De part l’utilisation de listes de valeurs pour les boutons, je vais également pouvoir créer une boucle pour leur définition et leur mise en place sur la fenêtre.
    • Le pas vertical des boutons étant constant, je vais pouvoir calculer la coordonnée Y de chaque bouton dans la boucle. J’ai choisi un positionnement des boutons par la fonction place plutôt que par une grille. Ayant une fenêtre aux dimensions variables car fonction du nombre de boutons visualisés (4-8-12 ou 16), cette solution me paraissait aisée.
    • La définition de la liste Bout_Rel pourrait être optimisée par l’exécution d’une boucle. Bien que vu le faible nombre de valeur, je pense qu’elle peut rester ainsi.
    • Num_relais fera également l’objet d’une définition par liste car il est proposé d’affecter un n° de broche du port GPIO au choix à chaque bouton et non pas dans un ordre purement chronologique. Une fenêtre de paramétrage permet de définir au choix, le libellé de chaque bouton et le n° de broche du port GPIO associé.


    Encore un peu de pain sur la planche

    JP

  6. #6
    Membre averti
    Homme Profil pro
    Astronome amateur
    Inscrit en
    Juillet 2016
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Astronome amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 63
    Par défaut
    Juste pour conclure cette discussion, j'ai mis en oeuvre les préconisations de Wiztricks (utilisation de listes pour la définition des objets et des variables) ainsi que d'autres principes d'optimisation, ce qui a permis de passer le programme de 680 à 205 lignes.

    Si ça, c'est pas de l'optimisation

    Merci encore à Wiztricks pour ses conseils, et en route pour de nouvelles questions.

    JP

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

Discussions similaires

  1. [POO] Optimisation de code pour défilement vertical de div
    Par nicolas2603 dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 07/04/2009, 14h37
  2. optimisation du code pour des combobox
    Par oscar.cesar dans le forum Macros et VBA Excel
    Réponses: 12
    Dernier message: 08/03/2008, 13h30
  3. Réponses: 0
    Dernier message: 29/08/2007, 16h57
  4. Optimiser un code pour éviter " out of memory"
    Par risack dans le forum MATLAB
    Réponses: 16
    Dernier message: 19/03/2007, 09h36
  5. Réponses: 8
    Dernier message: 14/09/2006, 16h43

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