2017-10-27 9 views
-2

Dies ist ein Teil der Arbeit. In diesem Teil versuche ich ein Programm zu schreiben, um einen Hash zu erstellen. Die Schlüssel sind Zugriffsnummern in einer Datei, die Werte sind die gesamten Zeilen. Das Programm warnt mich jedoch. Der Code ist:Wie Sie einem Hash in Perl einen Wert zuweisen

#!/usr/bin/perl 

#psuedocode: 
#open file1, store uniport accesion as key and the line as value 
#open file2, store uniport accesion as key and the line as value which lines contain "IDA" 
#compare keys in two hashes, find out matched keys 
#print out lines from file2 that match 

use strict; 
use warnings; 
use feature qw(say); 

my $infile1 = "geneIDs3_MouseToUniProtAccessions.txt"; 
my $inFH1; 
open ($inFH1, "<", $infile1) or die join (" ", "Can't open", $infile1, "for reading:", $!); 
my @array1 = <$inFH1>; 
close $inFH1; 
shift @array1; 
my %geneID1; 
for ($a = 0; $a < scalar @array1; $a++){ 
    chomp $array1[$a]; 
    $array1[$a] =~ /.*?\t(.*?)\t.*/; 
    $geneID1{$1} = $array1[$a]; 
    #say ("$1", '->', "$geneID1{$array1[$a]}"); #test if the hash has been successfully created, however it doesn't 
    #say $array1[$a];    #test if the program can recognize the elements, it does 
} 

die Datei geneIDs3_MouseToUniProtAccessions.txt enthält 1000 Zeilen, so dass die Warnungen sind zahlreich. Die ersten beiden Zeilen sind:

From To Species Gene Name 
PNMA3 Q9H0A4 Homo sapiens paraneoplastic antigen MA3 

Die Warnung gefällt das:

Use of uninitialized value within %geneID1 in string at match_for_part_III_10.pl line 24. 
Q9H0A4-> 

fand ich die Lösung: Statt while Schleife verwenden. Es funktioniert nicht nur, es ist auch eleganter. Der neue Code ist:

#!/usr/bin/perl 

#psuedocode: 
#open file1, store uniport accesion as key and the line as value 
#open file2, store uniport accesion as key and the line as value which lines contain "IDA" 
#compare keys in two hashes, find out matched keys 
#print out lines from file2 that match 

use strict; 
use warnings; 
use feature qw(say); 

my $infile1 = "geneIDs3_MouseToUniProtAccessions.txt"; 
my $inFH1; 
open ($inFH1, "<", $infile1) or die join (" ", "Can't open", $infile1, "for reading:", $!); 
my %geneID1; 

while (<$inFH1>){ 
    $_ =~ /.*?\t(.*?)\t.*/; 
    $geneID1{$1} = $_; 
    say ("$1", '->', "$geneID1{$1}"); 
} 
close $inFH1; 

Vielen Dank für Ihre unglaubliche Hilfe!

+0

Warnungen = Sie nicht etwas Fall behandeln, wahrscheinlich fehlenden Daten. Warum drucken Sie sie nicht aus und werfen Sie einen Blick darauf. – xxfelixxx

+0

@zdim Andere Teile funktionieren gut. Ich muss '$ a' nicht angeben, bitte lesen Sie den Kommentar von meiner vorherigen Frage https: // stackoverflow.com/questions/46739301/tons-of-use-of-uninitialized-value-innerhalb-genetic-code-in-substitution-iterato –

+0

@ zdim, '$ a 'wird immer deklariert. – ikegami

Antwort

3
#!/usr/bin/perl 

use strict; 
use warnings; 
use feature qw(say); 

<>; # Skip header. 

my %geneID1; 
while (<>) { 
    chomp; 
    my @fields = split /\t/; 
    my $id = $fields[1]; 
    $geneID1{$id} = $_; 
} 

say "$_ => $geneID1{$_}" for sort keys %geneID1; 

(Pass geneIDs3_MouseToUniProtAccessions.txt als Argument.)

+0

Vielen Dank für Ihren Vorschlag. Nachdem ich while loop probiert habe, funktioniert es. Ich habe den neuen Code in meinen ursprünglichen Beitrag eingefügt –

+1

Es ist bedauerlich, dass die Fehler, die ich entfernt habe, wieder hinzugefügt?!? "$ 1" ist Müll, es sei denn, Sie stellen sicher, dass Ihre Übereinstimmung erfolgreich war, und Ihre Regex ist eine schlecht lesbare und langsame Art der Aufteilung auf Tabs. Es ist auch bedauerlich, dass Sie zu einer unflexiblen Schnittstelle zurückgekehrt sind, anstatt den Dateinamen als Argument zu akzeptieren. – ikegami

+1

@ yacc, Sie liegen falsch. Eine fehlgeschlagene Übereinstimmung ändert nicht "$ 1", wie Sie sehen, indem Sie Folgendes ausführen: 'perl -MFunktion = sagen -e'für (qw (abc def)) {/ (b) /; sage $ 1 // "[undef]"; } ''/// Desweiteren wäre die Einstellung' $ 1 'für fehlgeschlagene Übereinstimmungen zu' undef 'tatsächlich eine gute Sache gewesen, und mein Programm tut genau dasselbe (setzt' $ id 'auf' undef ', wenn es keine Tabs gibt). – ikegami

2

Es ist schwer zu sagen, was der Fehler ist, mit Tabs (Registerkarten sind sie?) Und Ändern von Code in der Frage.

Allerdings gibt es viele Elemente in dem Code, der

verbessert werden kann
use warnings; 
use strict; 
use feature 'say'; 

my $file = 'geneIDs3_MouseToUniProtAccessions.txt'; 
open my $fh, '<', $file or die "Can't open $file: $!"; 

my %geneID1; 

my $header = <$fh>;  
while (<$fh>) { 
    chomp; 
    $geneID1{ (split /\t/)[1] } = $_; 
} 

say "$_ => $geneID1{$_}" for sort keys %geneID1; 

Die eine "Wild Card" Ihre Daten sind; Wenn Sie sich nicht sicher sind TAB Zeichen verwenden Sie \s+ (entspricht Tabs auch), da Sie nur das zweite Feld benötigen. Nach split Standardeinstellungen können Sie dann (split)[1] tun.

Kommentare zu den ursprünglichen Code

  • nur eine Datei vor der Zeit lesen, wenn es einen ganz bestimmten Grund für diese

    ist
  • alles erklären, auch wenn einige spezielle Funktion ermöglicht es Ihnen nicht zu ($a)

  • Declare in kleinstem Umfang möglich und in der Nähe, wo sie gebraucht wird: open my $fh, ...

  • Verwenden Sie keine speziellen Variablen wie $a außer für was sie gedacht sind!

  • Es gibt praktisch nie eine Notwendigkeit für eine C-style for Schleife. Wenn Sie Indizes in Iteration benötigen

    foreach my $i (0 .. $#ary) { ... } 
    

    wo $#ary ist der Index des letzten Elements des Arrays @ary

+0

Vielen Dank für Ihren Rat. Ich erkläre '$ inFH1' früh für die Lesbarkeit. Es ist nur mein Stil. Ich weiß nicht, was C-Stil ist, ich lerne einfach programmieren, ich möchte so klar wie möglich sein. –

+0

@WenjiaZhai (1) Mit 'open' gibt es keinen Leistungsvorteil, aber es ist im Allgemeinen besser, genau dort zu deklarieren, wo Sie es brauchen. Wenn es direkt unter "offen" deklariert wird, gibt es nie Verwirrung darüber, wo es hingehört. (2) "C-Style" -Schleife bezieht sich normalerweise auf 'für (my $ i = 0, $ i zdim

+0

@WenjiaZhai Lernen Sie weiter, genießen Sie es :). Finden Sie Ihren Stil (aber beachten Sie auch "gute Praktiken") – zdim