Introduzione agli scripting languages ed ai WEB tools

Slides:



Advertisements
Presentazioni simili
Strutture dati per insiemi disgiunti
Advertisements

Shell: variabili di sistema PATH HOME USER PWD SHELL HOSTNAME HOSTTYPE Per visualizzare il valore di tutte le variabili dambiente si usa il comando set.
1 Introduzione ai calcolatori Parte II Software di base.
PHP.
MATLAB.
MATLAB. Scopo della lezione Programmare in Matlab Funzioni Cicli Operatori relazionali Esercizi vari.
Dipartimento di Matematica
File System Cos’è un File System File e Directory
Algoritmi e Programmazione
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
Informatica Generale Marzia Buscemi
Università La Sapienza Web programming e programmazione multimediale 1 Web Programming e comunicazione multimediale Lezione 10: PHP.
RB-alberi (Red-Black trees)
Alberi binari di ricerca
Programmazione Procedurale in Linguaggio C++
1 Istruzioni, algoritmi, linguaggi. 2 Algoritmo per il calcolo delle radici reali di unequazione di 2 o grado Data lequazione ax 2 +bx+c=0, quali sono.
Reaching Definitions. Tino CortesiTecniche di Analisi di Programmi 2 Reaching definitions Dato un punto del programma, quali sono i comandi di assegnamento.
Argomenti dalla linea dei comandi Gli argomenti possono essere passati a qualsiasi funzione di un programma, compresa la main(), direttamente dalla linea.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Lab 5 – Info B Marco D. Santambrogio – Riccardo Cattaneo –
Informatica di base A.A. 2003/2004 Algoritmi e programmi
File.
Algoritmo di Ford-Fulkerson
Informatica 2. Concetti fondamentali di programmazione Programmare vuol dire scrivere un algoritmo in un linguaggio che faccia funzionare un calcolatore.
Corso di Laurea in Biotecnologie Informatica (Programmazione)
Corso di Informatica (Programmazione)
MATLAB. …oggi… Programmare in Matlab Programmare in Matlab Funzioni Funzioni Cicli Cicli Operatori relazionali Operatori relazionali Esercizi vari Esercizi.
eliana minicozzi linguaggi1a.a lezione2
Algoritmi e strutture dati
Uso dei cicli y t =c+ty t-1 +e Un uso dei cicli può essere quello di creare una serie storica per cui y t =c+ty t-1 +e dove poniamo c e t scalari ed e~N(0,1).
Il linguaggio Fortran 90: 4. Array: Vettori e Matrici
Introduzione alla programmazione lll
Unità Didattica 2 I Linguaggi di Programmazione
Strutture di controllo in C -- Flow Chart --
I File.
Espressioni condizionali
Sistemi Operativi - Introduzione 1 Il sistema operativo UNIX Dettagli e comandi avanzati Niccolò Battezzati Politecnico di Torino Dip. Automatica e Informatica.
Sistemi Operativi - Introduzione 1 Il sistema operativo UNIX Dettagli e comandi avanzati Niccolò Battezzati Politecnico di Torino Dip. Automatica e Informatica.
Sistemi Operativi - Introduzione 1 Il sistema operativo UNIX AWK Niccolò Battezzati Politecnico di Torino Dip. Automatica e Informatica.
GESTIONE DEI FILE Per poter mantenere disponibili i dati tra le diverse esecuzioni di un programma (persi-stenza dei dati) è necessario poterli archi-viare.
Corso di PHP.
DBMS ( Database Management System)
Javascript: fondamenti, concetti, modello a oggetti
Elementi di Informatica di base
Esercizio 10.* Un cassiere vuole dare un resto di n centesimi di euro usando il minimo numero di monete. a) Descrivere un algoritmo goloso per fare ciò.
CODIFICA Da flow-chart a C++.
2000 Prentice Hall, Inc. All rights reserved. Capitolo 10 (Deitel) Strutture, unioni ed enumerazioni Sommario Introduzione Definire le strutture.
21 marzo 2002 (ri-)Avvisi: Giovedi 28 marzo la lezione e sospesa. Nuovo indirizzo di Spedire messaggi e esercizi solo.
1 Ly-LAB Sistema di gestione dei dati analitici di laboratorio.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Array e stringhe Marco D. Santambrogio – Ver. aggiornata al 9 Agosto 2013.
BIOINFO3 - Lezione 201 Come in ogni corso di introduzione ad un linguaggio di programmazione, proviamo a scrivere lormai celebre primo programma di prova.
BIOINFO3 - Lezione 41 ALTRO ESEMPIO ANCORA Progettare il comando di creazione di una tabella di pubblicazioni scientifiche. Come chiave usare un numero.
Fopndamenti di programmazione. 2 La classe String Una stringa è una sequenza di caratteri La classe String è utilizzata per memorizzare caratteri La classe.
Corso JAVA Lezione n° 11 Istituto Statale di Istruzione Superiore “F. Enriques”
ISTITUTO STATALE DI ISTRUZIONE SUPERIORE F. ENRIQUES CORSO JAVA – PROVA INTERMEDIA DEL 12 MARZO 2007 NOME: COGNOME: ________________________________________________________________________________.
File e Funzioni Si possono distinguere tre tipi di file che vengono utilizzati in MATLAB: M-file: hanno estensione .m e in essi vengono memorizzati i.
ASP – Active Server Pages Introduzione Pagine Web Statiche & Dinamiche(ASP)
Il linguaggio Fortran 90: 3. Procedure e Funzioni
Lezione 3 Struttura lessicale del linguaggio
A.P. cat. B - 1 Per chi vuole: Libro di testo D.P. Curtis, K. Foley, K. Sen, C. Morin Informatica di base 2° edizione Mc Graw-Hill Companies.
Script di shell (bash).
1 Esercitazione Sistemi distribuiti: sistemi che risisedono su più calcolatori interconnessi da una rete di comunicazione Algoritmi distribuiti: programmi.
Introduzione a Javascript
Esercitazione su Vector. Permette di definire collezioni di dati generiche, che sono in grado di memorizzare elementi di ogni sottotipo di Object Definito.
1 PROGRAMMAZIONE IN SHELL The Unix Programming Environment Kernigham - Pike.
TW Asp - Active Server Pages Nicola Gessa. TW Nicola Gessa Introduzione n Con l’acronimo ASP (Active Server Pages) si identifica NON un linguaggio di.
Ancora sulla shell. Shell e comandi La shell e' un programma che interpreta i comandi dell'utente. I comandi possono essere dati da terminale, oppure.
Informatica e Informatica di Base
Cloud informatica V anno. Introduzione a PHP Lo scripting PHP PHP è un linguaggio di scripting lato server. Le caratteristiche di un linguaggio di scripting.
Eprogram informatica V anno. Introduzione a PHP Introduzione La diffusione di PHP ha avuto un notevole incremento dalla fine degli anni Novanta a oggi,
Transcript della presentazione:

Introduzione agli scripting languages ed ai WEB tools Dario Menasce I.N.F.N. e Universita' degli Studi di Milano

Introduzione Cosa sono gli scripting languages Perche’ ci interessa PERL in particolare rispetto ad altri linguaggi di scripting Guida di sopravvivenza minimale Breve introduzione alla sintassi Sviluppo di un semplice esempio come programma stand-alone Breve introduzione al protocollo HTML e CGI Interfacciamento del programma di esempio ad un WEB browser Suggerimenti per reperire documentazione in rete Conclusioni

Cos’e’ uno scripting language? Scripting language ---> collante tra le funzionalita’ di un sistema operativo o, piu’ in generale, tra le funzioni primitive di un ambiente applicativo.

Es: shell script kumac Tcl/Tk JavaScript . . . . . . . Gli shell script sono legati non solo al soggiacente sistema operativo (UNIX, Win98…) ma addirittura alla particolare shell in uso (sh, bash, tcsh, …) (problemi di portabilita’) D’altra parte uno shell script per girare necessita di minime risorse di sistema. Questo e’ molto importante per un sistemista, in quanto una macchina in grado di funzionare in modo minimale e’ sicuramente dotata almeno di una shell (generalmente la shell sh), per cui gli script di quella shell potranno, in linea di principio, funzionare anche in assenza di ulteriori risorse, quali un interpreter PERL. Kumac e’ lo scripting language nativo di PAW: abbastanza sofisticato ma non dotato di capacita’ di interazione col sistema operativo. Vedremo come e’ possibile usare PERL (con grande vantaggio e soddisfazione) per fargli generare degli script kumac (un modo di usare PERL come meta-linguaggio)

Es: shell script kumac Tcl/Tk JavaScript . . . . . . . Tcl/Tk e’ una coppia di linguaggi adatti alla creazione di interfacce grafiche. Tcl e’ sofisticato, ma dotato di strutture di dati non sufficientemente articolate. Esiste un modulo di PERL, chiamato PERL/Tk, che sostituisce Tcl nella coppia di linguaggi: e’ possibile con esso scrivere sofisticate interfacce utente, come ad esempio un completo browser o un’interfaccia ad un DAQ. JavaScript e’ uno scripting language che opera ESCLUSIVAMENTE all’interno di un WEB browser (tipicamente Netscape o InternetExplorer). E’ utilizzato per aggiungere funzionalita’ dinamiche alle pagine WEB, come ad esempio verificare la validita’ dei campi di input di un form prima che questo venga spedito al server. Questo risparmia al server di verificare la validita’ dei dati in arrivo da centinaia di clients, demandando ad essi tutta la computazionalita’ necessaria.

Es: shell script kumac Tcl/Tk JavaScript . . . . . . . Tutti gli esempi indicati sono legati all’ambiente particolare per i quali erano stati progettati: PERL, al contrario, e’ quasi totalmente portabile e general-purpose. E’ universalmente disponibile in rete ed e’ gratuito. E’ aperto (esistono i sorgenti) E’ supportato e sviluppato da una vastissima comunita’ Esistono ricche librerie di moduli liberamente disponibili in rete come pure vastissima e’ la documentazione disponibile

Kumac: scripting language di PAW (Physics Analysis Workstation) unix> paw Limiti PAW> fun1 1 sin(x)/x 100 -20 20 Identifier (Id) Numero di punti (bins)

Kumac: scripting language di PAW (Physics Analysis Workstation) unix> paw PAW> fun1 1 sin(x)/x 100 -20 20 PAW> fun2 2 sin(x)/x*sin(y)/y 100 -10 10 100 -10 10

Kumac: scripting language di PAW (Physics Analysis Workstation) Dopo aver definito gli istogrammi salviamoli su disco in un file: unix> paw PAW> fun1 1 sin(x)/x 100 -20 20 PAW> fun2 2 sin(x)/x*sin(y)/y 100 -10 10 100 -10 10 PAW> his/file 10 histograms_file.his 1024 N PAW> hrout 0 Unita’ di I/O Nome file Record size Flag: New file Salva tutti (0) gli istogrammi definiti PAW> close 10 PAW> exit unix>

Kumac: scripting language di PAW (Physics Analysis Workstation) unix> paw PAW> fun1 1 sin(x)/x 100 -20 20 PAW> fun2 2 sin(x)/x*sin(y)/y 100 -10 10 100 -10 10 PAW> his/file 10 histograms_file.his 1024 N PAW> hrout 0 PAW> close 10 PAW> exit unix> ls -la *.his -rw-r--r-- 1 menasce e831 21451365 Sep 8 19:43 histograms_file.his Vogliamo ora riaprire questo file e stampare gli istogrammi in formato grafico

Ripristina in memoria i dati degli istogrammi unix> paw PAW> his/file 10 histograms_file.his PAW> his/lis Ripristina in memoria i dati degli istogrammi leggendoli dal file precedentemente salvato ===> Directory : //PAWC 1 (1) sin(x)/x 2 (2) sin(x)/x*sin(y)/y PAW> zon 2 2 PAW> his/plo 1 PAW> Palette 1 PAW> Set Ncol 50 PAW> his/plo 2 colz PAW> surf 2 PAW> h/plo 2 surf4

Supponiamo ora di avere a disposizione 4 files di istogrammi e di voler sommare gli istogrammi con Id=15 fra loro, mettendo il risultato nell’istogramma con Id=100. Sara’ utile allo scopo preparare uno script (somma.kumac) e farlo eseguire in PAW. Macro somma MaxHistos = 4 Definisce il numero di files da considerare Do I = 1, [MaxHistos] EndDo Predispone i cicli per ogni file Case [I] in EndCase A seconda del ciclo corrente, definisce un diverso nome di file a aprire in lettura (1) File = ‘pixelreadout.his’ (1) File = ‘pixelreadout.his’ (2) File = ‘pixelnocharge.his’ (3) File = ‘newpixeldata.his’ (4) File = ‘pixelredesign.his’ (2) File = ‘pixelnocharge.his’ (3) File = ‘newpixeldata.his’ (4) File = ‘pixelredesign.his’ Il primo istogramma viene copiato pari pari in un nuovo istogramma con Id=100 his/fil 1 [File] if ([I] .Eq. 1) then else endif his/copy 15 100 Ogni nuovo istogramma viene sommato a quello con Id=100 his/oper/add 15 100 100 Sistema poco pratico, soprattutto se i file hanno nomi non componibili con un algoritmo automatico e sono in numero molto elevato. his/plo 100 somma.kumac Vedremo come l’uso di PERL ci faciliti nel compito di automatizzare la scrittura degli scripts (useremo PERL come meta-linguaggio)

Domanda: io che sono un fisico e non uno studioso di informatica, quali vantaggi posso trarre dall’uso di PERL nella mia attivita’ quotidiana? E perche’ linguaggi come il FORTRAN o gli shell scripting possono non essere ugualmente adeguati allo scopo? La curva di apprendimento ha una derivata piccola. Si possono facilmente riciclare le conoscenze di C e di shell programming Semplice da imparare Molto sofisticato e flessibile Pur essendo semplice da imparare, e’ pur sempre un linguaggio estremamente ricco di attributi e funzionalita’ Portabile Questo e’ uno dei maggiori punti di forza di PERL: una volta scritto il codice, esso funzionera’ senza modifiche sul 99% delle piattaforme esistenti. Ottimo collante fra processi PERL e’ nato per manipolare file e stringhe, ma si e’ evoluto fino a divenire un ottimo collante fra procedure eterogenee, poiche’ sa interagire col soggiacente sistema operativo in modo molto efficace. E’ estremamente sintetico La sua sintassi e’ molto concisa: cio’ permette di descrivere in poche istruzioni algoritmi piuttosto complessi. Cio’ potenzialmente minimizza la possibilita’ di introdurre errori involontari nel codice

E’ interpretato Pur essendo interpretato e’ piuttosto veloce in esecuzione. Inoltre ha la caratteristica di avere accesso a run-time al proprio compilatore La sua velocita’ non e’ pero’ comparabile a quella di un programma compilato (inadatto ad applicazioni che siano critiche nei tempi di esecuzione, tipo DAQ o real-time) Prima di passare ad una descrizione del linguaggio PERL, vediamo se il nostro computer ha una versione installata e recente dell’interpreter.

> which perl > whereis perl > locate perl > perl -v Fornisce il full path-name dell’eseguibile purche’ sia in uno di quelli specificati nella variabile PATH > which perl > whereis perl Cerca l’eseguibile, e le eventuali man-pages associate in tutto il tree / (root directory tree) > locate perl Cerca in un apposito database del sistema (solo su LINUX) tutte le istanze di files contenenti la stringa perl interpretata come regular-expression Versione 5.004_01 > perl -v This is perl, version 5.004_01 Copyright 1987-1997, Larry Wall Perl may be copied only under the terms of either the Artistic Licence or the GNU General Public Licence, which may be found in the PERL 5.0 source kit. Interpreta il file source.pl, stampa eventuali warnings di compilazione, e lo esegue > perl -w source.pl Interpreta il file source.pl, stampa eventuali warnings di compilazione, ma NON lo esegue > perl -c source.pl

La sintassi di PERL I tipi di variabili Gli scalari test.pl $Number = 16 ; Come in C, anche in PERL un’istruzione e’ terminata dal ; $mass = 1.868 ; $myName = “Dario Menasce” ; $Address = “Via Celoria” ; $FullAdd = “$myName $Address $Number.” ; print(“ ”) ; $FullAdd \n > chmod +x test.pl > perl -w test.pl Dario Menasce, Via Celoria 16. $myName $Address $Number

La sintassi di PERL I tipi di variabili I vettori Come in C, i vettori in PERL partono da 0 !!! @VectorA = (1,2,3,4,5,6) ; @VectorB = ( ) ; “Bob” ,25 ,$VectorA[3] ,(25,26,’String’) @VectorC = ( ) ; @VectorB ,$VectorA[0] Nome collettivo Un singolo elemento di un vettore e’ uno scalare! Il nome collettivo di un vettore e’ identificato dal simbolo @ Vediamo alcune delle operazioni utili sui vettori che e’ possibile realizzare con una singola istruzione (i fisici amano i vettori…)

La sintassi di PERL (I) @fred = (1, “ab”, $var) ; Inizializziamo un vettore con tre elementi: @fred = (1, “ab”, $var) ; Ne facciamo una copia @barney = @fred ; Calcoliamo il numero di elementi del vettore $length varra’ 3 $length = @fred ; Estraiamo il primo elemento del vettore (equivalente a $one = $fred[0] ossia 1) ($one) = @fred ; Estraiamo i singoli elementi del vettore $a = 1, $b = “ab” e $c = $var ($a,$b,$c) = @fred ; Scambiamo $a con $b ($b,$a) = ($a,$b) ; Riassegna un valore al secondo elemento del vettore $fred[1] = “alpha” ; Incrementa il primo elemento del vettore (diventa 2) $new = $fred[0]++; Incrementa il secondo elemento del vettore: poiche’ e’ una stringa, incrementa il valore ASCII dell’ultimo carattere della stringa (diventa ac) $new = $fred[1]++ ; Scambia fra loro il secondo e terzo elemento del vettore (operando su slices del vettore) @fred[1,2] = @fred[2,1]; Restituisce l’indice dell’ ultimo elemento del vettore (in questo caso 2) $fred[2] += 4 ;

La sintassi di PERL (II) Inizializziamo un vettore con tre elementi: @fred = (1, “ab”, $var) ; Restituisce l’ultimo elemento del vettore ($var) $last = $fred[-1] ; Restituisce l’indice dell’ ultimo elemento del vettore (in questo caso 2) $lastind = @#fred ; Aumenta la dimensione del vettore a 9 elementi definendo l’ultimo: gli elementi [4],[5],[6],[7] avranno valore undef $fred[8] = “$pippo” ; Concatena al secondo elemento del vettore la stringa “cd” (si ottiene “abcd”) $fred[1] .= “cd” ;

La sintassi di PERL Sono possibili manipolazioni arbitrariamente complesse sugli elementi di un vettore (il confronto con il FORTRAN diverra’ evidente) @fred = (“sette”, “otto”, “nove”) ; Inizializzo un vettore a tre elementi contenenti ognuno una stringa di caratteri Vediamo come fare per invertire l’ordine degli elementi di questo vettore: @ord = (2, 1, 0 ) ; Inizializzo un secondo vettore a tre elementi contenente tre numeri che rappresentano l’ordine con cui voglio riassemblare il primo vettore @back = @fred( ) ; @ord Cio’ e’ equivalente a: @back = @fred(2, 1, 0) ; Che e’ a sua volta equivalente a: @back = ($fred[2], $fred[1], $fred[0]) ; @back = (“nove”, “otto”, “sette”) ;

La sintassi di PERL Gli operatori di stacking: push, pop, shift and unshift @mylist = (1, “two”, “three”) ; $newvalue = 4 ; push @mylist, $newvalue ; print( “mylist = @mylist\n” ) ; mylist = 1 two three 4 Ai vettori e’ associato un ricco assortimento di operatori capaci di agire su di essi in modo sintetico. Vediamone alcuni: 1 $mylist[0] Stack two $mylist[1] three $mylist[2] push estende la dimensione del vettore e aggiunge l’ultimo elemento in coda 4 $mylist[3]

La sintassi di PERL Gli operatori di stacking: push, pop, shift and unshift $lastadded = pop( @mylist ) ; print( “Last added = $lastadded\n” ) ; Last added = 4 1 $mylist[0] two $mylist[1] three $mylist[2] 4 $mylist[3] pop rimuove l’ultimo elemento dello stack (la gestione degli indici e’ a carico di pop)

La sintassi di PERL Gli operatori di stacking: push, pop, shift and unshift $mylist = (1,”two”,”three”) ; unshift( @mylist, “zero” ) ; print( “mylist = @mylist\n” ) ; mylist = zero 1 two three unshift agginunge un elemento al primo posto nel vettore: poiche’ rinumera gli elementi, puo’ essere inefficiente per vettori molto grandi. zero $mylist[0] 1 $mylist[1] two $mylist[2] three $mylist[3] 1 $mylist[0] two $mylist[1] three $mylist[2]

La sintassi di PERL Gli operatori di stacking: push, pop, shift and unshift $out = shift( @mylist) ; print( “Taken out = $out\n” ) ; Taken out = zero shift rimuove il primo elemento dello stack: di nuovo, viene rinumerato tutto il vettore. zero $mylist[0] 1 $mylist[1] two $mylist[2] three $mylist[3] 1 $mylist[0] two $mylist[1] three $mylist[2]

La sintassi di PERL Gli operatori di ordinamento e sorting: @dritto = (1, 2, 3, 4) ; @rovescio = reverse( @dritto ) ; print(“@rovescio\n”) ; 4 3 2 1 @sparso = (“gamma”, “beta”, “alfa” ) ; @ordinato = sort (@sparso) ; print(“@ordinato\n”) ; alfa beta gamma Come faccio a riempire un vettore digitando gli elementi dalla tastiera del terminale? @list = <STDIN> ; Un programma fatto da questa sola istruzione riempie ogni elemento del vettore list con una riga digitata in input. Il procedimento termina quando viene digitato un EOF (^D)

La sintassi di PERL I tipi di variabili Le hash tables Una hash table e’ una collezione di scalari raggruppata sotto un unico nome, la cui posizione e’ identificata, invece che da un numero intero positivo, come accade nel caso dei vettori, da una arbitraria stringa di caratteri. I tipi di variabili Le hash tables $sede{“Dario Menasce”} = “Milano” ; $sede{“$utente”} = “Torino” ; Questa sintassi e’ equivalente a: Chiave Valore %sede{ “Dario Menasce” => “Milano” , “$utente” => “Torino” } ; Ed e’ anche equivalente a: Chiave Valore %sede = (“Dario Menasce”, “Milano”, $utente, “Torino” } ; Chiave Valore Chiave Valore @lista = %sede ; Una hash puo’ essere trasformata in una lista... %nuovasede = @lista ; … e viceversa

La sintassi di PERL . I tipi di variabili Le hash tables Le hash sono le strutture dati native di PERL dotate della maggior versatilita’ per la costruzione di strutture piu’ complesse, come hash di hash ecc… $FirstName = “Dario” ; $LastName = “Menasce” ; $City = “Milano” ; $Employee = “$FirstName $LastName” ; $Street{“Dario Menasce” = “Via Celoria 16” ; $Street{“Daniele Pedrini” = “Piazza Duomo 2” ; $Address{ } = “$FirstName-$LastName” “$Street{$Employee}” . “$City ” ; print(“Address of $FirstName-$LastName: $Address{$FirstName-$LastName} \n” ) ; Address of Dario Menasce: via Celoria 16 Milano

La sintassi di PERL I tipi di variabili Gli operatori sulle hash tables L’operatore each $Hash{“alpha”} = “a” ; $Hash{“beta”} = “b” ; $Hash{“rho”} = “r” ; $Hash{“pi”} = “p” ; L’operatore each restituisce, in un contesto vettoriale, tutte le coppie chiave/valore definite per la hash in questione while ( ) { print (“ \n”) ; } ($greek,$latin) = each(%Hash) La lettera greca $greek corrisponde alla latina $latin La lettera greca pi corrisponde alla latina p La lettera greca rho corrisponde alla latina r La lettera greca beta corrisponde alla latina b La lettera greca alpha corrisponde alla latina a

La sintassi di PERL I tipi di variabili Gli operatori sulle hash tables L’operatore keys $Hash{“alpha”} = “a” ; $Hash{“beta”} = “b” ; $Hash{“rho”} = “r” ; $Hash{“pi”} = “p” ; @List = keys ( %Hash ) ; print (“@List\n”) ; pi rho beta alpha L’ordine non e’ quello di inserimento, bensi’ quello determinato dall’algoritmo di hashing. Se vogliamo una lista ordinata alfabeticamente useremo l’operatore sort @List = sort keys ( %Hash ) ; print (“@List\n”) ; alpha beta pi rho L’operatore values agisce sui valori della hash in modo analogo: @List = sort values ( %Hash ) ; print (“@List\n”) ; a b p r

La sintassi di PERL I tipi di variabili Gli operatori sulle hash tables Esistono innumerevoli modi per assegnare elementi ad una hash $record{“Fred”} = 205 ; $record{“Barney”} = 195 ; $record{“Wilma”} = 30 ; Ad ogni personaggio associamo il suo record personale a bowling... Queste due forme di assegnazione sono completamente equivalenti @record{“Fred”, “Barney”, “Wilma”} = (205, 195, 30) ; Un altro modo ancora... @Vincitori = {“Fred”, “Barney”, “Dino”} ; @Valori = (205, 195, 30) ; @record( ) = ; @Vincitori @Valori Indipendentemente da come @record viene assegnato... while (($persona, $valore) = each %record) { print(“Il record di $persona e’ $valore\n” ) ; } Il record di Barney e’ 195 Il record di Fred e’ 205 Il record di Wilma e’ 30

La sintassi di PERL Le strutture di controllo Analoghe a quelle di molti linguaggi (tipo C) Qualsiasi espressione che, una volta valutata, dia un valore diverso da zero if (condition1) { block1 ; } elsif (condition2) { block2 ; } else { block3 ; } while (condition) { block ; } until (condition) { block ; } do { block ; } while (condition); do { block ; } until (condition); In questo caso, prima viene eseguito il blocco di istruzioni block, poi viene valutata la condizione condition per eventualmente reiterare il blocco unless (condition) { block ; } for(init;test;incr){ block ; } foreach $i (@list) { block ; }

La sintassi di PERL Operazioni di I/O Il concetto di file-handle open (IN, “myfile.dat”) ; while ( <IN>) { print ; } close(IN) ; Un filehandle e’ il nome dato ad una connessione fra il corrente processo di PERL ed il mondo esterno: e’ quindi un canale di I/O con il soggiacente sistema operativo, analogo alla UNIT del FORTRAN $_= (“$_\n”) La sintassi estremamente concisa di PERL permette di omettere in molti casi il nome di una variabile specifica: il $_ e’ una variabile implicita di PERL Questo script si comporta in modo identico al comando UNIX cat myfile.dat

La sintassi di PERL > Operazioni di I/O Il concetto di file-handle (cont..) open ( LOG, “ myfile.dat” ) ; print LOG (“Process $proc has completed \n” ); close( LOG ) ; > || die “Cannot open file myfile.dat” Se la condizione alla destra del simbolo di or, ||, e’ falsa, ossia se il file non puo’ essere aperto, il programma muore producendo la frase indicata a destra Ridirige ogni output a LOG verso il file myfile.dat, analogamente a quanto avviene in UNIX con > o >> Esiste una ricca serie di qualificatori capaci di restituire informazioni circa un file; il loro uso e’ molto semplice: $file = “myfile.dat” ; if (-e “$file”) { print(“File $file alredy exists!\n”) ; }

La sintassi di PERL Operazioni di I/O Il concetto di file-globbing Come faccio a mettere in un vettore la lista dei files di una directory che iniziano con la stringa host seguito da qualsiasi carattere? @list = < > ; /etc/host* foreach $file (@list) { print (“$file”) ; } In modo ancora piu’ conciso: Con una sola istruzione otteniamo i seguenti risultati: con gli operatori < e > abbiamo aperto un canale di I/O con la wild-card * specifichiamo un intero range di nomi l’output dell’operatore < > consiste in una lista di oggetti e viene quindi valutato in un contesto vettoriale: di conseguenza ogni oggetto viene inserito in un elemento del vettore list foreach (</etc/host*>) { print ; }

La sintassi di PERL Operatori di interazione col filesystem locale Un altro punto di forza di PERL e’ la sua portabilita’ : questa e’ realizzata creando un’abstraction layer tra la funzionalita’ e l’ implementazione di un comando diretto al sistema operativo. Vediamo alcuni esempi utili: Equivale a... unlink (“myfile.dat”) ; rm myfile.dat rename (“myfile.dat myfile.old”) ; mv myfile.dat myfile.old link (“fred barney”) ; ln fred barney symlink (“fred barney”) ; ln -s fred barney mkdir (“newdir”, 0755) ; mkdir newdir; chmod 755 newdir Ecc… ecc...

Controllo di processi E’ frequente la necessita’ di interagire con il sistema operativo dall’interno di un processo, sia per ricevere informazioni che per far partire e gestire processi esterni. Vediamo quali strumenti offre PERL per risolvere questo problema assieme a qualche utile esempio. In quasi tutti i linguaggi di programmazione e’ possibile fornire dei comandi al soggiacente sistema operativo: cio’ e’ utile per diversi motivi: Quando occorre eseguire un’operazione per la quale esiste un opportuno comando di sistema che non si vuole reinventare, come ad esempio il comando di stampa di un file, lpr, o il comando di cancellazione file

Controllo di processi Il metodo piu’ semplice e’ l’uso della funzione system: system(“ “) ; ls -la *.txt comando In seguito all chiamata a system, PERL procede alla creazione (forking) di un sottoprocesso, detto processo figlio (child process), nell’ambito del quale viene eseguito il comando specificato (il comando viene passato alla shell sh). comando al sistema operativo In questo caso viene fatto partire il processo montecarlo.exe ma non si aspetta che esso abbia termine per far tornare il controllo al processo padre. L’uso e’ problematico nel caso il figlio generi dell’output , poiche’ questo verra’ mescolato in modo asincrono con quello del padre. L’eventuale output prodotto dal comando viene passato allo STANDARD OUTPUTdel processo padre (PERL), assieme allo STANDARD ERROR (si dice che il figlio eredita STDIN, STDOUT e STDERR dal processo padre) system(“montecarlo.exe &”) ; PERL mi fornisce anche lo strumento per avere accesso alle variabili ambientali del sistema operativo: foreach $key ( ) { print(“$key=$ENV{$key}\n”) ; } sort keys %ENV Queste istruzioni sono assolutamente equivalenti al comando printenv System e’ utile, ma l’output generato dal comando eseguito dal sistema operativo, una volta mandato allo STDOUT, e’ perso, non possiamo usarlo all’interno dello script PERL che lo ha lanciato!!!.

Controllo di processi L’operatore backticks (`): un primo modo per catturare l’output di un processo di sistema $now = “Current date is “ ; . ` ` date Backticks... Dalla shell, il comando date produce il seguente output: Fri Nov 6 15:00:12 MET 1998 print(“$now\n”) ; Current date is Fri Nov 6 15:00:12 MET 1998 In questo caso, date produce una sola linea di output, e quindi i backticks vengono valutati in un contesto scalare ed il risultato posto in una variabile scalare. @ListOfConnectedPeople = `who` ; Il comando who genera un output con diverse linee, una per ogni utente: l’output viene quindi valutato in un contesto vettoriale, ed ogni linea verra’ memorizzata in un elemento del vettore @ListOfConnectedPeople

Controllo di processi Un modo ancora piu’ flessibile e’ dato dall’operatore open associato ad una pipe open( , “who “) ; CHI | Apriamo un altro canale di I/O sul quale manderemo il comando di stampa... open( OUT, “ lpr -Pps_hplit3” ) ; Il nome di un file-handle: esso conterra’ il canale di I/O associato all’output prodotto dal comando who. Occorre specificare che who deve ridirigere l’output ad una pipe, ossia allo script corrente, ossia... | Occorre terminare il comando con il simbolo di pipe !!! while (<CHI>) { print ; } Per mandare degli argomenti ad una pipe, occorre far precedere il comando per il sistema operativo dal simbolo di pipe!!! OUT Il comando di print OUT spedisce cio’ che who ha prodotto alla pipe OUT, ossia al comando lpr e quindi alla stampante!! Qui’ c’e’ un semplice print: in realta’ possiamo manipolare ogni riga di output di who agendo sulla variabile $_ . close(CHI) ; E se volessimo mandare l’output, eventualmente modificato, direttamente ad una stampante laser? Facile...

La capacita’ di PERL di interagire con il sistema operativo, nel modo visto dagli esempi precedenti e’ uno dei motivi che hanno reso PERL cosi’ popolare Consideriamo il seguente esempio: vogliamo scrivere un programma che accetti in input un’arbitraria serie di istruzioni e le esegua. Una caratteristica interessante di PERL, e’ la capacita’ di eseguire una stringa di caratteri, interpretandola come un blocco di istruzioni. La stringa puo’ essere composta leggendo dati dall’esterno del programma: diviene allora possibile scrivere oggetti di estrema generalita’ come pocket-calculators e simili. Cio’ e’ possibile grazie al fatto che il linguaggio PERL ha accesso al proprio interpreter, al quale puo’ fornire ulteriori parti di programma composte a run-time, dopo che una prima parte del programma e’ gia’ stata compilata ed eseguita...

Consideriamo il seguente esempio: vogliamo scrivere un programma che accetti in input un’arbitraria serie di istruzioni e le esegua. Poiche’ 1 e’ costante, questo loop e’ infinito: lo interrompero’ con ^C Cio’ che viene dato in input dal terminale viene valutato interpretandolo come espressione in PERL ed il risultato della medesima viene posto nella variabile $result che puo’ essere stampata while(1) { print(“> “) ; $result = eval <STDIN> ; print(“$result\n”) ; } Stampa il prompt > sul terminale La variabile $result viene infine stampata sullo STDOUT Eseguiamo ora il programma dando il seguente input: > $px=12.34; $py=11.34;$pz=123.12; $M=1.869; $p=sqrt($px**2+$py**2+$pz**2); $E=sqrt($M**2+$p**2); 124.269460290934 RETURN Torna il prompt: qualunque altro tipo di calcolo diamo in pasto al programma esso sara’ in grado di eseguirlo e darci il risultato!!!! > $a=3; $ b=4; $c = sqrt($a**2 + $b**2 ) ; 5 > $a=3; $ b=4; $c = sqrt($a**2 + $b**2 ) ; print(“ \n” ) ; sqrt($a**2 + $b**2 ) = $c sqrt(3**2 + 4**2) = 5 1 La funzione print di PERL restituisce 1, valoreche viene mandato allo STDOUT subito dopo la stringa che print doveva stampare... Questo semplicissimo programma non solo funge da pocket-calculator, ma e’ in grado di eseguire qualsiasi parte di un un programma in PERL che gli venga fornito in input!!!!

Un altro importante utilizzo di eval riguarda il cosiddetto error-trapping (detto anche exception- handling) $a = 14 ; print(“Enter denominator: “ ) ; $b = <STDIN> ; $r = eval { } ; Blocco di istruzioni potenzialmente capaci di generare un errore $c = $a / $b In caso di divisione per zero viene generato un errore: in quel caso PERL riempie la variabile implicita $@ con la stringa di caratteri che descrive il tipo di errore generato, in questo caso Illegal division by zero if ($@ =~ /Illegal/) { print(“Fatal!… $@”) ; } else { print(“Result: $r\n”) ; } Enter denominator: 7 Result: 2 Enter denominator: Fatal!… Illegal division by zero at esempio_0_1.pl line 4.

Le regular expressions in PERL Uno dei problemi piu’ difficili e comuni da risolvere nella automazione di procedure complesse e’ quella del riconoscimento di pattern di caratteri: lo strumento principe per risolvere questa categoria di problemi e’ l’uso delle regular expression, strumento disponibile in diverse famiglie di linguaggi Una regular expression non e’ altro che un modo sintetico per descrivere un particolare pattern di caratteri, spesso mediante l’uso di meta-characters: nel caso di PERL e’ quasi un meta-linguaggio, dotato di proprieta’ complesse. L’esempio piu’ semplice di regular expression e’ la wild-card (il simbolo *), spesso usato in congiunzione al comando ls di UNIX: essa rappresenta in modo astratto il concetto “qualunque insieme di caratteri” Vediamo un esmpio articolato, per risolvere il quale l’uso di una regular expression si dimostri particolarmente efficace

Pero’ non vogliamo questo file... Troppi: vogliamo selezionare solo alcuni di questi file, usando un criterio di selezione basato sulla presenza nel nome di un certo pattern di caratteri: > ls -la *three* -rw-r--r-- 1 menasce e831 202 Nov 25 1997 drve831_threepi.runsts -rwxr-xr-x 1 menasce e831 524 Nov 21 1997 mcfocus_threepi.csh -rw-r----- 1 menasce e831 64010 Nov 9 1997 mcfocus_threepi.log -rw-r--r-- 1 menasce e831 2485 Nov 14 1997 mcfocus_threepi.make -rw-r--r-- 1 menasce e831 222 Nov 9 1997 mcfocus_threepi.mcf -rw-r--r-- 1 menasce e831 2193 Nov 19 1997 mcfocus_threepi.nam -rw-r----- 1 menasce e831 2864 Nov 9 1997 mcfocus_threepi.out_dat -rw-r--r-- 1 menasce e831 70 Nov 21 1997 mcfocus_threepi.paw -rwxr-x--x 1 menasce e831 2002 Sep 15 1997 mcfocus_threepi.run -rw-r--r-- 1 menasce e831 742 Apr 14 1998 mcfocus_threepi.sf -rw-r--r-- 1 menasce e831 460 Nov 20 1997 new_threepi_mc.txt -rw-r--r-- 1 menasce e831 15793 Nov 21 1997 new_threepi_PAW_mc.txt -rw-r--r-- 1 menasce e831 2360 Jul 16 1997 threepi.kumac -rw-r--r-- 1 menasce e831 753 Jul 16 1997 threepi_match.kumac -rw-r--r-- 1 menasce e831 3710 Jul 16 1997 threepi_res.ftn -rw-r--r-- 1 menasce e831 257 Jul 16 1997 threepi_res.kumac -rw-r--r-- 1 menasce e831 47331 Nov 25 1997 ugly_threepi.sf -rw-r--r-- 1 menasce e831 384 Jul 10 1997 under_threepi.sf -rw-r--r-- 1 menasce e831 5051 Nov 9 1997 usrinit_threepi.sf -rw-r--r-- 1 menasce e831 268 Jul 10 1997 usrmisc_threepi.sf -rw-r--r-- 1 menasce e831 268 Jul 10 1997 usrpack_threepi.sf -rw-r--r-- 1 menasce e831 484 Nov 9 1997 usrstop_threepi.sf -rw-r--r-- 1 menasce e831 268 Jul 10 1997 usrunpk_threepi.sf -rw-r--r-- 1 menasce e831 202 Nov 25 1997 drve831_threepi.runsts -rwxr-xr-x 1 menasce e831 524 Nov 21 1997 mcfocus_threepi.csh -rw-r----- 1 menasce e831 64010 Nov 9 1997 mcfocus_threepi.log -rw-r--r-- 1 menasce e831 2485 Nov 14 1997 mcfocus_threepi.make -rw-r--r-- 1 menasce e831 222 Nov 9 1997 mcfocus_threepi.mcf -rw-r--r-- 1 menasce e831 2193 Nov 19 1997 mcfocus_threepi.nam -rw-r----- 1 menasce e831 2864 Nov 9 1997 mcfocus_threepi.out_dat -rw-r--r-- 1 menasce e831 70 Nov 21 1997 mcfocus_threepi.paw -rwxr-x--x 1 menasce e831 2002 Sep 15 1997 mcfocus_threepi.run -rw-r--r-- 1 menasce e831 742 Apr 14 1998 mcfocus_threepi.sf -rw-r--r-- 1 menasce e831 460 Nov 20 1997 new_threepi_mc.txt -rw-r--r-- 1 menasce e831 15793 Nov 21 1997 new_threepi_PAW_mc.txt -rw-r--r-- 1 menasce e831 2360 Jul 16 1997 threepi.kumac -rw-r--r-- 1 menasce e831 753 Jul 16 1997 threepi_match.kumac -rw-r--r-- 1 menasce e831 3710 Jul 16 1997 threepi_res.ftn -rw-r--r-- 1 menasce e831 257 Jul 16 1997 threepi_res.kumac -rw-r--r-- 1 menasce e831 47331 Nov 25 1997 ugly_threepi.sf -rw-r--r-- 1 menasce e831 384 Jul 10 1997 under_threepi.sf -rw-r--r-- 1 menasce e831 5051 Nov 9 1997 usrinit_threepi.sf -rw-r--r-- 1 menasce e831 268 Jul 10 1997 usrmisc_threepi.sf -rw-r--r-- 1 menasce e831 268 Jul 10 1997 usrpack_threepi.sf -rw-r--r-- 1 menasce e831 484 Nov 9 1997 usrstop_threepi.sf -rw-r--r-- 1 menasce e831 268 Jul 10 1997 usrunpk_threepi.sf -rw-r--r-- 1 menasce e831 202 Nov 25 1997 drve831_threepi.runsts -rwxr-xr-x 1 menasce e831 524 Nov 21 1997 mcfocus_threepi.csh -rw-r----- 1 menasce e831 64010 Nov 9 1997 mcfocus_threepi.log -rw-r--r-- 1 menasce e831 2485 Nov 14 1997 mcfocus_threepi.make -rw-r--r-- 1 menasce e831 222 Nov 9 1997 mcfocus_threepi.mcf -rw-r--r-- 1 menasce e831 2193 Nov 19 1997 mcfocus_threepi.nam -rw-r----- 1 menasce e831 2864 Nov 9 1997 mcfocus_threepi.out_dat -rw-r--r-- 1 menasce e831 70 Nov 21 1997 mcfocus_threepi.paw -rwxr-x--x 1 menasce e831 2002 Sep 15 1997 mcfocus_threepi.run -rw-r--r-- 1 menasce e831 742 Apr 14 1998 mcfocus_threepi.sf -rw-r--r-- 1 menasce e831 460 Nov 20 1997 new_threepi_mc.txt -rw-r--r-- 1 menasce e831 15793 Nov 21 1997 new_threepi_PAW_mc.txt -rw-r--r-- 1 menasce e831 2360 Jul 16 1997 threepi.kumac -rw-r--r-- 1 menasce e831 753 Jul 16 1997 threepi_match.kumac -rw-r--r-- 1 menasce e831 3710 Jul 16 1997 threepi_res.ftn -rw-r--r-- 1 menasce e831 257 Jul 16 1997 threepi_res.kumac -rw-r--r-- 1 menasce e831 47331 Nov 25 1997 ugly_threepi.sf -rw-r--r-- 1 menasce e831 384 Jul 10 1997 under_threepi.sf -rw-r--r-- 1 menasce e831 5051 Nov 9 1997 usrinit_threepi.sf -rw-r--r-- 1 menasce e831 268 Jul 10 1997 usrmisc_threepi.sf -rw-r--r-- 1 menasce e831 268 Jul 10 1997 usrpack_threepi.sf -rw-r--r-- 1 menasce e831 484 Nov 9 1997 usrstop_threepi.sf -rw-r--r-- 1 menasce e831 268 Jul 10 1997 usrunpk_threepi.sf Iniziamo con l’eliminare dalla lista quelli che contengono i caratteri mc Pero’ non vogliamo questo file... Vogliamo la lista di questi soli files (terminano tutti per sf) Risultato raggiunto, ma in un modo poco flessibile: vediamo come si puo’ ottenere lo stesso risultato utilizzando le regular expressions in uno script PERL > ls -la *three* | grep -v mc | grep sf > ls -la *three* | grep -v mc -rw-r--r-- 1 menasce e831 202 Nov 25 1997 drve831_threepi.runsts -rw-r--r-- 1 menasce e831 2360 Jul 16 1997 threepi.kumac -rw-r--r-- 1 menasce e831 753 Jul 16 1997 threepi_match.kumac -rw-r--r-- 1 menasce e831 3710 Jul 16 1997 threepi_res.ftn -rw-r--r-- 1 menasce e831 257 Jul 16 1997 threepi_res.kumac -rw-r--r-- 1 menasce e831 47331 Nov 25 1997 ugly_threepi.sf -rw-r--r-- 1 menasce e831 384 Jul 10 1997 under_threepi.sf -rw-r--r-- 1 menasce e831 5051 Nov 9 1997 usrinit_threepi.sf -rw-r--r-- 1 menasce e831 268 Jul 10 1997 usrmisc_threepi.sf -rw-r--r-- 1 menasce e831 268 Jul 10 1997 usrpack_threepi.sf -rw-r--r-- 1 menasce e831 484 Nov 9 1997 usrstop_threepi.sf -rw-r--r-- 1 menasce e831 268 Jul 10 1997 usrunpk_threepi.sf A questo punto basta chiedere che compaia la coppia di caratteri sf

Le regular expressions in PERL Vediamo come realizzare questa stessa cosa in PERL utilizzando il meccanismo delle regular expressions #!/usr/local/bin/perl open(PIPE, “ls -la”) ; while(PIPE) { } close(PIPE) ; print ; Fatto cosi’, il programma stampa la lista di TUTTI i files della directory corrente!!

Le regular expressions in PERL Vediamo come realizzare questa stessa cosa in PERL utilizzando il meccanismo delle regular expressions #!/usr/local/bin/perl open(PIPE, “ls -la”) ; while(PIPE) { } close(PIPE) ; if (m/sf/) {print} ; m sta per match sf e’ una regular expression che sta per: qualsiasi coppia contigua composta da e solo da s seguito da f minuscoli In realta’ a noi interessano solo i files che terminano con sf: Aggiungiamo alla regexp sf il metacharacter $ che indica in modo sintetico il concetto di “la regexp deve terminare con”

Le regular expressions in PERL Vediamo come realizzare questa stessa cosa in PERL utilizzando il meccanismo delle regular expressions #!/usr/local/bin/perl open(PIPE, “ls -la”) ; while(PIPE) { } close(PIPE) ; Se poi non desideriamo nella lista i file che iniziano con mc modifichiamo ulteriormente la regexp: if (m/sf$/ && !m/^mc/) {print} ; if (m/sf$/) {print} ; Simbolo di NOT Caret: significa “inizia per” Questo semplice esempio chiarisce molto bene il concetto di regular expression: si tratta di un modo simbolico di rappresentare un pattern di caratteri da utilizzare come filtro di selezione in una richiesta condizionale Una regular expression: puo’ essere qualcosa di estremamente complesso e criptico da interpretare, ma si tratta di uno strumento veramente molto potente. Supponiamo di voler cercare le parole duplicate in un testo:

Le regular expressions in PERL #!/usr/local/bin/perl while(<DATA>) { } { print ; } __END__ Questo testo contiene un certo certo numero di parole duplicate. Scopo dello script di cui sopra e’ trovarle e indicare in quale paragrafo paragrafo esse si trovano Eseguendo questo programma, il testo indicato verra’ semplicemente stampato sul terminale;

Le regular expressions in PERL #!/usr/local/bin/perl while(<DATA>) { } while ( m{ }xig ) Per ogni riga letta, itera sui seguenti elementi della riga: \b Considera tutti i word boundaries come punto di inizio dell’iterazione: \w\S+ Considera tutti caratteri che non siano SPACE come possibile parola... ( ) \s+ \1 Il tutto finche’ compare uno spazio seguito dagli stessi caratteri appena trovati…. Quando cio’ avviene, memorizza cio’ che sta fra le parentesi rosse in una variabile interna di PERL, $1, che conterra’ quindi cio’ che ha soddifatto il criterio di selezione + \b Il tutto ripetuto ad libitum fino al prossimo spazio bianco x: usa il set completo di metacharacter. i: la ricerca deve essere case-insensitive. g: la ricerca non deve arrestarsi al primo pattern trovato per ogni parola analizzata { print(“La parola $1 risulta duplicata nel paragrafo $.\n” ) ; } __END__ Questo testo contiene un certo certo numero di parole duplicate. Scopo dello script di cui sopra e’ trovarle e indicare in quale paragrafo paragrafo esse si trovano

Le regular expressions in PERL #!/usr/local/bin/perl while(<DATA>) { } while ( m{ }xig ) \b \w\S+ ( ) La variabile $1 corrisponde a cio’ che e’ stato catturato dalle parentesi tonde ossia ogni pattern che ripete se stesso dopo uno o piu’ spazi bianchi \s+ \1 + \b { print(“La parola $1 risulta duplicata nel paragrafo $.\n” ) ; } __END__ Questo testo contiene un certo certo numero di parole duplicate. Scopo dello script di cui sopra e’ trovarle e indicare in quale paragrafo paragrafo esse si trovano

Questo corso ha uno scopo troppo limitato per poter dare una scorsa approfondita alle regular expressions. Ci limiteremo quindi alle seguenti considerazioni: Le regular expressions costituiscono uno dei punti di forza di PERL (pur essendo utilizzate in molti linguaggi, come awk, sed, egrep, la loro implementazione in PERL e’ la piu’ sofisticata). L’apprendimento della sintassi delle regexp e’ piuttosto arduo. Cio’ nonostante, il loro uso permette la costruzione di programmi ed algoritmi estremamente efficienti e compatti: il beneficio che se ne trae vale sicuramente lo sforzo di imparare a conoscerle. Esiste un testo appositamente dedicato alle regexp, di cui daremo la citazione bibliografica al termine del corso Passiamo ora ad una serie di piccoli esempi pratici che mostrano come PERL possa essere utilizzato nell’attivita’ di un ricercatore impegnato in un’attivita’ di analisi dei dati. Prima, pero’, un commento:

PERL, come gia’ detto, e’ perfettamente adatto anche per rappresentare e risolvere problemi di matematica, anzi offre molte interessanti proprieta’: vediamo un esempio. $x = [ [ 3, 2, 3 ], [ 5, 9, 8 ] ] ; $y = [ [ 4, 7 ], [ 2, 3 ], [ 6, 1 ] $z = mmult( $x, $y ) ; PrintMatrix( $z ) ; Un classico problema di moltiplicazione di matrici: $x e $y sono in realta’ puntatori a delle strutture (che non sto a dettagliare) che contengono le matrici realizzate come vettori di vettori. [ 3, 2, 3 ], [ 5, 9, 8 ] [ 4, 7 ], [ 2, 3 ], [ 6, 1 ] Se eseguiamo questo programma otteniamo: $x * $y = [ [ 34 30 ] [ 86 70 ] ] L’implementazione del prodotto e’ codificata in questa funzione: contrariamente al FORTRAN, essa e’ in grado di determinare da se’ il rango delle matrici e dimensionare opportunamente la matrice risultato (in questo caso $z) La funzione PrintMatrix non fa altro che stampare il risultato $z in un formato opprotuno, analogo a quello con cui sono definiti $x e $y

Un modo ancora piu’ elegante e sintetico per fare questo tipo di calcolo, e’ quello di usare un modulo matematico, detto PDL, disponibile su WEB, che realizza il prodotto di matrici tramite la funzionalita’ di function-overloading (analoga quella del C++). use PDL ; $x = [ [ 3, 2, 3 ], [ 5, 9, 8 ] ] ; $y = [ [ 4, 7 ], [ 2, 3 ], [ 6, 1 ] $z = $x * $y ; PrintMatrix( $z ) ; [ 3, 2, 3 ], [ 5, 9, 8 ] [ 4, 7 ], [ 2, 3 ], [ 6, 1 ] L’inclusione del mudulo PDF, fa si’ che l’operatore * venga ridefinito in modo da agire sulle matrici x ed y, realizzando il prodotto righe per colonne.

da una procedura PERL e quale vantaggio ne otteniamo Torniamo ora all’esempio citato all’inizio dello script di PAW che somma istogrammi provenienti da diversi files, e vediamo come sia possibile far scrivere questo script da una procedura PERL e quale vantaggio ne otteniamo Vi rammento che il problema consiste nell’automatizzare la scrittura di questo pezzo del codice (in questo esempio) nel caso in cui la lista dei file con istogrammi da sommare sia ingente (dell’ordine di centinaia o migliaia di files). Macro somma MaxHistos = 4 Do I = 1, [MaxHistos] Case [I] in (1) File = ‘pixelreadout.his’ (2) File = ‘pixelnocharge.his’ (3) File = ‘newpixeldata.his’ (4) File = ‘pixelredesign.his’ EndCase If ([I] .Eq. 1) then His/fil 1 [File] Else His/copy 15 100 Endif His/oper/add 15 100 100 His/plo 100 EndDo

#!/usr/local/bin/perl SetFilterRegexp() ; sub SetFilterRegexp { $Filter = “pixel” ; } Definisco una variabile che conterra’ la regexp per selezionare i file voluti GetFilesList() ; sub GetFilesList { while( $File = <*.his> ) { if( $File =~ m/$Filter/i ) { push @FileList, $File ; } Ciclo su tutti i file della directory corrente e quelli che soddisfano il criterio di selezione espresso dalla regexp $Filter vengono aggiunti al vettore @FileList Apro in scrittura il file che conterra’ lo script $Script = “adder.kumac” ; open(OUT,”>$Script”) || die “Cannot open file $Script at $!” ; PrintHeader() ; sub PrintHeader { print OUT <<EOB Macro adder Close 0 H/Del 0 EOB sub SpecifyFiles { $i = 0; foreach $file (sort @FileList) { $i++ ; print OUT (“ H/Fil 1 $file\n” ) ; if( $i == 1 ) { print OUT (“ H/Copy 15 100\n” ) ; } else { print OUT (“ H/Oper/Add 15 100 100\n” ) ; } print OUT (“ Close 1\n\n” ) ; SpecifyFiles() ; Macro adder Close 0 H/Del 0 H/Fil 1 pixelreadout.his H/Copy 15 100 H/Oper/Add 15 100 100 Close 1 H/Fil 1 pixelnocharge.his ... Questo e’ il testo dello script sche abbiamo appena creato

Quali vantaggi abbiamo ottenuto nel far scrivere lo script kumac a PERL invece di crearlo noi a mano con l’editor? Lo script e’ del tutto generale: al cambiare dei files nella directory, lo script si autoconfigura opportunamente per tenere conto delle novita’ (file nuovi o file spariti) per selezionare files basati su un diverso aloritmo di selezione bastera’ cambiare il valore della variabile $Filter o implementare un algoritmo piu’ sofisticato per avere uno script sempre up-to-date Nel caso in cui i files siano diverse centinaia o migliaia risulta in pratica l’unico modo per creare lo script PERL e’ un linguaggio dotato di maggiore versatilita’ che non kumac, e cio’ e’ il motivo per cui risulta cosi’ efficace nell’agire come meta-linguaggio. Questa tecnica di generazione automatica di programmi in altri linguaggi e’ molto utile in numerosi altri casi (vedremo come cio’ e’ particolaremte vero nel caso di pagine HTML generate on demand in tempo reale.).

Vediamo ora come si puo’ usare PERL per scrivere un programma che possa essere attivato da un bottone situato in una pagina WEB. Due parole su come funziona il protocollo WWW

Questo e’ il server dove girera’ lo script in PERL che ci accingiamo a scrivere Comunicano tramite il protocollo TCP/IP (Internet) httpd (server daemon) Il server ha attivo un daemon che riceve richieste dal client (il browser) e risponde fornendo i documenti richiesti. Il server agisce tramite una serie di files di configurazione che descrivono come deve rispondere a richieste dal mondo esterno Le richieste possono essere di due tipi: fornire un documento (testo,immagine,audio,video…) eseguire un programma e spedire l’output di questo indietro al browser (tramite protocollo CGI) Questo e’ il vostro browser

Vediamo ora come realizzare un pagina WEB che contenga un bottone, premendo il quale ci venga restituita una lista di files di istogrammi (realizzati con HBOOK). I files saranno locati sulla macchina remota alla quale avremo sottomesso la richiesta.

esempio_2_0.html esempio_2_0.html <HTML> <TITLE> </TITLE> Com’e’ fatta una pagina WEB? Molto schematicamente... esempio_2_0.html Un tag HTML e’ una direttiva al browser per comunicargli come interpretare il testo racchiuso fra direttive. Convenzionalmente indichero’ le direttive in color magenta <BODY BGCOLOR=“OldLace”> <CENTER> </CENTER> <FORM ACTION= METHOD= > </FORM> FORM specifica l’indirizzo del programma da eseguire sulla macchina remota e la lista degli strumenti di controllo per fornirgli un input (bottoni, campi di input ecc…) “http://sgimida.mi.infn.it /cgi-bin/scripts /histo_server.pl” “Get” Nome del nodo remoto Si tratta di un programma da eseguire, un CGI ! Nome del programma <INPUT > INPUT specifica il tipo di strumento di controllo da associare al programma da eseguire. In questo caso ci sara’ un bottone di attivazione. Type=“Submit” Name=“SubmitButton” Value=“Show list of available histograms”

http://sgimida.mi.infn.it/~cntc/esempio_2_0.html Da un qualsiasi browser selezioniamo ora l’indirizzo del file HTML appena creato:

Questo e’ il bottone associato all’attivazione del programma Prima di procedere a premere questo tasto, diamo un’occhiata al codice PERL dello script associato a questo bottone dalla direttiva ACTION

Con un normale editor, creiamo il file histo_server.pl Questa direttiva informa il browser che cio’ che gli verra’ trasmesso dal corrente processo sara’ da interpretare come un testo di tipo HTML histo_server.pl #!/usr/local/bin/perl print(“Content type: text/html\n\n” ) ; $HisDir = “/vtx/boss/mcarlo/histos” ; Importante!!!! Lo STANDARD OUTPUT del corrente processo viene ritrasmesso al browser che ne ha richiesto l’esecuzione print <<EOB ; EOB <HTML> <TITLE> List of files in $HisDir </TITLE> <Center> List of available histogram files on sgimida.mi.infn.it in $HisDir </Center> <OL> Cio’ che viene posto tra i simboli EOB verra’ passato verbatim allo STANDARD OUTPUT Inizio di una ORDERED LIST <OL> Testo . . . . @ListOfFiles = <$HisDir/*.his> ; Esempio di FILE GLOBBING: l’operatore < > restituisce la lista dei files con suffisso his nella directory $HisDir (agisce in un contesto vettoriale) foreach $File (@ListOfFiles) { print(“<LI> $File \n” ) ; } print(“</OL>\n” ) ;

E’ giunto il momento di premere questo tasto:

Difficile? L’appetito vien mangiando: a questo punto vorremmo tanto che ogni elemento di questa lista fosse un link al contenuto del file, in modo che selezionando un file ci venisse mostrata la directory degli istogrammi ivi contenuti…. Difficile?

No, basta una piccola modifica allo script di prima, in aggiunta ad un nuovo script che faccia girare PAW per fornire ls lista richiesta. Vediamo come:

Stesso script di prima... #!/usr/local/bin/perl print(“Content type: text/html\n\n” ) ; $HisDir = “/vtx/boss/mcarlo/histos” ; print <<EOB ; EOB <HTML> <TITLE> List of files in $HisDir </TITLE> <Center> List of available histogram files on sgimida.mi.infn.it in $HisDir </Center> <OL> @ListOfFiles = <$HisDir/*.his> ; foreach $File (@ListOfFiles) { print(“<LI> $ \n” ) ; } print(“</OL>\n” ) ; histo_server.pl Stesso script di prima... $Server = “http://sgimida.mi.infn.it/cgi-bin/scripts” ; Coppia chiave/valore separati dal segno = $Ref = “<A HREF= > </A>” ; $Server /show_histos.pl ? File=$File $File Marker di inizio dei parametri da passare allo script come input Definizione di hyperlink Stringa di caratteri che su browser apparira’ in blu e sottolineata a rappresentare il link richiesto (in questo caso l’esecuzione dello script) Indirizzo del nodo su cui sta lo script da eseguire Indirizzo dello script da eseguire $Ref Infine stampiamo il valore del link cosi’ formato sullo STANDARD OUTPUT del processo corrente (che ovviamente corriponde alla pagina del browser)

Voila’, ogni file e’ in realta’ un link ad uno script che, facendo girare PAW, produrra’ la lista degli istogrammi contenuti nel file medesimo! Prima pero’ vediamo come e’ fatta questa pagina HTML, output prodotto dallo script appena descritto...

View Show  Increase font Ctrl+] Decrease font Ctrl+[ Reload Ctrl R Show Images Refresh Stop page loading <ESC> Stop animations Page source Ctrl U Page info Ctrl I Character set 

1. /vtx/boss/mcarlo/histos/carrara_3pi.his <HTML> <TITLE>List of available histogram files</TITLE> <Body Bgcolor="OldLace"> <Center> List of available histogram files on sgimida.mi.infn.it in /vtx/boss/mcarlo/histos </Center> <OL> <LI> <A HREF=..../show_histos.pl?File=/vtx/boss/mcarlo/histos/carrara_3pi.his>/vtx/boss/mcarlo/histos/carrara_3pi.his</A> <LI> <A HREF=..../show_histos.pl?File=/vtx/boss/mcarlo/histos/carrara_kkp.his>/vtx/boss/mcarlo/histos/carrara_kkp.his</A> <LI> <A HREF=..../show_histos.pl?File=/vtx/boss/mcarlo/histos/carrara_kpp.his>/vtx/boss/mcarlo/histos/carrara_kpp.his</A> <LI> <A HREF=..../show_histos.pl?File=/vtx/boss/mcarlo/histos/ccbar_3pi.his>/vtx/boss/mcarlo/histos/ccbar_3pi.his</A> <LI> <A HREF=..../show_histos.pl?File=/vtx/boss/mcarlo/histos/clseccut_dt.his>/vtx/boss/mcarlo/histos/clseccut_dt.his</A> <LI> <A HREF=..../show_histos.pl?File=/vtx/boss/mcarlo/histos/clseccut_mc.his>/vtx/boss/mcarlo/histos/clseccut_mc.his</A> <LI> <A HREF=..../show_histos.pl?File=/vtx/boss/mcarlo/histos/data_3pi.his>/vtx/boss/mcarlo/histos/data_3pi.his</A> <LI> <A HREF=..../show_histos.pl?File=/vtx/boss/mcarlo/histos/data_3pi_1.his>/vtx/boss/mcarlo/histos/data_3pi_1.his</A> <LI> <A HREF=..../show_histos.pl?File=/vtx/boss/mcarlo/histos/data_kkp.his>/vtx/boss/mcarlo/histos/data_kkp.his</A> <LI> <A HREF=..../show_histos.pl?File=/vtx/boss/mcarlo/histos/data_kpp.his>/vtx/boss/mcarlo/histos/data_kpp.his</A> <LI> <A HREF=..../show_histos.pl?File=/vtx/boss/mcarlo/histos/dt_2k2pi.his>/vtx/boss/mcarlo/histos/dt_2k2pi.his</A> <LI> <A HREF=..../show_histos.pl?File=/vtx/boss/mcarlo/histos/dt_2k2piws.his>/vtx/boss/mcarlo/histos/dt_2k2piws.his</A> .................................................... 1. /vtx/boss/mcarlo/histos/carrara_3pi.his

Ovviamente ora viene la parte un po’ piu’ complessa: dobbiamo infatti scrivere il programma che fa partire PAW sul file selezionato...

Abbiamo visto che la definizione di un hyperlink e’ fatta nel modo seguente: $Ref = “<A HREF= > </A>” ; $Server /show_histos.pl ? File=$File $File La coppia chiave/valore che segue il ? viene spedita al server, il quale la passa allo script show_histos.pl tramite una environmental variable, chiamata QUERY_STRING Si possono passare piu’ coppie, separandole con & QUERY_STRING File=$File & Parameter=$value & ... Possiamo a questo punto scrive il programma che, facendo girare PAW sul file selezionato con un click sullo hyperlink, ci fornisca l’elenco degli istogrammi. Lo script non dovra’ far altro che leggere la QUERY_STRING (PERL offre delle funzioni adatte allo scopo) e separare le coppie chiave/valore. Chiave diverra’ il nome di una variabile il cui contenuto sara’ valore.

DecodeQueryString() ; Sub PrintHeader { print <<EOB; Content-type: text/html <HTML> <TITLE> Output di PAW </TITLE> <PRE> EOB } #!/usr/local/bin/perl PrintHeader() ; DecodeQueryString() ; Sub DecodeQueryString { $qs = $ENV{‘QUERY_STRING’} ; @pairs = split( /&/, $qs ) ; foreach $key_val (@pairs) { ($key, $value) = split(/=/, $key_val); . . . . $$key = $value ; } open (OUT, “>lista2.kumac”) || die “Cannot open kumac file” ; print OUT<<EOB ; EOB Macro lista H/Del 0 Message Working on file $File H/Fil 1 $File H/Lis Close 1 Ecco lo script KUMAC che verra’ eseguito da PAW!! Fornisce la variabile $File con il nome selezionato dall’ utente con lo hyperlink close(OUT) ; open (OUT, “>paw2.sh”); print OUT<<EOB ; EOB La KUMAC e’ pronta: ora bisogna creare uno shell script che faccia partire PAW dandogli in pasto la KUMAC da eseguire. #!/usr/bin/sh /disk3/products/pawx11 <<+++ exec lista2.kumac +++ A questo punto non resta che far eseguire questo script per avviare PAW. Ovviamente vanno prima sistemate le protezioni per poterlo far eseguire dal WEB server!!!!… system(“chmod +x paw2.sh” ) ; Lo script show_histos.pl e’ pronto per essere eseguito dal WEB server in seguito alla richiesta di un utente dal browser!!!

… continuazione open( PAW, “./paw2.sh |”) ; while( <PAW> ) { } Apriamo una PIPE per eseguire lo script che fa girare PAW show_histos.pl open( PAW, “./paw2.sh |”) ; while( <PAW> ) { } Mentre lo script paw2.sh viene eseguito, tutto cio’ che esso produce sul suo STDOUT viene catturato nella variabile $_ e stampato sullo STDOUT del corrente processo (il nostro browser). Ricordo che l’output di paw2.sh e’ cio’ che stampa la kumac che produce la lista degli istogrammi. print ; Stampiamo questo output sullo STDOUT, che, ricordo, e’ la pagina del browser... close (PAW) ; Chiudiamo la PIPE, e voila’, lo script e’ pronto a ricevere comandi dal browser e a fornire liste di istogrammi

Clicchiamo ora su uno dei files...

Sarebbe a questo punto certamente possibile rendere cliccabile ogni singolo istogramma di questa lista, in modo che venga eseguito un script che ci restituisca l’istogramma in questione in formato grafico (GIF) direttamente sul browser (e magari provvedesse un link aggiuntivo per la versione POSTSCRIPT ad alta risoluzione….

Lo script che possa fare cio’ non e’ molto piu’ complicato di quanto abbiamo visto finora, ma esula dallo scopo di questo corso. Cio’ che e’ importante e’ cogliere il fatto che e’ relativamente semplice creare una interfaccia WEB a normali programmi di analisi dati, col beneficio che tutti i membri di unavasta collaborazione internazionale hanno rapido accesso ai dati ed anche ai programmi tramite un’interfaccia standard quale un browser

L’estrema parsimonia sintattica di PERL puo’ essere utilizzata con grande vantaggio, purche’ cio’ sia fatto cum grano salis, in quanto il risultato puo’ essere qualcosa di estremamente incomprensibile e quindi di difficile manutenzione. Un paio di esempi tratti dallo Annual Obfuscated PERL Contest : Molto bello esteticamente, ma francamente non sono riuscito a capire cosa fa... Calcola e stampa i numeri primi… (sic)

Buon divertimento!

Operatori di file-test -r File is readable by effective uid. -w File is writable by effective uid. -x File is executable by effective uid. -o File is owned by effective uid. -R File is readable by real uid. -W File is writable by real uid. -X File is executable by real uid. -O File is owned by real uid. -e File exists -z File has zero size (it’s empty) -f File is a plain-file -d File is a directory -l File is a symbolic link -p File is a nmed pipe -s File is socket -b File is a block special file -c File is a character special file -t Filehandle is opened to a tty -T File is a text file -B File is a binary file -M Age of file (at startup) in days since modification -A Age of file (at startup) in days since last access -C Age of file (at startup) in days since inode change Back...

Back... test.pl #!/usr/local/bin/perl system(“ls -la *.txt“) ; > chmod +x test.pl > ./test.pl -rw------- 1 menasce e831 112 Sep 10 14:39 CP_violation.txt -rwx------ 1 menasce e831 1499 Nov 13 1996 banner.txt -rw------- 1 menasce e831 80 Sep 10 21:42 example.txt -rwx------ 1 menasce e831 1639 Nov 13 1996 plots.txt -rw------- 1 menasce e831 8927 Sep 11 13:41 plots_beauty.txt -rw------- 1 menasce e831 8685 Sep 10 20:27 plots_charm.txt -rw-r----- 1 menasce e831 11623 Sep 10 20:27 psi_cross_section.txt -rwx------ 1 menasce e831 1580 Nov 13 1996 ratio.txt drwxr-x--- 2 menasce e831 8192 Sep 10 18:44 rose_scheme.txt -rwx------ 1 menasce e831 1552 Nov 13 1996 transparencies_bristol.txt drwx------ 4 menasce e831 8192 Sep 11 13:41 usage.txt -rw-r----- 1 menasce e831 27248640 Sep 10 20:22 zero_level.txt Back...