Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Help needed on script! 2

Status
Not open for further replies.

Captainrave

Technical User
Nov 16, 2007
97
GB
Basically I read two files into a script:
The big file has "big" values like -
100 1000
1200 1600
1700 2050 ...

The small file with values like-
5 15
120 125

I wrote a script which finds any small value located within the big values...then for any match it is supposed to output all the values. It is also meant to perform a calculation of exactly WHERE the small value lies in the big value (in the form of a percentage). But it doesn't work:

Code:
use strict;
use warnings;

open(OUTPUT,"newfile.csv");

open BIG, 'big values.xls' or die "$!";
my @big = map {[split/\s+/]} <BIG>;
close BIG;

open SMA, 'small values.csv' or die "$!";
LOOP: while (<SMA>) {
   my ($s,$e) = split(/\,/);
   foreach my $array (@big) {
      if ($s >= $array->[0] && $e <= $array->[1]) {
         calculate($s,$e,$array->[0],$array->[1],$.);
         next LOOP;
      }
   }
}
close SMA;
close OUTPUT;


sub calculate {
   my ($small_start, $small_end, $big_start, $big_end, $line_num) = @_;
   my $calculation = ( ( ($big_start/$big_end) / ($small_start/$small_end) ) * 100 );
   print OUTPUT "small_start,$small_end,$big_start,$big_end,$calculation,/n";
}

I have no idea why it doesnt work, and I need help! If it isnt obvious why it isnt working, can someone show me how I could literally JUST output the matches found. I could dfo the calculations in excel!

Hope that makes sense! HELP!!!!
 
You are not opening [tt]OUTPUT[/tt] for output: [tt]open(OUTPUT,">newfile.csv");[/tt].
To test the program use [tt]print "$small_start,$small_end,$big_start,$big_end,$calculation,/n";[/tt] in the sub and you'll see your results on the screen (notice also that other mistake in red!).
Note that it is bad practice to use in a sub a handle that's opened in the main.

Franco
: Online engineering calculations
: Magnetic brakes for fun rides
: Air bearing pads
 
Try putting a chomp @big; in there and another chomp; after the read of SMA. The extra newlines are probably screwing up your comparisons.

You might want to print the parameters to the subroutine on the console as an interim debugging aid - just now you are missing a $ at the start of the print statement. And I haven't worked out what the purpose of passing the line number is, but it would be a good idea to print that too, at least for debugging...

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Cheers, that has certainly fixed a few problems (without chomp). Although the output needs rearranging, so I suspect chomp is required. However after:

open BIG, 'big values.xls' or die "$!";

I put chomp @big (same for SMA)...but I get an error:

"Variable "@BIG" is not imported and the script wont run. Why is that?
 
Ok I have changed this around, the files are now like:

The big file has "big" values-
100 1000
1200 1600
1700 2050 ...

The small file with values-
TTTTT 5 15
AAAAAA 120 125 ...

Code:
use strict;
use warnings;

open(OUTPUT,"+>outputname.csv");

open BIG, 'bigfilename.xls' or die "$!";
my @big = map {[split/\s+/]} <BIG>;
close BIG;

open SMA, 'smallfilename.csv' or die "$!";
LOOP: while (<SMA>) {
   my ($c,$s,$e) = split(/\,/);
   foreach my $array (@big) {
      if ($s >= $array->[0] && $e <= $array->[1]) {
         calculate($c,$s,$e,$array->[0],$array->[1],$.);
         next LOOP;
      }
   }
}
close SMA;
close OUTPUT;

sub calculate {
   my ($composition, $small_start, $small_end, $big_start, $big_end, $line_num) = @_;
   my $calculation = ( ( ($big_start/$big_end) / ($small_start/$small_end) ) * 100 );
   print OUTPUT "$line_num,$composition, $small_start,$small_end,$big_start,$big_end,$calculation,/n";
}

So I should get on each line of the output file:
Line number,the letters,small start,small end,big start,big end,the calculation

But instead the lines are muddled. So chomp must be important, but I think I am putting it in wrong!
 
Try it here:
Perl:
sub calculate {
   [red]chomp @_;[/red]
   my ($composition, $small_start, $small_end, $big_start, $big_end, $line_num) = @_;
   my $calculation = ( ( ($big_start/$big_end) / ($small_start/$small_end) ) * 100 );
   print OUTPUT "$line_num,$composition, $small_start,$small_end,$big_start,$big_end,$calculation,/n";
}

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top