sabato 20 ottobre 2007

httpxmlfixture

L'ultima cosa di cui mi sono occupato, per lavoro, è la creazione di una fixture per fitnesse, per fare acceptance testing e test driven development di applicazioni web.

Si tratta praticamente di una evoluzione di questa fixture che consente di fare alcune verifiche basate su xpath rispetto al contenuto di una pagina web, ovvero verificare che un certo nodo, individuato via espressione xpath, sulla pagina indicata da una certa url esista o meno, che abbia un certo valore, oppure che il numero di nodi che "matchano" l'espressione sia quello che ci si aspetta.

A questo ho aggiunto le seguenti caratteristiche:

- poter accedere a pagine che richiedono autenticazione (basic o, in alcuni casi, form)
- poter lavorare anche su pagine che non sono ben formate come xml, usando jTidy come preprocessor
- gestire i cookies così potendo gestire anche la sessione di navigazione (se basata su cookie)
- gestire eventuale submission di parametri via post o get.
- poter generare automaticamente un test che va a buon fine rispetto ad un esempio statico.

In teoria dovrebbe essere sufficiente per poter fare dei chiari test di accettazione per applicazioni web, almeno se si tratta di testare solamente cose "server side" (niente javascript/ajax quindi).

Per esempio: il customer si dice soddisfatto che l'applicazione renderizzerà una pagina in modo conforme ad un certo esempio fornito come pagina statica. A quel punto la pagina statica viene "processata" da xml2xpath, e viene creato il relativo test che ha successo quando la pagina viene "deployata".

Supponiamo che nella pagina vi sia una tabella, che dovrà poi contenere dati dinamici.
Il customer vorrà magari che "in quella tabella poi dovranno essere presenti i dati che verranno inseriti in una certa form".
Allora si modifica subito l'espressione xpath che verifica i dati in tabella, e si fa in modo che il test sia esteso in modo da incluere anche l'azione di "inserire un certo dato, e poi andare nella pagina dell'elenco ed aspettarsi di trovare quel dato".

La cosa descritta adesso è più o meno una user story e l'idea è di scrivere un test che la "descrive", e ne verifica anche la corretta implementazione.

Un po' più in dettaglio se la pagina statica pensata all'inizio è del tipo:


<html>
<head/>
<body>
<table>
<tr>
<td>entry1</td>
</tr>
<tr>
<td>entry2</td>
</tr>
<tr>
<td>entry3</td>
</tr>
</table>
</body>
</html>



allora lo stylesheet xml2xpath genera il seguente pezzo di tabella di test:

| Value | /html/body/table/tr/td | entry1 |
| Value | /html/body/table/tr[2]/td | entry2 |
| Value | /html/body/table/tr[3]/td | entry3 |

a questo punto, se si progetta che l'azione di inserimento di questi dati dovrà essere data da una certa jsp che si chiamerà submitaction.jsp, con un parametro entryname, allora, prendendo un po' spunto dal test precedente, l'intera storia "sottometti il dato entryX e poi verifica che
visualizzando la tabella, esso sia presente", è un po' come segue":

...
|newUrlPost|http://myserver/submitaction.jsp|
|NameValuePair|entryname|entryX|
|newUrlGet|http://myserver/visualize.jsp |
|AValue|/html/body/table/tr[*]/td | entryX |

Ovviamente poi il test resta lì utile anche a verificare non solo quando l'implementazioe è corretta, ma anche che continui a rimanere corretta.

cosa e' (era) learph

Cercando in rete e' ancora possibile trovare, in qualche pagina che raccoglie informazioni sui sistemi di sintesi e riconoscimento vocale, un riferimento a "learph. Trainable text-to-phonemes software by Antonio Lucca" (che sarei io), e che risale al lontano '93.

(Il nome fa veramente schifo, avevo messo insieme la parola "learn" e "phonemes".
Considerando poi che l'inglese è una lingua che usa spesso parole onomatopeiche, lasciamo stare.)

Non è possibile scaricarlo perché il link non è più valido. Potrei ripubblicarlo ma non so se ne valga la pena.

Questo programma non sarebbe altro che una "demo", in C, utilizzabile in riga di comando, che "impara", a partire da un training set di esempi di parole inglesi associate alla loro corrispondente rappresentazione fonetica, le regole di traduzione da parola a fonemi, cioè sostanzialmente le regole del modo in cui si pronunciano.

Il training set era stato ottenuto banalmente prendendo un vocabolario ed applicando ad ogni sua parola un preesistente algoritmo di traduzione testo-fonemi.

Quindi in sostanza il progetto era di creare un sistema che, sulla base di esempi, impara ad eseguire un compito per il quale già esiste un algoritmo! :-)

(La descrizione è qui semplificata perché esiste la possibilita che un gruppo di lettere sia associato a più fonemi e viceversa, che una lettera sia muta e così via. Per gestire questo avevo modificato il training set un po' a mano aggiungendo queste informazioni, sulla base di decisioni sostanzialmente arbitrarie ma intuitivamente valide. Inoltre, per semplificare, avevo eliminato i simboli relativi all'intonazione/accento/stress)

Il progetto mi era venuto in mente per le seguenti motivazioni:
. ero un orgoglioso possessore del Commodore Amiga, che era uno dei pochi computer dotati di software per la sintesi vocale
. seguivo il corso di cibernetica e teoria dell'informazione, che trattava di temi come il computational learning, e ho scelto questo progetto come tesina
. avevo sentito dire che era stato implementato un sistema basato su reti neurali, chiamato NetTalk, che era stato concepito per quello scopo

Avevo dato un'occhiata al codice relativo ad algoritmi ad hoc per questo compito, e si tratta di algoritmi abbastanza "ingarbugliati", perché sostanzialmente non c'è una precisa regolarità nella pronuncia.

Tuttavia una metaregola generale banalmente c'è, su cui anche il "nettalk" è basato: il fatto che ogni lettera si pronuncia in modo diverso in funzione del suo contesto, cioè delle lettere vicine.

L'algoritmo che avevo implementato è basato su questo principio ed in particolare si comporta come segue:
memorizza ogni associazione singola lettera->fonema riscontrata negli esempi, ed assumi in prima istanza che questa associazione sia una regola generale, a meno che tu non trovi un esempio che contraddice questa regola
Quando trovi un esempio che contraddice questa regola, allora elimina la regola, e crea nuove regole in cui tieni conto delle informazioni di contesto del primo e del secondo caso, ovvero regole che associano non la lettera stessa al fonema, ma la lettera preceduta da una certa lettera e seguita da una certa altra lettera.

Naturalmente anche queste regole potrebbero essere in contraddizione tra loro, cioè no risolvere completamente l'ambiguità. In quel caso si espande l'ipotesi e si include nel contesto anche la lettera immediatamente precedente e successiva al quella "tripla".

E così via fino a che le regole risultano tutte consistenti rispetto al training set.

Una volta memorizzate le regole, l'algoritmo di pronuncia che associa ad una parola la sua rappresentazione fonetica non fa altro che parsare lettera per lettera la parola in ingresso, e fa un lookup sulle regole memorizzate, che dicono sostanzialmente come andrebbe pronunciata quella lettera in quel contesto.

Naturalmente questo significa che per le parole appartenenti al training set il sistema funziona perfettamente, mentre se ci sono parole non appartenenti al training set potrebbe esserci ancora qualche ambiguità. In quel caso non ricordo bene che scelta feci. Se non erro c'era un mix di euristica unita ad una scelta casuale, tra quelle possibili.

Comunque funzionava abbastanza bene, nel senso che il principio era sufficentemente semplice e generale, funzionava al 100% sul training set (mentre è noto che con le reti neurali questo di solito non avviene), la struttura dati contenente le regole era relativamente piccola, una sorta di albero di decisione, e consentiva una buona generalizzazione.

Questo progetto fu fatto nel lontano '93, ma non ricordo quando lo feci aggiungere al repository comp.speech, ne' so quante persone lo abbiano scaricato, visionato.

mercoledì 17 ottobre 2007

annotations speciali associate a metodi "mutators" e "observers" per mostrare una prova empirica della sostituibilita' tra oggetti

Ho creato un nuovo progetto su esperimenti relativi alla nozione object oriente di sottoclasse, sostituibilità usando le annotazioni di java 5.

http://testlspjava5.googlecode.com/

I metodi possono distinguersi in diversi tipi, tra cui, mutators ed observers.
Grosso modo: i mutators modificano lo stato dell'oggetto, gli observer ne ispezionano lo stato.
Sono associabili, tramite annotazioni, per ogni mutator, degli "instance genertor" che generano una sequenza ripetibile di n-pla di parametri applicabili a tale metodo mutator.

Viene così simulata, sotto il controllo di junit, una computazione "casuale" ma ripetibile, che coinvolge la classe e che agisce sui mutators, creando dunque una sequenza di stati per un generico oggetto della classe.
Viene ripetutta una seconda volta la stessa computazione usando la sottocalsse anziché la classe.

La prova empirica della sostituibilità sta nel fatto che la sequenza di stati della prima computazione (che riguarda la classe) è equivalente alla seconda sequenza di stati della computazione (che riguarda la sottoclasse).

L'equivalenza è definita in termini di observers, ovvero, ricorsivamente, di equivalenza di stato di tutti i valori/oggetti restitui dagli observers.

Informazioni personali

La mia foto
I have been coding from the old C64 times. Studied Computer Sciences at Milan University. I also worked there in technical operations. Many years of experiences in coding Java and C#, desktop and web applications, with practices like unit testing. I used to play with 3d graphics in architecture recently with Blender 3d. Now I look for support related to some projects I am working on, oriented in automation in tourism related services, using functional programming framework, specifically F# and Suave.IO. email
tonyx1 (at) gmail.com github https://github.com/tonyx