>>>>> "CS" == Chris Stinemetz <[email protected]> writes:
CS> Thanks Chris
CS> I am trying to build a sub routine that computes the following equation
CS> When $data[262] has the value of 1
CS> Take the value of $data[261] and return the solution of:
$data[261]+13)/6.6/8/2*10)/10
CS> When I call the sub routine before I push the array I would like
CS> to return the value in 0.1 decimal.
that makes no sense. a floating number is just what it is. only when
printing it does counting decimal places make sense.
CS> use warnings;
CS> use strict;
CS> my $filepath = 'C:/temp/PCMD';
CS> my $outfile = 'output.txt';
CS> open my $fh, '<', $filepath or die "ERROR opening $filepath: $!";
CS> open my $out, '>', $outfile or die "ERROR opening $outfile: $!";
CS> my @array = ();
CS> while (<$fh>){
better to assign the line to a variable. using $_ all the time isn't a
great idea for several reasons. the topmost one is that named variables
make the program more readable.
CS> next unless /;/;
CS> chomp;
CS> my @data = split /;/;
CS> my($cell,$sect,$chan,$carr,$dist,$precis) =
($data[31],$data[32],$data[38],$data[39],$data[261],$data[262]);
use a slice to save typing and eyestrain. you can access multiple
array/hash elements at one time:
my($cell,$sect,$chan,$carr,$dist,$precis) = @data[31,32,38,39,261,262];
CS> if ($data[38] == 15)
why are you using @data again when you just assigned 38 to $chan? use
the scalar so it makes more sense to the reader.
rule: always write code so the reader will understand it.
CS> {
CS> $data[39] = 2;
CS> } else {
CS> $data[39] = 1;
CS> }
again, use the scalar. and i don't see $data[39] used anywhere else so
that assignment is lost. also use the conditional expression. that whole
thing reduces to this:
$carr = ( $chan == 15 ) ? 2 : 1 ;
also since you are overwriting $chan there, you don't need it in the
slice above. $carr can be declared right here too.
CS> if( length($data[261]) >
12)
CS> {
CS> $dist =
getDist;
CS> }
CS> else
CS> {
CS> $dist =
"";
CS> }
ditto here.
my $dist = ( length( $dist ) > 1 ) ? getDist() : '' ;
CS> push @array, {
don't name arrays, @array. pick a name that describes the data in it.
CS> cell => $cell,
CS> sect => $sect,
CS> carr => $carr,
CS> RTD => $RTD,
where does $RTD come from? i don't see it anywhere else so it will fail
under strict.
CS> };
CS> }
CS> my @sorted = map { $_->[0] }
CS> sort {
CS> $a->[1] <=> $b->[1]
CS> || $a->[2] <=> $b->[2]
CS> || $a->[3] <=> $b->[3]
CS> }
CS> map { [ $_, $_->{cell}, $_->{sect}, $_->{carr} ]}
CS> @array;
gack. i won't even address that now. but look at Sort::Maker on cpan for
an easier and more descriptive way to sort complex things.
also since you already have the values in a hash, there is no reason to
assign them to an array in there.
CS> for my $tuple ( @sorted ){
CS> print "$tuple->{cell} $tuple->{sect} $tuple->{carr} $tuple->{RTD}\n";
CS> }
slice to the rescue again:
print join( ' ', @tuple{ qw( cell sect carr RTD ), "\n" ;
CS> for my $tuple ( @sorted ){
CS> print $out "$tuple->{cell} $tuple->{sect} $tuple->{carr}
$tuple->{RTD}\n";
CS> }
CS> close $out;
but why print the same thing twice? store the string in a var, and then
print to both places. or even better, use File::Slurp and simplify.
here is a complete rewrite (untested):
use warnings;
use strict;
use File::Slurp ;
my $filepath = 'C:/temp/PCMD';
my $outfile = 'output.txt';
my %cols = (
cell => 31,
sect => 32,
chan => 38,
dist => 261,
precis => 262,
) ;
my @records ;
my @lines = read_file( $filepath ) ;
chomp @lines ;
foreach my $line ( @lines ) {
next unless $line =~ /;/ ;
my %record ;
# this gets just what you want into a hash using a hash slice and an
# array slice. the order of keys and values will be the same for any
# given hash
@record{ keys %cols } = (split /;/, $line)[ values %cols ] ;
$record{carr} = ( $record{chan} == 15 ) ? 2 : 1 ;
$record{dist} = ( length( $record{dist}) > 1 ) ? getDist() : '' ;
push( @records, $record ) ;
}
my @sorted = sort {
$a->{cell} <=> $b->{cell} ||
$a->{sect} <=> $b->{sect} ||
$a->{carr} <=> $b->{carr}
} @records ;
my @report = map "@{$_{ keys %cols }}\n", @records ;
print @report ;
write_file( $output, @report ) ;
now isn't that a lot cleaner? some parts (all the slicing) may take a
little understanding but that isn't too hard.
uri
--
Uri Guttman ------ [email protected] -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
--
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
http://learn.perl.org/