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"; }
Scarica

Perl_2015_16 - Benvenuti da poincare.unile.it