"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>


Reply via email to