Category: KDE

Coller du code dans IPython

Par virtual_eye, 25 janvier 2009 20 h 58 min

Il vous est sûrement déjà arrivé de vouloir tester un petit bout de code trouvé sur le Net. Ou ne tester qu’un petit bout d’un algorithme faisant partie de votre application.
IPython vous permet de coller du texte dans son interface en utilisant %cpaste, et vous permet de ne pas retaper la partie à tester, surtout si elle se fait relativement longue.

Un exemple simple avec des décorateurs :

In [269]: %cpaste
Pasting code; enter '--' alone on the line to stop.
:def decorateur(func):                                   
:    class MaClasse:                                 
:        def __init__(self,*a,**k):                
:            print "Les arguments passés : ",a,k                
:    return MaClasse                                 
:                                                  
:@decorateur                                             
:def ma_fonction(a):                                  
:    return a*3                                    
:--

Et voilà notre code près à être testé :

In [286]: ma_fonction 2,2
--------> ma_fonction(2,2)
Les arguments passés :  (2, 2) {}
Out[286]: <__main__.MaClasse instance at 0xa66c76c>

Oui dans IPython, on peut se permettre de ne pas mettre de parenthèse pour appeler une fonction car il est notre ami et sait qu’on est fainéant !!

IPython et le shell

Par virtual_eye, 24 janvier 2009 21 h 45 min

IPython vous permet très simplement d’affecter le retour d’une commande shell à une variable entièrement manipulable.

In [64]: var = !ls -R | grep b
 
In [65]: var
Out[65]: SList (.p, .n, .l, .s, .grep(), .fields() available). Value:
0: build
1: Public
2: ./build:
3: beastbible
4: ./Documents/projets/beastbible:
5: ./Documents/projets/beastbible/artist:
6: ./Documents/projets/beastbible/review:
7: ./Public:

Il suffit simplement d’ajouter le caractère ‘ ! ‘ avant votre commande !!

Alors heureux ?

IPython et la fonction magique %edit

Par virtual_eye, 24 janvier 2009 21 h 14 min

[size=15]IPython fournit une quantité de fonctions dites « magiques ». Oui, on est bien dans le monde Python alors pourquoi se priver de telles fonctions !
Voici donc une description de la puissante fonction %edit[/size]

L’interpréteur de commande, aussi sympa soit-il, commence à devenir lourd dès lors que l’on veut tester un code sur plusieurs lignes.
Genre une boucle ou même un script entier.
Vous me direz, c’est fait pour ? IPython vous répond oui !

1) Lancer IPython
Tout d’abord, sachez que lorsque vous lancer IPython, vous avez accès à un certains nombres d’options. Je ne vais pas développer plus loin, car une seule m’intéresse pour vous parler de %edit, l’option -editor.
En effet, cette option vous permettra de choisir votre éditeur de texte préféré à l’appel de %edit. IPython honorera votre éditeur de texte par défaut (vim ??) si cette option n’est pas précisée.

2) Taper votre script dans votre éditeur préféré
Depuis IPython, faites

%edit

Voilà ce qui s’affiche tandis que votre éditeur se lance

IPython will make a temporary file named: /tmp/ipython_edit_*****.py

Taper votre code, qui sera par exemple (volontairement faux pour la suite, le flag re.X manque):

import re
reg = re.compile(r"""(?P<artist>[\w ]+)    # match le groupe 'artist' - au moins 1 caractère alphamunérique ou un espace
                     -                     # un tiret
                     (?P<album>[\w ]+)     # match le groupe 'album' - au moins 1 caractère alphamunérique ou un espace""")
print reg.match("Iron Maiden-Powerslave").groupdict()

On sauvegarde ces quelques et ferme notre éditeur.
Le code tapé est directement exécuté dans IPython ! Le résultat s’affiche ainsi que le code tapé dans votre éditeur !

Editing... done. Executing edited code...
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
 
/tmp/ipython_edit_f88xWz.py in <module>()
      2                      -                     # un tiret
      3                                           (?P<album>[\w ]+)     # match le groupe 'album' - au moins 1 caractere alphamunerique ou un espace""")
----> 4 print reg.match("Iron Maiden-Powerslave").groupdict()
      5
      6
 
AttributeError: 'NoneType' object has no attribute 'groupdict'
WARNING: Failure executing file: </tmp/ipython_edit_f88xWz.py>
Out[28]: 'reg = re.compile(r"""(?P<artist>[\\w ]+)    # match le groupe \'artist\' - au moins 1 caractere alphamunerique ou un espace\n                     -                     #un tiret\n                                          (?P<album>[\\w ]+)     # match le groupe \'album\' - au moins 1 caractere alphamunerique ou un espace""")\nprint reg.match("Iron Maiden-Powerslave").groupdict()\n'

Ici, vu l’erreur, il en résulte une belle exception. Mince je vais devoir retaper tout ça pour corriger l’erreur !!

3) Récupérer son fichier temporaire
Eh bien non, %edit possède une option se chargeant de récupérer votre ancien fichier temporaire et d’en créer un nouveau à partir de celui-ci. Ah oui ? Mais pourquoi en créer un nouveau ? Il se peut que vous exploriez différentes pistes pour votre script. Vous pouvez donc constater l’évolution de votre code et revenir en arrière !

On tape

%edit -p

Miracle, on récupère tout et on corrige ! Ce qui donne :

Editing... done. Executing edited code...
{'album': 'Powerslave', 'artist': 'Iron Maiden'}
 
Out[29]: 'reg = re.compile(r"""(?P<artist>[\\w ]+)    # match le groupe \'artist\' - au moins 1 caractere alphamunerique ou un espace\n                     -                     #un tiret\n                                          (?P<album>[\\w ]+)     # match le groupe \'album\' - au moins 1 caractere alphamunerique ou un espace""", re.X)\nprint reg.match("Iron Maiden-Powerslave").groupdict()\n'

Si votre script est long vous avez également une option pour ouvrir votre fichier à une ligne spécifiée

%edit -n 167 -p

Magnifique ! Mais je vous vois venir. On n’a pu tester la regex qu’avec une valeur hardcodée.

4) Ne pas exécuter le code tapé tout de suite
On récupère notre fichier et au lieu d’hardcoder la string passée match, on spécifie une valeur passée au script
On spécifie à la fonction %edit que l’on ne veut pas qu’elle exécute le code de cette manière

%edit -x -p

On édite notre code :

import re
import sys
 
reg = re.compile(r"""(?P<artist>[\w ]+)    # match le groupe 'artist' - au moins 1 caractere alphamunerique ou un espace
                     -                     # un tiret
                                          (?P<album>[\w ]+)     # match le groupe 'album' - au moins 1 caractere alphamunerique ou un espace""", re.X)
print reg.match(sys.argv[1]).groupdict()

On sauvegarde et ferme, ce qui donne dans IPython

IPython will make a temporary file named: /tmp/ipython_edit_N4NcvF.py
Editing...

5) Exécuter notre code avec l’argument passé au match
IPython peut exécuter des scripts dans son interface via une autre fonction magique qui est %run. Je ne m’y attarderai pas, ce n’est pas le sujet ici. On a toute les info pour exécuter notre code puisque ce gentil IPython nous fournit le nom du fichier temporaire généré

%run /tmp/ipython_edit_N4NcvF "Nirvana-Nevermind"

Et on obtient:

{'album': 'Nevermind', 'artist': 'Nirvana'}

Ca marche !! Voilà une belle petite fonctionnalité qui nous évite les interminables
> vim monfichier.py
> python monfichier.py
fail
Mince comment on fait déjà ?
> ipython
Je teste ! J’ai trouvé
> vim monfichier.py
> python monfichier.py
works

Ceci est une première fonctionnalité d’IPython, il y en a une flopée d’autres !

Panorama Theme by Themocracy