Valid XHTML     Valid CSS2    

  Solutions des exercices du tuteur Perl (gH)

   Téléchargez l'archive des programmes perl présentés.

Solution de l'exercice "E1. numérotation des lignes d'un fichier"

Si l'énoncé n'avait pas demandé que les numéros de ligne soient biens cadrés, on aurait pu, sous Unix, se contenter d'utiliser la commande grep -n "" nom_fichier.

Une solution classique vérifie l'existence du paramètre, l'ouverture possible du fichier avant de nommer $lig la ligne vue dans le fichier avec une variable explicite nommée $numero qu'on incrémente dans la boucle de lecture, soit le programme :

   #  test des paramètres

   if ($ARGV[0] eq "") {
        print " syntaxe : perl numerote.pl nom_de_fichier \n" ;
        exit(-1) ;
   }  ; # fin de test sur les arguments

   $fichier = $ARGV[0] ; # récupération du nom du fichier

   # ouverture du fichier

   open( FIC ,"<$fichier")
     || die "\n impossible d'ouvrir le fichier nommé $fichier \n\n" ;

   # affichage numéroté

   $numero = 0 ;
   while ($lig=<FIC>) {
     $numero++ ;
     print sprintf("  %04d  ",$numero).$lig ;
   } ; # fin de tant que

Une écriture plus "perlienne" vient utiliser les variables spéciales aux noms barbares à savoir $. et $_ :


   die(" syntaxe : perl numerote.pl nom_de_fichier \n ")
      if ($ARGV[0] eq "") ;

   open( FIC ,"<$ARGV[0]")
      or die "\n impossible d'ouvrir le fichier nommé $ARGV[0] \n\n" ;

   while (<FIC>) { print sprintf("  %04d  ",$.).$_ ; } ;

Solution de l'exercice "E2. variables d'environnement"

Une solution classique consiste à stocker dans un fichier-texte le résultat de la commande set puis à parcourir les lignes et à les découper (le séparateur est le symbole "égale"), soit le programme :

     print "\n Variable           Valeur\n\n" ;

     $ficenv = "set.tmp" ;

     # sauvegarde dans un fichier

     `set > $ficenv ` ;

     # parcours du fichier

     open(FENV,"<$ficenv") or die ("impossible d'ouvrir $ficenv") ;
     $nbve = 0 ;
     while ($ligne=<FENV>) {
       $nbve++ ;
       chop($ligne) ;
       @ligenv = split(/=/,$ligne) ;
       ($tvar[$nbve],$tval[$nbve]) = @ligenv ;
     } ; # fin de tant que

     # affichage

     for ($idve=1;$idve<=$nbve;$idve++) {
           print  sprintf(" %-20s",$tvar[$idve])
                 .sprintf("%-40s",$tval[$idve])."\n" ;
     } ; # fin de pour chaque
Remarque : au lieu de
       @ligenv = split(/=/,$ligne) ;
       ($tvar[$nbve],$tval[$nbve]) = @ligenv ;

on aurait pu écrire :

       ($tvar[$nbve],$tval[$nbve]) = split(/=/,$ligne) ;

Une solution plus "perliste" consiste à savoir que la table de hachage nommée %ENV contient les variables d'environnement et leurs valeurs. On remarquera qu'on trie au passage (ce qui n'est sans doute pas nécessaire) les clés sans utiliser keys car Perl s'en doute !

     print "\n Variable           Valeur\n\n" ;

     foreach $ve (sort %ENV) {
       if (defined $ENV{$ve}) {
           print  sprintf(" %-20s",$ve)
                 .sprintf("%-40s",$ENV{$ve})."\n" ;
       } ; # fin de si variable définie
     } ; # fin de pour chaque

 
Pour l'affichage en cgi avec de la couleur, nous renvoyons le lecteur au code-source de la page http://forge.info.univ-angers.fr/scripts/env.pl
 

Solution de l'exercice "E3. dictionnaires d'un fichier-texte"

Nous laissons (comme nouvel exercice) le soin au lecteur de détailler les instructions Perl utilisées. A part =~, tr et s/ toutes ces instructions ont déja été vues...

 

     #  test des paramètres

     if ($ARGV[0] eq "") {
          print " syntaxe : perl dicos.pl nom_de_fichier \n" ;
          exit(-1) ;
     }  ; # fin de test sur les arguments

     $fictxt = $ARGV[0] ; # récupération du nom du fichier

     # ouverture du fichier

     open( FICT ,"<$fictxt") 
       || die "\n impossible d'ouvrir le fichier nommé $fictxt \n\n" ;

     # parcours du fichier, remplissage du hachage au passage

     $nbLig = 0 ; # nombre de lignes du fichier
     $nbMot = 0 ; # nombre de mots en tout
     $nbMdi = 0 ; # nombre de mots différents

     while ($ligne=<FICT>) {
       $nbLig++ ;
       chop($ligne) ;
       # on élimine la ponctuation
       $ligne  =~  tr/,.:!'"();/         / ;
       # on élimine le double tiret
       $ligne  =~  s/--//g ;
       @mots = split(/ /,$ligne) ;
       foreach $m (@mots) {
         if (length($m)>0) {
           $nbMot++;
           $cntMot{$m}++ ;
           if ($cntMot{$m}==1) {
               $nbMdi++ ;
           } ; # finsi nouveau mot
         } ; # finsi mot non vide
       } ; # fin pour chaque mot
     } ; # fin de tant que

     print " Analyse du fichier $fictxt :\n" ;
     print "    $nbLig ligne(s), $nbMot mot(s) 
                    dont $nbMdi mot(s) différent(s).\n" ;

     $dicNom =  "dic_$fictxt.mot" ;  # fichier alphabétique
     $dicOcc =  "dic_$fictxt.occ" ;  # fichier fréquenciel

     open(DICM,">$dicNom ") 
        or die ("impossible d'écrire dans $dicNom") ;
     print DICM  "fichier $dicNom issu de $0 $fictxt\n" ;
     foreach $m (sort keys(%cntMot)) {
       print DICM  sprintf("   %-20s",$m)
                  .sprintf("%4d",$cntMot{$m})."\n" ;
       # on en profite pour remplir un tableau pour les occurences
       $cle = sprintf("%04d",$cntMot{$m})."_$m" ;
       $tabMot{$cle}=$m ;
     } ; # fin pour chaque
     close(DICM) ;

     open(DICK,">$dicOcc ") 
        or die ("impossible d'écrire dans $dicOcc") ;
     print DICK  "fichier $dicOcc issu de $0 $fictxt\n" ;
     foreach $c (reverse sort keys(%tabMot)) {
       # on sait comment Perl convertit les %s en %c, on en profite :
       print DICK  sprintf("   %-20s",$tabMot{$c})
                  .sprintf("%4d",$c)."\n" ;
     } ; # fin pour chaque
     close(DICK) ;

     print " Vous pouvez consulter les fichiers  $dicNom et $dicOcc \n" ;
     print " dont voici le début : \n\n" ;
     system("head -n 20 $dicNom") ;
     system("head $dicOcc") ;

 

Solution de l'exercice "E4. calcul de Chi2"

Installer un module consiste à recopier le fichier-texte correspondant dans "le bon répertoire". Lorsqu'on est root, ceci peut se faire en ligne de commande. Si on dispose des droits suffisants, pour notre exemple, on écrit seulement

     perl -MCPAN -e 'install Statistics::Distributions'
L'utilisateur courant peut alors se contenter d'écrire
     use Statistics::Distributions ;
     $df = 17  ;
     $pr = 5 ;
     $vc = Statistics::Distributions::chisqrdistr ($df,$pr);
     print "  valeur de chi2 : $vc \n" ;
Si par contre on de dispose pas des droits root, il est possible de copier le fichier localement et de l'indiquer à perl. Par exemple si on crée le répertoire /home/info/gh/Bin/Perl_lib/, si on y crée ensuite le répertoire /home/info/gh/Bin//Perl_lib/Statistics et si on met le fichier Distributions.pm dans ce répertoire Statistics alors il suffit d'ajouter au début du programme perl précédent la ligne
     use lib "/home/info/gh/Bin/Perl_lib" ;
pour que perl aille chercher ce qu'il lui manque comme module à l'endroit indiqué.

Solution de l'exercice "E5. fichiers DBF"

Le format Dbase et plus généralement le format Xbase sont des formats qui permettent de stocker "proprement" des tableaux rectangulaires de données. Sans être des fichiers de base de données lourdes comme Oracle ou Sql, ces fichiers sont lisibles par la plupart des logiciels comme Excel ou les autres tableurs courant. Leur grand intérêt est d'utiliser comme unité de base de structure les colonnes (ou "champs"). Ils garantissent donc la constance du nombre de champs sur l'ensemble des lignes et l'homogénéité des données à l'intérieur d'une même colonne. De plus ils sont très économiques en terme de stockage car après la définition des colonnes on trouve les données bout à bout sans caractère de controle. Ainsi pour 18 lignes de 59 caractères soit 1062 octets, le fichier DBF fait 1384 octets (soit moins de 2 kO) alors que le même fichier lu sous Excel 10 et enregistré au format XLS fait 14 384 octets soit plus de 14 kO c'est à dire 10 fois plus !. Après avoir lu la page de man de XBASE disponible ici il est relativement simple d'écrire le programme dbase.pl suivant :

 
 
     use lib "/home/gh/Bin";
     use XBase ; 
 
     $nomBase = "vins.dbf" ; 
     $table = new XBase $nomBase or die XBase-\>errstr; 
     $nbr = $table-\>last_record ; 
 
     print " il y a  ".(1+$nbr)." enregistrements dans la base $nomBase ;
     for (0 .. $nbr) { 
         print sprintf("%5d. ",1+$_) ; 
         @enrc = $table->get_record($_) ; 
         $ndc = -1 ; 
         foreach $ch (@enrc) { 
            $ndc++ ; 
            if ($ndc>0) { print "$ch" ; }
         } ; # fin pour chaque champ 
         print "\n \n" ;
     } ; # fin pour enregistrement
 
Si on l'applique au fichier vins.dbf proposé, on voit alors :
 
  il y a  18 enregistrements dans la base vins.dbf                
     1. CHMP 7069 3786 12578 8037 13556 9664 10386 206            
     2. MOS1 2436 586 2006 30 1217 471 997 51                     
     3. MOS2 3066 290 10439 1413 7214 112 3788 330                
     4. ALSA 2422 1999 17183 57 1127 600 408 241                  
     5. GIRO 22986 22183 21023 56 30025 6544 13114 3447           
     6. BOJO 17465 19840 72977 2364 39919 17327 17487 2346        
     7. BORG 3784 2339 4828 98 7885 3191 11791 1188               
     8. RHON 7950 10537 7552 24 8172 11691 1369 1798              
     9. ANJO 2587 600 2101 0 7582 143 872 131                     
    10. AOCX 17200 22806 15979 50 20004 1279 4016 944             
    11. VDQS 1976 1029 1346 0 2258 212 1017 487                   
    12. XXXX 38747 19151 191140 7992 101108 1029 26192 38503      
    13. PROV 1375 1150 2514 0 284 401 9 236                       
    14. MUSC 2016 2908 1529 0 12891 18 716 653                    
    15. RHOF 785 1648 1009 6 775 643 542 35                       
    16. AOCF 160 246 135 8 1177 26 7 0                            
    17. XXXF 24 1533 160 0 480 0 0 0                              
    18. XXFF 2415 74 208 8 1705 12 36 47                          
En, rajoutant les instructions de tableau TR, TD etc. (voir le programme dbaset.pl) on obtient alors le joli affichage de la page dbaset.htm

Solution de l'exercice "E6. extractions d'adresses"

Lorsqu'on met .* perl cherche à satisfaire l'expression régulière en mode gourmand sans garder une trace de ce qui correspond. Mettre ? permet de satisfaire l'expression régulière en mode modéré et utiliser les parenthèses met en mémoire ce qui correspond dans les variables $1, $2 etc.

Ici, on veut dans une ligne comme <a href="www.google.fr">google</a> récupérer les champs entre <a href=" et le guillemet suivant et récupérer aussi ce qu'il y a entre le > et </a> ; comme on veut pas récupérer ce qu'il y a entre les deux (comme par exemple target="_blank" ) on ne met pas de parenthèses.

Si on met +=1 l'affectation est faite après l'affichage après et on ne voit que les références utilisées au moins 2 fois, soit :


 
  Homo sapiens                   http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?name=Homo+sapiens 
  Mus musculus                   http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?name=Mus+musculus 
  Sus scrofa                     http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?name=Sus+scrofa 
  Pseudomonas aeruginosa         http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?name=Pseudomonas+aeruginosa 
  Escherichia coli               http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?name=Escherichia+coli 
  Bos taurus                     http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?name=Bos+taurus 
  Bacillus stearothermophilus    http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?name=Bacillus+stearothermophilus 
  Spinacia oleracea              http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?name=Spinacia+oleracea 
 

Solution de l'exercice "E7. que fait ce programme ?"

Visiblement, ce programme perl attend en entrée le nom d'un fichier php. Il lit ce fichier ainsi que tous les fichiers inclus (via include, include_onc et require_once). Quand un fichier à inclure n'est pas vu, le programme le dit et s'arrête. Si tous les fichiers sont vus, ldpphp.pl passe en revue toutes les définitions de fonctions et indique leur nom et position dans le fichier. Ensuite, ldphp.pl fournit la liste des fonctions par fichier. Le fichier produit est nommé ldphp.sor. Voici son contenu pour std.php (qui inclut strfun.php) :


      Analyse du fichier std.php 
      ==========================
       28/01/2011 9:51
     
      Liste des fichiers inclus 
      ------------------------- 
      (format : nom du fichier et nombre de lignes dans le fichier) 
     
            1. * std.php               1337
            2.   strfun.php             250
                              total    1587 lignes
     
      Liste des fonctions  (et position dans le fichier)
      --------------------
     
            1.  abbr                           std.php                          1001
            2.  afficheRubrique                                                    0
            3.  ahref                          std.php                          1070
            4.  aname                          std.php                          1082
            5.  ancre                          std.php                          1054
            6.  b                              std.php                           391
            7.  blockquote                     std.php                           705
            8.  br                             std.php                           661
            9.  center                         std.php                           697
           10.  cmt                            std.php                           465
           11.  code                           std.php                           649
           12.  comptageSqlSimple              std.php                          1190
           13.  compteMots                     strfun.php                         31
           14.  copies                         strfun.php                         15
           15.  dd                             std.php                           507
           16.  debutPage                      std.php                            71
           17.  debutPageGeneral               std.php                           155
           18.  debutPageMinimal               std.php                          1148
           19.  debutPageMinimale              std.php                           300
           20.  debutPageRedir                 std.php                           331
           21.  debutSection                   std.php                           364
           22.  debutdd                        std.php                           511
           23.  debutdl                        std.php                           527
           24.  debutdt                        std.php                           519
           25.  debutli                        std.php                           495
           26.  div                            std.php                           783
           27.  dt                             std.php                           503
           28.  em                             std.php                           397
           29.  fieldset                       std.php                           813
           30.  finPage                        std.php                           251
           31.  finPageGeneral                 std.php                           273
           32.  finPageMinimal                 std.php                          1179
           33.  finPageMinimale                std.php                           318
           34.  finSection                     std.php                           376
           35.  finabbr                        std.php                          1005
           36.  finblockquote                  std.php                           709
           37.  fincenter                      std.php                           701
           38.  fincode                        std.php                           657
           39.  findd                          std.php                           515
           40.  findiv                         std.php                           794
           41.  findl                          std.php                           531
           42.  findt                          std.php                           523
           43.  finfieldset                    std.php                           821
           44.  finform                        std.php                           585
           45.  finli                          std.php                           499
           46.  finnoscript                    std.php                           997
           47.  finol                          std.php                           487
           48.  finp                           std.php                           689
           49.  finpre                         std.php                           611
           50.  finselect                      std.php                           962
           51.  finspan                        std.php                           555
           52.  fintable                       std.php                           719
           53.  fintd                          std.php                           759
           54.  fintdk                         std.php                           779
           55.  fintextarea                    std.php                           989
           56.  finth                          std.php                           767
           57.  fintr                          std.php                           729
           58.  finul                          std.php                           479
           59.  form                           std.php                           809
           60.  gbleu                          std.php                           563
           61.  gbleuf                         std.php                           571
           62.  ghBleu                         std.php                          1020
           63.  ghRouge                        std.php                          1014
           64.  grouge                         std.php                           559
           65.  gvert                          std.php                           575
           66.  gvertf                         std.php                           579
           67.  h                              std.php                           409
           68.  h1                             std.php                           422
           69.  h2                             std.php                           428
           70.  h3                             std.php                           434
           71.  h4                             std.php                           438
           72.  hh1                            std.php                           445
           73.  hh2                            std.php                           455
           74.  hh3                            std.php                           461
           75.  hr                             std.php                           798
           76.  href                           std.php                          1076
           77.  img                            std.php                          1027
           78.  imgh                           std.php                          1045
           79.  input_checkbox                 std.php                           857
           80.  input_hidden                   std.php                           840
           81.  input_option                   std.php                           966
           82.  input_password                 std.php                           851
           83.  input_radio                    std.php                           865
           84.  input_reset                    std.php                           885
           85.  input_select                   std.php                           954
           86.  input_select_fin               std.php                           958
           87.  input_submit                   std.php                           876
           88.  input_text                     std.php                           844
           89.  js                             std.php                          1124
           90.  jsf                            std.php                          1134
           91.  kbd                            std.php                           403
           92.  label                          std.php                           825
           93.  legende                        std.php                           830
           94.  li                             std.php                           491
           95.  listeSelectFromTxt             std.php                           974
           96.  menu                                                               0
           97.  mot                            strfun.php                         61
           98.  nbdif                          strfun.php                        210
           99.  nbmots                         strfun.php                         95
          100.  nbsp                           std.php                           669
          101.  noscript                       std.php                           993
          102.  ol                             std.php                           483
          103.  on                                                                 0
          104.  on                                                                 0
          105.  on                                                                 0
          106.  on                                                                 0
          107.  on                                                                 0
          108.  on                                                                 0
          109.  p                              std.php                           589
          110.  pct                            std.php                          1207
          111.  pj                             std.php                           685
          112.  pre                            std.php                           600
          113.  pre_fichier                    std.php                           615
          114.  premierCarNonNul               strfun.php                        125
          115.  ptexte                         std.php                           681
          116.  pvide                          std.php                           693
          117.  rubriqueParNumero                                                  0
          118.  s_gbleu                        std.php                           567
          119.  s_nbsp                         std.php                           677
          120.  s_span                         std.php                           540
          121.  sbr                            std.php                           665
          122.  sdl                            std.php                           469
          123.  setNumcrub                                                         0
          124.  showurl                        std.php                          1110
          125.  showurlbr                      std.php                          1118
          126.  showurlcmt                     std.php                          1098
          127.  showurlcmtbr                   std.php                          1088
          128.  snbsp                          std.php                           673
          129.  span                           std.php                           551
          130.  surncard                       strfun.php                        165
          131.  surncardnbsp                   strfun.php                        195
          132.  surncardzero                   strfun.php                        180
          133.  surncarg                       strfun.php                        150
          134.  table                          std.php                           713
          135.  tableauDar                     std.php                          1279
          136.  td                             std.php                           733
          137.  tdk                            std.php                           771
          138.  tdm                                                                0
          139.  tdvide                         std.php                           763
          140.  textarea                       std.php                           894
          141.  textarea_fichier               std.php                           911
          142.  th                             std.php                           746
          143.  titre                                                              0
          144.  tr                             std.php                           723
          145.  ul                             std.php                           475
     
      Fonction(s) du fichier std.php  (et position dans le fichier)
      ------------------------------
            1.  abbr                             1001
            2.  ahref                            1070
            3.  aname                            1082
            4.  ancre                            1054
            5.  b                                 391
            6.  blockquote                        705
            7.  br                                661
            8.  center                            697
            9.  cmt                               465
           10.  code                              649
           11.  comptageSqlSimple                1190
           12.  dd                                507
           13.  debutPage                          71
           14.  debutPageGeneral                  155
           15.  debutPageMinimal                 1148
           16.  debutPageMinimale                 300
           17.  debutPageRedir                    331
           18.  debutSection                      364
           19.  debutdd                           511
           20.  debutdl                           527
           21.  debutdt                           519
           22.  debutli                           495
           23.  div                               783
           24.  dt                                503
           25.  em                                397
           26.  fieldset                          813
           27.  finPage                           251
           28.  finPageGeneral                    273
           29.  finPageMinimal                   1179
           30.  finPageMinimale                   318
           31.  finSection                        376
           32.  finabbr                          1005
           33.  finblockquote                     709
           34.  fincenter                         701
           35.  fincode                           657
           36.  findd                             515
           37.  findiv                            794
           38.  findl                             531
           39.  findt                             523
           40.  finfieldset                       821
           41.  finform                           585
           42.  finli                             499
           43.  finnoscript                       997
           44.  finol                             487
           45.  finp                              689
           46.  finpre                            611
           47.  finselect                         962
           48.  finspan                           555
           49.  fintable                          719
           50.  fintd                             759
           51.  fintdk                            779
           52.  fintextarea                       989
           53.  finth                             767
           54.  fintr                             729
           55.  finul                             479
           56.  form                              809
           57.  gbleu                             563
           58.  gbleuf                            571
           59.  ghBleu                           1020
           60.  ghRouge                          1014
           61.  grouge                            559
           62.  gvert                             575
           63.  gvertf                            579
           64.  h                                 409
           65.  h1                                422
           66.  h2                                428
           67.  h3                                434
           68.  h4                                438
           69.  hh1                               445
           70.  hh2                               455
           71.  hh3                               461
           72.  hr                                798
           73.  href                             1076
           74.  img                              1027
           75.  imgh                             1045
           76.  input_checkbox                    857
           77.  input_hidden                      840
           78.  input_option                      966
           79.  input_password                    851
           80.  input_radio                       865
           81.  input_reset                       885
           82.  input_select                      954
           83.  input_select_fin                  958
           84.  input_submit                      876
           85.  input_text                        844
           86.  js                               1124
           87.  jsf                              1134
           88.  kbd                               403
           89.  label                             825
           90.  legende                           830
           91.  li                                491
           92.  listeSelectFromTxt                974
           93.  nbsp                              669
           94.  noscript                          993
           95.  ol                                483
           96.  p                                 589
           97.  pct                              1207
           98.  pj                                685
           99.  pre                               600
          100.  pre_fichier                       615
          101.  ptexte                            681
          102.  pvide                             693
          103.  s_gbleu                           567
          104.  s_nbsp                            677
          105.  s_span                            540
          106.  sbr                               665
          107.  sdl                               469
          108.  showurl                          1110
          109.  showurlbr                        1118
          110.  showurlcmt                       1098
          111.  showurlcmtbr                     1088
          112.  snbsp                             673
          113.  span                              551
          114.  table                             713
          115.  tableauDar                       1279
          116.  td                                733
          117.  tdk                               771
          118.  tdvide                            763
          119.  textarea                          894
          120.  textarea_fichier                  911
          121.  th                                746
          122.  tr                                723
          123.  ul                                475
     
      Fonction(s) du fichier strfun.php  (et position dans le fichier)
      ---------------------------------
            1.  compteMots                         31
            2.  copies                             15
            3.  mot                                61
            4.  nbdif                             210
            5.  nbmots                             95
            6.  premierCarNonNul                  125
            7.  surncard                          165
            8.  surncardnbsp                      195
            9.  surncardzero                      180
           10.  surncarg                          150
     
     
     

 

Pour quelqu'un qui développe en PHP, cela peut-être utile, en complément à stdphp.php.

 

Retour au tuteur Perl (gH)

 

retour gH    Retour à la page principale de   (gH)