"N, Guruguhan (GEAE, Foreign National, EACOE)" wrote:
> Hi All,
> I have written a perl code for filtering data contained in a file
> ($input_file_name) based on the filter expression($expr). While doing this, I face
> some problems. When I hard code the arrays @data and @col
> ( in red color)
Please don't do that. HTML is filtered out of postings to this list, so anything that
relies on markup will be lost.
> in the code, I am getting the results. But the moment I get the arrays @col and
> @data based on the user input file ($input_file_name) inside the "if" loop, there is
> no filter. The reason is @data array inside the "if" loop (red colored) when
> accessed outside has only one value and that doesn't satisfy the filter expression.
> Then I changed it look like the one given in blue color. Now I don't know how should
> I modify
> 1. the sub routine sub filterdata
> 2. my @result array
> 3. print join function
> All the three are highlighted in blue color.
>
> Can some one please suggest me what changes I have to do, so that I can get the
> results? Any help in this regard is solicited.
>
>
> #! /usr/bin/perl -w
> use strict; #- matter of style
Yes--do use strict, and no--it is not just amatter of style.
> use warnings; #- and again
Likewise as above. Not just a matter of style, but a critical necessity if you wish
to learn how to write solid, orbust programs in Perl.
>
>
> my (@col,@data,$input_file_name,@temp,$header,$data_line,$i);
Don't do this. Declaring all your variables in an unrelated lump defeats the purpose
of using strict. Declare your variables as close as possible to the place where they
are initialized.
>
> $input_file_name= "MC_data.dat";
>
> if (-s $input_file_name ) {
> open(INPUT, $input_file_name) || die "Cannot open: \nReason: $!\n";
Don't indent here. Indentation should mark execution blocks. The flow of execution
does not change here, so all lines within this if statement should be vertically
aligned.
>
> @temp = <INPUT> ;
Here is your immediate problem. The line above puts the first line of the file into
the first element of @temp. If you must dump all your data into an array, then you
will have to put the input operation into list context by enclosing it in parentheses:
@temp = (<INPUT>);
>
> chomp @temp;
> $header = shift(@temp);
> $header =~ s/^\s+(.*)/$1/; #Remove the leading white spaces
> @col = split /\s+/, $header;
>
> foreach $i ( 0 .. $#temp ) {
Do indent here. Everything within this for loop should be indented by however many
spaces you are using as standard indentation. Indent after the opening brace.
Unindent the line that holds the closing brace.
perldoc perlstyle
>
> $data_line = $temp[$i];
> $data_line =~ s/^\s+(.*)/$1/; #Remove the leading white spaces
> @data = split /\s+/, $data_line;
@data, huh? Is there anything you would be processing that is not data?!? Use
variable names that mean something.
>
> $data[$i] = split /\s+/, $data_line;
> }
> }
>
> @col = qw (RUN a1 a2 a3 weight sig1 sig2 sig3);
>
> @data=(
> [qw( 1 0.200000 0.200000 0.200000 0.765685 75881.9
> 29289.3 -46592.6)],
Why qw? These all look like numbers to me. Much more clear to write:
[1, 0.2, 0.2, 0.2, 0.765685, 75881.9, 29289.3, -46592.6],
Unless there is some very good reason why these *must* be stored as character strings
rather than numbers.
>
> [qw( 2 0.200345 0.200000 0.200345 0.966661 75766.0
> 29268.4 -46497.6)],
> [qw( 3 0.200000 0.200345 0.200000 0.766030 75867.1
> 29259.8 -46607.4)],
> [qw( 4 0.359575 0.253987 0.359575 1.271019 43898.7
> 19675.6 -24223.1)],
> [qw( 5 0.359921 0.253987 0.359921 1.271995 43861.3
> 19666.1 -24195.2)]
> );
>
> map
What array is being assigned the return value of map? If you are not trying to return
an array, map is not an appropriate tool. You should probably be using a for loop to
iterate through the array.
> { my $i=$_;
What are you doing with $r? Where are you using it? Please don't assign things to
variables that then vanish into thin air.
> no strict 'refs'; *{"filter::$col[$i]"} = sub{$_->[$i]} }
This probably does something. It's really not worth it to try to figure out what,
though. Do you understand what it is doing? If you do not, then don't use it. Hint:
if you have to turn strict off, you probably are doing something that will be
undependable.
Calling well-constructed subroutines is much more simple and clear than this
filterdata($validation_function_ref, @lines_to_be_tested);
>
> 0..$#col;
>
> sub filterdata
> {
> my $cref=shift;
> grep &$cref,@_
> }
>
> sub filterspec
> {
> my $e = shift;
> map{ $e =~ s/\b$_\b/filter::$_()/g } @col;
> eval "sub{ $e }"
> }
>
> my $expr = "weight < 1.2 && sig1 > 75800";
>
> my $filter_handler = filterspec( $expr ) or die $@;
>
> my @result = filterdata ($filter_handler,@data);
>
> print join("$/",map{join(" ",@$_)[EMAIL PROTECTED]).$/;
> Thanks
> Regards
> Guruguhan
> EACoE, India.
Overall, I would recommend that you back up a few paces, and work on one coding
concept at a time. You seem to have trouble even with one-dimensional arrays. You
should do more exercises with simple arrays, and get a better understanding of the way
they work, before you try to tackle more complicated structures.
Remember--if it is hard for a human to make sense of, it is even less likely that a
compiler will understand it. Write for clarity.
Joseph
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>