> >>>>> "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
> ---------
Thanks for the explanations. This really cleaned up my code. Do you think you
could explain to me how to get
my dist sub routine to work correctly? I am very new to perl so please forgive
my ignorance.
I am getting the following errors.
syntax error at ./DOband1.pl line 12, near "$record{dist"
syntax error at ./DOband1.pl line 12, near "13)"
Execution of ./DOband1.pl aborted due to compilation errors.
My updated code is on the bottom.
#!/usr/bin/perl
use warnings;
use strict;
use File::Slurp;
my $filepath = 'C:/temp/PCMD';
my $output = 'output.txt';
sub Dist {
my $record{dist}+13)/6.6/8/2*10)/10 # I'm am not sure how to handle this.
}
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, my $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) ;
--
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
http://learn.perl.org/