précédant | suivant | sommaire

Exercice commenté
alain Adelmar a.adelmar@wanadoo.fr


Ce faire son propre traducteur Anglais-Français:

Nous allons voir ligne par ligne comment se fabriquer un traducteur d'anglais - français, français - anglais évolutif (évolutif dans le sens que plus on l'utilisera plus il sera complet). Je l'ai appelé Tafed (Traducteur Anglais Français EDitable)

Voyons voir sur Windows ou sur Linux ce qu'il nous faut :
    1) D'abord il faut que Perl soit installé (sur Linux c'est déjà fait) sinon installer Perl.
    2) Il nous faut aussi un dico_a-f.dico : On va le créer dans la foulée

Pour Windows un clic droit de la souris sur le bureau, puis Nouveau, puis document texte, OK
On ouvre ce document puis on écris dedans une ou deux ligne, comme ci-dessous sans espace :

first,premier
link,lien
load,charger,télécharger,attrape,comprendre
last,dernier,final|last time=la dernière fois

Voilà, le dico est fait, tout au moins il existe, on sauve en lui donnant le nom de " dico_a-f.dico ".

Voilà le topo, il ne nous reste plus qu'a faire ce programme. Fastoche isn't it?
-----------------------------------------
En gros que va faire ce programme ?

Il va vous accueillir et vous demander ce que vous voulez faire dans un petit menu, style :

**********************************************
Bonjour, ceci est le petit traducteur Tafed (Traducteur Anglais Français EDitable)
Faite votre choix :
Anglais-français [1], Français-Anglais [2], ajouter quelques définition [3], quitter [q ]
**********************************************

Puis suivant votre réponse il ouvrira le dico et vous demandera d'entrer un mot ou une lettre
Puis il vérifiera les équivalences et vous présentera le résultat comme ceci :
Si vous tapez last :
>last = dernier final (exemple. : last time = la dernière fois)
si vous tapez juste ‘l’ :
>last   = dernier final
>link   = lien
>load  = charger télécharger attraper comprendre

Ceci est très pratique lorsqu'on ne se rappelle pas exactement de l'orthographe du mot.

Dans le cas ou vous choisissez d'éditer quelques mots supplémentaires, il vous dira comment les entrer, puis vérifiera si elle n'existe pas déjà dans le dico et vous demandera de confirmer après vous avoir monter l'équivalence qu'il à découverte comme ceci :
>Le mot link existe déjà dans le dico, sous cette forme : link = lien
voulez vous le garder [Oui-Non] ?

Quand au Français-Anglais il va chercher dans toutes les traductions, sur tous les niveau, la concordance.

Maintenant nous allons voir comment on va lui faire faire cela. Ligne par ligne mot par mot.



Le Code

_________________________________________________________________
Code couleur de cet exemple:
Chaque ligne d'explication sera écrite                   en grisé
Tous les numéro de ligne de code seront              en Orangé
Tous les exemple de sortie écran seront              en violé
Et toute les 10 lignes je récapitulerai en réécrivant l'ensemble des 10 lignes sans commentaires. Si quelque chose vous échappe ou vous laisse perplexe mailez moi.
__________________________________________________________________________

Tout programme ou script Perl commence par un Bang. C'est une ligne qui va être reconnu par l'interpréteur du système que l'on utilise (MSDOS pour Windows, bash, ash, sh pour Linux).

Pour Linux il sera ainsi :
01 #!/usr/bin/perl –w
alors que pour Windows il sera comme ça:
01 #!perl –w
info :le petit " w " comme argument signifie que vous désirez voir écrit le compte rendu de l'interprétation du script passé au debuggage (très utile, il vous indique les erreur et la ligne ou l'erreur à était relevé).
récapitulation la ligne 01 s'appelle le Bang, qui indique que ce script doit être interprété en Perl et commence par #!
puis le nom de l'interpréteur ("perl" sous windows) et ("/usr/bin/perl sous Linux), l'argument -w signifie "tenez moi au courant des erreurs"

02 # ***************************************************************************
la ligne 02 est en commentaire, une ligne pour faire joli, toute les lignes commençant par un dièse "#" son des commentaire au script. C'est à dire qu'elle ne seront pas interprétées lorsque nous exécuterons le script. (pareil que REM en DOS)
03 # remd: petit logiciel de traduction de mot simple anglais->français
04 # et vice versa ainsi qu'une option Edit pour étoffer le dico.
05 # pensez à faire suivre le dico_af-fr.dico dans le même répertoire.
06 # alain adelmar 10 Août 2001. Version 1.02
les lignes 3,4 et 5 sont en commentaires et ne sont là que pour prévenir le programmeur qui voudrai savoir comment est écrit ce script. Je met toujours une balise remd: en seconde ligne (pour plus de précision voir quoi.html et alias.html) cela me permet de me faire un idée. En tapant "quoi tafed" il me sort:
            remd: petit logiciel de traduction de mot simple anglais->français
            et vice versa ainsi qu'une option Edit pour étoffer le dico.
            pensez à faire suivre le dico_uk-fr dans le même répertoire.
            alain adelmar 10 Août 2001. Version 1.02

07 $dico = "dico_uk-fr";
la ligne 7 est une assignation*
c'est à dire que l'on alloue une valeur (ici le nom du dico) à une variable scalaire* ($dico)
c'est à dire que la variable $dico aura comme valeur la suite de caractères "dico_uk-fr"
c'est à dire que l'on va prévenir le programme que quand il verra $dico c'est le nom du dico
08 # $kk = 0;
la ligne 8 ne sert à rien, car en commentaire, mais cette assignation de la valeur 0 à la variable $kk est une initialisation
c'est à dire que l'on alloue la valeur 0 à $kk pour pouvoir s'en servir plus tard. Bien que perl est capable de géré les variables en leur assignant une valeur nulle si elle n'on pas encore servie, il peut être intéressant de savoir initialiser quelques variables. Quand il y en a plusieurs on écrit:
$a = $b = $c =0;   # qui signifie que $a est égale a $b et a $c est vaut 0.

On continu, donc avec l'ouverture du fichier dico_uk-fr:
09 # lecture du dico******************************************
la ligne 09 est un commentaire qui sert à prévenir le programmeur des phases du script, ici il indique que l'on va lire le dico.

10 open F, "$dico" or die "Ouverture de dico impossible $!";
la ligne 10 représente l'ouverture en lecture, d'un fichier. La fonctionopen* suivie de son Filehandle*(F) que l'on va faire pointer, lier à "$dico" qui lui même contient le nom du fichier, sers à ouvrir ce fichier (ici simplement en lecture).  + d'info sur open et F.
Si l'ouverture du fichier ne peut pas se faire correctement, soit parce qu'il est déjà ouvert ou parce qu'il est inexistant ou son orthographe est inexacte, qu'il à changé de place, enfin ....peut importe il faut arrêter le script et prévenir l'utilisateur de pourquoi le script s'est arrêté. Nous faisons tout ça grâce au deux fonctionsoret die suivies d'une ligne d'explication.

11 @traduction = <F>;
la ligne 11 est aussi une assignation car elle créée à la variable liste @traduction en lui attribuant la valeur du contenu de dico_uk-fr, représenté par le handle de fichier F. On peut traduire cette ligne par:
- attribu la totalité du fichier dico_uk-fr qui est représenté par F à la variable liste @traduction (un élément par ligne, c'est à dire que chaque ligne du fichier $dico sera un élément de la liste @traduction ).
- créé et prend en compte la variable liste @traduction comme étant le contenu (ligne par ligne) du fichier représenté par le handle de fichier <F> ($dico = "dico_uk-fr")
Personnellement je me représente les pointes à gateaux comme "tout le contenu de", comme "tout ce qui arrive de".

Bon récapitulons:
on a ouvert le fichier dico_uk-fr représenté par F
on a placer son contenu dans une variable liste qu'on a appelé @traduction
Il n'y a plus qu'à fermer le fichier. Puissqu'on a son contenu plus besoin de garder ce fichier ouvert.

12 close F || die "fermeture impossible $!";
la ligne 12 ferme le fichier représenté par F (le handle de fichier) de la même manière qu'il l'a ouverte mais avec la fonction close. On aurai pu écrire comme à l'ouverture: close F, "$dico" or die "fermeture de $dico impossible $!";
mais quand on ferme il n'ai pas nessessaire de répéter l'assignation du handle puissque Perl sait déjà que F représente "$dico" et les deux barres || represente le même ou que or. Souvent on a tendance à écrire juste: close F
Mais il ne coute rien de contrôler le retour de close et traiter l'erreur si elle à lieu.
Maintenant on va présenter le traducuteur et son menu

13 $x = "x*" x 25;
la ligne 13 est une concaténation*
c'est à dire que la valeur de la variable $x sera calculé et sera le résultat de la chaîne de caractère "x*" multiplier par 25
c'est à dire 25 fois "x*"  soit  "x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*"
Un expression qui doit être calculé et mis en forme est une concaténation, c'est le résultat de 25 reproduction de "x*".

14 $donc = "\n\tdonc\n";
la ligne 14 est aussi une concaténation, une assignation à calculer. Qui signifie que la variable $donc représente le signe
"\n" (un saut de ligne, retour chariot) + le signe "\t" (une tabulation) a la suite, suivie du mot "donc + le signe "\n" (un autre saut de ligne retour chariot). Le tout est la valeur de $donc et donne:

    donc
si nous avions $y = "$x$donc$x"; # nous aurions en sortie:
x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*
    donc
x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*

15 print "\n\n\n$x\n";
la ligne 14 est une concaténation de plusieurs signes précédés de la fonction print.
La fonction print donne l'ordre d'écrire sur le STDOUT (dans ce cas l'écran, sur la console de l'application où vous avez ouvert le script ). D'abord le signe "\n" qui est un saut de ligne retour chariot suivi de deux autres puis la valeur $x puis un autre saut de ligne retour chariot.
résultat: 3 saut de ligne retour chariots + la valeur de $x + un autre saut de ligne retour chariot. Ça donne
 
 

x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*

16 MENU:print "\nBienvenu sur le petit traducteur tafed\noffert par a_l_a_i_n \/\/ a_d_e_l_m_a_r aadelmar\@free.fr\n";
17 print "Anglais-français(1)\nFrançais-anlais(2)\nAjouter quelques lignes au dico(3)\t\t\treponse: ";
la ligne 16 et 17 contiennent beaucoup de chose voyons cela mot à mot:
d'abord "MENU:" qui est une balise qui servira pour revenir à cet endroit précisément plus tard dans le programme.
Puis la fonction print qui affichera à l'écran, un retour a la ligne suivi de "Bienvenu sur le petit traducteur taf" saut de ligne, retour chariot "offert par a_l_a_i_n" puis la barre "\" qui signifie (ne prendre en compte le signe suivant que pour son aspect littéral, c'est à dire qu'un \\n ne voudra pas dire saut de ligne mais juste les deux caractères \n, car l'anti-slash devant signifie que le signe qui suit, n'a pas d'autre signification que "une barre en travers" et un "n". Idem pour l'anti-slash devant l'arobas "@" qui n'est pas une référence à une variable liste mais simplement un arobas.  Ceci est très important : il faut toujours lire les signes de gauche à droite en désamorçant avec les anti-slash ce qui doit être désamorcé.
la ligne 17 elle commence par une fonction print donc continu d'écrire sur STDOUT, la sortie standard (l'écran), par défaut.
Oui print affiche sa sortie sur STDOUT lorsqu'il n'est pas suivi d'un handle de fichier (une ou plusieurs lettre majuscules).
Nous verrons plus loin comment écrire sur un fichier (ligne  ).
récapitulation des deux dernière lignes 16 et 17: (ça donnera):

Bienvenue  sur le petit traducteur tafed
offert par a_l_a_i_n // a_d_e_l_m_a_r aadelmar@free.fr
Anglais-français(1)
Français-anlais(2)
Ajouter quelques lignes au dico(3)        reponse:

Voilà ce que ça donne. C'est un menu, l'utilisateur prend connaissance des choix qui lui sont fait et va donner le sien en entrant un caractère suivi de la touche de validation <Enter>.
Donc on va s'attendre à requeillir la réponse de l'utilisateur, et se sur le clavier (il a que ça pour s'éxprimer dans cet exemple).

18 $trad = <STDIN>;
la ligne 18 assigne à la variable $trad la valeur que l'utilisateur lui donnera.
C'est à dire que <STDIN> (l'entré standard, le clavier) donnera la valeur de $trad. Tant que vous n'aurez pas entrée un mot ou une ligne le programme sera stoppé car il attend la touche "\n" (Enter) pour valider l'entrée et du même coup la valeur de $trad.
C'est ainsi que l'on questionne l'utilisateur en général . Important donc.

19 chomp $trad;
la ligne 19 va traiter la variable $trad (qui est ce que vous avez entré au clavier + la touche <Enter> (pour valider)) par la fonction chomp qui justement sert à ôter le dernier caractère de la variable si et seulement si ce caractère et un "\n" (saut de ligne retour chariot, c'est à dire la touche Enter qui justement sert à sauter une ligne et à renvoyer le chariot au début de l'autre). Et oui, lorsque vous appuyer sur Enter, vous valider une entrer mais aussi accessoirement vous sauter une ligne et repositionner le chariot sur le début de la suivante. La fonction chomp ôte cette touche si elle est placer en fin de variable. On peut aussi écrire les deux dernière phrase en une seule en tapant:
chomp($trad = <SDTIN>);

récapitulation avant de poursuivre plus avant: voici les lignes que l'on à vu.
01 #!perl –w
02 # *************************************************
03 # remd: petit logiciel de traduction de mot simple anglais->français
04 # et vice versa ainsi qu'une option Edit pour étoffer le dico.
05 # pensez à faire suivre le dico_af-fr.dico dans le même répertoire.
06 # alain adelmar 10 Août 2001. Version 1.02

07 $dico = "dico_uk-fr";
08 # $kk = 0;

09 # lecture du dico******************************************
10 open F, "$dico" or die "Ouverture de dico impossible $!";
11 @traduction = <F>;
12 close F || die "fermeture impossible $!";

13 $x = "x*" x 25;
14 $donc = "\n\tdonc\n";
15 print "\n\n\n$x\n";
16 MENU:print "\nBienvenu sur le petit traducteur tafed\noffert par a_l_a_i_n \/\/ a_d_e_l_m_a_r aadelmar\@free.fr\n";
17 print "Anglais-français(1)\nFrançais-anlais(2)\nAjouter quelques lignes au dico(3)\t\t\treponse: ";
18 $trad = <STDIN>;
19 chomp $trad;
Pour le moment on a défini quelques variables tel que le nom du fichier dico_uk-fr
On l'a ouvert, lu et stocké dans une variable liste @
ouvert le script en donnant un petit topo sur ce qu'il fait ( en guise de commentaire )
On a indiquer aussi au script ou ce trouver le dico (dans $dico)
puis on à afficher le menu de façon à ce que l'utilisateur sache ou appuyer pour avoir ce qu'il veut.
Nous avons aussi récupéré sa réponse $trad que nous avons nettoyé du dernier caractère qui est le "\n" (Enter)
Nous allons voir maintenant comment ouvrir et lire dans le dico, placer son contenu dans une variable liste.
faire comprendre a l'utilisateur que l'on a compris que l'on est bien dans la section qu'il désire.

# menu possible de l'application**************************

if ($trad <= 1) {

print "$donc---- Anglais-français ----\n\n";

$trad = "af";

&le_mot($mota);

&anglais_francais;

}

elsif ($trad == 2) {

print "$donc---- Français-anglais ----\n";

$trad = "fa";

&le_mot($mota);

&francais_anglais($trad);

}

elsif ($trad >= 3) {

print "$donc---- Ajout au Dico perso ----\n";

print "Les lignes que vous ajoutez à votre dico personnel\ndoivent être écritent:\nmot_anglais,mot_français1,mot_francais2,mot_français3|exemple_angl = en_français\n";

print "(ne laisser pas d'espace entre les mots, juste une virgule)\n";

print "on y va? (o/n)\t";

$trad = "ed";

chomp ($repon = <STDIN>);

&oui_non($repon);

&edition($trad);

}

print "\n$x\n";

print "tchao !!!\n$x\n";
 
 

sub anglais_francais {

while ($mota ne "q"){

foreach $ligne(@traduction) {

chomp($ligne);

# laisser comme ça car plus complet

if ($ligne =~ /^$mota/) {

($line, $exemple)= split(/\|/, $ligne);

($angl, $fr, $fr1, $fr2, $fr3) =split(/,/, $line);

print "$angl = $fr\t$fr1\n";

if ($fr2 ne "") {

print "$angl = $fr2\t$fr3\n";

}

if ($exemple ne "") {

print "exemple: $exemple\n";

}

}

}

&choix;

}

# print "tchao !!!\n";

}

sub francais_anglais($trad) {

while ($mota ne "q"){

foreach $ligne(@traduction) {

($line, $exemple)= split(/\|/, $ligne);

($angl, $fr, $fr1, $fr2, $fr3) =split(/,/, $line);

if ($fr =~ /^$mota/) {

print "$fr = $angl\n";

}

if ($fr1 =~ /^$mota/) {

print "$fr1 = $angl\n";

}

if ($fr2 =~ /^$mota/) {

print "$fr2 = $angl\n";

}

if ($fr3 =~ /^$mota/) {

print "$fr3 = $angl\n";

}

}

&choix;

}

# print "tchao !!!\n$x\n";

}

sub edition($trad) {

while(! oui_non($repon)) {

LABEL:print "\nEntrez votre ligne\n";

chomp ($ligne_in = <STDIN>);

($linei, $exemplei)= split(/\|/, $ligne_in);

($angli, $fri, $fr1i, $fr2i, $fr3i) =split(/,/, $linei);

foreach $ligne(@traduction) {

($line, $exemple)= split(/\|/, $ligne);

($angl, $fr, $fr1, $fr2, $fr3) =split(/,/, $line);

if ($angl eq $angli|| $fr eq $fri ) {

print "cette ligne présente des similitudes avec la ligne:\n";

print "$angl = $fr\t$fr1\t$fr2\t$fr3\t$exemple\n";

print "voulez vous quand même entrer votre ligne dans le dico?\n";

$resp = <STDIN>;

chomp $resp;

if ($resp =~ /^n/i) {

print "elle ne sera donc pas intégré à votre dico\n";

goto LABEL;

}

}

}

$ligne_in = "$ligne_in" . "\n";

push @traduction, $ligne_in;

print "on continu? (o/n):\t";

chomp($repon = <STDIN>);

}

open(D, ">$dico") or die "Ouverture de dico impossible $!";

print D @traduction;

close D or die "fermeture impossible $!";

print "Vos lignes ont été rajouté au dictionnaire de traduction $dico\n";

&choix;

}

sub choix {

print "---------- (q) quitte, (m) menu ou un autre mot:\n";

$mota= <STDIN>;

chomp $mota;

if ($mota eq "m") {

goto MENU;

}

}

sub le_mot($mota) {

print "entrer votre mot pour le traduire ou (m) menu ou (q) quitter)\n";

chomp ($mota = <STDIN>);

}

sub oui_non($repon) {

my ($repon) = @_;

$repon =~ tr/A-Z/a-z/;

if ($repon =~ /^o|y/) {

return 0;

}

elsif ($repon =~ /^n/) {

return 1;

}

else {

print "\a";

print "Veuillez repondre par Oui ou par non\n";

chomp ($repon = <STDIN>);

&oui_non($repon);

}

}

END;



lexique:

variable scalaire: une variable scalaire est une variable qui ne contient qu'une information, qu'une valeur. Maintenant cette information, cette valeur peut être faite de plusieurs caractères, mais le tout ne représente qu'une information. On pourrai remplacer scalaire par singulière. Elle est représenté toujours avec un signe $ qui la précéde.
exemple: $s = "sardine";
Dans Perl il y à 3 types de variables prisent en compte: les variables scalaires, les variables listes (ou tableaux) et les variables de hashage.

variable liste ou tableau: une variable liste ou variable tableau est une variable qui contient un liste d'élément, de valeur. Maintenant elle ne peut contenir qu'une valeur (si la liste n'a qu'un élément). Les variable liste appelé aussi variable tableau sont représentés par le signe @ qui les précédent.
exemple: @s = ("s", "a", "r", "d", "i", "n", "e");
ou    $s[0] représentera l'élément "s"
        $s[1] représentera l'élément "a"
etc... jusqu'à
        $#s[-1] qui représentera le dernier élément "e".

variable de hashage: une variable de hashage est une variable qui contient une paire d'élément sous la forme "clé" et "valeur". Ce qui est très pratique.  Les clés et valeurs peuvent être de n'importe quelle nature.
Elle sont représentés par le signe % qui les précédent.
exemple: %s = ("poisson" => "sardine");
ou $s{"poisson"} = "sardine";

une assignation: assigné est le fait de donner une valeur à une variable, le fait de convenir que telle variable ou autre bout de code contiendra une valeur.
exemple: $a = "bonjour";  # on assigne le mot bonjour, la valeur "bonjour" à la variable $a
on peut le faire aussi avec une procédure, une routine, une fonction, un filehandle etc...
exemple: while (! oui-non) {  # qui veut dire tant que la procédure oui-non sera fausse faite

sub oui-non {
    if ($respond =~ /^o|y/) {
      return 1;
      }
    else {
      return 0;
      }
}

la concaténation: c'est le résultat d'une mise en forme calculé. exemple:
print "\nBonjour\n" . "\tle monde\n";
qui donnera une fois interprété, puis ajouté bout à bout:

Bonjour
    le monde

On dit de deux chaînes ou fichiers ajouter l'un à l'autre qu'ils sont concaténés. Pour savoir plus.

filehandle (poignée à fichier, qui sers à attraper un fichier). Un filehandle est la représentation d'une source de donnée, il est toujours sous la forme d'une ou plusieurs lettres et/ou chiffre (ici F pour File, mais on aurai pu l'appelé MYWAY). On se sers d'un filehandle pour toute sortes de raisons, en fait chaque fois que l'on désigne une source de données, comme:
Pour ouvrir un fichier, auquel cas on en profite pour lui assigner sa valeur (l'endroit qu'il désigne, ici "$dico" qui représente le fichier "dico_uk-fr" ):
open F, "$dico"    # que l'on aurez pu écrire aussi:  open F, "dico_uk-fr" ou aussi: open (F, "$dico") les 3 sont compris par Perl.

Pour désigner le contenu du fichier: @fichier = <F>; # se qui signifie que la variable liste @fichier a pour valeur tout le fichier, chaque ligne est un élément de la liste @fichier.   Pratique non?

open (ouvre): la fonction open suivie d'un filehandle de fichier ouvre un fichier. On l'écrit comme ceci:
open F, "$dico" or die "Ouverture de $dico impossible $!"; ou open (F, "$dico") || die "Ouverture de $dico impossible$!";
Perl l'interprétera comme:
Ouvre F, qui représente 'C:\doc\dico_uk-fr' ou arrête tout en affichant l'erreur "Ouverture de C:\doc\dico_uk-fr impossible".
Si l'on avait voulu ouvrir le même fichier mais en (lecture - écriture) on l'aurai indiqué en ajoutant le signe > devant $dico comme:
open F, ">$dico" or die "Ouverture de $dico impossible $!";
auquel cas on pouvaient écrire dedans.
On doit pensez aussi à prévoir les problèmes d'ouvertures et fermetures de fichiers, donc on oriente le <STDERR> vers la fermeture du script suivi d'un message explicatif (ici "Ouverture de $dico impossible "). Pensez à refermer vos fichier, sinon il reste ouvert pendant toute votre session, créant des problèmes et même des bugs sous Windows.

or ou||: les fonctions or et || représente le ou , si tel chose ne peut se faire les instructions après ou sont exécutés.
die (meurs): arrête le script, fini et vide les variables.
le menu c'est quoi?
C'est un éventail de propositions qui va permetre à l'utilisateur d'orienter le programme suivant son choix, ce choix ce fera par le traitement de la reponse de l'utilisateur. En général le menu est traité dans une même procédure


retour en haut de page


précédant | suivant | sommaire