Perl Practical extraction Report Language Pathologically eclectic rubbish
Perl Practical extraction Report Language Pathologically eclectic rubbish lister : -) Variabili e strutture dati Corso Perl per Biotecnologie (2019)
Il manualetto di riferimento in Italiano: Stefano Rodigliero Pocket Perl Ed: APOGEO
The "Hello World" program Consideriamo il seguente programmino: #!usrbinperl # Hello World use strict; use warnings; # # variabili lessicali(usare my) evidenzia anche gli errori non critici my $message="Ciao, Mondo"; print "$message n"; print " End of program $0 n";
LISTA DELLE FUNZIONI IN PERL Esistono molti siti web dove trovare la lista delle funzioni del linguaggio Perl. https: //perldoc. perl. org/index-functions. html
Perl Variables #!usrbinperl è chiamata 'shebang-line' Windows la considererà un commento use strict; # variabili (usare my, our, state, local) Con questa direttiva, siamo obbligati a dichiarare le variabili con I prefissi: my state our local my $v, my @W, my %HV' ; quello più usato state $k=0; our $name; crea un alias in un package usato in un blocco {… } per modifiche locali
Perl Variables my $message: dichiariamo una variable lessicale. Usando 'my' Perl ci avvisa nel caso di errori di digitazione della variabile; es: my $numer=2; my $v = $Numer +1; # $numer NON è $Numer !!!!! A volte con lo stesso nome di variabile conserviamo piu' di una informazione ( $V e @V e %V sono diversi !! ). Tutti i linguaggi (dei computer) hanno la capacità di creare variabili per poter memorizzare e modificare dati. Perl è diverso da tanti altri linguaggi perché non specifica il "tipo" (i. e. integer, real, character, etc. ) ma solo la "complessità" dei dati.
Perl Variabili Perl ha 3 maniere per memorizzare I dati: 1. Scalari (scalars) Ø Per dati singoli, come numberi o stringhe. 2. Vettori (arrays) Ø Intesi come liste di scalari. Scalari indicizzati da numeri. 3. Vettori Associativi detti "hashes" Ø simili ai vettori, ma usano delle chiavi ("keys") per identificare gli scalari. I simboli “$” , “@” e “%” anteposti ai nomi delle variabili si chiamano “sigilli”. In realtà gli hashes possono essere ricondotti agli arrays
Perl Variabili I simboli “$” , “@” e “%” anteposti ai nomi delle variabili si chiamano “sigilli”. I nomi di variabile iniziano sempre con un sigillo (o simbolo) che indica il tipo del valore della variabile. Le variabili scalari (Scalari) usano il simbolo del dollaro ($). Le variabili array (Array) usano il simbolo chiocciola (@). Le variabili hash (Hash) usano il simbolo della percentuale (%): In realtà gli hashes possono essere ricondotti agli arrays
Variabili Scalari (sigillo “$”) Esempi # my $no_of_chrs=24; # intero my $per_cent_identity=0; # intero my $per_cent_identity=99. 50; # ridefinito come reale my $pi = 3. 1415926535; # floating point (reale) my $e_value=1 e-40; # notazione scientifica my $dna="GCCTACCGTTCCACCAAAA"; # string -double quotes my $dna='GCCTACCGTTCCACCAAAA'; #string -single quotes my $n = 0 b 1110011; # intero binario my $var = 01234; # intero ottale my $n = 0 x 5 FA 8; # intero esadecimale
Variabili Scalari MAIUSCOLO e minuscolo $DNA ≠ $dna; (sono due variabili differenti) Le variabili scalari devono avere un prefisso, il simbolo $ (se c'è il $ → è uno scalare). Il carattere successivo deve essere una lettera e non un numero (valido per tutte le variabili create dall'utente ). Gli scalari possono essere facilmente ridefiniti (ex: integer → real → string): # esempio my $dna = 0; # integer $dna = "GGCCTCGAACGTCCAGAAA"; # ora è una stringa
Usiamo gli scalari. . my $a =1. 5; my $b =2. 0; $c=3; my $sum = $a+$b*$c; # moltiplica $b per $c, poi somma $a # my $j = 1; while ($j<100) { $j++; # significa $j=$j+1, i. e. add 1 to j print "$jn"; } # my $dna 1="GCCTAAACGTC"; my $poly. A="AAAAAAAA"; $dna 1. = $poly. A; # aggiunge una stringa ad un'altra # (equiv. $dna 1 = $dna 1. $poly. A) my $no_of_bases = length($dna 1); # lunghezza dello scalare
Stringhe. . Esiste una notevole differenza tra stringhe con il singolo apice ' e stringhe con I doppi apici " double quotes # $nchr = 23; $message="pairs of chromosones in human cell =$nchr"; print $message; $message = 'pairs of chromosones in human cell =$nchr'; print $message; exit; OUTPUT pairs of chromosones in human cell =23 single quotes pairs of chromosones in human cell =$nchr
Strings …. (interpolazione) I doppi apici " interpretano le variabili, gli apici singoli ' non lo fanno: $dna='GTTTCGGA'; OUTPUT print "sequence=$dna"; sequence=GTTTCGGA print 'sequence=$dna'; sequence=$dna Si usano piu' spesso I doppi apici (") quando usiamo l'istruzione print. ' single quote " double quotes
Variabili in Perl • • • Perl è case sensitive ($a è diverso da $A) Variabili scalari: contengono sia stringhe che numeri $nome = 'Marco'; $n=3; $pigreco=3. 14; • • Variabili array @nomi=('Marco', 'Michele', 'Paolo'); @nomi=(Marco, Michele, 13); Il primo elemento di un array ha indice 0 Per accedere agli elementi dell'array si usano le variabili scalari: $nomi[1] prende il valore Michele •
Operazioni e assegnamento • • • $a=1+2; #addizione $a=3 -4; #sottrazione $a=3*4; #moltiplicazione $a=8/2; #divisione $a= 2**4; #elevamento a potenza $a=5%2; #modulo $a++; ++$a; #post e pre_incremento $a+=$b; $a-= $b; $a. =$b #assegnamento $a=$b. $c; #concatenazione di stringhe $a=$b x $c; #ripetizione di stringhe (non commutativa: "stringa " x "numero")
# Un po' di sintassi utili. . . • my $milione = 1_000 ; • my $esadecimale = 0 x. DEADBEEF; • my $ottale = 0210; • my $binario = 0 b 0101101; • print "$esadecimalen"; • print "$ottalen"; • print "$binarion"; ===== OUTPUT ===== 1000000 3735928559 136 45
# Ancora sintassi utili. . . $var 1 = 1; $var 2 = 2; $var 3 = "pippo"; $var 4 = "pluto"; print "var 1=$var 1 t var 2=$var 2 t var 3=$var 3 t var 4=$var 4 n"; $tot 1=$var 1+$var 2; print "tot 1=var 1+var 2 = $tot 1 n "; $tot 2=$var 1. $var 2; print "tot 2= var 1. var 2 = $tot 2 n "; print "var 1+var 2 = $tot 1n"; # var 1+var 2 = 3 print "var 1. var 2 = $tot 2n"; # var 1. var 2 = 12 $tot 1=$var 3+$var 4; # NUM + STRINGA! ? Perl ci prova comunque. $tot 2=$var 3. $var 4; # concatenazione print "var 3+var 4 = $tot 1n"; # var 3+var 4 = 0 print "==== $var 3. $var 4 = $tot 2n"; # var 3. var 4 = pippopluto $tot 1=$var 3+1; print "var 3+1 = $tot 1n"; # var 3+1 = 1
Strutture di controllo • Operatori di confronto • Il Perl mette a disposizione 3 tipi di operatori di confronto, ognuno dei quali va applicato su un determinato tipo di dato: numeri, stringhe e file • Il Perl effettua una conversione di tipo delle variabili prima di effettuare il confronto coerentemente col tipo dei dati conivolti
Operatori logici Gli operatori logici del Perl per le espressioni booleane sono • && and • || or • ! not AND e OR hanno una precedenza bassa rispetto a && e ||. OPERATORI BITWISE(tra bits) | (or), & (and) ^ (xor)
Operatori di confronto Tra numeri: • $a==$b uguaglianza • $a<$b minore (maggiore >) • $a<=$b minore(maggiore >) o uguale • $a!= $b diverso • Tra stringhe il minore - maggiore segue l'ordine alfabetico • $a eq $b • $a lt $b • $a le $b • $a ne $b uguaglianza minore (maggiore gt) minore(maggiore ge) o uguale diverso
Operatori di confronto su file e directory • Tra file • $a = "myfile. txt" • -r $a leggibile • -w $a scrivibile • -d $a è directory • -f $a file regolare ( non device) • -T $a file di testo • -e $a esiste
Arrays (VETTORI) Un array è una struttura dati che permette di accedere ad un set di variabili scalari direttamente attraverso un indice numerico; potremmo dire, in altri termini, che si tratta di una variabile a più componenti. I nomi degli array in Perl sono preceduti dal simbolo "@" per distinguerli dalle variabili scalari. Le singole componenti del vettore (array) sono delle variabili scalari.
Arrays (VETTORI) my @frutta = ('mele', 'pere', 'banane', 'uva'); definisce l'array @frutta come un vettore a quattro componenti; per accedere alla singola componente si deve usare un indice numerico, come nel seguente esempio: #!/usr/local/bin/perl # script "frutta. pl" my @frutta = ('mele', 'pere', 'banane', 'uva'); print "un cesto pieno di $frutta[1]. n"; OUTPUT: un cesto pieno di pere.
Arrays (VETTORI) I Vettori possono memorizzare collezioni di numeri, stringhe e altro. In Perl I vettori sono spesso chiamati liste ordinate di scalari, @days_in_month=(31, 28, 31, 30, 31); @days_of_the_week=('mon', 'tue', 'wed' , 'thu', 'fri', 'sat', 'sun'); @bases = ('adenine', 'guanine', 'thymine', 'cytosine', 'uracil'); @Gen. Bank_fields=( 'LOCUS', 'DEFINITION', 'ACCESSION', . . . ); array inizializzato con una lista
Array - gli elementi Per accedere ai singoli elementi dell'array si usano le PARENTESI QUADRE [ ] Il primo elemento di un array di n elementi in Perl , ha indice 0. L'ultimo elemento ha indice n-1. @poly_peptide=('gly', 'ser', 'gly', 'pro', 'lys', 'ser', 'phe'); # ora mutiamo il peptide $poly_peptide[0]='val'; # valina al posto # della glicina Nota! # stampiamo il vettore $i=0; indice del vettore while ($i<8) { print "$poly_peptide[$i] "; $i++; } I valori numerici usati per individuare gli elementi sono chiamati indici.
Arrays – gli elementi Quando si accede agli elementi del vettore si usa il simbolo $ ( perche' ? ) -- Perche' gli elementi del vettore sono scalari e gli scalari devono avere il sigillo “$”; @poly_peptide=(…); # definisce un array $poly_peptide[0] = 'val'; #varia il 10 elemento Questo significa che potremmo avere una variabile separata con nome $poly_peptide poiche' $poly_peptide[0] fa parte di @poly_peptide, ma NON lo e' $poly_peptide.
Variabili Perl - uso del contesto • my @names=(‘Marco’, ’Paolo’, ’Maria’ ); • print @names; # Marco. Paolo. Maria • print "@names"; # Marco Paolo Maria • print @names. ""; # 3 (n. di elementi del vettore)
Indici di un Array Gli indici dei vettori partono da 0 e non da 1 ; $poly_peptide[0]='var'; $poly_peptide[1]='ser'; $poly_peptide[7]='phe'; L'ultimo indice di un array puo' essere trovato con $#nome_di_array, e. g. $#poly_peptide. Si possono usare anche indici negativi: questo significa che potete partire dalla fine del vettore. Therefore $poly_peptide[-1] vale 'phe' $poly_peptide[$#poly_peptide] = $poly_peptide[7]
Proprieta' dei Vettori Lunghezza di un vettore: $len = $#poly_peptide+1; # 7+1 Non e' necessario ( in Perl) definire inizialmente la dimensione del vettore – essa puo' crescere dinamicamente : # costruzione di un array #!/usr/bin/perl my $i=0; my @ARR=(); # array senza elementi while ($i<100) { $ARR[$i]= 2*$i; print "n ARR[$i] = $ARR[$i] "; $i++; }
#!/usr/bin/perl stampa di un array my $cognome = 'Rossi'; my @nomi = ("Michele $cognome", 'Elena', 'Luca', 'Elisa'); print "n ===========n"; print "@nomi"; # Questo causerà la stampa dei vari elementi, # nell'ordine in cui erano stati inseriti, separati da uno spazio. # In questo caso l'output sarà: # Michele Rossi Elena Luca Elisa print "n ===========n"; my $k=0 ; while ($k <= $#nomi) { print "n k= [$k] "; print "n $nomi[$k] "; $k++; } print "n FINE DEL PROGRAMMA $0 n";
Estrarre dati dagli arrays #!/usr/bin/perl use feature 'say'; # dice a perl che userà la funzione say. @ARRAI= qw(K L D U Y T R E W A); say "@ARRAI"; @arrai 2 = @ARRAI[0. . 2]; # estrae i primi 3 elementi di @arrai say "@arrai 2"; @arrai 3 = @ARRAI[-2. . 3]; # say "@arrai 3"; # estrae il 3^, 7^ e 8^ elemento da @ARRAI @arrai 4 = @ARRAI[2, 6, 7]; say "@arrai 4"; $dim = @ARRAI; # $dim contiene il numero di elementi di @ARRAI say " in @ARRAI ci sono $dim elementi "; @unosolo = @ARRAI[8]; say "@unosolo array! "; # attenzione! @unosolo è un array con un solo elem e non uno scalare $unosolo = $ARRAI[8]; say "$unosolo = $unosolo scalare! "; # attenzione! $unosolo è uno scalare print "n FINE DEL PROGRAMMA $0 n";
Da stringa ad array e viceversa (split-and-Join. pl) #!/usr/bin/perl print "n da Stringa ad Array usando la funzione split() n"; my @testo = split ( "" , "questo testo verrà diviso in caratteri" ); my $dim = @testo; print "n dimensione di @testo = $dim n "; print "n @testo n" ; # riunisco gli elementi dell'array @ testo in una stringa print "n da Array a Stringa usando la funzione join() n"; my $stringa 1 = join("_" , @testo). "n"; # q_u_e_s_t_ ……… print "n $stringa 1 n"; my $stringa 2 = join("" , @testo). "n"; # questo print "n $stringa 2 n"; print "n da Stringa ad Array usando la funzione split() n" ; @testo = split ( " " , "ogni parola di questa frase diventerà elemento di un array" ); $dim = @testo; print "n dimensione di @testo = $dim n "; print "n @testo n" ; print "n EOJ $0 n "; __END__
Da stringa ad array e viceversa (split-and-Join. pl) da Stringa ad Array usando la funzione split() dimensione di @testo = 38 q u e s t o t e s t o v e r r à d i v i s o i n c a r a t t e r i da Array a Stringa usando la funzione join() q_u_e_s_t_o_ _t_e_s_t_o_ _v_e_r_r_à_ _d_i_v_i_s_o_ _i_n_ _c_a_r_a_t_t_e_r_i questo testo verrà diviso in caratteri da Stringa ad Array usando la funzione split() dimensione di @testo = 10 ogni parola di questa frase diventerà elemento di un array EOJ C: Usersmq 1App. DataLocalTempdzprltmp. pl
Array (Funzioni utili) PUSH and POP Funzioni comunemente usate per gestire una Pila(stack): PUSH POP F. I. L. O = First In Last Out La prima inserita e' l'ultima ad essere estratta. push @array, "elem 1"; pop @array;
Array (funzioni utili) SHIFT e UNSHIFT Funzioni comunemente usate per gestire una Coda : Shift estrae un elemento dalla testa SHIFT F. I. F. O = First In First Out La prima inserita e' la prima ad essere estratta dalla testa UNSHIFT inserisce un elemento in testa unshift @array, 4; shift @array;
Vettori - Funzioni usate – PUSH , POP, SHIFT, UNSHIFT #!/usr/bin/perl # programma che riempie un array use strict; use warnings; my @array = (); # si parte da una lista vuota my $tmp; push @array, "elem 1", "elem 2", "elem 3" , "sono il quarto"; print " n @array n"; print " n estraggo un elemento dalla coda ( da destra) n"; $tmp = pop @array; print " Ho estratto il valore ' $tmp ' n"; print " n estraggo gli elementi partendo da sinistra ovvero dalla testa n"; while ( @array ) # strano questo while! { $tmp = shift @array; # estrae gli elementi dalla testa ( ovvero "elem 1" poi "elem 2" etc. . . print " n estratto -> $tmp "; } print "n EOJ $0 n"; __END__
Vettori - Funzioni usate – PUSH , POP, SHIFT, UNSHIFT elem 1 elem 2 elem 3 sono il quarto estraggo un elemento dalla coda ( da destra) Ho estratto il valore ' sono il quarto ' estraggo gli elementi partendo da sinistra ovvero dalla testa estratto -> elem 1 estratto -> elem 2 estratto -> elem 3 EOJ qpush 2. pl
Esempio PUSH , POP, SHIFT, UNSHIFT #!/usr/bin/perl use 5. 010. 1; use strict; use warnings; my @array = qw(a b c d ); say "vettore iniziale -----> @array"; say " il terzo elemento --->$array[2]<---"; say 'inserisco tre elementi in testa ad array '; unshift @array, (1, 2, 3); say "@array"; say ' inserisco un elemento in coda ad array'; push @array, "eccomi!"; say "@array"; say ' inserisco 2 elementi in coda ad array'; push @array, ('X', 'Y'); say "@array"; say " elimino il primo e l'ultimo elemento di array"; pop @array; shift @array; say "@array";
Contesto Scalare $length = @poly_peptide ; (1) Se in una espressione sono coinvolti vettori (@) e scalari($) -come nell' espressione (1) – Perl cerchera' di interpretare l'istruzione in un contesto scalare. In questo caso si assegnera' a $length la lunghezza del vettore @poly_peptide La (1) è equivalente a $length=$#poly_peptide+1; Quindi il ciclo : while (@vector) {. . array in contesto scalare = lunghezza del vettore
Vettori – Funzione splice A volte capita, pero', di voler inserire nuovi elementi in un punto arbitrario di un array. Perl risolve questa necessita' con la funzione splice() della quale esistono molte forme: 1) splice ARRAY, OFFSET 2) splice ARRAY, OFFSET, LENGTH 3) splice ARRAY, OFFSET, LENGTH, LIST
Vettori – Funzione splice Cominciamo dal caso piu' semplice. splice ARRAY, OFFSET Questo uso di splice ha l'effetto di eliminare dall'ARRAY tutti gli elementi a partire dall'indice indicato (OFFSET) ESEMPIO: my @appo=("Anna", "Roberto", "Franco", "Pino", "Fabrizio"); print "@appon"; my @resto = splice (@appo, 3); print "@appon"; print "@reston"; __END__ Anna Roberto Franco Pino Fabrizio
Vettori – Funzione splice Vediamo ora il caso: splice ARRAY, OFFSET, LENGTH Questo uso di splice ha l'effetto di eliminare dall'ARRAY un numero LENGTH di elementi a partire dall'indice indicato (OFFSET) ESEMPIO: my @appo=("Anna", "Roberto", "Franco", "Pino", "Fabrizio", "Tony"); print "@appon"; my @resto = splice (@appo, 1, 2); print "@appon"; print "@reston"; __END__ Anna Roberto Franco Pino Fabrizio Tony Anna Pino Fabrizio Tony Roberto Franco
Vettori – Funzione splice Vediamo ora il terzo caso: splice ARRAY, OFFSET, LENGTH , LIST Questo uso di splice ha l'effetto di eliminare dall'ARRAY un numero LENGTH di elementi a partire dall'indice indicato (OFFSET) e, al posto di quelli eliminati, saranno inseriti quelli specificati da LIST #!/usr/bin/perl my @appo=("Anna", "Roberto", "Franco", "Pino", "Fabrizio", "Tony"); print "@appon"; my @lista= ('Ugo', 'Mauro'); my @resto = splice (@appo, 2, 3, @lista); print "@appon"; print "resto --> @reston"; __END__ Anna Roberto Franco Pino Fabrizio Tony Anna Roberto Ugo Mauro Tony resto --> Franco Pino Fabrizio
ARRAY e PEZZI DI ARRAY splice
Variabili speciali Perl usa molte variabili speciali. eccone alcune $_ Presente in molte situazioni dove non è espicitamente citata la variabile coinvolta ( per esempio come nella lettura di un file o in un ciclo foreach. $0 Nome del file corrente che e' eseguito. $] Versione di Perl usata. @_ Contiene i parametri passati ad una subroutine (sottoprogrammi). @ARGV Contiene gli argomenti passati al programma tramite la linea di comando. $! In contesto stringa contiene il motivo per cui si è verificato un errore.
Array Associativi (Hashes) Sono simili ai normali vettori ma gli elementi sono identificati dalle chiavi ( keys ) e non da indici. La chiavi possono essere piu' complesse in quanto stringhe di caratteri. Gli Hash sono caratterizzati dal fatto di avere il nome che inizia col simbolo % e possono essere inizializzati come I vettori: %Mio. Hash = (key 1, val 1, key 2, val 2, key 3, val 3. . );
Array Associativi (Hashes) Esempi my %mesi=('gen', 31, 'feb', 28, 'mar', 31, 'apr', 30); chiave Alternativamente è più chiaro! valore my %months=('gen'=> 31, 'feb'=> 28, 'mar'=> 31, 'apr'=> 30); => e' un sinonimo della virgola( , )
Array Associativi (Hashes) Esempio chiave valore my %persona = ( nome => 'Piero' , cognome => 'PASIMENI' , codfiscale => "PSMPRR 81 P 03 B 432 K", altezza => 180 ); Notare che il nome delle chiavi, nonostante siano delle stringhe, possono essere scritte senza apici o doppi apici. Questa e' una agevolazione fornita dall'operatore => (fat comma) che serve a separare le chiavi dai valori. Tale operatore considera sempre l'operando di sinistra come se fosse una stringa. my %persona = (nome, 'Piero', cognome, 'PASIMENI', codfiscale, 'PSMPRR 81 P 03 b 432 K', altezza , 180);
Associative Arrays (Hashes) Altro esempio… # %classificazione = ('cane' => 'mammifero', 'falco' => 'uccello', 'serpente' => 'rettile'); %genetic_code = ( 'TCA' => 'ser', Aminoacidi 'TTC' => 'phe', ser -> serina phe -> fenilalanina 'TTA' => 'leu', leu ->leucina pro-> prolina 'TGA' => 'STOP' ………. 'CCC' => undef, . . . );
Associative Arrays (Hashes) - elements Gli elementi scalari di un hash vengono manipolati usando le parentesi graffe, { e } : $genetic_code{TCA} = 'ser'; $genetic_code{CCC} = 'pro'; $genetic_code{TGA} = 'STOP'; $amino= $genetic_code{TCA}; Notare il segno $ : gli elementi sono scalari, pertanto devono essere preceduti dal segno del dollaro ( $), pur appartenendo ad un %Hash (proprio come nei vettori).
Associative Arrays (Hashes) funzioni utili exists indica se una particolare chiave esiste all'interno dell ' hash if (exists $genetic_code{$codon}) { Blocco di istruzioni; }else { print "Bad codon $codonn"; exit; }
Associative Arrays (Hashes) funzioni utili defined indica se una particolare chiave ha un valore oppure e' undef if (defined $genetic_code{'CCC'}) { print " definito "; }else { print " NON DEFINITO "; exit; }
Associative Arrays (Hashes) – funzioni utili keys e values generano vettori dalle chiavi( keys) e dai valori(values) di un hash. @codons = keys %genetic_code; @amino_acids = values %genetic_code; esempio d'uso: foreach $codon (keys %genetic_code) { if ($genetic_code{$codon} eq 'STOP') { last; # i. e. stop alla traduzione } else { # aggiungi alla proteina $protein. = $genetic_code{$codon}; }
Hash – aggiungere una chiave e un valore my %persona = ( nome => 'Piero' , cognome => 'PASIMENI' , codfiscale => "PSMPRR 81 P 03 B 432 K", altezza => 180 ); Supponiamo di voler aggiungere un'altra chiave , il peso, con il relativo valore. $persona{peso}=78;
Hash – cancellare una coppia chiave/valore my %persona = ( nome => 'Piero' , cognome => 'PASIMENI' , codfiscale => "PSMPRR 81 P 03 B 432 K", altezza => 180 , peso => 78 ); Per cancellare dalla struttura hash la coppia peso/valore basta scrivere : delete $hash{$key};
Stringhe e sottostringhe • Come si fa a cercare un pezzo di stringa all'interno di una stringa più grande? Perl fornisce una funzione per questo tipo di richiesta: index($Str. Lunga, $Str. Corta) Perl cerca la prima occorrenza della stringa corta all'interno della stringa lunga. il valore restituito può essere positivo, zero oppure -1.
Stringhe e sottostringhe. . index($Str. Lunga, $Str. Corta) valore 0 significa che $Str. Corta si trova proprio all'inizio della $Str. Lunga esempio : my $pos = index("guarda che mare", "gua"); # 0 valore 1 significa che $Str. Corta si trova all'interno di $Str. Lunga. esempio : my $pos = index("guarda che mare", "che"); # 7 valore -1 significa che $Str. Corta non esiste all'interno di $Str. Lunga. esempio : my $pos = index("guarda che mare", "orda"); # -1 NOTA: Rammentare che la posizione del primo carattere a sinistra di una stringa vale 0 e non 1! .
Stringhe e sottostringhe. . La sintassi della funzione index() può, all'occorrenza, avere anche un terzo parametro : index($Str. Lunga, $Str. Corta, $startpos) dove il valore numerico contenuto in $startpos significa che $Str. Corta sarà cercata in $Str. Lunga a partire dalla posizione $startpos esempio : #!/usr/bin/perl my $start = 5; my $pos = index("guarda che mare", "gua", $start); # -1 print " pos = $pos"; $pos = index("guarda che mare", "rda", $start); # -1 print " pos = $pos"; $pos = index("viva la vita", "vi", $start); # 8 print " pos = $pos"; print "n FINE DEL PROGRAMMA $0 n"; # filename Quso. INDEX. pl
E se volessimo conoscere la posizione dell'ultima occorrenza della stringa corta nella stringa lunga? Perl fornisce la funzione rindex() rindex($Str. Lunga, $Str. Corta) esempio: my $lastzeta= rindex("zio Fabrizio", "z"); # ritorna 9 print " pos ultimo zeta = $lastzeta"; Esiste anche Il terzo parametro opzionale index($Str. Lunga, $Str. Corta, $dadove) ma in questo caso rappresenta il massimo valore possibile di ritorno della funzione rindex. esempio: my $pos= rindex("Yabba doo!", "doo!", 10 ); # ritorna -1 print "n pos = $pos";
Funzione substr() La funzione substr($Stringa, $Posiniz, $lungh) estrae una pezzo di stringa da $Stringa partendo dalla posizione $Posinit per un certo numero di caratteri $lungh esempio: my $frase = "Prendo un pezzo di torta, grazie"; my $pz = substr($frase, 10, 5); # ritorna 'pezzo' print " n stringa estratta = $pz "; Se $lungh è assente , la stringa estratta parte dalla posizione $Posinit fino alla fine di $stringa Esempio: my $resto = substr($frase, 22); # ritorna 'ta , grazie' my $resto = substr($frase, 10); # ritorna 'ta , grazie'
Funzione substr()… La posizione iniziale $Posinit può essere anche negativa, in tal caso si conta dalla fine di $Stringa (partenza -1)e si estrae sempre verso destra Esempio: my $frase = "Prenda un pezzo di torta, _grazie"; my $dx = substr($frase, -9, 6); # ritorna 'a, _gra' Un altro esempio: my $frase = "Prenda un pezzo di torta, grazie"; substr($frase, -6, 6) = "Presto!"; print "n $frase"; # stampa: 'Prenda un pezzo di torta, Presto!' in questo caso abbiamo usato la funzione substr per alterare la stringa originale.
ITERAZIONI • In Perl esistono sostanzialmente tre principali strutture di controllo per realizzare cicli iterativi: • la struttura while. • la struttura for • ls struttura foreach
ITERAZIONI (while ) • Ripete un blocco di codice quando la condizione è vera. condizione my $count = 0; while ( $count < 10 ) { $count += 2; print "count is now $countn"; } # stampa i valori 2 4 6 8 10
ITERAZIONI (while ) • Ripete un blocco di codice quando la condizione è vera. #!/usr/bin/perl @frutta = ("mele", "pere", "pesche", "albicocche"); while (@frutta) { $frutto = shift @frutta; print "$frutton"; condizione } nota: la condizione (@frutta) è valutata in contesto scalare ovvero rappresenta il numero di elementi presenti nel vettore. L'istruzione shift ne toglie uno dalla testa, in ogni passaggio. Il ciclo finisce quando viene tolto l'ultimo elemento e la dimensione di @ frutta diventa =0 (quindi falso) esempio di ciclo infinito: while(1) { print "n ciclo che non finisce "; }
ITERAZIONI (do. . while ) • Ripete un blocco di codice almeno una volta ed infine verifica la condizione di continuazione del ciclo #!/usr/bin/perl condizione print "test do. . while n"; $i = 0; do { if ($i%2 == 1) { print " $i "; } $i++; } while ( $i < 10); print "n FINE DEL PROGRAMMA $0 n"; OUTPUT : stamperà 1 3 5 7 9 )
ITERAZIONI (do. . while ) • Ripete un blocco di codice almeno una volta ed infine verifica la condizione di continuazione del ciclo #!/usr/bin/perl print "test do {. . } while n"; $i = 0; do { if ($i%2 == 1) { print " $i "; $i++; } while ( $i < 10); Ho fatto una "leggera" modifica al programma precedente. Pensate che la modifica sia giusta?
ITERAZIONI (do. . while. . until ) • Ripete un blocco di codice almeno una volta ed infine verifica la condizione logica (se è vera esce dal ciclo) #!/usr/bin/perl print "test do {. . } until n"; $i = 0; do { if ($i%2 == 1) { print " $i "; } $i++; } until ( $i == 10); Quando $i prende il valore 10 il ciclo finisce.
ITERAZIONI - Ciclo for • La struttura for consente di ripetere un numero prefissato di volte un certo blocco di istruzioni, controllando la ripetizione del ciclo mediante un contatore. La sintassi dell'istruzione for è la seguente: for (condizione iniziale; condizione finale; incremento) { blocco di istruzioni } #!/usr/bin/perl @frutta = ("mele", "pere", "pesche", "albicocche"); for ($i=0; $i<=$#frutta; $i++) { print "$frutta[$i]n"; } condizione
ITERAZIONI - Ciclo for • Una versione ridotta di ciclo for nasconde il contatore ma mostra i valori di inizio e di fine. La variabile che contiene il conteggio viene fornita "gratuitamente" da Perl ! La variabile è $_ condizioni #!/usr/bin/perl for (1. . 10) { # come foreach loop da 1 a 10 print "counter is $_!n"; } for ($i = 1; $i < 10; $i++) { # Oops! Ho sbagliato qualcosa? print "counter is $_!n"; } esempio di ciclo for infinito: for (; ; ) {print "loop for infinito!n"; }
ITERAZIONI - foreach Permette di scandire un array oppure un hash elemento per elemento. Poniamo di aver definito il seguente array: @luoghi = ('Roma', 'Berlino', 'New York', 'Melbourne'); foreach $k(@luoghi) { print "$kn"; } Questa struttura memorizza in $k un elemento alla volta dell'array, e fa sì che le istruzioni nel blocco interno vengano eseguite finché tutta la lista è stata analizzata. Una delle comodità di foreach è quella di rendere possibile l'analisi di una copia modificata dell'array, senza per questo alterare l'originale. Ad esempio: foreach $k(sort @luoghi) { print "$kn"; } causerà la stampa di tutte le città ordinate alfabeticamente. In realtà @luoghi non viene assolutamente variato: ne viene creata ed utilizzata una copia anonima, contenente gli elementi ordinati. foreach (1. . 10) { print "counter is $_!n"; } # Perl fornsce $_ come variabile di controllo
Controllare le ITERAZIONI Perl dispone di alcuni operatori per controllare il flusso delle iterazioni. Si tratta di: last interrompe immediatamente il ciclo - -next -redo # Stampa tutte le linee che contengono la stringa 'fred' ma se incontra il marker __END__ il loop deve finire. while (<STDIN>) { if (/__END__/) { last; } elsif (/fred/) { print; } } ## last porta qui il programma #
Controllare le ITERAZIONI Perl dispone di alcuni operatori per controllare il flusso delle iterazioni. Si tratta di: - last interrompe immediatamente il ciclo -next fa partire l'iterazione successiva del ciclo -redo # legge un file -una riga la volta- e analizza solo le righe che non sono commenti. RIGA: while (<HFILE>) { next RIGA if /^#/; # Scarta i commenti # $L = length($_"); print "$_ ($L)"; etc……. . }
Controllare le ITERAZIONI Perl dispone di alcuni operatori per controllare il flusso delle iterazioni. Si tratta di: - last interrompe immediatamente il ciclo -next fa partire l'iterazione successiva del ciclo -redo fa ripetere il ciclo lasciando inalterate le variabili di controllo. # test usoredo. pl my @words = qw{ Pinuccio Ciccio franco gianni mauro DINO wilma Xyz 34 Q }; my $errori = 0; foreach (@words) { ## redo ritorna qui ## print "digita esattamente questo nome '$_': "; chomp(my $try = <STDIN>); if ($try ne $_) { print "Acc! - hai sbagliato riprova. nn"; $errori++; redo; # salta all'inizio del loop (jump back up to the top of the loop) } } print "Test completato , con $errori commessi. n";
CICLO UNTIL Il ciclo until è l'opposto del ciclo while : si esegue ripetutamente un blocco di istruzioni e smette quando la condizione di test diventa vera. In altre parole , il blocco diistruzioni viene eseguito quando il valore logico del test è falso. Sia il ciclo while che il ciclo until valutano la condizione di test prima di eseguire il blocco di istruzioni ; quindi se la condizione e' inizialmente falsa (perl il while) o vera (per until ) il blocco di istruzioni verrà saltato interamente. I controlli next, last e redo possono essere usati nel ciclo.
CICLO UNTIL Il ciclo until è l'opposto del ciclo while : si esegue ripetutamente un blocco di istruzioni e smette quando la # initializzo un array my $count = 0; my @numeri = qw(one two three four five); until(!@numeri) { $count++; shift(@numeri); } print "$count elementi cancellati !n"; # stampa: 5 elementi cancellati!
UNTIL usato come modificatore di istruzione until (EXPR) esempio #!/usr/bin/perl my $count = 10; print $count, " " until --$count <=0; print "n"; # stampa : 9 8 7 6 5 4 3 2 1 print "count = $countn"; # stampa count = 0 print "n FINE DEL PROGRAMMA $0 n";
LEGGERE un File filehandle (maniglia): open(IN, " <", "input. txt"); Apre un file in lettura , e lo collega ad un E Legge una riga dal filehandle , nello stesso modo come leggere da <STDIN>: my $line = <IN>; from file to scalar (and move to the next line) my @input. Lines = <IN>; Read all file to array Every filehandle opened should be closed: close(IN); Always check the open didn’t fail (e. g. if a file by that name doesn’t exists): open(IN, "<" "$file") or die "problems for $file $! ";
Scrivere su un file Apre un file in scrittuta , collegandolo ad un filehandle: open(OUT, ">", "output. txt") or die. . . NOTA: Se il file output. txt esiste sara’ sovrascritto! E’ anche possibile aprire un file in modalita’ ‘append ‘ e le righe verranno aggiunte alla fine del file esistente: open(OUT, ">", "output. txt") or die. . Scrivere sul file (in entrambi I casi): print OUT "This is an output line. n"; Nessuna virgola qui
Operatori di controllo Esiste la maniera per verificare alcune caratteristiche di un file o di una directory: if (-e $name) { print “Il file $name esiste!n"; } -e -r -w -z -s -f -d -l -T -B $name exists $name is readable $name is writable by you $name has zero size $name has non-zero size (returns size) $name is a file $name is a directory $name is a symbolic link $name is a text file $name is a binary file (opposite of -T).
Nome completo del file open( IN, '<' , ' D: workspacePerlp 53. fasta' ); • Usare il percorso completo di un file rende piu’ chiaro il programma • Ricordatevi di usare \ se usate I doppi apici open( IN, '<' , "D: \workspace\Perl\$name. fasta" • (oppure ) potete anche usare / open( IN, "<D: /workspace/Perl/$name. fasta" );
Esempio di apertura in append #!/usr/bin/perl # apro un file in append #( per aggiungere righe senza distruggere il file) use strict; use warnings; use 5. 010; my $filename = ‘C: /Perl/prove/amici. txt'; open(my $fh, '>>', $filename) or die "problema in apertura file '$filename' $!"; say $fh "Giuliano"; say $fh "Giulio"; say $fh "Fabrizio Rossi"; say $fh "Marina Verdi"; close $fh; say 'fatto';
ESEMPIO in PERL CAMBIAMENTO DI BASE Il programma chiede in INPUT: - la base ( da 2 a 16) - il numero positivo da trasformare nella nuova base
Cambio base #!/usr/bin/perl use strict; use warnings; use feature 'say'; my $Num ; my $base; my @resto = qw(0 1 2 3 4 5 6 7 8 9 A B C D E F); my @V=(); # vettore vuoto my $r = 0; # resto my $rt = "? "; # resto tabella print "n=========== "; print "n trasformazione in base x (2. . 16) "; print "n =========== "; say @resto; do { print "n inserire la base "; $base = <STDIN>; $base = int($base); } until ( ($base >1) && ($base < 17)); print "n Base scelta = $base " ; do { print "n inserire il numero non negativo "; $Num = <STDIN>; $Num = int($Num); } until ( ($Num >= 0)); print "n Numero scelto = $Num "; my $k =0; my $N = $Num; while ($N >0) { $r = $N % $base; say "(r=$r ) "; $rt = $resto[$r]; say "( rt = $rt ) n"; unshift(@V, $rt); $N = ($N - $r)/$base; } print "n fine ciclo while n n "; print "n ****************** n"; print " $Num in base $base = @V n "; print "****************** n"; print "n FINE PROGRAMMA $0 n ";
LINK Utili • http: //www. perl. it/documenti/modern_perl. html • • http: //perldoc. perl. org/index-functions. html http: //www. html. it/guide/guida-perl/ http: //www. tutorialspoint. com/perl/ http: //perldoc. perl. org/index-functions. html • http: //search. cpan. org/~enrys/POD 2 -IT-0. 12/IT/perl. pod • http: //www. perl. it/modern_perl/html
Esempio di 'state' use strict; use warnings; use 5. 010; sub count { state $counter = 0; # questa variabile sara' inizializzata a zero # solo la prima volta $counter++; return $counter; } say count(); # say " counter = $counter"; # errore! $ counter non viene vista # fuori dalla sub count
Esempio apertura e lettura di file #!/usr/bin/perl use 5. 010; use strict; my $L; open(HF, "<", 'C: PerlQTESTnames 2. txt'); # apro un file RIGA: while (<HF>) { next RIGA if /^#/; $L = length($_); print "$_ ($L)"; } close(HF); print "n fine del progr. $0 n"; # Scarta i commenti # Se eliminate RIGA in tutte le linee funziona lo stesso
Esempio cicli #!/usr/bin/perl use strict; print " test do . . until n"; my $i = 0; do { if ($i%2 == 1) { print " $i dispari n"; } $i++; } until ( $i == 10); print " n FINE ciclo do. . until n "; my @frutta = ("mele", "pere", "pesche", "albicocche"); for ($i=0; $i<=$#frutta; $i++) { print "$frutta[$i]n"; }
- Slides: 87