[Débutants] Exemple de simplification de code (+ exemple poo)

Python est le langage de prédilection du Raspberry Pi

Modérateurs : Francois, Manfraid

Répondre
Bud Spencer
Raspinaute
Messages : 1089
Enregistré le : lun. 15 août 2016 21:38

[Débutants] Exemple de simplification de code (+ exemple poo)

Message par Bud Spencer » lun. 29 juil. 2019 21:02

Petit exemple d’optimisation de code. Le code original est celui de Fréderic et concerne le topic ‘Un indicateur de charge CPU/RAM à LED pour le Raspberry Pi’ posté hier par François sur le Blog. C’est un petit indicateur à leds cpu/ram makerisé par Frédéric. Son programme fonctionne mais je me suis proposé de lui montrer comment il pouvait le simplifier et il a semblé intéressé quand j’ai écrit que l’on pouvait faire la même chose avec 80% de code en moins. Tout ça sans utiliser de truc de gourou mais juste en raisonnant différemment. Comme cela concerne des leds sur les GPIO et du python (sic…), cela pourra aussi servir à d’autres. Pour essayer d'etre compréhensible par les débutants, je vais procéder par étape jusqu'à a arriver a un code minimaliste qui fait la meme chose que l' initial.

Commençons par le plus simple, à savoir les leds d’usage CPU. Ce qui nous intéresse ici se trouve dans la boucle while infinie. Ceux qui me connaissent savent que d’habitude je mets toujours ‘Infernale’ devant ‘boucle infinie’, mais comme j’ai promis de rester avec du code de débutant, on va garder cette boucle et cela ne va pas nous empêcher d‘optimiser quand même. Voilà le code de la boucle écrit par Fréderic (pour plus de clarté, j’ai viré pour l’instant tout ce qui concerne les leds de dispo mémoire que je traiterai plus tard)
cpuLed#1.png
cpuLed#1.png (38.71 Kio) Vu 6113 fois
Si on résume le fonctionnement, il y a 5 leds, et s’allume celle qui correspond au % d‘usage cpu par tranche de 20% (0 à 20, 21 à 40, 41 à 60, 61 à 80, 81 à 100). Pour en arriver là on a :

- Une première série d’évaluation pour initialiser la variable cpuLed
- Ensuite 5 évaluations pour allumer la led qui correspond au résultat de la variable
-L’instruction de délais (Sleep)
-Puis encore 5 évaluations pour éteindre la led allumée avant de retourner au début

=> Reduction et Optimisation du code =>
Modifié en dernier par Bud Spencer le sam. 17 août 2019 12:21, modifié 4 fois.
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

Bud Spencer
Raspinaute
Messages : 1089
Enregistré le : lun. 15 août 2016 21:38

Re: [Débutants] Exemple de simplification de code

Message par Bud Spencer » lun. 29 juil. 2019 21:04

Pour moi, la première simplification qui me vient à l’esprit, plutôt que d’allumer la led pour l’éteindre ensuite, c’est de traiter l’allumage de façon exclusive. J’entends par la traiter dans un seul bloc d’instruction l’état que la led doit avoir. Cela fait un poil moins de code, on évalue cpuLed 2 fois moins souvent et en plus on ne devrait plus avoir de clignotement pas beau de la led entre chaque passage (c’est plus joli ...):
cpuLed#2.png
cpuLed#2.png (33.86 Kio) Vu 6112 fois
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

Bud Spencer
Raspinaute
Messages : 1089
Enregistré le : lun. 15 août 2016 21:38

Re: [Débutants] Exemple de simplification de code

Message par Bud Spencer » lun. 29 juil. 2019 21:04

Etape suivante : On voit que la valeur de cpuLed est conditionnée par la valeur de cpuPercent et qu’ensuite l’état des leds est conditionné par cpuled. On peu donc facilement prendre un raccourci en conditionnant directement l’état des leds à partir de cpuPercent, ce qui pourrait donner un truc du genre :
cpuLed#3.png
cpuLed#3.png (33.36 Kio) Vu 6112 fois
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

Bud Spencer
Raspinaute
Messages : 1089
Enregistré le : lun. 15 août 2016 21:38

Re: [Débutants] Exemple de simplification de code

Message par Bud Spencer » lun. 29 juil. 2019 21:05

Pour aller plus loin et optimiser encore, on va utiliser ce que l’on appelle un opérateur conditionnel (ou operateur ternaire). Rassurez-vous, ça reste très simple. Je cite les termes techniques pour vous permettre de faire des recherche avec l’ennemi google mais ici, ça va se résumer à modifier la façon d’ecrire le code en déplaçant le block ‘if else’ dans l’instruction GPIO.output et ça donne ça :
cpuLed#4.png
cpuLed#4.png (28.17 Kio) Vu 6112 fois
Si on regarde bien, plutôt que d’écrire :
Si cpuPercent est > 0 et est < 20 alors la sortie 11 est haute, sinon elle est basse
On écrit directement
La sortie 11 est haute Si cpuPercent est > 0 et est < 20 sinon elle est basse

Finalement, c'est pareil mais en mieu pas pire :lol:
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

Bud Spencer
Raspinaute
Messages : 1089
Enregistré le : lun. 15 août 2016 21:38

Re: [Débutants] Exemple de simplification de code

Message par Bud Spencer » lun. 29 juil. 2019 21:07

Avec GPIO en pyhton, l’instruction output qui initialise l’état d’une sotie peut accepter en second paramètre, soit une constante (HIGHT ou LOW) soit une valeur numérique (1 ou 0) ou encore un booléen (True ou False). C’est cette dernière option qui va nous permettre de simplifier encore plus.

Si par exemple j’écris :
x = cpuPercent >=0 and cpuPercent <=20
x est un booléen et il n’est vrai (True) que si cpuPercent >=0 et cpuPercent <=20, sinon il est forcément faux (False). Notre sortie GPIO pouvant de la meme façon etre soit True soit False, et que si elle est l’un elle n’est forcément pas l’autre, on peut donc ecrire :
cpuLed#5.png
cpuLed#5.png (19.11 Kio) Vu 6111 fois
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

Bud Spencer
Raspinaute
Messages : 1089
Enregistré le : lun. 15 août 2016 21:38

Re: [Débutants] Exemple de simplification de code

Message par Bud Spencer » lun. 29 juil. 2019 21:11

Puis comme cpuPercent est forcément >= 0 et forcement <= 100 on supprime les évidences pour arriver à ca :
cpuLed#6.png
cpuLed#6.png (17.3 Kio) Vu 6111 fois
Voila, on a déjà bien réduit le code et pourtant je n'ais utilisé aucun truc compliqué. La lecture du code est on ne peu plus claire et on peut dire ce que fait le programme d'un simple coup d'œil.

Demain je ferais la partie ram ou j’utiliserais bien sur la meme méthode que pour les leds cpu mais où il y a en plus beaucoup de simplification à faire dans la partie arithmétique. Ensuite je ferais une revue de la partie ‘sortie propre’ du programme qui ne l’est pas vraiment. Il restera après sans doute de la place pour voir comment on peut élever le niveau en utilisant des listes et des plages de données.
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

Frédéric
Messages : 17
Enregistré le : lun. 29 juil. 2019 19:47

Re: [Débutants] Exemple de simplification de code

Message par Frédéric » lun. 29 juil. 2019 22:00

Ha ouai c est vraiment plus court et surtout plus compréhensible. Les ternaires j ai toujours eût du mal a les ecrires, mais on les comprends bien. Vivement demain pour la suite et un truc intéressant c est aussi la sortie... Bon boulot. ++

dyox
Raspinaute
Messages : 969
Enregistré le : dim. 28 déc. 2014 15:28
Localisation : Le long de la côte, au dessus du pays des bigoudennes, aïe

Re: [Débutants] Exemple de simplification de code

Message par dyox » mar. 30 juil. 2019 11:38

Bonjour,

Merci Bud de prendre le temps de bien expliquer.

J'étais en train de regarder la bibliothèque Gpiozero, et j'ai vu qu'elle intègre "CPU Temperature Bar Graph" (cf 2.31 et 17.1.3). Certes c'est beaucoup moins didactique mais cela donne un autre exemple pour ceux qui veulent un bar graph.
Modifié en dernier par dyox le mar. 30 juil. 2019 12:59, modifié 1 fois.

Artemus24
Raspinaute
Messages : 1077
Enregistré le : ven. 15 sept. 2017 19:15

Re: [Débutants] Exemple de simplification de code

Message par Artemus24 » mar. 30 juil. 2019 12:38

Salut à tous.

Si je comprends bien le programme, il y cinq leds dont une seule est allumée.
L'alumage de la led dépend du pourcentage que l'on obtient.

Le calcul de l'intervalle du pourcentage qui est testé se fait par tranche de 20%.
Au lieu de dire dans quel intervalle je me trouve, comme cela est fait, le mieux est de faire un calcul pour déterminer dans quelle tranche on se trouve.
Par exemple de 0 compris à 20 non compris, je suis dans la tranche 0, de 20 compris à 40 non compris, je suis dans la tranche 1, et ainsi de suite.

A chaque itération, on éteint la led précédente et l'on allume la led suivante.
Puisque le but de cet exercice est de faire le plus court possible, voici ce que je propose :

Code : Tout sélectionner

tab = array([11,13,15,12,16,16])
rang=0
while (TRUE):
	GPIO.output(tab[rang], GPIO.LOW)
	rang = int(psutil.cpu_percent() / 20)
	GPIO.output(tab[rang], GPIO.HIGH)
	sleep(1)
Je ne connais pas python, donc désolé su j'ai commis une erreur. Mais l'idée est là !

@+
RPI4B/8GB + Argon FanHAt
Rpi3A+, Rpi3B+
RPi 2B + Joy-It I2C Serial 20x4 2004 LCD Module
RPi 2B + PIM273 Unicorn HAT HD 16x16 Leds RGB
RPi0v1.3, RPi0W + LibreElec/Kodi, Rpi0WH + Tuner TV HAT
NodeMCU ESP32

Frédéric
Messages : 17
Enregistré le : lun. 29 juil. 2019 19:47

Re: [Débutants] Exemple de simplification de code

Message par Frédéric » mar. 30 juil. 2019 19:19

@Artemus24 voui, ca doit bien le faire, l idee est bonne!

Répondre

Retourner vers « Python »