PROJET AUTOBLOG


Tiger-222

Site original : Tiger-222

⇐ retour index

Se protéger contre soi-même !

vendredi 8 novembre 2013 à 14:19
Un accès au compte root, la commande rm disponible... Un mélange détonnant qui peut faire très mal. Ça sent l'erreur de manipulation de débutant tout ça !

À fond dans mon nouveau projet, dont je vous parlerai plus tard, je dois supprimer les fichiers d'un répertoire. Si elle n'est pas belle celle-ci :
Misère avec la commande rm

Putain ! Encore heureux que je n'avais pas utilisé l'argument -r ou --recursive

L'erreur à la con, ici, c'est que j'ai utilisé la touche TAB pour que Zsh complète le nom des chemins automatiquement. Vite fait, bien fait, ça aurait pu m'être fatal !

La synthèse de cette histoire : toujours faire attention.
La morale de cette histoire : toujours faire très attention.
La morale de cette morale : toujours faire super attention. TOUJOURS !

Et afin de me protéger (contre moi-même), un alias qui va bien :
alias rm='rm -Iv'
L'argument -I est le mode intéractif. J'te jure, des fois... $#!°@☣

Se protéger contre soi-même !

vendredi 8 novembre 2013 à 13:19
Un accès au compte root, la commande rm disponible... Un mélange détonnant qui peut faire très mal. Ça sent l'erreur de manipulation de débutant tout ça !

À fond dans mon nouveau projet, dont je vous parlerai plus tard, je dois supprimer les fichiers d'un répertoire. Si elle n'est pas belle celle-ci :
Misère avec la commande rm

Putain ! Encore heureux que je n'avais pas utilisé l'argument -r ou --recursive

L'erreur à la con, ici, c'est que j'ai utilisé la touche TAB pour que Zsh complète le nom des chemins automatiquement. Vite fait, bien fait, ça aurait pu m'être fatal !

La synthèse de cette histoire : toujours faire attention.
La morale de cette histoire : toujours faire très attention.
La morale de cette morale : toujours faire super attention. TOUJOURS !

Et afin de me protéger (contre moi-même), un alias qui va bien :
alias rm='rm -Iv'
L'argument -I est le mode intéractif. J'te jure, des fois... $#!°@☣

MàJ : ArthurHoaro propose une solution moins chiante ☺

Code : fautes d'orthographe courantes

jeudi 7 novembre 2013 à 00:35
Codespell, de Lucas De Marchi, est un de ces petits utilitaires qui ne paie pas de mine, mais ô combien pratique ! Il vérifie les fautes d'orthographe courantes dans le code et les fichiers en relation (genre un README ou un CHANGELOG). Il n'a rien d'extraordinaire en soi, mais il permet de faire les choses correctement.
codespell

Dans les exemples ci-dessus, vous pouvez voir que j'ai merdé à trois reprises dans le module MSS... Mais aussi qu'il y a des erreurs dans le code officiel de Python 2.7.5 (personne n'est parfait) ! D'ailleurs, pour ceux et celles qui souhaitent participer à un projet open-source, c'est un excellent moyen pour se mettre dans le bain : proposer des patches qui corrigent les fautes d'orthographe. 😉


Les options


Si les couleurs vous dérangent, passez l'option --disable-colors. Et si les statistiques vous bottent, l'option --summary permet de savoir combien de corrections ont été appliquées.

Pour ne pas faire de recherches dans certains fichiers, utiisez l'option -S SKIP, dont les valeurs sont séparées par une virgule :
$ codespell -S .pyc,.txt

# Avec joker
$ codespell -S "*.pyc,.git,*backup*"

Bien évidemment, il est possible d'utiliser son propre dictionnaire à l'aide de l'option -D FICHIER, dont chaque ligne devra être telle que :
# mot_erroné->mot_correct
aberation->aberration

# mot_erroné->mot_correct, autre_mot_possible,
coorperation->cooperation, corporation,

# mot_erroné->mot_correct, explication
# Ceci aura pour effet de ne pas appliquer automatiquement les changements.
# Pratique pour les mots à double sens, réservés ou à tendance "faux positif".
cmo->com, disabled due to lots of false positives

Il existe même un mode intéractif ! C'est l'option -I VALEUR qui s'en charge. Elle n'est utilisable qu'avec l'option --write-changes, qui applique directement les changements sur les fichiers. Les valeurs possibles sont :
0 : aucune intéractivité, le comportement par défaut
1 : demander une confirmation avant chaque modification
2 : permet de choisir un mot parmis la liste, si choix il y a
3 : options 1 et 2

Enfin, pour gérer facilement les messages en sortie, l'option -q NIVEAU permet d'affiner tout ça :
 0 : tout est affiché, valeur par défaut
1 : pas d'averto en cas d'erreur d'encodage
2 : pas d'averto pour les fichiers binaires
4 : pas d'averto lors de non modification (explication dans le dictionnaire)
8 : ne rien afficher en mode non-automatique
16 : ne pas afficher les fichiers corrigés

Bonus : un alias qui va bien pour votre .bashrc (ou mieux, .zshrc) :
alias codespell='/opt/codespell/codespell.py'


3615 ma vie


Pour la petite histoire, j'ai découvert cet outil grâce à la dépêche Noyau : Sortie de Linux 3.12 sur LinuxFr.org. De fil en aiguille, j'en suis arrivé à décortiquer un pull-request de Ted Ts'o dans lequel j'ai pu lire :
ext4: Fix misspellings using 'codespell' tool

Du coup, je vous le donne en mille : le commit pour MSS, super original...

Code : fautes d'orthographe courantes

mercredi 6 novembre 2013 à 23:35
Codespell, de Lucas De Marchi, est un de ces petits utilitaires qui ne paie pas de mine, mais ô combien pratique ! Il vérifie les fautes d'orthographe courantes dans le code et les fichiers en relation (genre un README ou un CHANGELOG). Il n'a rien d'extraordinaire en soi, mais il permet de faire les choses correctement.
codespell

Dans les exemples ci-dessus, vous pouvez voir que j'ai merdé à trois reprises dans le module MSS... Mais aussi qu'il y a des erreurs dans le code officiel de Python 2.7.5 (personne n'est parfait) ! D'ailleurs, pour ceux et celles qui souhaitent participer à un projet open-source, c'est un excellent moyen pour se mettre dans le bain : proposer des patches qui corrigent les fautes d'orthographe. 😉


Les options


Si les couleurs vous dérangent, passez l'option --disable-colors. Et si les statistiques vous bottent, l'option --summary permet de savoir combien de corrections ont été appliquées.

Pour ne pas faire de recherches dans certains fichiers, utiisez l'option -S SKIP, dont les valeurs sont séparées par une virgule :
$ codespell -S .pyc,.txt

# Avec joker
$ codespell -S "*.pyc,.git,*backup*"

Bien évidemment, il est possible d'utiliser son propre dictionnaire à l'aide de l'option -D FICHIER, dont chaque ligne devra être telle que :
# mot_erroné->mot_correct
aberation->aberration

# mot_erroné->mot_correct, autre_mot_possible,
coorperation->cooperation, corporation,

# mot_erroné->mot_correct, explication
# Ceci aura pour effet de ne pas appliquer automatiquement les changements.
# Pratique pour les mots à double sens, réservés ou à tendance "faux positif".
cmo->com, disabled due to lots of false positives

Il existe même un mode intéractif ! C'est l'option -I VALEUR qui s'en charge. Elle n'est utilisable qu'avec l'option --write-changes, qui applique directement les changements sur les fichiers. Les valeurs possibles sont :
0 : aucune intéractivité, le comportement par défaut
1 : demander une confirmation avant chaque modification
2 : permet de choisir un mot parmis la liste, si choix il y a
3 : options 1 et 2

Enfin, pour gérer facilement les messages en sortie, l'option -q NIVEAU permet d'affiner tout ça :
 0 : tout est affiché, valeur par défaut
1 : pas d'averto en cas d'erreur d'encodage
2 : pas d'averto pour les fichiers binaires
4 : pas d'averto lors de non modification (explication dans le dictionnaire)
8 : ne rien afficher en mode non-automatique
16 : ne pas afficher les fichiers corrigés

Bonus : un alias qui va bien pour votre .bashrc (ou mieux, .zshrc) :
alias codespell='/opt/codespell/codespell.py'


3615 ma vie


Pour la petite histoire, j'ai découvert cet outil grâce à la dépêche Noyau : Sortie de Linux 3.12 sur LinuxFr.org. De fil en aiguille, j'en suis arrivé à décortiquer un pull-request de Ted Ts'o dans lequel j'ai pu lire :
ext4: Fix misspellings using 'codespell' tool

Du coup, je vous le donne en mille : le commit pour MSS, super original...

Python : mémoisation

jeudi 31 octobre 2013 à 03:20
Œuvre d'Anthony Heywood
Connaissez le dicton : avoir une mémoire d'...

La mémoisation est une technique d'optimisation de code consistant à réduire le temps d'exécution d'une fonction en mémorisant ses résultats d'une fois sur l'autre, une sorte de cache quoi. Ça peut-être super pratique dans certains cas, surtout lorsqu'il y a des calculs complexes ou beaucoup de données redondantes.
Étant donné que Sam & Max ont déjà couvert le sujet, je vais seulement montrer un exemple concrêt : le cas de mon module MSS.

Le contexte


Le module MSS est, comme sont nom ne l'indique pas, un module permettant de prendre des captures d'écran sans module tiers, seulement du python pur. J'utilise intensément le module ctypes, qui permet d'appeler des fonctions C/C++ depuis python.
Sous GNU/Linux, avec un code équivalent C <=> python permettant de prendre une capture d'écran, la différence de vitesse d'exécution est quintuplée, voire sextuplée. Ça fait beaucoup. Je me suis donc plongé dans le code pour voir ce qui pouvait être revu ou amélioré. Au final, il s'avère que les routines pour récupérer les pixels et générer l'image PNG seront améliorées. Mais le gain fût minime.
Le stockage des pixels reçus par la fonction XGetPixel met un temps fou, c'est un gouffre. C'est là qu'il faut farfouiller, voilà le code fautif :
def pix(pixel):
''' Apply shifts to a pixel to get the RGB values. '''
return b((pixel ET 16711680) >> 16) + b((pixel ET 65280) >> 8) + b(pixel ET 255)

get_pix = self.XGetPixel
pixels = [pix(get_pix(image, x, y)) for y in range(height) for x in range(width)]
La coloration syntaxique chie dans la colle, remplacez le ET par &.

Dans la fonction pix(), le décalage de bits n'est pas le plus gourmant, ce sont les concaténations. En effet, à chaque fois, il y a réallocation de mémoire et copie de données dont je me passerais bien.


Mémoisation


Dans la logique qui m'habite (rien de bien transcendant...), je me dis qu'il y a énormément de pixels identiques sur un écran. Il y a la dose même. Avec une telle quantitié de données, et sachant les opérations qu'il faille faire sur chacun des pixels, la mémoisation prend tout son sens :
def pix(px, _resultats={}):
# Apply shifts to a pixel to get the RGB values.
# This method uses of memoization.
if not px in _resultats:
_resultats[px] = b((px ET 16711680) >> 16) + b((px ET 65280) >> 8) + b(px ET 255)
return _resultats[px]

get_pix = self.XGetPixel
pixels = [pix(get_pix(image, x, y)) for y in range(height) for x in range(width)]
J'ai modifié pixel par px afin d'éviter les barres de défilement...

Étant donné que les paramètres sont initialisés à la déclaration, le paramètre _resultats de la fonction pix() ne sera pas recréé à chaque appel. Il s'agit d'un dict qui recevra tous les pixels et le résultat attendu pour chacun d'eux. Dans ladite fonction, on vérifie si le pixel a déja été traité, si non, on effectue les opérations sur celui-ci, puis on renvoie ce que le dict a en mémoire. Un petit cache tout simple et efficace.


Résultats


Avec un écran de 1280x1024, je passe de ±4 sec à <2 sec, reduisant les pixels traités de 1 310 720 à 11 204.
Avec un écran de 1920x1280, je passe de ±6 sec à <3 sec, reduisant les pixels traités de 2 457 600 à 8 236.

♪ Un gain non négligeable ! ♪