IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

problème avec hachage et traduction des mots


Sujet :

Langage Perl

  1. #1
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2012
    Messages : 30
    Points : 10
    Points
    10
    Par défaut problème avec hachage et traduction des mots
    Bonjour,
    Je voudrais créer un programme qui traduit des phrases tapés par l'utilisateur à l'aide de deux fichiers .txt .

    J'ai crée deux tableaux avec les mots en anglais et en français.
    Après, j'ai utilisé le tableau anglais comme clé et le tableau français comme valeurs dans une hachage.

    Maintenant je voudrais savoir comment je pourrais associer les mots tapés par l'utilisateur aux mots dans l'hachage. Je vous montre mon code.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #!/usr/bin/perl
    use warnings;
    use diagnostics;
    use Data::Dumper;
    $Data::Dumper::Terse = 1;
    $Data::Dumper::Indent = 0;
     
    my ($file_en, $file_fr, $user);
    my (@words, @mots);
    my %diz;
     
    $file_en = "en.txt";
    $file_fr = "fr.txt";
     
    open (EN, "<", $file_en);
    open (FR, "<", $file_fr);
     
    @words = <EN>;
    @mots = <FR>;
     
    @diz{@words} = @mots;
     
     
    print "Say me the word you want to translate\n";
     
     
    while ($user = <STDIN>) {
    	chomp($user);
    	if(defined($diz{$user})) {
    		print "the translation of $user is $diz{$user}\n";
    		}
    	else {
    		print "unknown\n";
    		}
    	print "another word?\n";
    }
    Merci pour l'aide !

  2. #2
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Où est ton problème ?
    A part ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    @words = <EN>;
    @mots = <FR>;
    à remplacer par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    chomp(@words = <EN>);
    chomp(@mots = <FR>);
    ton code à l'air correct. Sans les fichiers de test, difficile de dire ce qui ne va pas (il faut par exemple que les fichiers soient bijectifs).

  3. #3
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2012
    Messages : 30
    Points : 10
    Points
    10
    Par défaut
    avec chomp maintenant ça marche. Pourquoi il faillait l'écrire?

    et si je voulais traduire une phrase entière? Comment il faut le modifier?

    Merci!

  4. #4
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    chomp est une fonction qui supprime les retours à la ligne de fin de chaine. Pour que les mots du dictionnaires soient trouvés, il ne faut pas qu'ils contiennent ces caractères.

    Pour traduire "mot à mot" une phrase, il suffit de découper la phrase en mots (function split avec comme séparateur un motif adapté contenant espaces et ponctuations), traduire chaque mot, et les ré-assembler avec les même séparateurs de mots).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    while ($user = <STDIN>) {
      chomp($user);
      my @word = split /(\W+)/, $user;
      @word = {
        my $word = $_;
        if ($word =~ /\w+/) {
          if (exists $diz{$word}) {
            $word = $diz{$word};
          }
          else {
            $word = "[$word]";
          }
      } @word;
      print join "", @word;
    }
    Les mots non traduit sont mis entre [ ].

    Une remarque par rapport à ton script : utilise exists au lieu de defined pour tester l'existence d'une entrée dans un hash.

  5. #5
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Une remarque qui n'a rien à voir avec Perl.

    Traduire les différents mots d'une phrase est une chose, obtenir une traduction correcte ou même seulement à peu près compréhensible (ou ayant à peu près le sens de la phrase d'origine) en est une autre, très très éloignée.

    Et même simplement traduire les mots d'une phrase peut réserver bien des surprises, car certains mots ne sont clairs (non ambigus) qu'en fonction du contexte.

  6. #6
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2012
    Messages : 30
    Points : 10
    Points
    10
    Par défaut
    Citation Envoyé par Lolo78 Voir le message
    Une remarque qui n'a rien à voir avec Perl.

    Traduire les différents mots d'une phrase est une chose, obtenir une traduction correcte ou même seulement à peu près compréhensible (ou ayant à peu près le sens de la phrase d'origine) en est une autre, très très éloignée.

    Et même simplement traduire les mots d'une phrase peut réserver bien des surprises, car certains mots ne sont clairs (non ambigus) qu'en fonction du contexte.
    Je suis d'accord. ça c'est juste un exercice pour créer un hachage à partir de deux tableaux.

    Quand meme j'ai testé le code que vous m'avez donné et ça ne marche pas (je ne réussis meme pas à le comprendre surtout la partie après ligne 3 )

    Je pensais faire un cicle "while" comme ça en utilisant push et pas split

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while ($user = <STDIN>) {
      chomp($user);
     push @phrase, $user;
     }
    mais après comment je pouirrais dire "prends le mot tapé par l'utilisateur et cherche dans l'hachage pour obtenir la traduction"?

    je pensais quelque chose comme "foreach $element de @phrase, if $element correspond à la clé de %diz, écris la value correspondante".

    Selon vous, ça marche? Comment faut-il l'écrire?

  7. #7
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2012
    Messages : 30
    Points : 10
    Points
    10
    Par défaut
    Voici un exemple de résultat :
    Texte utilisateur : you are a dog
    Texte traduit : Tu es un chien.

    Au cas où il ne trouve un mot ça devient:
    Texte utilisateur : You are a dog
    Texte traduit : You es un chien.


    Avec ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    foreach my $elt (@phrase) {
    	if (exists  ($diz{$elt})) {
    	print "la traduction de $elt est $diz{$elt}\n";
    	}
    	else {
    	print "$elt\n";
    	}
    	$elt++;
    }
    J'arrive à affichier les mots traduits un par un mais pas une phrase...

  8. #8
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    déjà, enlève la ligne:

    qui n'a aucun sens ($elt est un mot, pas un nombre) et, au mieux, ne sert à rien.

    Ensuite, tu peux imprimer tes mots traduits au fur et à mesure en ajoutant un espace, quelque chose comme cela (non testé):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    foreach my $elt (@phrase) {
    	if (exists  ($diz{$elt})) {
    	print "$diz{$elt} ";
    	}
    	else {
    	print "$elt ";
            }
    }
    print "\n";
    L'autre solution est de stocker les mots traduits (ou non traduits, le cas échéant) dans un tableau, puis d'imprimer le contenu du tableau à la fin.

  9. #9
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2012
    Messages : 30
    Points : 10
    Points
    10
    Par défaut
    c'est parfait !
    On m'avait dit qu'il fallait utiliser $elt++ (meme si ça est un mot) pour avancer comme s'il était un "for".

    Vous etes vraiment gentils ! Et j'apprends beaucoup comme ça!
    Quelqu'un qui puisse m'expliquer la fonction de " $_ " dans un script perl ?

  10. #10
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    $_ est la "variable spéciale par défaut" pour les entrées-sorties, de nombreuses fonctions et autres constructions. Le truc est que, comme elle est par défaut, la plupart du temps elle n'apparaît pas là.

    Par exemple, le code que j'ai posté hier soir peut être ré-écrit comme suit en utilisant la variable par défaut:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    foreach (@phrase) { # je n'utilise pas $elt, mais $_ prend successivement comme valeur chaque mot de @phrase
    	if (exists  ($diz{$_})) { # ici, je suis obligé de la mettre
    	print "$diz{$_} "; # là aussi
    	}
    	else {
    	print ; # imprime $_
            }
    }
    print "\n";
    Cette variable sert de valeur par défaut pour de nombreuses fonctions (on n'est donc pas obligé de la mettre), comme print, chomp, uc, lc, exists, defined, split, stat, glob, int, log, sin, cos, chr, ord, eval, length, etc.

    Par exemple, pour découper les lignes d'un fichier en mots (séparés par des espaces), je peux faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while (my $ligne = <$fh>){
         chomp $ligne;
         my @words = split ' ', $ligne;
         # ... code pour travailler sur le tableau @words
    ou simplement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while (<$fh>){
         chomp;
         my @words = split;
         # ... code pour travailler sur le tableau @words

    Elle sert aussi de variable par défaut dans les expressions régulières. Par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while (my $ligne = <$fh>){
         chomp $ligne;
         $ligne =~ s/\s+/ /g; # remplace les espaces multiples par un seul espace
         print $ligne if $ligne =~/toto/; # imprime la ligne si elle contient le mot toto
    }
    peut se réécrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while (<$fh>){
         chomp;
         s/\s+/ /g; # remplace les espaces multiples par un seul espace
         print if /toto/; # imprime la ligne si elle contient le mot toto
    }
    Son rôle dans map, grep, for, foreach est un peu particulier: ces fonctions prennent un tableau en paramètre et effectuent le code spécifié sur $_, qui prend successivement comme valeur chaque élément du tableau.

    Elle est à utiliser avec modération dès que les choses deviennent un peu compliquées.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème avec un switch contenant des strings
    Par dessinateurttuyen dans le forum Langage
    Réponses: 6
    Dernier message: 18/07/2006, 13h56
  2. Réponses: 1
    Dernier message: 22/12/2005, 10h39
  3. [VB Excel] Problème avec le nom automatique des TCD
    Par RedBurn dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 03/12/2005, 14h30
  4. Problème avec une TImageList contenant des grandes images
    Par Manopower dans le forum Composants VCL
    Réponses: 8
    Dernier message: 17/11/2005, 16h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo