Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – [email protected] Dr. Alessandro...

103
Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – [email protected] Dr. Alessandro Laganà – [email protected]

Transcript of Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – [email protected] Dr. Alessandro...

Page 1: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

BioinformaticaLinguaggio Perl (2)

Dr. Giuseppe Pigola – [email protected]. Alessandro Laganà – [email protected]

Page 2: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Corrispondenza di pattern Uno degli strumenti di PERL per riconoscere pattern

sono le espressioni regolari;

Le espressioni regolari sono quasi un linguaggio a parte;

Sono un metodo formale di descrivere i pattern da trovare;

Nel seguito vedremo come creare semplici espressioni regolari, usare le espressioni regolari nella corrispondenza di pattern e modificare le stringhe usando le espressioni regolari;

2 Bioinformatica

Page 3: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Pattern semplici In PERL i pattern sono racchiusi in un operatore di

corrispondenza di pattern, che alle volte è rappresentato come m//:

Il pattern precedente corrisponde alle lettere S-i-m-o-n in sequenza;

Se non specificato diversamente il pattern viene cercato in $_;

Se il pattern specificato da m// è trovato nella variabile $_, l’operatore di corrispondenza restituisce vero:

m/Simon/

if (m/Piglet/) {

: # Il pattern “Piglet” è in $_

}

3 Bioinformatica

Page 4: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Metacaratteri Nel pattern ogni carattere corrisponde a se stesso a

meno che non si tratti di un metacarattere;

I metacaratteri sono i caratteri che cambiano il comportamento della corrispondenza di pattern: ^ $ ( ) \ | @ [ { ? . + *

Se il pattern contiene un metacarattere da usare come valore letterale, si deve far precedere il metacarattere da un backslash:

m/I won \$10 at the fair/; # Il carattere $ è trattato come simbolo del dollaro letterale

4 Bioinformatica

Page 5: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

// o altri delimitatori Oltre che usando gli slash, è possibile rappresentare

l’operatore di corrispondenza utilizzando qualsiasi altro carattere:

Spesso il delimitatore viene sostituito quando il pattern contiene slash:

Ma così è più leggibile:

if (m,Waldo,) { print “Found Waldo.\n”; }

if (m/\/usr\/local\/bin\/hangman/) { print “Found…”; }

if (m:/usr/local/bin/hangman:) { print “Found…”; }

5 Bioinformatica

Page 6: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Delimitatori // - Variabili Se i delimitatori sono slash si può anche scrivere la

corrispondenza di pattern senza la m e scrivere ad es. /Cheetos/ al posto di m/Cheetos/;

Anche le variabili possono essere usate nelle espressioni regolari. Se un’espressione regolare contiene una variabile scalare, PERL valuta prima la variabile e la interpola; quindi esamina l’espressione regolare:$pat=<STDIN>; chomp $pat;

$_=“The phrase that pays”;

if (/$pat/) {

print “\”$_\” contains the pattern $pat\n”;

}

6 Bioinformatica

Page 7: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Regole del gioco… Generalmente, le corrispondenze di pattern iniziano a

sinistra della stringa obiettivo e procedono verso destra;

Le corrispondenze di pattern restituiscono vero (in qualsiasi contesto) solo se l’intero pattern è presente nella stringa obiettivo;

E’ trovata per prima la prima corrispondenza possibile (quella più a sinistra) nella stringa obiettivo. Le espressioni regolari non lasciano indietro una buona corrispondenza per cercarne un’altra;

Si prende la prima corrispondenza più grande possibile. L’espressione regolare potrebbe trovare subito una corrispondenza e cercare di estenderla il più possibile. Le espressioni regolari cercano di estendere quanto più possibile la corrispondenza.

7 Bioinformatica

Page 8: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Un metacarattere semplice: . Il metacarattere punto . corrisponde a qualsiasi

carattere singolo a eccezione del carattere di nuova riga;

Per es., nel pattern /p.t/, il punto corrisponde a qualsiasi carattere singolo;

Questo pattern troverebbe corrispondenza in pot, pat, pit, carpet, python, …

8 Bioinformatica

Page 9: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

I non stampabili \n carattere di nuova riga;

\r ritorno a capo;

\t tabulazione;

\f carattere di avanzamento di pagina;

9 Bioinformatica

Page 10: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Quantificatori Un quantificatore è un tipo di metacarattere che

indica all’espressione regolare quante occorrenze consecutive di qualcosa deve trovare;

Un quantificatore può essere inserito dopo qualsiasi carattere singolo o gruppo di caratteri;

Il quantificatore più semplice è il metacarattere +, che fa sì che il carattere precedente corrisponda almeno una volta. Quindi, /do+g/ si trova in: hounddog ma non in badge hotdog ma non in doofus doogie howser ma non in Doogie doooooog ma non in pagoda

10 Bioinformatica

Page 11: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

I metacaratteri * e ? * è simile a +, ma fa sì che il carattere precedente corrisponda

zero o più volte;

Ad es. il pattern /t*/ indica di trovare quante più corrispondenze è possibile, ma anche nessuna. Quindi /car*t/ corrisponde a: carted ma non a carrot cat ma non a carl carrrt ma non a caart

Il metacarattere ? fa sì che il carattere precedente corrisponda zero o una volta (al più).

Così /c?ola/ trova cola e ola ma non ccola.

/c*ola/ invece trova cola, ola e ccola.11 Bioinformatica

Page 12: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Ancora quantificatori PERL consente di trovare il numero esatto di

corrispondenze desiderate usando le parentesi graffe { }: pat{n,m}

In questo caso, n è il numero minimo di corrispondenze e m il numero massimo di corrispondenze, mentre pat è il gruppo di caratteri da quantificare;

Vediamo alcuni esempi: /x{5,10}/ x occorre almeno 5 volte, ma non più di 10 /x{9,}/ x occorre almeno 9 volte, ma anche di più /x{0,4}/ x occorre fino a 4 volte, ma anche 0 /x{8}/ x occorre esattamente 8 volte

12 Bioinformatica

Page 13: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

.* La scrittura .* consente di trovare qualsiasi cosa tra

due cose desiderate;

Ad es. /first.*last/ cerca di trovare la parola first seguita da qualsiasi cosa, quindi la parola last: first then last; The good players get picked first, the bad last; The first shall be last, and the last shall be first;

13 Bioinformatica

Page 14: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Classi di caratteri Un’altra pratica comune nelle espressioni regolari è chiedere

una corrispondenza di “uno qualsiasi di questi caratteri” Le espressioni regolari di PERL offrono un tale strumento (classe

di caratteri). Per scrivere una classe di caratteri, i caratteri contenuti devono

essere racchiusi tra parentesi quadre [ ]. I caratteri in una classe di caratteri sono trattati come un

carattere singolo durante la corrispondenza:

[abcde] Corrisponde a qualsiasi a,b,c,d o e [a-e] Idem [Gg] Corrisponde a G o a g [0-9] Una cifra [0-9]+ Una o più cifre in sequenza [A-Za-z]{5} Qualsiasi gruppo di cinque caratteri

alfab. [*!@#$%&()] Tutti questi caratteri di punteggiatura. In

questo caso * rappresenta un letterale.

14 Bioinformatica

Page 15: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Classi di caratteri (2) Se il primo carattere di una classe di caratteri è un

accento circonflesso (^), la classe viene negata: /[^A-Z]/

In questo caso trova caratteri alfabetici non maiuscoli.

Poiché ], ^ e – sono speciali in una classe di caratteri, esistono alcune regole per la corrispondenza di questi caratteri in modo letterale: Per trovare un ^ letterale si deve esser certi che

non sia il primo carattere della classe; Per trovare un ] letterale è necessario inserirlo

come primo carattere o farlo precedere da un \: /[abc\]]/.

Per inserire un – letterale è necessario inserirlo come primo carattere o farlo precedere da un \.

15 Bioinformatica

Page 16: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Classi speciali di caratteri \w un carattere parola; equivale a [a-zA-Z0-9_] \W un carattere non parola (inverso di \w) \d una cifra; equivale a [0-9] \D un carattere diverso da una cifra \s uno spazio bianco; equivale a [ \t\f\r\n] \S un carattere che non sia uno spazio bianco

Esempi

/\d{5}/ corrisponde a 5 cifre /\s\w+\s/ corrisponde a un gruppo di caratteri parola

circondati da uno spazio bianco

16 Bioinformatica

Page 17: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Gruppi e alternanze In un’espressione regolare può capitare di voler

sapere se viene trovato uno qualsiasi di un insieme di pattern. La soluzione si chiama alternanza:

Se cerchiamo però le parole frog, bog, log, flog o clog l’espressione /frog|bog|log|flog|clog/ diventa troppo ripetitiva. In questo caso: /(fr|b|l|fl|cl)og/

if (/dogs|cats/) {

print “\$_ contains a pet\n”;

}

17 Bioinformatica

Page 18: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Gruppi e alternanze (2) E’ possibile nidificare le parentesi per formare gruppi

all’interno di altri gruppi. /(fr|b|(f|c)?l)og/

In un contesto elenco l’op. di corrispondenza restituisce una lista delle porzioni dell’espressione trovata racchiuse in parentesi. Ogni valore in parentesi è un valore di ritorno della lista oppure 1 se il pattern non contiene parentesi:

In questo caso il pattern trova qualsiasi cosa (come gruppo), quindi lo spazio bianco, la parola is, un altro spazio bianco e ancora qualsiasi cosa (sempre come gruppo).

Le due espressioni raggruppate sono restituite all’elenco sul lato sinistro e assegnate a $fruit e $color.

$_=“apple is red”;

($fruit, $color)=/(.*)\sis\s(.*)/;

18 Bioinformatica

Page 19: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Riferimenti I riferimenti si usano per indicare al motore di espressioni

regolari dove cercare il pattern: all’inizio della stringa o alla fine.

Il carattere ^ all’inizio di un’espressione regolare fa sì che l’espressione corrisponda solo all’inizio di una riga. /^video/ trova la parola video solo se si trova all’inizio di una

riga Il simbolo $ alla fine di un’espressione regolare fa sì che il

pattern corrisponda solo alla fine di una riga. /earth$/ trova earth ma solo alla fine di una riga.

Altri esempi /^Help/ Le righe che iniziano con Help /^Frankly.*darn$/ Le righe che iniziano con Frankly e

finiscono con darn e tutto ciò che sta in mezzo /^hysteria$/ Le righe che contengono solo la parola hysteria /^$/ Righe vuote /^/ Tutte le righe

19 Bioinformatica

Page 20: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Sostituzione Per sostituire i pattern trovati:

L’op. di sostituzione s/// (dove / può essere sostituito con altri caratteri, es. s###) cerca $_ per patterncercato e sostituisce l’intera espressione regolare trovata con sostituzione.

L’operatore restituisce il numero di corrispondenze o sostituzioni eseguite, o 0 se non ha trovato nulla:

s/patterncercato/sostituzione/;

$_=“Our house is in the middle of our street”;

s/middle/end/;

s/in/at/;

if (s/apartment/condo/) {

# questo codice non è raggiunto

}

20 Bioinformatica

Page 21: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Lavorare con altre variabili Piuttosto che lavorare con $_ sarebbe meglio in

generale lavorare con altre variabili;

Per usare l’operatore di corrispondenza e l’operatore di sostituzione su variabili diverse da $_ è necessario associarle alla variabile usando l’op. di associazione =~:

L’op. =~ non effettua assegnazioni ma si limita a prendere l’op. di destra e a farlo agire sulla variabile a sinistra.

$weight=“185 lbs”;

$weight=~s/ lbs//; # toglie lbs dalla stringa

21 Bioinformatica

Page 22: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Modificatori e corrispondenze multiple Per trovare parole senza preoccuparsi se sono maiuscole o

minuscole:

Ovviamente PERL offre una soluzione più comoda:

Un altro modificatore per le corrispondenze e le sostituzioni è il modificatore di corrispondenza globale g: l’espressione regolare (o sostituzione) è eseguita ripetutamente nell’intera stringa, effettuando ogni corrispondenza (o sostituzione) subito dopo la prima;

I modificatori possono essere combinati specificandoli tutti dopo l’operazione di corrispondenza o sostituzione. Per es. gi trova tutte le occorrenze di pattern nella stringa, in maiuscolo o minuscolo.

/[Mm][Aa][Cc][Bb][Ee][Tt][Hh]/;

/macbeth/i;

22 Bioinformatica

Page 23: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Modificatori In un contesto elenco, il modificatore di corrispondenza

globale restituisce una lista di tutte le porzioni dell’espressione regolare racchiuse tra parentesi:

In un contesto scalare il modificatore g itera la corrispondenza sulla stringa restituendo vero per ogni corrispondenza e falso quando non trova più corrispondenze:

$_=“One fish, two frog, red fred, blue foul”;

@F=m/\W(f\w\w\w)/g; # restituisce in @F fish frog fred foul

$letters=0;

$phrase=“What’s my line?”;

while($phrase=~/\w/g) {

$letters++;

}

23 Bioinformatica

Page 24: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Riferimenti all’indietro Quando si usano le parentesi nelle espressioni

regolari, PERL memorizza la porzione della stringa obiettivo che corrisponde a ogni espressione in parentesi;

Queste porzioni trovate sono salvate in una variabile speciale di nome $1 (per il primo insieme di parentesi), $2 (per il secondo) etc;

Il pattern dell’esempio seguente trova i numeri telefonici del Nord America – per. Es. 800-555-1212 – e memorizza ogni porzione in $1, $2 e $3:if (/(\d{3})-(\d{3})-(\d{4})/) {

print “The area code is $1”;

}

24 Bioinformatica

Page 25: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

La funzione grep PERL offre una funzione particolare per cercare pattern negli

array:

La funzione grep itera ogni elemento nella lista ed esegue l’espressione o blocco. Nell’espressione o blocco, $_ è impostata a ogni elemento della lista valutato. Se l’espressione restituisce vero, l’elemento è restituito da grep:

In questo caso ogni elemento di @dogs è assegnato, a turno, a $_. L’espressione /hound/ è quindi testata su $_. Ogni elemento che restituisce vero, viene inserito in una lista restituita da grep e memorizzata in @hounds.

grep espressione, lista

grep blocco lista

@dogs=qw(greyhound bloodhound terrier mutt chihuahua);

@hounds=grep /hound/, @dogs;

25 Bioinformatica

Page 26: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Ancora grep E’ importante notare che $_ nell’espressione si

riferisce al valore effettivo nella lista, non a una copia. Modificare $_ cambia l’elemento originale nell’elenco:

Ora @hounds contiene greyhounds e bloodhounds, con una s alla fine. L’array @dogs originale è anch’esso modificato;

grep può essere usato con qualsiasi altra funzione:

@hounds=grep s/hound/hounds/, @dogs

@longdogs=grep length($_)>8, @dogs;

26 Bioinformatica

Page 27: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

La funzione map map ha una sintassi identica a grep ma restituisce il

valore dell’espressione (o blocco), non il valore di $_. Si può usare la funzione map per produrre un secondo array basato sul primo:

In questo caso ogni elemento dell’array @input è diviso sugli spazi, producendo una lista di parole, che viene aggiunta alla lista restituita dalla funzione map. Una volta divisa ogni riga consecutiva di @input, le parole accumulate sono memorizzate in @words.

@words = map { split ‘ ‘, $_ } @input;

27 Bioinformatica

Page 28: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Gli hash Gli hash rappresentano un altro tipo di dati collettivo;

Come gli array, gli hash contengono una serie di scalari. La differenza tra array e hash consiste nel fatto che gli hash accedono ai dati scalari per nome, invece di usare un valore numerico come fanno gli array;

Gli elementi degli hash sono composti da due parti: una chiave e un valore. La chiave identifica ogni elemento dell’hash, mentre il valore rappresenta i dati associati alla chiave. Questa relazione è definita come coppia chiave-valore;

Esempi di strutture dati con natura hash sono i numeri seriali dei prodotti, la registrazione di pazienti le bollette, il file system del disco, raccolte CD, etc.

28 Bioinformatica

Page 29: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Gli hash in PERL Un hash in PERL può contenere tutti gli elementi desiderati o

almeno quelli consentiti dalla memoria disponibile nel sistema;

Gli hash vengono ridimensionati man mano che si aggiungono e si eliminano elementi;

L’accesso ai singoli elementi è molto rapido e non rallenta in modo significativo man mano che l’hash aumenta di dimensioni;

Le chiavi dell’hash possono avere la lunghezza desiderata (sono scalari) così come le parti dei dati;

Le variabili hash sono indicate dal segno percentuale %. Non condividono i nomi con gli array e gli scalari. Ad es. possiamo avere un hash di nome %a, un array di nome @a e uno scalare di nome $a.29 Bioinformatica

Page 30: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Riempire l’hash E’ possibile creare singoli elementi di hash come segue:

In questo es. viene assegnato un elemento all’hash %Authors. La chiave di questo elemento è il termine ‘Dune’, mentre i dati sono costituiti dal nome ‘Frank Herbert’;

Il valore associato alla chiave, $Authors{‘Dune’}, può essere considerato come qualsiasi altro scalare;

Perché abbiamo usato $Authors anziché %Authors? Come gli array quando gli hash sono rappresentati come singola entità, presentano un indicatore davanti al nome della variabile (%). Quando si accede ad un singolo elemento invece si accede ad uno scalare.

$Authors{‘Dune’}=‘Frank Herbert’;

30 Bioinformatica

Page 31: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Inserimento di valori nell’hash

Questa operazione si può abbreviare così:

$food{‘apple’}=‘fruit’;

$food{‘pear’}=‘fruit’;

$food{‘carrot’}=‘vegetable’;

%food = (‘apple’, ‘fruit’, ‘pear’, ‘fruit’, ‘carrot’, ‘vegetable’);

31 Bioinformatica

Page 32: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Operatore virgola-freccia => Questo operatore consente di rendere le

assegnazioni più leggibili:

E’ possibile scrivere i termini sinistri degli operatori => senza apici. Inoltre una chiave hash a parola singola tra parentesi graffe viene automaticamente racchiusa tra apici:

%food = (‘apple’ => ‘fruit’, ‘pear’ => ‘fruit’, ‘carrot’ => ‘vegetable’);

$Books{Dune} = ‘Frank Herbert’;

%food = (apple => ‘fruit’, pear => ‘fruit’, carrot => ‘vegetable’);

32 Bioinformatica

Page 33: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Ottenere i dati da un hash

Spesso non è conveniente accedere a ogni chiave per nome. La funzione keys può essere usata per recuperare tutte le chiavi di un hash restituite come elenco, che può essere quindi esaminato per trovare tutti gli elementi dell’hash:

%Movies = (‘The Shining’ => ‘Kubrick’, ‘Ten Commandments’ => ‘DeMille’, Goonies => ‘Donner’);

print $Movies{‘The Shining’};

foreach $film (keys %Movies) {

print “$film was directed by $Movies($film).\n”;

}

33 Bioinformatica

Page 34: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Recuperare valori La funzione values consente di recuperare tutti i

valori memorizzati in un hash:

Ogni elemento di @Directors e @Films contiene un riferimento alla stessa coppia chiave-valore di %Movies. Il nome del regista contenuto in $Directors[0] corrisponde al nome del film memorizzato in $Films[0] e così via.

@Directors=values %Movies;

@Films=keys %Movies;

34 Bioinformatica

Page 35: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Invertire l’hash A volte è necessario recuperare elementi individuali

dall’hash in base al valore invece che in base alla chiave. Il metodo migliore per far questo è invertire l’hash, cioè creare un nuovo hash in cui tutte le chiavi dell’hash originale diventano valori e i valori diventano chiavi:

Se i valori (che devono diventare chiavi) non sono univoci si finirà per avere un hash con meno elementi di quello originale. Quando i valori duplicati vengono inseriti nel nuovo hash, le chiavi presenti sono sostituite con quelle nuove.

%Movies = (‘The Shining’ => ‘Kubrick’, ‘Ten Commandments’ => ‘DeMille’, Goonies => ‘Donner’);

%ByDirector= reverse %Movies

35 Bioinformatica

Page 36: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Liste e hash Quando un hash viene usato in un contesto elenco,

PERL lo trasforma in una lista normale di chiavi e valori. Questa può essere assegnata agli array:

E’ possibile eseguire qualsiasi operazione di array normale su @Data e riassegnare l’array a %Movies:

%Movies = (‘The Shining’ => ‘Kubrick’, ‘Ten Commandments’ => ‘DeMille’, Goonies => ‘Donner’);

@Data = %Movies;

%Movies = @Data

36 Bioinformatica

Page 37: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Ancora sugli hash Per copiare un hash è possibile assegnarlo

semplicemente ad un altro hash:

E’ possibile inserire hash all’interno di hash:

Se %Second contiene una chiave che compare anche in %First, la seconda occorrenza della coppia chiave-valore sostituisce la prima in %Both.

%New_Hash = %Old_Hash;

%Both = (%First, %Second);

%Additional = (%Both, key1 => ‘value1’, key2 => ‘value2’);

37 Bioinformatica

Page 38: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Controllo delle chiavi in un hash Per verificare se una chiave esiste in un hash:

if( exists $Hash{keyval} ) {

}

38 Bioinformatica

Page 39: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Rimuovere chiavi da un hash Nel modo seguente:

Per rimuovere tutte le chiavi e i valori:

delete $Hash{keyval};

%Hash = ();

39 Bioinformatica

Page 40: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Impiego dell’hash: determinare le distribuzioni di frequenze

Il pattern cercato è un carattere parola \w seguito da nessuno o più caratteri parola oppure trattini [\w-]*;

Con le parentesi la stringa corrispondente viene memorizzata in $1;

$1 viene impostato, a turno, a ogni parola corrispondente al pattern della seconda riga. Questa parola viene usata come chiave all’hash %Words;

La prima volta che appare la parola, la chiave non esiste ancora nell’hash quindi PERL restituisce un valore undef per la coppia.

while ( <>) {

while ( /(\w[\w-]*)/g ) {

$Words{$1}++;

}

}

40 Bioinformatica

Page 41: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Incrementandolo, PERL imposta il valore a 1, creando la coppia;

La seconda volta che compare una parola, la chiave esiste già nell’hash %Words e viene incrementata da 1 a 2;

Alla fine l’hash %Words contiene una distribuzione di frequenze delle parole lette:

Impiego dell’hash: determinare le distribuzioni di frequenze (2)

foreach ( keys %Words ) {

print “$_ $Words{$_}\n”;

}

41 Bioinformatica

Page 42: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Trovare elementi unici negli array Consideriamo la seguente lista:

Per trovare gli elementi senza i duplicati:

@fishwords=(‘one’, ‘fish’, ‘two’, ‘fish’, ‘red’, ‘fish’, ‘blue’, ‘fish’);

%seen = ();

foreach (@fishwords) {

$seen{$_}=1; # $_ potrebbe essere sostituito da $fishwords[$i];

}

@uniquewords = keys %seen;

42 Bioinformatica

Page 43: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Elaborare l’intersezione degli array L’intersezione fra due array:

La funzione grep viene iterata per l’elenco dei politici impostando $_ a ogni politico. Il nome viene quindi cercato nell’hash %seen. Se viene restituito vero il nome è nell’hash e grep restituisce il valore di $_.

@stars=(‘R. Reagan’, ‘C. Eastwood’, ‘M. Jackson’, ‘Cher’, ‘S. Bono’);

@pols=(‘N. Gingrich’, ‘S. Thurmond’, ‘R. Reagan’, ‘S. Bono’, ‘C. Eastwood’, ‘M. Tatcher’);

%seen=();

foreach (@stars) {

$seen{$_}=1; }

@intersection=grep($seen{$_}, @pols);

43 Bioinformatica

Page 44: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Elaborare la differenza tra due array La differenza tra due array:

Per i nomi di @pols che compaiono in %seen, grep restituisce falso e tali nomi non vengono inseriti in difference.

@stars=(‘R. Reagan’, ‘C. Eastwood’, ‘M. Jackson’, ‘Cher’, ‘S. Bono’);

@pols=(‘N. Gingrich’, ‘S. Thurmond’, ‘R. Reagan’, ‘S. Bono’, ‘C. Eastwood’, ‘M. Tatcher’);

%seen=();

foreach (@stars) {

$seen{$_}=1; }

@difference=grep(! $seen{$_}, @pols);

44 Bioinformatica

Page 45: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Ordinare gli hash

E’ possibile ordinare secondo quanto specificato in un blocco:

Il blocco fornito per ordinare viene chiamato ripetutamente con $a e $b impostati a ogni coppia di valori che sort richiede al codice di ordinare. In questo caso $a e $b sono impostati alle varie chiavi di %Words. Invece di confrontare $a e $b direttamente, il codice cerca i valori di tali chiavi e li confronta.

foreach ( sort keys %Words ) {

print “$_ $Words{$_}\n”;

}

foreach ( sort { $Words{$a} <=> $Words{$b} } keys %Words ) {

print “$_ $Words{$_}\n”;

}

45 Bioinformatica

Page 46: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Funzioni Per creare subroutine definite dall’utente:

Ad es.

sub subroutine_name {

}

Sub countdown {

for ($i=10; $i>=0; $i-) {

print “$i –”;

}

}

46 Bioinformatica

Page 47: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Richiamare subroutine Quando il programma deve usare il codice della

subroutine:

Oppure:

La seconda sintassi può essere usata se la subroutine è già stata dichiarata nel codice;

Quando viene chiamata la subroutine, PERL ricorda la sua posizione, esegue il codice della subroutine e ritorna alla posizione memorizzata.

&countdown();

countdown();

47 Bioinformatica

Page 48: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Chiamare subroutine da altre subroutine

sub world {

print “World!”;

}

sub hello {

print “Hello, “;

world();

}

hello();

48 Bioinformatica

Page 49: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Restituire valori dalle subroutine Una subroutine ha un valore detto valore di ritorno;

Questo è il valore dell’ultima espressione valutata nella subroutine o un valore restituito esplicitamente dall’istruzione return:

sub two_by_four {

2 * 4;

}

print 8*two_by_four();

49 Bioinformatica

Page 50: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Return Restituire un valore:

sub x_greaterthan100 {

return(1) if ( $x > 100 );

0;

}

$x = 70;

if (x_greaterthan100()) {

print “$x is greater than 100\n”;

}

50 Bioinformatica

Page 51: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Restituire valori complessi Le subroutine possono restituire scalari, array e

hash:

sub shift_to_uppercase {

@words = qw( cia fbi un nato unicef );

foreach (@words) {

$_ = uc($_);

}

return (@words);

}

@acronyms=shift_to_uppercase();

51 Bioinformatica

Page 52: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Argomenti Per passare argomenti ad una subroutine si può

usare una delle sintassi seguenti:

La seconda sintassi può essere usata solo se PERL ha già incontrato la definizione della subroutine.

subname(arg1, arg2, arg3);

subname arg1, arg2, arg3;

&subname(arg1, arg2, arg3);

52 Bioinformatica

Page 53: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Accedere agli argomenti In una subroutine gli argomenti passati sono

accessibili tramite la variabile speciale @_:

Per accedere ai singoli argomenti:

sub printargs {

print join(‘,’, @_);

}

printargs (‘market’, ‘home’, ‘roast beef’);

sub print_third_argument {

print $_[2];

}

53 Bioinformatica

Page 54: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Ancora sugli argomenti Le funzioni che prendono più argomenti spesso

iniziano assegnando un nome a questi argomenti, per rendere più chiara la loro funzione:

Modificando @_, o un suo elemento, vengono modificate le variabili originali nell’elenco di argomenti.

sub display_box_score {

($num_hits, $num_at_bats)=@_;

print “For $num_at_bats trips to the plate, “;

print “he’s hitting “, $num_hits/$num_at_bats, “\n”;

}

display_box_score(50, 210);

54 Bioinformatica

Page 55: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Passare array e hash

Passare due o più array o hash può dare risultati indesiderati:

sub sort_numerically {

print “Sorting…”;

return( sort { $a <=> $b } @_); }

@sorted_items=sort_numerically(@items);

@first = (1,2,3); @second= (6,5,4);

sub display_arrays {

(@a, @b) = @_;

print “The first array: @a\n”;

print “The Second array: @b\n”; }

display_arrays(@first,@second); #i dati vengono posti tutti in @a e @b è vuoto

55 Bioinformatica

Page 56: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Passare array e hash (2) I due array @first e @second sono elencati assieme e gli

elementi sono inseriti in @_ durante la chiamata alla subroutine. La fine degli elementi di @first non è distinguibile dall’inizio degli elementi di @second in @_: si tratta di un’unica lista molto lunga;

All’interno della subroutine tutti gli elementi vengono assegnati a @a e @b rimane vuoto;

Insieme a un array o un hash è possibile passare uno o più scalari, ammesso che questi siano passati prima nella lista di argomenti e si sappia quanti ce ne sono:

sub lots_of_args {

($first, $second, $third, %hash) = @_;

… }

lots_of_args($foo, $bar, $baz, %myhash);

56 Bioinformatica

Page 57: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Ambito di validità e funzioni pure Le funzioni pure sono quelle subroutine capaci di

funzionare autonomamente e quindi riutilizzabili da altri programmi:

Ecco la stessa cosa scritta in modo scadente:

sub moonweight {

($weight) = @_;

return($weight / 6);

}

print moonweight(150);

sub moonweight {

return($weight / 6); }

$weight = 150;

print moonweight();

57 Bioinformatica

Page 58: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Ambito di validità e variabili locali PERL consente di riutilizzare più volte i nomi di

variabili con scopi diversi all’interno di un programma esteso. Le variabili di PERL sono visibili per impostazione predefinita nel corpo principale del programma e nelle subroutine (variabili globali);

Per rendere la variabile $weight dell’es. precedente locale rispetto alla subroutine:

sub moonweight {

my $weight;

($weight) = @_;

return($weight / 6);

}

58 Bioinformatica

Page 59: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Ambito di validità La parte di programma in cui la variabile è visibile è nota

come ambito di validità della variabile. Si può usare l’operatore my per dichiarare variabili scalari,

array e hash locali rispetto alla subroutine. Filehandle, subroutine e variabili speciali di PERL non

possono essere contrassegnati come locali. Per dichiarare più variabili locali:

my($larry, @curly, %moe);

sub player_stats {

my($num_at_bats, $num_hits, $num_walks)=@_;

}

59 Bioinformatica

Page 60: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Altri posti per my Si possono dichiarare variabili con un ambito di validità

ancora più limitato di quello di una subroutine, ad es. in un blocco:

La dichiarazione può avvenire anche all’interno delle strutture di controllo, per esempio for, foreach, while o if. E’ anche possibile, da PERL 5.004 in poi, dichiarare come locali gli iteratori dei cicli for e foreach e le condizioni di verifica di while ed if:

$y=20;

{ my $y=500;

print “The value of \$y is $y\n”; # Stampa 500

}

print “$y\n”; # Stampa 20

foreach my $element (@array)

while(my $line=<STDIN>)

60 Bioinformatica

Page 61: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Dichiarare variabili local

$foo è dichiarata come locale rispetto alla subroutine myfunc();

Una variabile dichiarata con local si comporta come una dichiarata con my;

La differenza consiste nel fatto che una variabile dichiarata con local può essere vista all’interno del blocco dell’ambito di validità e all’interno di ogni subroutine chiamata da questo blocco.

sub myfunc {

local($foo)=56;

}

61 Bioinformatica

Page 62: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Ricorsività

sub factorial {

my ($num)=@_;

return(1) if ($num <= 1);

return($num * factorial($num – 1));

}

print factorial(6);

62 Bioinformatica

Page 63: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Effettuare ricerche negli scalari: index Se si vuole semplicemente trovare una stringa all’interno di

un altro scalare, PERL fornisce la funzione index:

La funzione index inizia a sinistra di string e cerca substring; restituisce la posizione in corrispondenza della quale viene trovata substring, con 0 che corrisponde al carattere più a sinistra. Se la substring non viene trovata restituisce -1.

Opzionalmente si può dare a index una posizione di partenza nella stringa per l’inizio della ricerca:

index string, substring

index string, substring, start_position

index “Ring around the rosy”, “around”; # restituisce 5

@a=qw(oats peas beans);

index join(“ “,@a), “peas”; # restituisce 5

index “dasher dancer prancer vixen”, “da”, 1; # restituisce 763 Bioinformatica

Page 64: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Cercare all’indietro con rindex La funzione rindex opera come index, tranne per il

fatto che la ricerca inizia a destra e procede verso sinistra:

Qualche esempio:

rindex string, substring

rindex string, substring, start_position

$a=“She loves you yeah, yeah, yeah.”;

rindex($a, “yeah”); # restituisce 26

rindex($a, “yeah”, 25); # restituisce 20

64 Bioinformatica

Page 65: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Estrarre parti di scalari con substr La funzione substr fornisce un metodo generico per

estrarre informazioni dagli scalari e per modificarli:

substr richiede string, che inizia alla posizione offset, e restituisce il resto della stringa da offset alla fine. Se viene specificato length allora vengono presi length caratteri:

Se l’offset specificato è negativo, substr inizia a contare da destra. Ad es. substr($a, -5) restituisce gli ultimi 5 caratteri di $a. Se length è negativo substr restituisce dalla posizione iniziale alla fine della stringa, meno length caratteri.

substr string, offset

substr string, offset, length

$a=“I do not like green eggs and ham.”;

print substr($a, 25); # stampa “and ham.”

print substr($a, 14, 5); # stampa “green”

65 Bioinformatica

Page 66: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Ancora substr Si può usare substr sul lato sinistro di una

espressione di assegnazione. Quando viene usata a sinistra, substr indica quali caratteri verranno sostituiti in uno scalare. Il primo valore deve essere un valore assegnabile:

$a=“countrymen, lend me your wallets”;

# sostituisce il primo carattere di $a con “Romans, C”

substr($a, 0, 1)=“Romans, C”;

# inserisce “Friends ,” all’inizio si $a

substr($a, 0, 0)=“Friends, “;

substr($a, -7, 7)=“ears.”; # sostituisce gli ultimi 7 caratteri

66 Bioinformatica

Page 67: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Traslitterazione

L’operatore di traslitterazione, tr///, cerca in una stringa gli elementi in searchlist e li sostituisce con gli elementi corrispondenti in replacementlist.

Di default tr/// cerca e modifica la variabile $_. Per cercare e modificare altre variabili, si usa un operatore di associazione come per le corrispondenze nelle espressioni regolari:

I gruppi logici di caratteri sono accettati con trattini tra di essi; per es. A-Z rappresenta le maiuscole da A a Z:

tr/searchlist/replacementlist/

tr/ABC/XYZ/; # in $_ sostituisce tutte le A con X, le B con Y, …

$r=~tr/ABC/XYZ/; # la stessa cosa ma con $r

tr/A-Z/a-z; # cambia tutte le maiuscole in minuscole

67 Bioinformatica

Page 68: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Traslitterazione (2) Se replacementlist è vuota o identica a searchlist, i

caratteri che corrispondono vengono contati da tr/// e restituiti. La stringa di destinazione non viene modificata:

$eyes=$potato=~tr/i//; # conta le i in $potato e mette il risultato in $eyes

$nums=tr/0-9//; # conta le cifre in $_ e mette il risultato in $nums

68 Bioinformatica

Page 69: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Stampa formattata con printf

La stringa formatstring descrive il formato dell’output, list è una lista di valori che printf deve visualizzare.

formatstring è una stringa letterale (di solito) o uno scalare. Ogni carattere in formatstring viene stampato letteralmente, eccettuate quelle sequenze che iniziano con un %.

Il % indica l’inizio di uno specificatore di campo, il cui formato è: %-w.dx

il segno – e il . decimale sono opzionali. w indica la larghezza totale del campo, d il numero di cifre decimali, x il tipo di campo. Il segno – indica la giustificazione a sinistra, altrimenti viene giustificato a destra. Solo % e x sono obbligatori.

printf formatstring, list

printf filehandle formatstring, list

69 Bioinformatica

Page 70: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

printf Alcuni tipi di specificatori:

c carattere s stringa d intero decimale, la parte frazionaria viene

troncata f numero in virgola mobile

perldoc –f printf è la pagina del manuale con l’elenco completo dei tipi di specificatori.

Qualche esempio:printf(“%20s”,”Jack”); # giustifica a destra “Jack” in 20 car.

printf(“%-20s”,”Jill”); # giustifica a sinistra “Jill” in 20 car.

$amt=7.12;

printf(“%6.2f”,$amt); # stampa “ 7.12”

printf(“%c”, 65); # stampa il carattere ASCII 65, cioè “A”

70 Bioinformatica

Page 71: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Ancora printf Ogni specificatore di campo usa un elemento della

lista. Per ogni elemento deve esserci uno specificatore di campo e per ogni specificatore di campo deve esserci un elemento della lista:

La sequenza %% rappresenta un simbolo di percentuale.

printf(“Totals: %6.2f %15s %7.2f %6d”, $a, $b, $c, $d);

71 Bioinformatica

Page 72: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

sprintf La funzione sprintf è identica a printf, tranne per il

fatto che invece di essere stampato, l’output formattato viene restituito da sprintf, pronto per essere assegnato a uno scalare o per essere usato in un’altra espressione:

$weight=85;

$moonweight = sprintf(“%.2f”, $weight / 6);

print “You weight $moonweight on the moon”;

72 Bioinformatica

Page 73: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Un elenco come stack PERL offre la struttura dati stack, implementata

solitamente con array. Le funzioni per lavorare con gli stack sono:

push, per collocare elementi in cima allo stack pop, per estrarre elementi dalla cima shift, per rimuovere elementi dal basso unshift, per aggiungere elementi al fondo

Le sintassi sono le seguenti:

pop target_array;

shift target_array;

unshift target_array, new_list;

push target_array, new_list

73 Bioinformatica

Page 74: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Le funzioni dello stack pop e shift rimuovono un solo elemento da

target_array e lo restituiscono. Restituiscono undef se l’array è vuoto;

Le funzioni push e unshift aggiungono gli elementi di new_list a target_array:

@band = qw(trombone);

push @band, qw(ukulele clarinet);

$brass=shift @band;

$wind=pop @band;

unshift @band, “harmonica”;

74 Bioinformatica

Page 75: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Lo stack è un array Gli elementi dell’array in uno stack sono ancora

semplicemente normali elementi di array e possono essere indirizzati con indici;

Il fondo dello stack è l’elemento 0, mentre la sommità è costituita dall’ultimo elemento;

Usando unshift per aggiungere elementi e pop per eliminarli o usando push per aggiungere elementi e shift per eliminarli si realizza una coda.

75 Bioinformatica

Page 76: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

La funzione splice

La funzione splice toglie elementi da array a partire da offset e restituisce la lista degli elementi estratti dall’array.

Valori negativi di offset fanno sì che il conteggio degli elementi inizi alla fine dell’array. Se viene specificato length, vengono eliminati sono length elementi. Se viene specificato list, allora vengono eliminati length elementi e sostituiti con gli elementi di list:

splice array, offset

splice array, offset, length

splice array, offset, length, list

@veg=qw(carrots corn);

splice(@veg, 0, 1); # @veg = corn

splice(@veg, 0, 0, qw(peas)); # @veg = peas, corn

76 Bioinformatica

Page 77: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

La funzione system() Il modo più semplice per eseguire un comando fuori da

PERL, consiste nell’usare la funzione system, che mette il programma PERL in pausa, esegue il comando esterno e fa proseguire l’esecuzione del programma PERL:

dove command è il comando che si vuole eseguire. Il valore restituito da system è 0 se tutto va bene e un valore diverso da 0 se si verifica un problema.

system command;

system(“dir /w”); # stampa un elenco di file

if (system(“perldoc –f system”)) {

print “Your documentation isn’t installed correctly!\n”;

}

$file=“myfile.txt”; system(“notepad.exe $file”);77 Bioinformatica

Page 78: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Catturare l’output La funzione system non offre un buon sistema per catturare

l’output del comando e fornirlo a PERL per l’analisi. Si può aggirare il problema come segue:

PERL dispone di un altro metodo per gestire questa situazione: i backtick o apici rovesciati. Qualsiasi comando all’interno dei backtick `` (ASCII Alt+96) viene eseguito da PERL come un comando esterno e l’output viene catturato e restituito come valore di ritorno dei backtick:

system(“dir > outfile”);

open(OF,”outfile”) || die “Cannot open output: $!”;

@data=<OF>;

close<OF>;

$directory=`dir`;

78 Bioinformatica

Page 79: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

backtick Un esempio:

PERL dispone di un altro sistema per rappresentare i backtick: qx{ }:

Al posto di { } si possono usare altre coppie di caratteri come <>,( ), [ ].

@dir=`dir`;

foreach(@dir) {

}

$perldoc=qx{perldoc perl};

79 Bioinformatica

Page 80: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Evitare la shell Consideriamo il seguente esempio:

$HOME è la variabile $HOME di PERL o la variabile $HOME di ambiente della shell?

$HOME è interpolata da PERL, quindi rappresenta una variabile del programma;

Per ovviare a questo problema si può inserire un backslash prima delle variabili che non si vuole vengano interpolate da PERL:

$myhome = `ls $HOME`;

$myhome=`ls \$HOME`;

80 Bioinformatica

Page 81: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Riferimenti Creiamo e assegniamo una variabile scalare:

Adesso in memoria esiste un’area etichettata $a che contiene la stringa “Stones”.

Se si volesse assegnare lo scalare $a a $b, cioè $b=$a, si otterrebbero due copie dei dati con due nomi diversi.

Ma se si vuole che $b faccia riferimento a $a? Si deve creare un riferimento.

Per creare un riferimento a una variabile si deve mettere un backslash prima del nome della variabile con il suo identificatore di tipo:

$a=“Stones”;

$ref=\$a; # crea un riferimento a $a

81 Bioinformatica

Page 82: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Riferimenti (2) Per ottenere il valore interno a $a tramite $ref

occorre deferenziare $ref:

Ovviamente si può assegnare un riferimento come si farebbe con qualsiasi altro valore scalare:

$ref=\$a; # crea un riferimento a $a

print $$ref; # stampa Stones

$$ref=“Sticks”;

Print $a; # stampa Stick

$name=”Gandalf”;

$nref=\$name;

$oref=$nref;

82 Bioinformatica

Page 83: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Riferimenti (3) Si può anche memorizzare un riferimento a un

riferimento, come segue:

$book=“Lord of the Rings”;

$bref=\$book; # riferimento a $book

$bref2=\$bref; # riferimento a $bref

print $$bref; # Stampa Lord of the Rings

print $$$bref2; # Stampa Lord of the Rings

83 Bioinformatica

Page 84: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Riferimenti ad array Si possono anche creare riferimenti ad array ed hash. Tali

riferimenti vengono creati nello stesso modo in cui viene creato un riferimento ad uno scalare:

Per maggiore chiarezza: $$aref[0] è uguale a ${$aref}[0] @$aref[2,3] è uguale a @{$aref}[2,3] @$aref è uguale a @{$aref}

$aref=\@arr;

$$aref[0]; # il primo elemento di @arr

@$aref[2,3]; # una porzione di @arr

@$aref; # l’intero array @arr

foreach $element (@{$aref}) {

print $element; }

84 Bioinformatica

Page 85: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Riferimenti a hash Per creare un riferimento a hash:

$href=\%hash;

$$href{key}; # una singola chiave in %hash

${$href}{key};# idem

%$href; # l’intero hash

foreach $key (keys %$href) {

print $$href{$key};

}

85 Bioinformatica

Page 86: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Riferimenti come argomenti Ricordiamo che il codice seguente non funziona:

Ma con i riferimenti…

sub getarrays {

my(@a, @b)=@_;

…}

sub getarrays {

my($fruit_ref, $veg_ref)=@_;

print @$fruit_ref; # Stampa correttamente l’array

print @$veg_ref; # Stampa correttamente l’array

}

@fruit=qw(apples oranges banana);

@veggies=qw(carrot cabbage turnip);

getarrays(\@fruit, \@veggies);

86 Bioinformatica

Page 87: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Riferimenti e modifiche Quando i riferimenti a scalari, array o hash vengono

passati a funzioni come argomenti, la funzione può manipolare i dati originali a cui il riferimento punta:

sub changehash {

my(%local_hash)=@_;

$local_hash{mammal}=‘bear’;

return;

}

%hash=(fish => ‘shark’,bird => ‘robin’);

changehash(%hash);

sub changehash {

my($href)=@_;

$$href{mammal}=‘bear’;

return;

}

%hash=(fish => ‘shark’, bird => ‘robin’);

changehash(\%hash);

87 Bioinformatica

Page 88: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Memorizzazione anonima Consideriamo il seguente codice:

Nonostante l’hash sia interno al blocco, esso continuerà ad esistere fuori dal blocco proprio a causa del riferimento;

PERL offre la possibilità di creare un riferimento senza usare un hash intermedio: memorizzazione anonima!

my $href;

{

my %hash=(phone=>’Bell’, light=>’Edison’);

$href=\%hash;

}

print $$href{light};

88 Bioinformatica

Page 89: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Memorizzazione anonima (2) Memorizzazione anonima (Creazione di un hash

mediante riferimento):

Un array anonimo:

Ma se un riferimento punta ad una variabile privata, cioè interna ad un blocco, i dati a cui punta svaniscono quando la variabile esce dall’ambito di validità.

$ahref={ phone => ‘Bell’, light=> ‘Edison’ };

foreach $key ( keys( %${ahref} ) ) {    print "\n [ $key ] tramite riferimento       = " . ${$ahref}{$key};    print "\n [ $key ] tramite riferimento smart = " . $href->{$key}}

$aaref=[ qw( Crosby Stills Nash Young ) ];

89 Bioinformatica

Page 90: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Strutture: Liste di liste Le liste di liste sono spesso utilizzare per

rappresentare matrici:

Per trovare il numero di elementi nella lista esterna:

@list_of_lists=(

[ qw(Mustang Bronco Ranger) ],

[ qw(Cavalier Suburban Buick) ],

[ qw(LeBaron Ram) ],

);

$list_of_lists[0][1]; # Bronco, 1a riga, 2° elemento

$list_of_lists[1][2]; # Buick

$#list_of_lists; # 2

scalar(@list_of_lists); # 3

90 Bioinformatica

Page 91: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Liste di liste (2) Trovare il numero di elementi in uno degli elenchi

più interni è più difficile:

Per attraversare ogni elemento nell’elenco degli elenchi:

scalar(@{$list_of_lists[2]}); # num di elementi nella riga 3

$#{$list_of_lists[1]}; # indice dell’ultimo elemento della riga 2

foreach my $outer (@list_of_lists) {

foreach my $inner (@{$outer}) {

print “$inner ”;

}

print “\n”; }

push(@list_of_lists, [qw(Mercedes BMW Lexus)]); #nuova riga

push(@{$list_of_lists[0]},qw(Taurus)); # nuovo elemento

91 Bioinformatica

Page 92: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

I moduli PERL può essere esteso attraverso l’uso di moduli,

collezioni di routine che permettono di aggiungere funzionalità al linguaggio;

La direttiva use permette di usare un modulo nel proprio programma PERL. Ad es. per includere il modulo cwd:

La posizione di tale direttiva nel codice non è importante, anche se, è meglio inserirla all’inizio del programma;

La funzione cwd, messa a disposizione nel modulo Cwd restituisce il nome della directory di lavoro corrente.

use Cwd;

92 Bioinformatica

Page 93: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Alcuni moduli di PERL: File::Find

find ha due parametri: subref è un riferimento a subroutine (si crea con il nome della subroutine preceduto da backslash; si deve usare la & prima del nome della subroutine per definire un riferimento ad essa). La subroutine in questione viene chiamata per ogni file e directory trovato in dirlist.

Troviamo ad es. il file important.doc:

use File::Find;

find subref, dirlist;

use File::Find;

sub wanted {

if($_ eq “important.doc”) {

print $File::Find::name; } }

find \&wanted, ‘/documents’;

93 Bioinformatica

Page 94: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Alcuni moduli di PERL: File::Copy Il modulo File::Copy fornisce il modo per copiare file:

La funzione copy restituisce 1 in caso di successo oppure 0 se si è verificato un problema;

Il modulo File::Copy fornisce anche una funzione move che sposta un file da una directory ad un’altra:

use File::Copy;

copy(“sourcefile”, “destination”) || warn “Could not copy files: $!”;

move(“important.doc”, “d:/archives/documents/important.doc”);

94 Bioinformatica

Page 95: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Alcuni moduli di PERL: Net::Ping Il modulo Net::Ping fornisce il modo di determinare

se il sistema può comunicare in rete (il secondo parametro indica il timeout):

use Net::Ping;

if (pingecho(www.yahoo.com, 15)) {

print “Yahoo is on the network.”;

} else {

print “Yahoo is unreachable.”;

}

95 Bioinformatica

Page 96: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Persistenza dei dati: File DBM Uno dei modi più semplici per PERL di ricordare i dati in modo

organizzato è mediante i file DBM;

Un file DBM è un file che è stato connesso a un hash di PERL;

Per vincolare il proprio hash a un file DBM:

Il filename che si fornisce, crea uno o due file su disco rigido con nomi che sono varianti di filename: filename.pag e filename.dir, oppure filename.db. PERL usa questi file per memorizzare l’hash;

mode rappresenta le autorizzazioni sui due file DBM che PERL crea;

La funzione dbmopen restituisce vero se l’hash è stato correlato con successo al file DBM.

dbmopen(hash, filename, mode);

96 Bioinformatica

Page 97: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

File DBM (2) Una volta correlato un hash ad un file

si può lavorare tranquillamente con l’hash come visto finora:

Quando si recuperano le informazioni, PERL riprende chiave e dati dal file DBM:

Per disconnettere l’hash dal file DBM:

dbmopen(%hash, “dbmfile”, 0644) || die “$!”;

$hash{feline}=“cat”;

$hash{canine}=“dog”;

print $hash{canine};

dbmclose(%hash);

97 Bioinformatica

Page 98: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

DBM (3) E’ importante sapere che:

La lunghezza delle chiavi e dei dati adesso è limitata. Gli hash associati a un file DBM hanno una lunghezza limitata di chiave e valore, normalmente intorno ai 1024 caratteri per la combinazione chiave-valore. Il numero totale di chiavi e valori invece è limitato solo dal file system;

I valori nell’hash prima di dbmopen vengono persi;

I valori nell’hash mentre quest’ultimo è associato al file DBM scompaiono dopo l’esecuzione di dbmclose.

98 Bioinformatica

Page 99: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Esaminare gli hash legati a DBM Consideriamo il codice seguente:

Il codice è corretto ma se l’elenco di chiavi in %recs è ampio l’istruzione keys %recs potrebbe richiedere del tempo per l’esecuzione. PERL ha un’altra funzione che permette di iterare su un hash una chiave alla volta:

dbmopen(%recs, “records”, 0644) || die “$!”;

foreach my $key (keys %recs) {

print “ $key = $recs{$key}\n”;

}

dbmclose(%recs);

while( ($key, $value)=each %recs) {

print “ $key = $value\n”;}

99 Bioinformatica

Page 100: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Ancora sui Moduli EData::Dumper Per il debugging CGI & CGI::Pretty Interfaccia per l’ambiente

CGI DBI Interfaccia per DB

relazionali DateTime Date e tempo HTML::TreeBuilder HTML parsing Spreadsheet::ParseExcel Leggere in file Excel Spreadsheet::WriteExcel creare documenti excel XML::Twig trattare dati XML

100 Bioinformatica

Page 101: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Programmazione Orientata agli Oggetti Una classe è semplicemente un package:

Per inizializzare un oggetto:

Usare un metodo:

#!/usr/local/bin/perlpackage Cat;sub new {…}sub meow {…}

$new_object = new ClassName;

101 Bioinformatica

$cat->meow();

Page 102: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Programmazione Orientata agli Oggetti Esempio:

Shift() prende i parametri di input e li assegna alle variabili

1:  #!/usr/bin/perl           2:3:  package Lampadina;     4:  sub new {     5:    my $self = shift() || { stato => 'spenta‘, potenza => '0W', attacco => 'baionetta', luce => 'gialla', };  6:    bless $self; # Indica a Perl che $self non è una variabile qualsiasi ma un riferimento all’oggetto   7:    return $self;    8:  }    9:     10:  sub switch {    11:    my $self = shift;   # Reference all’oggetto di cui fa parte12:    $self{state} = $self{state} eq 'accesa' ? 'spenta' : 'accesa';    13:  }    14:     15:  sub state {    16:    my $self = shift;     # Reference all’oggetto di cui fa parte17:    return $self{state};    18:  }    

102 Bioinformatica

Page 103: Bioinformatica Linguaggio Perl (2) Dr. Giuseppe Pigola – pigola@dmi.unict.it Dr. Alessandro Laganà – lagana@dmi.unict.it.

Programmazione Orientata agli Oggetti Usare la classe:

1:  #!/usr/bin/perl           2:  package main;    3:     4:  my $lampadina = new Lampadina({stato=>'spenta‘,potenza=>'60W‘ ,attacco=>'edison',luce =>'bianca‘,});    5:     6:  if ( $lampadina->state() eq 'spenta' ) {    7:    $lampadina->switch();    8:    print "la lampadina ora è accesa\n";    9:  } else {    10:    $lampadina->switch();    11:    print "la lampadina è spenta\n";    12:  }

103 Bioinformatica