Re: [Python] doctest con funzioni che aprono files

2008-11-28 Per discussione Giovanni Marco Dall'Olio
2008/11/26 Daniele Varrazzo [EMAIL PROTECTED]:


 On Wed, 26 Nov 2008 19:11:24 +0100, Giovanni Marco Dall'Olio
 [EMAIL PROTECTED] wrote:

 Tu sei sicuro che una docstring nella quale hai buttato dentro tutto il
 codice boilerplate per fargli aprire un file temporaneo abbia ancora una
 qualche utilità come docstring?

 Per alcune cose che devo fare, si.
 Sto contribuendo al progetto biopython, una collezione di moduli per
 la bioinformatica in python.

 Lo conosco, ho studiato bioinformatica per la tesi di laurea e ci ho
 lavorato a Siena per 2-3 annetti :)

Davvero? Con biopython specificamente?
Se ti va di dare qualche contributo nella ml, e' ben accetto :)

 Visto che questi moduli devono essere utilizzati da terze parti,
 aggiungere un esempio del file di input nel doctest e' una cosa
 utilissima.
 In questo modo, un utente che si ritrovi a riutilizzare le mie
 librerie, potra' avere una idea chiara del formato per il quale un
 modulo e' stato scritto (pensa soprattutto a quando devi parsare un
 particolare formato di testo).

 Ok, quindi nella docstring metti anche il formato del file di testo da
 parsare.

Ci sono diversi formati con nomi simili e a volte anche omonimi, e
aggiungere un esempio del formato di input nella doc permette agli
utenti di non rischiare di utilizzare il parser sbagliato, che e' una
cosa buona.

Inoltre e' un grosso aiuto durante lo sviluppo del modulo.


 Certamente, anche se devo ammettere di non aver usato molto unittest.

 Questo mi spiega ancora meglio come mai usi così estensivamente doctest e
 non unittest :)

ufff grazie mille per le risposte, pero' per favore, lasciamo i
dibattiti doctest vs unittest ad altre discussioni.
Non ho detto che uso esclusivamente uno dei due, ne' che ho intenzione
di farlo; solo mi serve sapere un dettaglio dell'implementazione.

 Secondo me hai sbagliato in partenza a far sì che le tue funzioni di
 parsing accettino un filename in input. Se le tue funzioni accettassero un
 file object invece avresti i seguenti vantaggi (i primi che mi vengono in
 mente):


Si, pero' a volte e' necessario scrivere delle funzioni che accettino
nomi di file.
Per esempio, ci sono dei moduli che chiamano programmi esterni (io
sono contrario, perche' lo farei in altra maniera): quello che ho
fatto fino ad adesso e' aggiungere un doctest per illustrare il
formato del file, crearlo con NamedTemporaryFile, e passare
NamedTempFile.name.

Un'altra obiezione e' che e' meno chiaro passare un oggetto di tipo
file gia' aperto. Lavoro a fianco di persone che conoscono poco di
python, e se apro il file in una funzione e lo parso in un'altra, si
perdono, non capiscono il perche'.

Altrimenti in linea di massima sarei d'accordo con te, mi sembra che
sia anche la linea di condotta utilizzata in biopython.


  - potresti parsare stdin (e quindi mettere una serie di script in pipe).
   Per esempio parsare un file preso da internet con curl URL | python
 parser.py

  - potresti usare la doctest con lo StringIO :)

Si, per adesso ho fatto cosi'.
Creare un oggetto file-like con StringIO richiede solo 2 passaggi, e
quindi e' molto comodo usarlo con doctest.
Il problema e' che non posso utilizzarlo con funzioni che aprono il
file al loro interno.
Se solo StringIO avesse un attributo come 'name' di NamedTempFile, o
anche solo una maniera di passarne un riferimento, sarebbe molto piu'
comodo.


 Lo svantaggio nell'aprire un file normale è minimo: anzichè fare
 parse(filename) farai parse(open(filename)).

 È anche facile fare una funzione che, in caso di stringa, la apra
 assumendo un filename (if isinstance(file, basestring): file =
 open(file)), ma poi vorrai anche distinguere una url per aprirla con
 urllib, ma a volte la stringa contiene i dati... la cosa migliore per fare
 un parser generico credo sia accettare solo un file object in input e
 lasciare che sia il cliente della funzione ad accontentarla (mi sembra una
 corretta divisione delle responsibilità).

Si, anche questo si puo' fare... per fortuna non credo che avro' a che
fare con oggetti urllib e simili.
Grazie mille per le risposte :)

p.s. avete mai notato che doctest non usa doctest per la sua
documentazione (a parte pochi casi)? :)


 --
 Daniele Varrazzo - Develer S.r.l.
 http://www.develer.com




-- 

My blog on bioinformatics (now in English): http://bioinfoblog.it
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


[Python] doctest con funzioni che aprono files

2008-11-26 Per discussione Giovanni Marco Dall'Olio
Ciao a tutti,
e' da un po' di tempo che utilizzo doctest, e sono felice :).

Lo trovo molto comodo per scrivere funzioni che calcolano statistiche
e parsano particolari formati di files.

Quello che non capisco ancora e' come utilizzarlo per testare funzioni
che prendano in input il nome (path) di un file, e lo aprano.
Qualcosa del genere:
---
 def read_first_line(filename):
... fh = file(filename, 'r')
... for line in fh:
... do things...
---

(mi dispiace per il modo in cui gmail formattera' questo messaggio :( ).

Una possibile opzione e' utilizzare StringIO. Il problema e' che gli
oggetti StringIO non hanno un equivalente di un filename che si possa
passare ad una funzione, quindi sono costretto a scrivere moduli che
prendano in input file handlers invece che file names.

---
def read_first_line(fh):

 from StringIO import StringIO
 fh = StringIO('contenuto del file')
 read_first_line(fh)
   contenuto del file

print fh.readline()
---

Una seconda opzione e' quella di usare tempfile.NamedTemporaryFile.
Il problema e' che e' una opzione un poco brutta esteticamente, che
aggiunge un sacco di istruzioni non necessarie nella documentazione
(incasinandola).
---
def read_first_line(filename):

 from tempfile import NamedTemporaryFile
 fh = NamedTemporaryFile()
 fh.write('contenuto del file')
 fh.seek(0)
 read_first_line(fh.name)
contenuto del file

fh = file(filename)
print fh.readline()
---

Sul serio, chiedo scusa per la maniera con cui questo messaggio verra'
formattato da google. Se non e' comprensibile, lo posto da qualche
parte.

In parole povere, io sto cercando una funzione che mi permetta di
creare un oggetto simile ad un file, che sia accessibile tramite un
filename, di scriverci dentro del testo, e di riavvolgerlo al primo
bit, e tutto questo in una o due istruzioni.
Qualche suggerimento?


-- 

My blog on bioinformatics (now in English): http://bioinfoblog.it
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] doctest con funzioni che aprono files

2008-11-26 Per discussione Daniele Varrazzo


On Wed, 26 Nov 2008 17:44:55 +0100, Giovanni Marco Dall'Olio
[EMAIL PROTECTED] wrote:
 Ciao a tutti,
 e' da un po' di tempo che utilizzo doctest, e sono felice :).
 
 Lo trovo molto comodo per scrivere funzioni che calcolano statistiche
 e parsano particolari formati di files.
 
 Quello che non capisco ancora e' come utilizzarlo per testare funzioni
 che prendano in input il nome (path) di un file, e lo aprano.

Tu sei sicuro che una docstring nella quale hai buttato dentro tutto il
codice boilerplate per fargli aprire un file temporaneo abbia ancora una
qualche utilità come docstring?

È una mia idea personale, ma le doctest a me sembrano innanzitutto doc,
e solo come cosa secondaria e pythonesca test. In particolar modo, è
più un test della documentazione stessa che della funzione. Ma questo può
ovviamente essere stiracchiato un pochino, e quindi il test, come effetto
collaterale, testa che la funzione non cominci a sbagliare. Stiracchiando
stiracchiando però aggiungi documentazione utile ai fini del test e non
ai fini della documentazione, fino al punto che non è più documentazione
in lingua umana, ma codice Python che descrive codice Python.

È sempre una mia opinione personale, ma mi sembra che le doctest non
vogliano essere questo, al punto che non offrono nessuna facility di
costruzione di test suite. A me sembra che quello che tu stia facendo sia
una unit test completa, che ha bisogno di dati di appoggio ed eventualmente
funzioni di setup e cleanup.

 Una seconda opzione e' quella di usare tempfile.NamedTemporaryFile.
 Il problema e' che e' una opzione un poco brutta esteticamente, che
 aggiunge un sacco di istruzioni non necessarie nella documentazione
 (incasinandola).

Questo è quello che farei io, ma in una test suite. Questo credo sia il
punto dove la doctest smette di essere bella (documentazione che come
effetto collaterale si auto-testa) e diventa brutta (codice di test
scritto dove sarebbe dovuta andare la documentazione).

Puoi avere tutti e due, unittest e doctest non sono esclusive. Penso che le
doctest siano una bella abitudine: fossi in te sceglierei pragmaticamente
il meglio dei due mondi :)

-- 
Daniele Varrazzo - Develer S.r.l.
http://www.develer.com
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] doctest con funzioni che aprono files

2008-11-26 Per discussione Giovanni Marco Dall'Olio
2008/11/26 Daniele Varrazzo [EMAIL PROTECTED]:


 On Wed, 26 Nov 2008 17:44:55 +0100, Giovanni Marco Dall'Olio
 [EMAIL PROTECTED] wrote:
 Ciao a tutti,
 e' da un po' di tempo che utilizzo doctest, e sono felice :).

 Lo trovo molto comodo per scrivere funzioni che calcolano statistiche
 e parsano particolari formati di files.

 Quello che non capisco ancora e' come utilizzarlo per testare funzioni
 che prendano in input il nome (path) di un file, e lo aprano.

 Tu sei sicuro che una docstring nella quale hai buttato dentro tutto il
 codice boilerplate per fargli aprire un file temporaneo abbia ancora una
 qualche utilità come docstring?

Per alcune cose che devo fare, si.
Sto contribuendo al progetto biopython, una collezione di moduli per
la bioinformatica in python.
Visto che questi moduli devono essere utilizzati da terze parti,
aggiungere un esempio del file di input nel doctest e' una cosa
utilissima.
In questo modo, un utente che si ritrovi a riutilizzare le mie
librerie, potra' avere una idea chiara del formato per il quale un
modulo e' stato scritto (pensa soprattutto a quando devi parsare un
particolare formato di testo).

Qualche settimana fa ho scritto un post sul mio blog per spiegare
questo; vedi se l'esempio puo' essere piu' chiaro:
- http://bioinfoblog.it/2008/11/biopython-e-doctest/
In questi giorni sto scrivendo molti parsers cosi':
- 
http://github.com/dalloliogm/biopython---popgen/tree/master/src%2FPopGen%2FGio%2FfastPhaseOutputIO.py


 È una mia idea personale, ma le doctest a me sembrano innanzitutto doc,
 e solo come cosa secondaria e pythonesca test. In particolar modo, è
 più un test della documentazione stessa che della funzione. Ma questo può
 ovviamente essere stiracchiato un pochino, e quindi il test, come effetto
 collaterale, testa che la funzione non cominci a sbagliare. Stiracchiando
 stiracchiando però aggiungi documentazione utile ai fini del test e non
 ai fini della documentazione, fino al punto che non è più documentazione
 in lingua umana, ma codice Python che descrive codice Python.

In parte si'. Te lo posso confermare, perche' ultimamente ho scritto
dei doctest enormi.
Pero', se scrivi la doctest ancora prima del codice, poi viene molto
piu' facile scrivere il resto (beh, questo e' vero con tutti i test).

 È sempre una mia opinione personale, ma mi sembra che le doctest non
 vogliano essere questo, al punto che non offrono nessuna facility di
 costruzione di test suite. A me sembra che quello che tu stia facendo sia
 una unit test completa, che ha bisogno di dati di appoggio ed eventualmente
 funzioni di setup e cleanup.

In parte si, e comunque li puoi integrare con unittest (doctest.DocTestSuite)


 Una seconda opzione e' quella di usare tempfile.NamedTemporaryFile.
 Il problema e' che e' una opzione un poco brutta esteticamente, che
 aggiunge un sacco di istruzioni non necessarie nella documentazione
 (incasinandola).

 Questo è quello che farei io, ma in una test suite. Questo credo sia il
 punto dove la doctest smette di essere bella (documentazione che come
 effetto collaterale si auto-testa) e diventa brutta (codice di test
 scritto dove sarebbe dovuta andare la documentazione).

come dicevo prima, se devi scrivere del codice riutilizzabile da altre
persone, la doctest e' utile.
E' molto comoda anche se stai lavorando al fianco di persone che non
sanno molto di programmazione, e vuoi farli capire esattamente cosa
verra' fuori nei risultati. Ho dei buoni esempi su questo, ma ora non
ho il tempo di caricarli :)

 Puoi avere tutti e due, unittest e doctest non sono esclusive. Penso che le
 doctest siano una bella abitudine: fossi in te sceglierei pragmaticamente
 il meglio dei due mondi :)

Certamente, anche se devo ammettere di non aver usato molto unittest.


 --
 Daniele Varrazzo - Develer S.r.l.
 http://www.develer.com




-- 

My blog on bioinformatics (now in English): http://bioinfoblog.it
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] doctest con funzioni che aprono files

2008-11-26 Per discussione Daniele Varrazzo


On Wed, 26 Nov 2008 19:11:24 +0100, Giovanni Marco Dall'Olio
[EMAIL PROTECTED] wrote:

 Tu sei sicuro che una docstring nella quale hai buttato dentro tutto il
 codice boilerplate per fargli aprire un file temporaneo abbia ancora una
 qualche utilità come docstring?
 
 Per alcune cose che devo fare, si.
 Sto contribuendo al progetto biopython, una collezione di moduli per
 la bioinformatica in python.

Lo conosco, ho studiato bioinformatica per la tesi di laurea e ci ho
lavorato a Siena per 2-3 annetti :)


 Visto che questi moduli devono essere utilizzati da terze parti,
 aggiungere un esempio del file di input nel doctest e' una cosa
 utilissima.
 In questo modo, un utente che si ritrovi a riutilizzare le mie
 librerie, potra' avere una idea chiara del formato per il quale un
 modulo e' stato scritto (pensa soprattutto a quando devi parsare un
 particolare formato di testo).

Ok, quindi nella docstring metti anche il formato del file di testo da
parsare.

 Certamente, anche se devo ammettere di non aver usato molto unittest.

Questo mi spiega ancora meglio come mai usi così estensivamente doctest e
non unittest :)

Secondo me hai sbagliato in partenza a far sì che le tue funzioni di
parsing accettino un filename in input. Se le tue funzioni accettassero un
file object invece avresti i seguenti vantaggi (i primi che mi vengono in
mente):

 - potresti parsare stdin (e quindi mettere una serie di script in pipe). 
   Per esempio parsare un file preso da internet con curl URL | python
parser.py

 - potresti usare la doctest con lo StringIO :)

Lo svantaggio nell'aprire un file normale è minimo: anzichè fare
parse(filename) farai parse(open(filename)). 

È anche facile fare una funzione che, in caso di stringa, la apra
assumendo un filename (if isinstance(file, basestring): file =
open(file)), ma poi vorrai anche distinguere una url per aprirla con
urllib, ma a volte la stringa contiene i dati... la cosa migliore per fare
un parser generico credo sia accettare solo un file object in input e
lasciare che sia il cliente della funzione ad accontentarla (mi sembra una
corretta divisione delle responsibilità).

-- 
Daniele Varrazzo - Develer S.r.l.
http://www.develer.com
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python