in reply to Re^2: howto accomodate multiple values
in thread howto accomodate multiple values

Ok, finally we get closer to the solution and I can put my chrystal ball back into its box. Now please go back to your code, add use strict; at the top of the script and resolve all the errors that occur. If that doesn't resolve the issues you have (hint: undefined variables), feel free to come back.


Oh, and please use <br> or <br/> and not </br>. That only works in IE and doesn't for those of use who use a real browser.

Thank you.


holli, /regexed monk/

Replies are listed 'Best First'.
I have solved the problem
by aspirado (Initiate) on Dec 28, 2008 at 17:48 UTC
    Hey Holli I have solved the problem myself ;) I am soooo
    happy. Thanks God I have done it and that also myself.
    Anyway thanks for your help and patience to hear me.
    I am really very very happy ;0)
    Actually in my second for loop I was using the name $role
    but in the code below I was using $key instead of $role
    That was the actual mistake. Very simple but blown my mond
    because I was new to Data Structures in Perl.
    Now I have gone through all (hashofhash,
    arrayhash,hasharray and arrayofarray)
    Again I thank you for your patience and help.
      was using the name $role but in the code below I was using $key instead of $role
      If that is all you changed, then you've still got some serious code smells and at least one serious potential bug. See my node above.


      holli, /regexed monk/
        I changed this code
        for my $href ( @AoH ) { for my $role ( sort keys %$href ) { my $key; if ( ! exists $sequences{$key} ) { warn "KEY $key in File1 not found in File2\n"; next; } if ( length( $sequences{$key} ) < $href->{$role} ) { warn "KEY $key: File2 string length too short for File1 positi +on value\n"; next; } my $index = rindex( $sequences{$key}, "TTT", $href->{$role} ); if ( $index < 0 ) { warn sprintf( "KEY %s: No TTT in File2 string prior to positio +n %d\n", $key, $href->{$role} ); next; } $index += 3 while ( ($index + 3) < $href->{$role} ); print "$key $href->{$role} " . substr($sequences{$key}, $index, 3) + . "\n"; }
        with this code
        for my $href ( @AoH ) { for my $key ( sort keys %$href ){ if ( ! exists $sequences{$key} ) { warn "KEY $key in File1 not found in File2\n"; next; } if ( length( $sequences{$key} ) < $href->{$key} ) { warn "KEY $key: File2 string length too short for File1 positi +on value\n"; next; } my $index = rindex( $sequences{$key}, "TTT", $href->{$key} ); if ( $index < 0 ) { warn sprintf( "KEY %s: No TTT in File2 string prior to positio +n %d\n", $key, $href->{$key} ); next; } $index += 3 while ( ($index + 3) < $href->{$key} ); print "$key $href->{$key} " . substr($sequences{$key}, $index, 3) +. "\n"; }
        I am getting exact outputs now ;)
Re^4: howto accomodate multiple values
by aspirado (Initiate) on Dec 28, 2008 at 15:42 UTC
    l use warnings; use strict; my $fh1 = "File1.txt"; my $fh2 = "File2.txt"; open(FH, "$fh1") || die ("Can't open: $!"); my @AoH;
      This is a commented version of your script along with hopefully improved code. I think that will take you further.
      #!/usr/bin/perl use warnings; use strict; use Data::Dumper; my $fh1 = "File1.txt"; my $fh2 = "File2.txt"; #> so far, so good. though in a flexible program at least better writt +en as #> that way you can call it: perl scriptname file1 file2 # my ($position_file, $sequence_file) = @ARGV; open(FH, "$fh1") || die ("Can't open: $!"); my @AoH; #> that's "ok", too. three quirks: - unnecessary quoting. if you mean +the plain value of a variable #> there's no need to quote it ("") - The use of a Filehandle. Best pr +actice are lexical variables for filehandles. #> - variable names: for sake of you own sanity: use DESCRIPTIVE varia +ble names. ALWAYS. #> so: # open(my $file, '<', $position_file) || die ("Can't open $position_fi +le: $!"); # my %positions; while ( <FH> ) { push @AoH, { split /[\s]+/ }; } # this will not do what you think. it creates a hashref from the a +rray split of your positions file # this will trigger the "Odd number of elements in anonymous hash +at ashnator.pl line 12, <FH> line 1." warnings # you want: # Create a hash of arrays of positions # while ( <$file> ) { # my ($key, $pos) = split /\s+/; # if (!$positions{$key}) { # #create array at $key for the first position per key # $positions{$key} = [$pos]; # } else { # # add position for all subsequent lines # my $ref = $positions{$key}; # push @$ref,$pos; # } # } my %sequences; { #> uneccessary block open(FD, "$fh2") || die("Cannot open: $!"); my $key; while (<FD>) { if ( s/^>// ) { $key = ( split /\|/ )[1]; } else { chomp; $sequences{$key} .= $_; } } } #> print Dumper(\%sequences); #> same critics than above, but this time the loop works and i assume +you understand how. for my $href ( @AoH ) { for my $role ( sort keys %$href ) { my $key; # why $key when $role is the loop variable? #> RULE OF THUMB: Think before you copy and paste! #> because the data structure is now a bit different we make this: #> while ( my ($key, $position_list) = each %positions ) #> { #> for my $position ( @$position_list ) #> { #> print "key: $key, position: $position\n"; #> # ... your inner loop code } }
      Update: added @ARGV explanation


      holli, /regexed monk/
      for my $role (sort keys %$href ){ my $key; if (!exists $sequences{$key}){ # line 33
      While $key is declared it is uninitialized which is what Perl is complaining about when it tells you: "use of uninitialized value in exists at sample.pl line 33". Changing each mention of $key to $role gives
      12345 21 GCT 12345 42 CAG 67891 32 GCA
      I can't tell if that is what you were expecting. I would consider choosing a better name for $href.