Perl
Practical extraction Report Language
Pathologically eclectic rubbish lister :-)
Variabili e strutture dati
Corso Perl per Biotecnologie (2015)
Il manualetto di
riferimento in Italiano:
Stefano Rodigliero
Pocket Perl
Ed:APOGEO
The “Hello World” program
Consideriamo il seguente programmino:
#!\usr\bin\perl
#
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”;
__END__
Perl Variables
#!\usr\bin\perl è 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.
In realtà gli hashes possono essere ricondotti agli arrays
Esempi
Variabili Scalari
#
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=1e-40;
# notazione scientifica
my $dna=“GCCTACCGTTCCACCAAAAAAAA”; # string -double quotes
my $dna=‘GCCTACCGTTCCACCAAAAAAAA’; #string -single quotes
my $n = 0b1110011;
# intero binario $n = 01234; # intero ottale
my $var = 01234;
# intero ottale
my $n = 0x5FA8;
# 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 “$j\n”;
}
#
my $dna1=“GCCTAAACGTC”;
my $polyA=“AAAAAAAAAAAAAAAA”;
$dna1 .= $polyA; # aggiunge una stringa ad un’altra
# (equiv. $dna1 = $dna1.$polyA)
my $no_of_bases = length($dna1); # 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<>$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_000 ;
my $esadecimale = 0xDEADBEEF;
my $ottale = 0210;
my $binario = 0b0101101;
print "$esadecimale\n";
print "$ottale\n";
print "$binario\n";
===== OUTPUT ==========
1000000
3735928559
136
45
# Ancora sintassi utili...
$var1 = 1;
$var2 = 2;
$var3 = "pippo";
$var4 = "pluto";
print "var1=$var1 \t var2=$var2 \t var3=$var3 \t var4=$var4 \n";
$tot1=$var1+$var2;
print "tot1=var1+var2 = $tot1 \n ";
$tot2=$var1.$var2;
print "tot2= var1.var2 = $tot2 \n ";
print "var1+var2 = $tot1\n";
# >var1+var2 = 3
print "var1\.var2 = $tot2\n";
#
>var1.var2 = 12
$tot1=$var3+$var4; # warning NUM + STRINGA! Perl ci prova
comunque.
$tot2=$var3.$var4; # concatenazione
print "var3+var4 = $tot1\n";
# >var3+var4 = 0
print "==== \$var3.\$var4 = $tot2\n";
# >var3.var4 = pippopluto
$tot1=$var3+1;
print "var3+1 = $tot1\n";
#
>var3+1 = 1
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,30,31,31,30,31,30,31);
@days_of_the_week=(‘mon’, ‘tue’, ‘wed’
,’thu’,’fri’,’sat’,’sun’);
@bases = (‘adenine’, ‘guanine’, ‘thymine’, ‘cytosine’,
‘uracil’);
@GenBank_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’,’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 simbolo $;
@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;
#
MarcoPaoloMaria
• print "@names";
Maria
#
• print @names.”";
elementi del vettore
Marco Paolo
#
>3 n. di
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";
@arrai2 = @ARRAI[0..2];
# estrae i primi 3 elementi di @arrai
say "@arrai2";
@arrai3 = @ARRAI[-2..3]; #
say "@arrai3";
# estrae il 3^, 7^ e 8^ elemento da @ARRAI
@arrai4 = @ARRAI[2,6,7];
say "@arrai4";
$dim = @ARRAI; # $dim contiene il numero di elementi di @ARRAI
say " in \@ARRAI ci sono $dim elementi ";
@unosolo = @ARRAI[8];
say "\@unosolo @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 $stringa1 = join("_" , @testo)."\n";
print "\n $stringa1 \n";
my $stringa2 = join("" , @testo)."\n";
print "\n $stringa2 \n";
#
#
q_u_e_s_t_ ………
questo
;
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
questo testo verrà diviso in caratteri
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:\Users\mq1\AppData\Local\Temp\dzprltmp.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, "elem1“;
push @array;
Array (funzioni utili)
SHIFT e UNSHIFT
Funzioni comunemente usate per gestire una Coda :
Shift estrae un elemento dalla testa
F.I.F.O = First In
First Out
SHIFT
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, "elem1", "elem2", "elem3" , "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 "elem1" poi "elem2" etc...
print " \n estratto -> $tmp ";
}
print "\n EOJ $0 \n";
__END__
Vettori - Funzioni usate – PUSH ,POP, SHIFT,UNSHIFT
elem1 elem2 elem3 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 -> elem1
estratto -> elem2
estratto -> elem3
EOJ qpush2.pl
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 "@appo\n";
my @resto = splice (@appo, 3);
print "@appo\n";
print "@resto\n";
__END__
Anna Roberto Franco Pino Fabrizio
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 "@appo\n";
my @resto = splice (@appo, 1,2);
print "@appo\n";
print "@resto\n";
__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 "@appo\n";
my @lista= ('Ugo','Mauro');
my @resto = splice (@appo, 2,3,@lista);
print "@appo\n";
print "resto --> @resto\n";
__END__
Anna Roberto Franco Pino Fabrizio Tony
Anna Roberto Ugo Mauro Tony
resto --> Franco Pino Fabrizio
ARRAY e PEZZI DI ARRAY
splice
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:
%MioHash = (key1,val1,key2,val2,key3,val3..);
Array Associativi (Hashes)
Esempi
my %mesi=(‘gen’,31,’feb’,28,’mar’,31,’apr’,30);
Alternativamente
chiave
valore
my %months=(‘gen’=> 31,
‘feb’=> 28,
‘mar’=> 31,
‘apr’=> 30);
=> e’ un sinonimo della virgola( , )
è più chiaro!
Array Associativi (Hashes)
Esempio
chiave
my %persona = ( nome => 'Piero' ,
cognome => 'PASIMENI' ,
codfiscale => "PSMPRR81P03B432K",
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’, ’
PSMPRR81P03b432K,’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 $codon\n”;
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 => "PSMPRR81P03B432K",
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 => "PSMPRR81P03B432K",
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($StrLunga,$StrCorta)
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($StrLunga,$StrCorta)
valore 0 significa che $StrCorta si trova proprio all’inizio della $StrLunga
esempio :
my $pos = index(“guarda che mare”,”gua”); # 0
valore 1 significa che $StrCorta si trova all’interno di $StrLunga.
esempio :
my $pos = index(“guarda che mare”,”che”); # 7
valore -1 significa che $StrCorta non esiste all’interno di $StrLunga.
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($StrLunga,$StrCorta,$startpos)
dove il valore numerico contenuto in $startpos significa che $StrCorta
sarà cercata in $StrLunga 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 QusoINDEX.pl
E se volessimo conoscere la posizione dell’ultima
occorrenza della stringa corta nella stringa lunga?
Perl fornisce la funzione rindex()
rindex($StrLunga,$StrCorta)
esempio:
my $lastzeta= rindex("zio Fabrizio","z"); # ritorna 9
print " pos ultimo zeta = $lastzeta";
Esiste anche Il terzo parametro opzionale index($StrLunga,$StrCorta,$dadove)
ma in questo caso rappresenta il massimo valore possibile di ritorno
della funzione rindex.
esempio:
my $pos= rindex(“Yabba dabba 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,100); # 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 $count\n";
}
# 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 "$frutto\n";
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 "$k\n"; }
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 "$k\n"; }
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
-next
-redo
interrompe immediatamente il ciclo
# Stampa tutte le linee che contengono la stringa
marker __END__
il loop deve finire.
while (<STDIN>)
{
if (/__END__/)
{ last; }
elsif (/fred/)
{ print; }
}
## last porta qui il programma #
‘fred’
ma se incontra il
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 /^#/;
$L = length($_”);
print “$_ ($L)“;
etc. etc……..
}
# Scarta i commenti #
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.
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
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 = $count\n"; # stampa count = 0
print "\n FINE DEL PROGRAMMA $0 \n";
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/POD2-IT-0.12/IT/perl.pod
Esempio di
‘state’
use strict;
use warnings;
use 5.010;
sub count {
state $counter = 0;
$counter++;
return $counter;
}
#
main
say count();
say count();
say count();
# posto a zero solo la prima volta
# 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:\Perl\QTEST\names2.txt');
RIGA:
while (<HF>)
{ next RIGA if /^#/;
$L = length($_);
print "$_ ($L)";
}
close(HF);
print "\n fine del progr. $0 \n";
# apro un file
# 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"; }