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 :

hash de hash


Sujet :

Langage Perl

  1. #1
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut hash de hash
    Bonjour à tous,


    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
    	# hash Characteristics[StdInChIKey]
    	# hash de hash, key1 : $Compound and key2 : corresponding $StdInChIKey  (we have to find only one k2 per k1)
    	my %comp_tab;
    	for my $i (1..$#tab){
    		my $Compound = $tab[$i][$Compound_index];
    		my $StdInChIKey = $tab[$i][$StdInChIKey_index];
     
    		next if (($Compound eq '') or ($StdInChIKey eq ''));
    		$Compound = lc($Compound);
    		$comp_tab{$Compound}{$StdInChIKey}++;
    	}
     
    	# check if we have only one K2 : $StdInChIKey per K1 : $Compound
    	foreach my $Compound (keys %comp_tab){
    		my $StdInChIKey_num = (keys %{$comp_tab{$Compound}});
    		if ($StdInChIKey_num > 1){
    			print "ERROR : $rep\t$Compound\n";
    		}
    	}
    J'ai 2 colonnes dans un tableau, $Compound et $StdInChIKey, contenant chacune le même nombres de valeurs.
    Je veux vérifier que pour chaque valeur de Compound, j'ai un StdInChIKey unique.
    Je place donc Compound en première clé du hash, StdInChIKey en seconde clé dans un hash imbriqué.
    Je vérifie ensuite, que pour chaque clé Compound, une seule entrée existe dans StdInChIKey.

    Cela fonctionne très bien, mais je me demandais comment aurais-je pu faire plus simple.
    N'hésiter pas à me poser des question si cela n'est pas clair.

    D'avance merci pour votre aide.
    -- Jasmine --

  2. #2
    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 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Bonjour Jasmine,

    cela me paraît être une bonne manière de faire.

    Toutefois, il serait peut-être possible de simplifier en utilisant un hash simple dont les clés serait des concaténations de $Compound et $StdInChIKey (avec de préférence un séparateur qui ne risque pas de se trouver dans le contenu de ces deux variables, j'ai mis ci-dessous un point-virgule, modifie en fonction de tes données). Quelque chose comme cela (non testé, pas de données):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    	my %comp_tab;
    	for my $i (1..$#tab){     # es-tu sûre que ça ne commence pas à 0?
    		my $Compound = $tab[$i][$Compound_index];
    		my $StdInChIKey = $tab[$i][$StdInChIKey_index];
     
    		next if (($Compound eq '') or ($StdInChIKey eq ''));
    		$Compound = lc $Compound;
    		$comp_tab{"$Compound;$StdInChIKey"}++;
    	}
     
    	# check if we have only one K2 : $StdInChIKey per K1 : $Compound
    	print "ERROR : $rep\t$_\n" for map {my $c = (split /;/)[0]; $c} grep {$comp_tab{$_} > 1;} keys %comp_tab;

  3. #3
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut
    Bonjour Lolo,

    Je te remercie pour ton intervention.

    Par exemple, dans ces 3 $Compound;$StdInChIKey, je veux afficher l'erreur que Chlorobenzene possède 2 StdInChIKey différentes, ce qui est incorrect

    exeemple de clés :
    ---------------------------
    Chlorobenzene;MVPPADPHJFYWMZ-UHFFFAOYSA-N
    Chlorobenzene;GVPFVAHMJGGAJG-UHFFFAOYSA-L
    Diethyl maleate;IEPRKVQEAMIZSS-WAYWQWQTSA-N

    J'aurai donc 2 clés différentes : Chlorobenzene;MVPPADPHJFYWMZ-UHFFFAOYSA-N et Chlorobenzene;GVPFVAHMJGGAJG-UHFFFAOYSA-L
    => chacune avec $comp_tab{$_} == 1 ... si j'ai bien compris ton code, je ne pense pas que cela fera ce que je veux, car elles ne seront pas détectées en tant qu'erreur car elles sont toutes 2 des clés uniques

    Merci et bon week-end,
    -- Jasmine --

  4. #4
    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 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Hum,

    je n'ai donc pas tout compris à ton problème, mais je continue à penser que c'est probablement la solution.

  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 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Bonjour Jasmine,

    je relis attentivement ce que tu cherches à faire, et, si j'ai finalement bien compris à la lumière de ton dernier message, clairement, ce que j'avais proposé n'est pas la solution.

    Je continue à penser, cependant, que le hash de hash, bien que ce soit une solution possible, n'est pas la solution la plus simple et n'est pas indispensable, et qu'un simple hash est sans doute suffisant: dès que tu vois une clef et une valeur, tu la mets dans un hash, dès que tu revois la même clef, tu imprimes un message d'erreur si la valeur est différente, tout cela en une seule passe. Un truc dans ce genre (toujours pas testé, faute de données de test significatives):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    	my %comp_tab;
    	for my $i (1..$#tab){     # es-tu sûre que ça ne commence pas à 0?
    		my $Compound = $tab[$i][$Compound_index];
    		my $StdInChIKey = $tab[$i][$StdInChIKey_index];
    		next if (($Compound eq '') or ($StdInChIKey eq ''));
    		$Compound = lc $Compound;
    		if (exists $comp_tab{$Compound}) {
    			print "ERROR : $rep\t$Compound\n" if  $comp_tab{$Compound} ne $StdInChIKey;   #  je suppose que ce n'est pas une erreur si on trouve deux fois la même valeur
    		} else {
    			$comp_tab{$Compound} = $StdInChIKey;
    		} 
    	}

  6. #6
    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 : 58
    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
    Pour ce genre de besoin, j'utilise à la place un hash de array.
    Il est facile alors de trouver les clés pour lesquelles il y a plusieurs valeurs. Et lorsque la consommation mémoire devient critique (sur de très gros échantillon), j'utilise un hash de (scalaire ou array : scalaire pour le premier éléments, que je transforme en array si un nouvel élément devait être ajouté).
    Et quand la consommation mémoire devient vitale, j'utilise un hash de scalaire (clés de 2e ordre concaténées avec join "\x0" par exemple).

    Exemple hash de array :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    my %std_in_chi_key;
    while (defined(my $compound = <$COMPOUND>)) {
      chomp($compound);
      chomp(my $std_in_chi_key = <$STDINCHIKEY>);
      push @{$std_in_chi_key{$compound}}, $std_in_chi_key;
    }
     
    warn "The following Compound have several StdInChiKeys :", join ", ", grep @{$std_in_chi_key{$_}}>1, keys %std_in_chi_key;
    (attention, j'ai testé ce code très rapidement).

    Si tu es intéressé par les deux autres approches, je peux développer.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  7. #7
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut
    Bonjour à vous deux,

    Merci pour vos réponses, je ne vous oublie pas, dès que j'ai un peu de temps, j'y reviens.
    Pour les données à tester, si cela peut vous aider, ce sont tous les fichiers 's_Study.txt' de chaque répertoire de ftp://ftp.ebi.ac.uk/pub/databases/mi...a/NTC/archive/.

    Bonne journée,

    Jasmine.


    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
    #!/usr/bin/perl
     
    use strict;
    use warnings;
     
    use List::Compare;
    use List::MoreUtils qw(firstidx singleton);
    use Data::Dumper;
     
     
    ...
     
     
     
                    # array de array contenant toutes les valeurs
    		# dont la premiere liste possede les en-tetes
    		# un tableau pour chacun des 2 fichiers a fusionner
    		my @tab1;
     
    			open(DATA,$file1) or die "Couldn't open file, $!"; 
    			while (my $l = <DATA>){ 
    				chomp($l);
    				 # ligne non vide
    				 if ($l =~ m/^\w/){
    					my @val = split /\t/, $l ; 
    					push @tab1, \@val;
    				 }
    				 else{
    					print "ERROR F1 $file1 >> $l\n";
    				 }
    			close(DATA);			
    # check the correspondances of Factor Value[Compound]	and Characteristics[StdInChIKey]
    chemical_correspondences  ($rep, 's_', \@tab1);


    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    sub chemical_correspondences {
     
    	my $rep  = $_[0];
    	my $file_type = $_[1];
    	my $ref_tab = $_[2];
     
    	my @tab = @{$ref_tab};
     
    	# first line of file, headers names in @{$tab1[0]} Value[Compound]	and Characteristics[StdInChIKey]
    	# firstidx { $_ == 4 } @list;  Returns the index of the first element in LIST for which the criterion in BLOCK is true. 
    	my $Compound_index = firstidx { $_ =~ /Value\[Compound\]/} @{$tab[0]};
    	my $StdInChIKey_index = firstidx { $_ =~ /Characteristics\[StdInChIKey\]/} @{$tab[0]};
     
    	# hash de hash, key1 : $Compound and key2 : corresponding $StdInChIKey  (we have to find only one k2 per k1)
    	my %comp_tab;
     
    	# hash de hash, key1 : $StdInChIKey and key2 : corresponding $Compound  (we have to find only one k2 per k1)	
    	my %StdInChIKey_tab;
     
    	for my $i (1..$#tab){
    		my $Compound = $tab[$i][$Compound_index];
    		my $StdInChIKey = $tab[$i][$StdInChIKey_index];
     
    		next if (($Compound eq '') or ($StdInChIKey eq '') or ($StdInChIKey eq 'NA'));
    		$Compound = lc($Compound);
    		$comp_tab{$Compound}{$StdInChIKey}++;
    		$StdInChIKey_tab{$StdInChIKey}{$Compound}++;
    	}
     
    	# check if we have only one K2 : $StdInChIKey per K1 : $Compound
    	foreach my $Compound (keys %comp_tab){
    		my $StdInChIKey_num = (keys %{$comp_tab{$Compound}}); 
    		if ($StdInChIKey_num > 1){ 
    			print "ERROR 1\t$rep\t$Compound\t$StdInChIKey_num different InChIKey\n";
    		}
    	}
     
    	# check if we have only one K2 : $Compound per K1 : $StdInChIKey
    	foreach my $StdInChIKey (keys %StdInChIKey_tab){ 
    		my $Compound_num = (keys %{$StdInChIKey_tab{$StdInChIKey}}); 
    		if ($Compound_num > 1){
    			print "ERROR 2\t$rep\t$StdInChIKey\t$Compound_num different coumpound names\n";
    		}
    	}
     
    }
    nb :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	my $rep  = $_[0];
    	my $file_type = $_[1];
    accessoires pour tester le code, pour l'affichage (et que je retrouve l'origine des données), peuvent être supprimés
    -- Jasmine --

  8. #8
    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 : 58
    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
    J'ai écrit un petit script qui parcours ton dossier FTP et fait les analyses pour tous les fichiers study.
    Il montre des tas d'erreurs. Je pense qu'il faudrait que tu jettes un oeil si c'est correct.

    Le script nécessite les modules WWW::Mechanize et Mojo::DOM (j'aurais pu faire plus simple, mais bon ...)
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #!/usr/bin/perl
     
    use strict;
    use warnings;
    use feature qw(:5.10);
     
    use WWW::Mechanize;
    use Mojo::DOM;
     
    sub analyse_study($) {
      my ($study) = @_;
     
      local $/ = "\r\n";
     
      my @cols = ("Factor Value[Compound]", "Characteristics[StdInChIKey]");
      open my $STUDY, "<", \$study;
      my ($header, %header) = (0);
      my $h = <$STUDY>;
      $header{$_} = $header++ foreach map { chomp ; $_ } split /\t/, $h;
      my %std_in_chi_key;
      foreach my $line (<$STUDY>) {
        chomp($line);
        my ($compound, $std_in_chi_key) = (split /\t/, $line)[@header{@cols}];
        push @{$std_in_chi_key{$compound}}, $std_in_chi_key;
        #say "Compound=$compound std_in_chi_key=$std_in_chi_key";
      }
      if (my @duplicated = grep @{$std_in_chi_key{$_}}>1, keys %std_in_chi_key) {
        say "The following Compound have several StdInChiKeys:\n",
          join "\n", map { "  $_: @{$std_in_chi_key{$_}}" } @duplicated;
      }
    }
     
    my $mech = WWW::Mechanize->new();
     
    my $ftp_root = "ftp://ftp.ebi.ac.uk/pub/databases/microarray/data/dixa/NTC/archive/";
    $mech->add_header("Accept" => "text/html");
    $mech->get($ftp_root);
    if ($mech->success()) {
      my $root_dir = Mojo::DOM->new($mech->content);
      foreach my $dir_url ($root_dir->find("a")->attr("href")->each) {
        say "Looking in $dir_url";
        $mech->get("$ftp_root/$dir_url/s_Study.txt");
        analyse_study($mech->content);
      }
    }
    else {
      die "Can't access to $ftp_root\n";
    }
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  9. #9
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut
    Bonjour Philou,

    Puis-je utiliser Mojo::DOM sur un windows 64 ... dans le fichier readme, il est écrit qu'il est portable

    Merci,

    Jasmine.
    -- Jasmine --

  10. #10
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut
    Citation Envoyé par Philou67430 Voir le message
    Pour ce genre de besoin, j'utilise à la place un hash de array.
    Il est facile alors de trouver les clés pour lesquelles il y a plusieurs valeurs. Et lorsque la consommation mémoire devient critique (sur de très gros échantillon), j'utilise un hash de (scalaire ou array : scalaire pour le premier éléments, que je transforme en array si un nouvel élément devait être ajouté).
    Et quand la consommation mémoire devient vitale, j'utilise un hash de scalaire (clés de 2e ordre concaténées avec join "\x0" par exemple).

    Exemple hash de array :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    my %std_in_chi_key;
    while (defined(my $compound = <$COMPOUND>)) {
      chomp($compound);
      chomp(my $std_in_chi_key = <$STDINCHIKEY>);
      push @{$std_in_chi_key{$compound}}, $std_in_chi_key;
    }
     
    warn "The following Compound have several StdInChiKeys :", join ", ", grep @{$std_in_chi_key{$_}}>1, keys %std_in_chi_key;
    (attention, j'ai testé ce code très rapidement).

    Si tu es intéressé par les deux autres approches, je peux développer.
    J'ai compris l'idée de hash de array, ici j'ai un petit échantillon ça devrait suffir. Mais, j'essaie de bien comprendre les autres idées, ça peut servir plus tard.
    Un hash de scalaire, c'est juste un hash .... $hash{k}= 'val1\x0val2\x0val3\x0val4';
    Pourquoi \x0 ?



    Merci
    -- Jasmine --

  11. #11
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut
    Bonjour Lolo,


    Citation Envoyé par Lolo78 Voir le message
    Bonjour Jasmine,

    je relis attentivement ce que tu cherches à faire, et, si j'ai finalement bien compris à la lumière de ton dernier message, clairement, ce que j'avais proposé n'est pas la solution.

    Je continue à penser, cependant, que le hash de hash, bien que ce soit une solution possible, n'est pas la solution la plus simple et n'est pas indispensable, et qu'un simple hash est sans doute suffisant: dès que tu vois une clef et une valeur, tu la mets dans un hash, dès que tu revois la même clef, tu imprimes un message d'erreur si la valeur est différente, tout cela en une seule passe. Un truc dans ce genre (toujours pas testé, faute de données de test significatives):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    	my %comp_tab;
    	for my $i (1..$#tab){     # es-tu sûre que ça ne commence pas à 0?
    		my $Compound = $tab[$i][$Compound_index];
    		my $StdInChIKey = $tab[$i][$StdInChIKey_index];
    		next if (($Compound eq '') or ($StdInChIKey eq ''));
    		$Compound = lc $Compound;
    		if (exists $comp_tab{$Compound}) {
    			print "ERROR : $rep\t$Compound\n" if  $comp_tab{$Compound} ne $StdInChIKey;   #  je suppose que ce n'est pas une erreur si on trouve deux fois la même valeur
    		} else {
    			$comp_tab{$Compound} = $StdInChIKey;
    		} 
    	}
    Oui, cela commence bien à 1 car 0 est la première ligne du fichier, les en-tête de colonne que je veux passer (mais dont j'ai eu besoin antérieurement)
    Cette idée effectue ce que je veux.


    Merci.
    -- Jasmine --

  12. #12
    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 : 58
    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
    Citation Envoyé par Jasmine80 Voir le message
    Bonjour Philou,

    Puis-je utiliser Mojo::DOM sur un windows 64 ... dans le fichier readme, il est écrit qu'il est portable

    Merci,

    Jasmine.
    Je pense que oui, même si je n'ai pas testé avec Strawberry. Je l'ai testé sur Windows64 et Cygwin/perl.
    J'ai utilisé Mojo::DOM et WWW::Mechanize car j'avais une erreur en utilisant WWW::Mechanize::Query (qui regroupe les deux). J'ai mis à jour WWW::Mechanize::Cached et WWW::Mechanize, et à présent, ça fonctionne parfaitement avec WWW::Mechanize::Query.

    As-tu testé le script ?

    Citation Envoyé par Jasmine80 Voir le message
    J'ai compris l'idée de hash de array, ici j'ai un petit échantillon ça devrait suffir. Mais, j'essaie de bien comprendre les autres idées, ça peut servir plus tard.
    Un hash de scalaire, c'est juste un hash .... $hash{k}= 'val1\x0val2\x0val3\x0val4';
    Pourquoi \x0 ?
    Merci
    \x0 est un caractère séparateur que je suis sûr de ne trouver dans aucune autre chaine de caractères. Par ailleurs, il est utile si l'on utiliser pack/unpack avec le format Z*. Pour des applications de Text Mining qui traitent des volumes gigantesques de données, je créé des structures de données dans des chaines de caractères compactées avec pack/unpack, et pour les strings, j'utilise le format Z*. Ça permet de gagner énormément de mémoire par rapport à une structure de données sous forme d'un hash. Ici, dans ton cas, le join/split est plus pratique.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  13. #13
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut
    Citation Envoyé par Philou67430 Voir le message
    As-tu testé le script ?
    Non, j'attendais ta réponse avant d'installer Mojo::DOM, je vais plutôt installer WWW::Mechanize::Query.

    Merci.
    -- Jasmine --

  14. #14
    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 : 58
    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
    L'installation de WWW::Mechanize::Query installera automatiquement Mojo::DOM

    Le script dans cette version :
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #!/usr/bin/perl
     
    use strict;
    use warnings;
    use feature qw(:5.10);
     
    use WWW::Mechanize::Query;
    #use Mojo::DOM;
     
    sub analyse_study($) {
      my ($study) = @_;
     
      local $/ = "\r\n";
     
      my @cols = ("Factor Value[Compound]", "Characteristics[StdInChIKey]");
      open my $STUDY, "<", \$study;
      my ($header, %header) = (0);
      my $h = <$STUDY>;
      $header{$_} = $header++ foreach map { chomp ; $_ } split /\t/, $h;
      my %std_in_chi_key;
      foreach my $line (<$STUDY>) {
        chomp($line);
        my ($compound, $std_in_chi_key) = (split /\t/, $line)[@header{@cols}];
        push @{$std_in_chi_key{$compound}}, $std_in_chi_key;
        #say "Compound=$compound std_in_chi_key=$std_in_chi_key";
      }
      if (my @duplicated = grep @{$std_in_chi_key{$_}}>1, keys %std_in_chi_key) {
        say "The following Compound have several StdInChiKeys:\n",
          join "\n", map { "  $_: @{$std_in_chi_key{$_}}" } @duplicated;
      }
    }
     
    my $mech = WWW::Mechanize::Query->new(-ignore_cache => 1);
     
    my $ftp_root = "ftp://ftp.ebi.ac.uk/pub/databases/microarray/data/dixa/NTC/archive/";
    $mech->add_header("Accept" => "text/html");
    $mech->get($ftp_root);
    if ($mech->success()) {
      #my $root_dir = $mech->dom; #Mojo::DOM->new($mech->content);
      foreach my $dir_url ($mech->find("a")->attr("href")->each) {
        say "Looking in $dir_url";
        $mech->get("$ftp_root/$dir_url/s_Study.txt");
        analyse_study($mech->content);
      }
    }
    else {
      die "Can't access to $ftp_root\n";
    }
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  15. #15
    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 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Jasmine80 Voir le message
    Un hash de scalaire, c'est juste un hash
    Oui, effectivement.

    En fait, un hash ne peut contenir que des scalaires, et rien d'autre.

    Mais ces scalaires peuvent être de simples chaînes de caractères ou des nombres (c'est alors un hash simple) ou peuvent être des références vers des tableaux ou d'autres hash, et on parle lors (de façon un peu abusive mais très parlante) de hash de tableaux ou de hash de hash.

  16. #16
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut
    Citation Envoyé par Philou67430 Voir le message
    L'installation de WWW::Mechanize::Query installera automatiquement Mojo::DOM

    Le script dans cette version :
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #!/usr/bin/perl
     
    use strict;
    use warnings;
    use feature qw(:5.10);
     
    use WWW::Mechanize::Query;
    #use Mojo::DOM;
     
    sub analyse_study($) {
      my ($study) = @_;
     
      local $/ = "\r\n";
     
      my @cols = ("Factor Value[Compound]", "Characteristics[StdInChIKey]");
      open my $STUDY, "<", \$study;
      my ($header, %header) = (0);
      my $h = <$STUDY>;
      $header{$_} = $header++ foreach map { chomp ; $_ } split /\t/, $h;
      my %std_in_chi_key;
      foreach my $line (<$STUDY>) {
        chomp($line);
        my ($compound, $std_in_chi_key) = (split /\t/, $line)[@header{@cols}];
        push @{$std_in_chi_key{$compound}}, $std_in_chi_key;
        #say "Compound=$compound std_in_chi_key=$std_in_chi_key";
      }
      if (my @duplicated = grep @{$std_in_chi_key{$_}}>1, keys %std_in_chi_key) {
        say "The following Compound have several StdInChiKeys:\n",
          join "\n", map { "  $_: @{$std_in_chi_key{$_}}" } @duplicated;
      }
    }
     
    my $mech = WWW::Mechanize::Query->new(-ignore_cache => 1);
     
    my $ftp_root = "ftp://ftp.ebi.ac.uk/pub/databases/microarray/data/dixa/NTC/archive/";
    $mech->add_header("Accept" => "text/html");
    $mech->get($ftp_root);
    if ($mech->success()) {
      #my $root_dir = $mech->dom; #Mojo::DOM->new($mech->content);
      foreach my $dir_url ($mech->find("a")->attr("href")->each) {
        say "Looking in $dir_url";
        $mech->get("$ftp_root/$dir_url/s_Study.txt");
        analyse_study($mech->content);
      }
    }
    else {
      die "Can't access to $ftp_root\n";
    }
    Merci Philou. J'obtiens ces 2 messages d'erreur :
    Unrecognized LWP::UserAgent options: -ignore_cache at (eval 52) line 56.
    Can't locate object method "attr" via package "Mojo::Collection" at Mechanize_Query.pl line 40.
    -- Jasmine --

  17. #17
    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 : 58
    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
    J'avais également ce genre d'erreur : j'ai dû mettre à jour les modules liés à WWW::Mechanize :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cpan
    cpan[1]> upgrade /WWW::Mechanize/
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  18. #18
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut
    Citation Envoyé par Philou67430 Voir le message
    J'avais également ce genre d'erreur : j'ai dû mettre à jour les modules liés à WWW::Mechanize :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cpan
    cpan[1]> upgrade /WWW::Mechanize/
    Voila, la mise à jour a été effectuée, j'ai un message me disant que tout est bien à jour ... mais toujours le même message d'erreur en effectuant le code perl que tu m'as donné. As-tu une autre idée d'où ça pourrait venir ? Peut-être mettre aussi à jour Mojo::DOM.
    -- Jasmine --

  19. #19
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut
    Nom : error.png
Affichages : 136
Taille : 5,0 Ko
    -- Jasmine --

  20. #20
    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 : 58
    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
    Je serai offline à partir de midi, et ce jusqu'à lundi matin.
    Désolé.
    Je regarde lundi matin avec strawberry
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

Discussions similaires

  1. Parcours d'un hash de hash de hash
    Par ngere dans le forum Langage
    Réponses: 5
    Dernier message: 06/07/2005, 09h53
  2. Réponses: 6
    Dernier message: 05/07/2005, 11h05
  3. Réponses: 2
    Dernier message: 09/03/2005, 14h35
  4. [langage] hash de hash
    Par Kinethe dans le forum Langage
    Réponses: 17
    Dernier message: 27/08/2004, 13h22
  5. [langage] probleme avec un hash de hash
    Par planetevoyage dans le forum Langage
    Réponses: 4
    Dernier message: 06/06/2003, 12h55

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