You are on page 1of 7
Lins & MODULES 8 RECETTES POUR ACCELERER VOS a ea 6 lecteurs les plus assi- du se souviendront que deux hors-séries compor tant des mémos touchant différents aspects de la programmation en Python ont été publigs en 2016 et 2018 [RI. Dans cet article, je vous propose quelques nouvelles recettes, 1. UTILISER UNE LISTE DE TESTS COMME CONDITION D'UNE BOUCLE WHILE 1.1 L’objectif Les « recettes » de programmation, ce sont de petits Nous possédons une liste de va- bouts decode, des squelettes qui peuvent étrefacilement _ lew® ul som routes infrieues 2308 réutilisés dans différentes situations et permettent de tant qu'aucune des valeurs nest supé- gagner beaucoup de temps ! rieure ou égale & 100 56 © GNU/Linux Magazine France N°241 hhtips:/www-gnulinuxmag.com 8 recettes pour accélérer vos développements en Python 1.2 La solution 01: from random import randint 02: 03: ma liste = (1, 45, 67, 32, 4, 22) 04: longueur = len (aa_liste) -1 05: print (ma liste) 06: 07: while all (elt < 100 for elt in ma liste 08: ma liste randint 0, Longueur) | += randint (0, 30) 09: print (ma Liste) 10: MM: print ("Fini 1") 1.3 Commentaires A chaque itération, on ajoute une valeur aléatoire comprise entre @ et 30 a un élément pris au hasard dans la liste. A un moment donné, néces- sairement la boucle sarréte (2, 45, 67, 32, 84, 22] cre a eT ear re cr ee eae] [ear ee ee OE Fini | Sans att(), 'Bcriture aurait &é ‘beaucoup plus lourde 08: while not finial 09: © ma_Liste randint (0, Longueur) “= randint (0, 30) 10: print\ma Liste) 11: for elt in ma Liste: a: Af elt >= 100: 13) finish = True u pire 08: while ma_liste{0} < 100 and ma_liste[1] < 100 and and ma_liste(5) <100 : 2. AFFICHER TOUTES LES VARIABLES DEFINIES DANS UN SCRIPT 2.1 L'objectif "Nous disposons d'un script long et complexe et nous aimerions savoir queles sont es variables qui sont utilisées. A titre dlexemple, nous uilserons un script trés simple interagissant avec Minecraft. Rien ne permet & la lecture de ce script de savoir quelles sont les variables définies dans API. : fron mine import * 03: me = Minecraft () 04: print ('Hello Minecraft !') 2.2 La solution On ajoute es lignes 05: print (£'LOCAL : {Locals())") 06: print (£'GLOBAL ; (globals()} 2.3 Commentaires A Texécution, on se rend effectivement compte que bon nombre de va- riables nous avaient échappé Peniieeates bio See Pc ease erm co SSO tan se uaa Pe Cee arse st. SoCo pers te aes eae rts GLOBAL : ("_name_': ' main‘, "Block": , ‘camera’: , ‘enabledNBT': False) eens cents oe pecans t tres Ser Presa t tee) ee a 3. APPELER UNE FONCTION A Soe Rare neu! Appel callback n.6 : INTERVALLE REGULIER Sees 3.1 L'objectif Ia fallu conjuguer deux modules pour obtenir Veffet souhaité : le mo- ule sched pour planifier Vexécution dune fonction au bout de 5 secondes (ignes 16 et 10) etlemoduie threading 3.2 La solution pour une exécution en tache de fond. Linitalsation du scheduler a lieu en 01: import sched ligne 15 avec Vutilisation de la fonc- 02: import time tion tine.time() pour obtenir fheure et time.steep() pour réaliser un dé- lai. Pour voir Fimpact de ces para- def my_caltback (mmber, start, it): mates, vous pouvez modifier égere~ now = int(time.time() - start, ment le code Print (£'Appel callback n. {number} : {now}s') Af number < it: scheduler.enter(5, 1, my_callback, (nunber + 1, Nous soubaitons quiau cours de Fexécution d'un code une fonction soit ap- pelée toutes les 5 secondes. 04: 06: def my callback (number, start, it) 0 now = int (time. ‘tine () - start) 08: print (f'Appel callback n.{nunber} : {now} scheduler = sched.scheduler(tine.time, time.sleep) scheduler.enter(5, 1, my_callback, (1, start, 7)) thread = threading. Thread (target = scheduler.run) thread. start () for i in range(10): print (‘Traitement courant. time. sleep (1) 58 GNU/Linux Magazine France N°241 hhtips:/www-gnulinuxmag.com 8 recettes pour accélérer vos développements en Python a scheduler.enter(5, 1, my_caliback, (number + | 4.2La solution 1, start, it)) 1: string =‘ don Snow Dasnerys ‘Targaryen 1 (02: string = ' ' join(steing.eplit()) 3; print (string) 4.3 Commentaires Cette solution utilise spLit() pour transformer la chaine de caractéres en liste en coupant suivant les espaces. Ensuite avec join(), nous transfor: scheduler.enter(5, 1, my_callback, (1, start, 7)) | | mons cette liste en chaine de carac- tres en joignant tous les éléments par thread = threading. Thread (target = scheduler.run) | ©. Voici fe détail de ce processus thread.start() de> string = ' Jon Snow Daenerys _‘Targaryen 4 >o> string. split () ['Jon', 'Snow', ‘Dasnerys', maegegea', "1 >>> || join string. split () "Jon Snov|Daenerys|Fargaryen|.* for i in range(10): print (‘Traitement courant...') ‘time. sleep(1) ‘Vous verrez alors apparaitre plus clairement e fonctionnement du scheduler. Pour que lexécution de la fonction my_eattback() reprenne toutes les 5 secondes, celle-ci relance un scheduler en ligne 11. C'est sur cette ligne (et en ligne 22) que l'on définitjustement le délai de 5 secondes (premier paramétre) NOTE avant Fappel de la fonction (trositme paramere et paramétres de la fonction. si vous ne soubaitez supprimer que sous forme de tuple en quatritme paramétre), Le deuxiéme paramétre indique Jes caractéres non imprimables en le niveau de priorité. ‘début ou en fin de chaine, vous pouver utiliser Pour que le scheduler soit actif, il faut appeler scheduter.run(). Ii, cet appel est fait au sein d'un thread (ligne 25) de maniére a étre lancé en arrigre- + strtp() : suppression des carac- plan (ligne 26). tres non imprimables a droite et 8 gauche ; * rstrip() : suppression des ca~ 4, SUPPRIMER LES ESPACES CONSECUTIFS —racresnonimprimables done D'UNE CHAINE DE CARACTERES _— * Ustrip() : suppression des carac- 4.1 Lobjectif teres non imprimables a gauche [Nous disposons d'une chatne de caracttres contenant des espaces en début, : |_ Ci pour lef en fin, mais également au milieu et nous souhaitons supprimer les doublons, triplets, etc. Nous prendirons pour exemple la chaine Si vous désirez simplement supp mer tous les espaces dune chaine de caractares, alors Cest reptace() quil ‘Nous souhaitons obtenir : faudra employer iaiaar aaepaTRRRaR B Misssiss seotace 9] Jon Snow Daenerys —Targaryen . @ www.ed-diamond.com GNU/Linux Magazine France N°241 LIBS & MODULES a1; 2: 03 04 05: 06 07 08 08 PYTHON 5. AUTOMATISER DES ACTIONS SUR UNE INTERFACE GRAPHIQUE 5.1 L’objectif ‘Quvrir depuis interface graphique la calculatrice et ré- aliser le calcul 7 + 5. 5.2 La solution Il faut installer le module PyAutoGui qui nécessite serot pour réaliser des captures d’eran Il nous faut des captures d'écran des éléments sur les- quels nous allons cliquer + Le bouton Applications (applications.pna) Applications “Le menu Accessoires 9S A-cecoires + Le bouton Galeulator (la calculatrice sous Debian, SH] Galculator Gelcutator.png) *Latouche 7(Gept.png): 7 + La touche + (plus. oh *Latouche 5(cing.pns): 5 + Latouche = (egal.png) Le code est ensuite : sport pyautogus af olde (inago): region = None eile region is None ‘agion = pyautogul. ocateCentezOnSereen (image) yautogui.acvelo (region) peint ('0n clique sur (inage}') yautogui.click if ==! main “Prautogui. PAUSE = togui.FAILSAFE = True élic|‘appiications.png') elic|'accessoires.png’) elic('Galculator.png") clic ('sept.png') clic| "plus png’ elic|'cing.png') clic|‘egal.png') 5.3 Commentaires Lorsque Ion automate des actions sur une interface grax pPhique, il est trés important lajouter une temporisaton pour éviter que le programme niall trop viteet ne cherche acliquer| sur des éléments qui rexistent pas. Cestce que fat la ligne 12 avec une PAUSE de 1 seconde apres chaque action du module PyAutoGUL La ligne 13 ajoute une sécurité: en positionnant la souris dans le coin supérieur gauche de ran (coordon- ‘65 (0, 0), on léve une exception FailSafeException Tout le travail du programme est réalisé par a fonction eLic() des lignes 3 39 |. Tant que region est & None, on cherche sur Pécran image passée en paramétre, Lorsqu‘lle est trouvé, les coordonnées de son centre sont placées dans. region (et on sort donc de la boucle) ; 2. On déplace la souris aux coordonnées trouvées en 1; 3. On effectue un clic gauche, NOTE La fonction eLiek() admet deux paramétres optionnels + eLicks qui permet dindiquer le nombre de clcs (pour effectuer un double-clic par exemple) : + button qui indique sur quel bouton cliquer. Les va~ leurs possibles sont ‘Left, ‘middle’ et ‘right'. (On peut éventuellement ajouter un troisiéme paramétre si clicks > 1 : le temps de pause entre chaque clic (paramatre interval). Ainsi, pour effectuer un triple-clic du bouton droit avec lune pause de 0,25 seconde entre chaque clic, on écrit pyautogui .click (button="righ! 60 GNU/Linux Magazine France N°241 hhtips:/www-gnulinuxmag.com 8 recettes pour accélérer vos développements en Python 6. TELECHARGER DES DONNEES COMPLETES 6.1 Lobjec ‘Télécharger des données accessibles depuis une URLet attendre la fin du tléchargement pour démarrer une nouvelle action. Typiquement, télécharger une archive compressée ct la décompresser. Nous prendrons pour exemple I'URL, hupsi/www.python.org/tp/python/3.8.5/Python-3.8.5.tgz 6.2 La solution + foe urllib.request inport urlretrieve sport os se _nane asin “arlretrieve(Thetps:7 /wwpython.org/ £tp/python/3.8.5/2ython-3.8.5.tg2", '/home/ ‘user/Download/Python-3.8.5.tgz') ehdir '/hone/iser/Downtoed') 6.3 Commentaires Lemploi de la fonction urtretrieve() du module urlLib, request est obligatoire pour sassurer que le tél&- changement est bien acheve, avant de lancer la commande de ‘décompression. Sans cel, la ligne 7 provoquera une erreur pees crreorry| peers ‘Vous pouver essayer de décompresser le fichier en ligne de commande : le nésultat sera le méme, car le fichier com- pressé n'est pas complet ! urlretrieve() « bloque » Fexécution du script jusqu’a ‘ce que le tichier soit completement tééchargé, ce qui nous assure un comportement cohérent de la commande de dé- compression. Si nous avions tenté de télécharger le fichier a Iaide d'un appel systéme a wget, nous aurions été dans le cas évoque précédemment qui provoque une erreur lors de la décompression. Vous pouvez tester cela en rempla- sant la ligne 5 par 05: os.systen| ‘wget -P ‘Sroae/sex/Download/ython-3.8.5.tgz hétps://inm. python.org/ftp/python/3.8.5/Bython-3.8.5.tgz! NOTE Si vous souhaitee télécharger un fichier texte et le tra- ter immédiatement, vous pouver passer directement par une lecture de la page from urllib. request import urlopen with urlopen|‘http://python.org/') as response html = response. read() La variable rtm contient maintenant le contenu de la page hetp://python.org. 7. CREER UN DECORATEUR AVEC ARGUMENTS 7.1 Lobjectif Créer un décorateur qui va afficher des lignes pour en- cadrer laftichage d'une fonction, Ces lignes formeront une sorte de boite contenant un titre qui sera passé en para- matre du décorateur. 7.2 La solution def box title def decorator (function) : size = len(title) peint('**" + size * '*!) peint('* "+ title) Print('*#*! + size + '*") print("*") def intern(*args, **kwargs) : function (*args, **kwargs) print('#") pint (/###! + size # '#") xeturn intern return decorator @box (title="Mn FONCTION") def test(argi, arg2, arg3): print("Exécution de 1a fonction "test”') Af _pame_ == ‘main test (I, 2, 3) www.ed-diamond.com GNU/Linux Magazine France N°241 LIBS & MODULES PYTHON 7.3 Commentaires 7.3.1 Le résultat En exécutant ce code, on obtient Peed Exécution de la fonction "test" 7.3.2 Explications (On rettouve ici la structure d'un décorateur classique (decorator), mais ce dernier est enfoui dans une autre fonction (box). Pour mieux voir ce principe, on pourrait créer un décorateur sans argument et leréutiliser pour eréer le décorateur avec arguments ‘def decorator (function) : def intern(*args, *"kwargs) : print ("Décorateur') function (‘args, **kwargs’ weturn intern def box (title, print (title Setura decorator 8. IMPORTER UN MODULE QUI N’EST PAS DANS LE REPERTOIRE COURANT 8.1 Lobjectif Nous avons créé un module modute.py et celui-ci se trouve dans un répertoite parent du répertoire courant qui rest pas couvert par le PYTHONPATH, Voici larborescence Rept ae Oey aos Seed Pour nous assurer que import fonctionne, nous défini- rons une simple fonction daffichage 01: def display 0 print ("Module chargé Nous souhaitons charger ce module dans notre pro- gramme mon_script.py. 8.2 La solution 01; import sys Af _name_ == ‘ays.path. insert | import module nodule.display | sert (0, 7. ./Rep i/Rep_2") 8.3 Commentaires A rexécution, nous obtenons bien Iafichage de notre phrase ! Bien entendu, le code n'est pas trés esthétique, avec un import qui vient se perdre au milieu du code. Nous au- rions pu opter pour une autre présentation sys-path.insert (0, '../Rep_1/Rep_2") + Amport eys import module 2 if _mame_ == '_main_': Rodule display Cette solution a le mérite de ne pas demander une in- tervention supplémentaire de l'utilisateur au moment de Tappel du programme, comme ce serait le cas avec la va~ riable dlenvironnement PYTHONPATH REFERENCES [N1T. COLOMBO, « Mémo Python », ‘GNUJLinux Magazine HS 1°86, seplembre/actobre 2016 htips://connect.ed-diamond.com (GNU-Linux-Magazine/GLMFHS-086 [2IT. COLOMBO, « Mémo Python - Saison 2 » GNU/Linux Magazine HS n-95, mars/avril 2018 hutps://connect.ed-diamond.com/ GNU-Linux-Magazine/GLMFHS-095 62 GNU/Linux Magazine France N°241 hhtips:/www-gnulinuxmag.com

You might also like