Langage de Recherche d`Information

Transcription

Langage de Recherche d`Information
Langage de Recherche d’Information
Travaux Pratiques
Jérôme Farinas
[email protected]
Institut de Recherche en Informatique de Toulouse
Université Paul Sabatier
13 janvier 2009
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
1 / 29
Conseils généraux pour les TP
Chaque exercice idéalement doit être testé, compris et parfois
complété. Pour être sauvegardé comme fichier éventuellement modifié
puis exécuté, chaque source fourni devra être saisi dans un éditeur de
texte (nedit par exemple)
Il est conseillé de ranger les exercices dans des sous-répertoires
spécifiques au TP. Les noms des fichiers sont proposés avec l’extension
.perl (qui ne joue aucun role, juste un signe de reconnaissance...)
Sous Unix, les fichiers pour être exécutables doivent porter la
permission x. Si nécessaire donner cette permission en passant la
commande, comme : chmod a+x monfichier.perl
Chaque script doit indiquer le chemin vers Perl avec cette 1ère ligne :
#!/usr/bin/perl -w (vérifier le chemin sur la machine que vous
utilisez en tapant dans le shell : which perl)
Un dossier sera constitué à la fin des TPs : tous les exercices marqués
avec une étoile devront etre présents. La notation prend en compte le
fait que le programme marche, la présentation du programme
(commentaires et indentation) ainsi que les méthodes utilisées.
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
2 / 29
Plan
1
TP2 : listes, tableaux et structures de contrôle
Rappels listes et tableaux
Exercices TP2
Exercices du cours
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
3 / 29
Plan
1
TP2 : listes, tableaux et structures de contrôle
Rappels listes et tableaux
Exercices TP2
Exercices du cours
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
4 / 29
Listes et tableaux : rappels I
La liste est la principale structure de données en Perl. Il convient de
bien en connaitre les possibilités.
Une liste est un ensemble ordonné d’éléments scalaires, tandis qu’un
tableau est un ensemble indicé de scalaires. Il s’agit en fait d’une
même structure de données. La différence réside dans la vision qu’on
en a et le type de manipulations effectuées.
Les éléments d’une même liste peuvent être de types quelconques :
nombres, chaines, variable, liste...
Les identificateurs des listes sont précédés du symbole @, MAIS les
éléments d’une liste sont notés avec $, car ce sont des valeurs scalaires
Les listes sont dynamiquement allouées, donc de dimension variable.
Les parenthèses (...), contenant une énumération avec des virgules,
jouent le rôle de constructeur de listes.
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
5 / 29
Listes et tableaux : rappels II
Exemple
$ville = "Melun";
@mesamis=("jules","julie", "julot");
@liste= ("toto", 25 , $ville , @mesamis);
# pour afficher la suite des éléments séparés par un espace
print "@liste\n";
L’exemple précédent montre qu’il n’a pas de construction directe de liste
de listes en Perl.
print "$liste[3]\n" # affiche "jules"
Création d’une liste par affectation directe de valeurs énumérées, ou
indiquées par des intervalles avec l’opérateur .. (et non pas - )
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
6 / 29
Listes et tableaux : rappels III
#!/usr/bin/perl
@chiffre = (0..9);
@centaine =(@chiffre, 10..99);
# va afficher la liste : 0 1 ...99
print "@centaine\n";
@alphabet = (a..z, A..Z);
# extraction d’une sous-liste :
@dix_premieres_lettres = @alphabet[0..9];
# La fonction qw() permet de s’affranchir
# des virgules et des quotes ou guillemets :
@mots= ("moi","toi","lui","nous","tous");
@mots= qw(moi toi lui nous tous);
# Opérateurs de manipulations d’une liste @liste
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
7 / 29
Listes et tableaux : rappels IV
En particulier push et pop permettent de traiter la liste comme une
pile.
I
I
I
I
ajout du coté droit (push) : push(@montableau,$nouvellevaleur) ;
suppression du coté droit (pop) : $vieillevaleur = pop(@montableau) ;
ajout du coté gauche (unshift) : unshift(@tab,$a) ;
suppression du coté gauche (shift) : $x = shift(@tab) ;
Utilisation d’une liste
I
I
I
I
I
I
print ”@liste”; permet d’afficher l’ensemble des éléments
$liste[1] est le second élément
$#liste est le dernier indice de la liste
$liste[$#liste] est donc son dernier élément
$taille = @liste; pour connaitre le nombre d’éléments
$der= $liste[-1] ..etc .. énumère les éléments à partir de la fin de la liste
Parcourir une liste
I
La boucle foreach fait parcourir la variable $element dans la liste @liste,
dans l’ordre de ses éléments.
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
8 / 29
Listes et tableaux : rappels V
foreach $element (@liste) {
print "$element\n";
}
I
façon classique avec une boucle for
for ($i =0 ; $i < @liste ; $i++ ) {
print "élément $i = $liste[$i]\n";
}
Créations et manipulations de listes
I
affectation de listes
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
9 / 29
Listes et tableaux : rappels VI
#!/usr/bin/perl
@centaine =(1..99);
@elements_cinq_a_sept = @centaine[4,5,6];
@elements_dix_a_vingt = @centaine[9..19];
print "@elements_cinq_a_sept\n@elements_dix_a_vingt\n";
I
I
I
I
$liste[@liste]=$n; ajoute un élément en fin de liste (pourquoi ?)
push @liste,$n; on empile sur la liste un élément scalaire ou une liste
(on l’ajoute ”à droite”)
unshift @liste, $n; on ajoute en tête (ou à gauche) un scalaire ou une
liste
@liste = ($d,@liste,$f);, dans ce contexte, l’opérateur ”parenthèses” est
un constructeur de liste
Quelques façons d’accéder aux éléments
I
I
$el = $liste[3] pour obtenir le 4ème élément
$el = pop @liste dépile et donc modifie la liste (attention !)
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
10 / 29
Listes et tableaux : rappels VII
I
I
I
$el = shift @liste pour récupérer l’élément de tête, c’est-à-dire $liste[0],
dépile donc la liste
($el) = @liste construit une liste contenant l’élément de tête de @liste
($a, $b, $c, @reste) = @liste affecte les 3 premiers éléments de la liste,
puis la liste du reste.
Quelques listes gérées par le système
I
I
@ARGV contient la liste des arguments passé sur la ligne de commande
après l’appel du script. (Le 1er argument passé est donc $ARGV[0]), ne
pas confondre avec $0 qui est le nom du script)
La variable système @ contient la liste des paramètres passés à une
fonction
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
11 / 29
Opérateurs de tri
Attention
Le tri est effectué par sort, en ordre ASCII ascendant !
Testez le code suivant
#!/usr/bin/perl
print "TRIS\n";
@liste = (4, 11, 24, 2, 43, 21, 16, 6);
print "Liste initiale : \n@liste\n";
@tri_alpha = sort @liste;
print "Liste triée alphabétiquement : \n@tri_alpha\n";
@tri_num = sort { $a <=> $b} @liste;
print "Liste triée numériquement (sens croissant) :
\n@tri_num\n";
@tri_num = sort { $b <=> $a} @liste;
print "Liste triée numériquement (sens décroissant) :
\n@tri_num\n";
@envers = reverse @liste;
print "Liste inversée : \n@envers\n\n";
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
12 / 29
Transformations chaı̂ne/liste I
split
split permet de construire une liste dont les éléments proviennent du
découpage d’une chaine suivant les occurrences d’un caractère choisi.
join
join effectue exactement l’opération inverse, en ”recollant” les éléments
d’une liste à l’aide d’un caractère séparateur pour former une seule chaine.
Exemple 1
$phrase = "Bonjour à toutes et à tous";
@mots = split " ",$phrase;
print "@mots\n";
$phrase1 = join " ", @mots;
print "$phrase1\n";
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
13 / 29
Transformations chaı̂ne/liste II
Cas particulier important
Si on utilise ”” (caractère vide) comme séparateur, on agit (en séparant
avec split ou en concaténant avec join) au niveau des caractères de la
chaine.
Exemple 2
$phrase = "Bonjour à toutes et à tous";
@caracteres = split "",$phrase;
print "@caracteres\n";
$phrase1 = join "", @caracteres;
print "$phrase1\n";
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
14 / 29
Plan
1
TP2 : listes, tableaux et structures de contrôle
Rappels listes et tableaux
Exercices TP2
Exercices du cours
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
15 / 29
Exercice 10 *
Exécutez et complétez le programme suivant :
#!/usr/bin/perl -w
@liste1 = qw(lundi mardi mercredi jeudi vendredi samedi
dimanche);
print "affichage global de la liste :\n";
print "- en dehors des guillemets :\n";
print @liste1,"\n";
print "- dans des guillemets :\n";
print "@liste1\n";
print "taille de \@liste1 = ... \n";
print "son premier élément est : ...\n";
print "son troisième élément est : ...\n";
print "son dernier élément est : ...\n";
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
16 / 29
Exercice 11
Commentez les instructions suivantes, et prévoir très précisément les
affichages avant d’expérimenter
#!/usr/bin/perl -w
@alpha = (’a’..’z’); @liste = (@alpha,0..9);
$el = $liste[3]; print "$el\n";
($a, $b, $c, @reste) = @liste ;
print "\$a= $a, \$b= $b, \$c =$c , \@reste= @reste\n";
($b, $a)= ($a, $b);
print "\$a= $a, \$b= $b \n";
$el = pop @liste;
print "\$el= $el, \@liste= @liste\n";
$el = shift @liste;
print "\$el= $el, \@liste= @liste\n";
print "\@alpha est la liste \n@alpha\n";
for ($i=0; $i<26 ; $i++) {
$el= pop @alpha;
unshift @alpha, $el;
}
print "\@alpha est maintenant \n@alpha\n";
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
17 / 29
Exercice 12
1
Commentez les instructions suivantes, prévoir les affichages
#!/usr/bin/perl
# pour placer la chaine saisie dans la variable $ligne
# rappel : le descripteur STDIN lié à l’entrée standard peut etre omis
$ligne = <STDIN> ;
# pour l’afficher à l’écran, au lieu de print STDOUT $ligne;
print "STDIN en contexte scalaire = " . $ligne ;
# Pour lire une à une les lignes saisies,
# on utilise une construction while
# pour sortir de cette boucle : ctrl-D
while ($ligne = <>) {
chomp($ligne) ;
@texte = (@texte, $ligne) ; # pour placer la ligne dans le tableau
}
print "STDIN en contexte liste = @texte\n" ;
2
Modifiez ce programme en utilisant <STDIN> dans un contexte de
liste
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
18 / 29
Exercice 12 I
Sur un système UNIX (qui n’utilise pas de système de répertoire
centralisé), les comptes utilisateurs sont décrits dans un simple fichier
texte /etc/passwd.
On souhaite récupérer ce fichier dans une liste. Voici la structure des
enregistrements de ce fichier :
############# extrait de /etc/passwd ####################
jean:x:500:500::/home/jean:/bin/bash
thierry:x:501:501::/home/thierry:/bin/bash
admin:x:502:502::/home/admin:/bin/bash
#########################################################
1
Compléter et commenter l’exécution du script
2
Donner 2 façons de remettre le compte root en tête de la liste
@comptes
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
19 / 29
Exercice 12 II
#!/usr/bin/perl -w
# ouvrir le fichier /etc/passwd en lecture
open P,"/etc/passwd";
# lire la première ligne, puis tout le reste
$root = ....
print $root,"\n";
@comptes = <P>;
print "\$root = $root\n";
print "2ème élément de \@comptes = ...\n";
# afficher le dernier compte :
print "Dernier compte créé dans \@comptes = ...\n";
# pour placer $root en 1ère place dans @comptes
.....
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
20 / 29
Exercice 13 * I
Il s’agit de rechercher les comptes utilisateurs sur un système Unix de
numéros (3ème champ) supérieurs à 500 (en effet dans beaucoup de
distributions les numéros internes de comptes (uid) commencent à 500
(ceci est réglable dans /etc/login.defs).
On demande d’afficher les champs suivants : nom, uid, répertoire
personnel en complétant le script ci-dessous)
1
Ouvrir le fichier /etc/passwd et extraire chaque ligne dans une boucle
2
Utiliser la fonction split() pour mettre les champs de chaque ligne
dans une liste @champs
3
Comparer à 500 le champ entier contenant l’UID (c’est le 3ème
champ).
4
Présenter une 2ème solution, en récupérant d’un coup le contenu du
fichier
5
Prolongement : compléter en trouvant le groupe principal et la liste
des groupes secondaires
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
21 / 29
Exercice 13 * II
#!/usr/bin/perl -w
$fichier="/etc/passwd";
print "Liste des comptes d’uid supérieur à 500\n";
open F, $fichier;
while (<F>) {
chomp();
@champs= ....
if ( ... >= 500) {
print " ....\n";
}
}
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
22 / 29
Exercice 14
Il s’agit de récupérer et de placer dans une (seule) liste nommée @liste,
toutes les lignes contenues dans 3 fichiers. Si on n’a pas de meilleure idée,
utiliser /etc/passwd, /etc/group et /etc/fstab
1
Construire @fichiers, la liste de ces noms de fichiers
2
Construire une boucle de parcours de @fichiers, dans laquelle on ouvre
chaque fichier en lecture et on empile dans @liste leur contenu
3
Afficher la liste @liste pour vérifier
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
23 / 29
Plan
1
TP2 : listes, tableaux et structures de contrôle
Rappels listes et tableaux
Exercices TP2
Exercices du cours
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
24 / 29
Exercices 15 à 17 : tableaux I
Exercice 15 Écrire un programme lisant une liste de chaı̂nes dans des
lignes individuelles et l’affichant en ordre inverse. Si vous
lisez la liste sur le terminal, vous devrez probablement en
délimiter la fin en produisant le caractère fin de fichier ,
certainement CTRL+D sous Unix, souvent CTRL+Z ailleurs.
Exercice 16 * Écrire un programme lisant un nombre puis une liste de
chaı̂nes (toutes dans des lignes individuelles), puis affichant
la ligne de la liste selectionnée par le nombre.
Exercice 17 Écrire un programme lisant une liste de chaı̂nes puis
sélectionnant et affichant une chaı̂ne quelconque de la liste.
Pour obtenir un élément quelconque de @untableau,
indiquez : srand ; au début de votre programme (cela
initialise le générateur de nombres aléatoires), puis utilisez :
rand(@untableau) à l’endoit où vous avez besoin d’une
valeur quelconque comprise entre zéro et la longueur moins
un de @untableau.
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
25 / 29
Exercices 18 à 22 : structures de contrôle I
Exercice 18 Écrire un programme demandant la température extérieure,
et affichant trop chaud si elle est supérieure à 20°C, et trop
froid autrement.
Exercice 19 Modifiez le programme de l’exercice précedent pour qu’il
affiche trop chaud si la température dépasse 22°C, trop froid
si elle est inférieure à 18°C, et convenable entre.
Exercice 20 Écrire un programme lisant une série de nombres (sur des
lignes distinctes) jusqu’à la lecture de 999, puis affichant la
somme de tous ces nombres (prenez soin de ne pas ajouter
999 !).
Exercice 21 Écrire un programme lisant une liste de chaı̂nes dans des
lignes distinctes, puis l’affichant en ordre inverse (sans
utiliser reverse).
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
26 / 29
Exercices 18 à 22 : structures de contrôle II
Exercice 22 * Écrire un programme affichant un tableau de nombres et
leur carrés, de zéro à 32. Essayez de trouver une solution qui
n’oblige pas à énumérer tous les nombres de 0 à 32 dans une
liste, puis essayez-en un qui utilise ce type de liste. Pour une
belle présentation, printf("%5g %8g\n",$a,$b)affiche le
nombre $asur cinq colonnes et le nombre $bsur huit colonnes.
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
27 / 29
Remerciements
Ces travaux pratiques sont largement inspirés des cours de programmation
de Jean Gourdin :
http://www.ac-creteil.fr/util/programmation/perl/
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
28 / 29
Bibliographie
1
http://www.perl.org/
I
2
http://perso.univ-rennes1.fr/francois.dagorn/perl/
I
3
un site avec un cours synthétique sur Perl
http://www.enstimac.fr/Perl/DocFr.html
I
4
le site officiel
documentation en français
http://articles.mongueurs.net/planning.html
I
articles de revues
Jérôme Farinas (IRIT)
TP PERL
13 janvier 2009
29 / 29