Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re: How can I get the results in a text file from counting in a string?

by kennethk (Monsignor)
on Aug 07, 2012 at 17:39 UTC ( #986041=note: print w/ replies, xml ) Need Help??


in reply to How can I get the results in a text file from counting in a string?

While there are some cosmetic issues I'd like to raise, the heart of your issue with the posted code is that you have not wrapped your output-to-file call to pos in the same while loop that you wrapped your output-to-screen block. Except, of course, then you try to output them both simultaneously, which is problematic because the first time through, you used two different loops. The following does what (I think) you intend:

#!/usr/bin/perl -w $str="BATCATDATEFEAT"; $A=0;$T=0; while ($str=~ /A/ig) {$A++;# Line 4 print"\n A=$A ends at ",pos $str,"\n";} while ($str=~ /T/ig) {$T++; print"\n T=$T ends at ",pos $str,"\n";} $output="Results .txt"; # Line 8 unless (open(RESULT,">$output")){ print"Cannot open file\"$output\".\n\n"; exit; # Line 11 } # Line 12 $A=0;$T=0; while ($str=~ /A/ig) {$A++;# Line 4 print RESULT "\n A=$A ends at ",pos $str,"\n";} while ($str=~ /T/ig) {$T++; print RESULT "\n T=$T ends at ",pos $str,"\n";} close(RESULT); # Line 17 exit;
with minimal changes to code. Note that this opens a file with a white space in the name, which is likely not what you intended and makes dealing with files generally a bigger pain.

You may want to check out open and die for some more readable code, strict for making debugging easier, and you may want to add line breaks and indents to make flow more obvious. So a cleaner version of this code may look like:

#!/usr/bin/perl -w use strict; my $str="BATCATDATEFEAT"; my $A=0; my $T=0; while ($str =~ /A/ig) { $A++;# Line 4 print "\n A=$A ends at ",pos $str,"\n"; } while ($str =~ /T/ig) { $T++; print"\n T=$T ends at ",pos $str,"\n"; } my $output="Results.txt"; # Line 8 open(my $fh, ">", $output) or die "Cannot open file '$output'.\n\n"; $A=0; $T=0; while ($str=~ /A/ig) { $A++; print $fh "\n A=$A ends at ",pos $str,"\n"; } while ($str=~ /T/ig) { $T++; print $fh "\n T=$T ends at ",pos $str,"\n"; }

#11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.


Comment on Re: How can I get the results in a text file from counting in a string?
Select or Download Code
Re^2: How can I get the results in a text file from counting in a string?
by ww (Bishop) on Aug 07, 2012 at 18:35 UTC
    Good advice, definitely cleaner; ++.

    But why require a second time thru each letter? Print to screen and immediately to file. For some, at least, this may rate as a minor improvement.

    #!/usr/bin/perl use 5.014; # 986041 my $str="BATCATDATEFEAT"; my $A=0; my $T=0; my $output = 'D:/_Perl_/PMonks/986041.txt'; open(RESULT,">>$output") or die "Can't open $output, $!"; while ($str=~ /A/ig) { $A++; # OP's Line 4 print "\n A=$A ends at ",pos $str,"\n"; print RESULT "\n A=$A ends at ",pos $str,"\n"; } while ($str=~ /T/ig) { $T++; print "\n T=$T ends at ",pos $str,"\n"; print RESULT "\n T=$T ends at ",pos $str,"\n"; } close(RESULT); # originally, Line 17 exit; =head execution: C:\>type d:\_Perl_\PMonks\986041.txt A=1 ends at 2 A=2 ends at 5 A=3 ends at 8 A=4 ends at 13 T=1 ends at 3 T=2 ends at 6 T=3 ends at 9 T=4 ends at 14 =cut

    (Perhaps obviously) console gets identical output.

      While I certainly think the code could use dramatic algorithmic improvement, I was attempting to keep the logic as consistent as possible, given the OP's apparent level of familiarity. My actual inclination would be to write it as a single pass, stashing results in a hash, so you could separate the processing and the output. Also reduces duplication of code. But to each their own, premature optimization, and all that jazz.
      #!/usr/bin/perl use 5.014; # 986041 my $str="BATCATDATEFEAT"; my $output = 'Results.txt'; open(my $fh, '>', $output) or die "Can't open $output, $!"; my %spots; while ($str =~ /([AT])/ig) { push @{$spots{uc $1}}, pos $str; } for my $key (keys %spots) { my $i = 0; for my $pos (@{$spots{$key}}) { $i++; my $text = "\n $key=$i ends at $pos\n"; print $text; print $fh $text; } } =head execution: C:\>type Results.txt A=1 ends at 2 A=2 ends at 5 A=3 ends at 8 A=4 ends at 13 T=1 ends at 3 T=2 ends at 6 T=3 ends at 9 T=4 ends at 14 =cut

      #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://986041]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (5)
As of 2014-09-20 22:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (163 votes), past polls