well what I will do is show you the actual code and then describe what it is doing. I think this will be a better learning experience than giving you psuedo code.
- Code: Select all
#!/usr/bin/perl -w
use strict;
$/ = '>';
my $total = 0;
while(<DATA>) {
chomp();
next unless($_);
my $subtotal;
for(split(/\n/)) {
next unless($_);
my ($first, $second) = split(/\s+/);
$subtotal += ($second - $first);
}
print "Subtotal: ".sprintf("%.2f",$subtotal),"\n";
$total += $subtotal;
}
print "Total: ".sprintf("%.2f", $total),"\n";
__DATA__
>
-95.168785 29.082421
-95.169151 29.082421
-95.169298 29.082421
-95.169151 29.082274
-95.168711 29.082274
-95.168785 29.082421
>
-95.167465 29.082568
-95.167831 29.082421
-95.167831 29.082201
-95.167611 29.082128
-95.167245 29.082128
-95.167098 29.082201
-95.167465 29.082568
>
-95.171792 29.082714
-95.172085 29.082861
-95.172012 29.082494
-95.171645 29.082054
-95.171425 29.082201
-95.171792 29.082714
>
Ok first off:
- Code: Select all
#!/usr/bin/perl -w
is called the shebang line and is what tells the system where to look for the interpretor to interpret the following code. It is pointed at the perl binary and is invoking warnings (that is the -w part).
- Code: Select all
use strict;
Is a module that is included with the perl standard library and forces strict references and lexical localization amongst other things (like quoted strings and what not).
Now the fun stuff...
$/ and $\ are the input and output record seperators. By default on most systems they are set equal to newlines "\n". This is what tells perl what is defined as a "record". Basically, by default perl reads records as a single line of text (because \n is the default record seperator).
Here I change that to be the '>' character so that in my while() loop, each iteration is processing what I define as a record and not what perl defaults to a record. it allows the app to grab all of the lines of data between the '>' characters as a single record for processing.
- Code: Select all
chomp();
next unless($_);
my $subtotal;
The above code does the initial processing on the record. It first chomp()'s the data. What chomp() does is removes the record seperator (newline by default or whatever you change it to) off the end of the record. Then it checks to see if $_ is NULL or not and if it is it skips to the next iteration oft he while loop. if it is not NULL then it continues to process it. The "my $subtotal" is called a variable instantiation and is required when using strict.
- Code: Select all
for(split(/\n/)) {
Here I do two things. I setup a for loop and feed it the output of the split() function which splits each record of the while loop into seperate lines for further processing. I probably should have used a foreach() loop here for better readability but a for loop used in this fashion acts in the same manner. A standard for loop usually has it's instantiation, conditional statement and increment all in the decleration of the loop (for(my $i=0; $i < 10; $i++){}). This usage does not.
- Code: Select all
next unless($_);
my ($first, $second) = split(/\s+/);
$subtotal += ($second - $first);
This is the guts of the for loop and what it does is check again to see if this local $_ is NULL ($_ is lexically scoped by default) and if it is not NULL it continues and if it is, then it skips to the next iteration of the for loop (not the while loop).
Then we split the contents of each line into two variables, $first and $second. Then we add the value of $subtotal to the difference between the two values.
- Code: Select all
print "Subtotal: ".sprintf("%.2f",$subtotal),"\n";
$total += $subtotal;
Here we print each records calculated subtotal according to what you said you wanted this app to do and then we add each records subtotal to the overall total which we print out after each record has been processed through the while loop.
My usage of sprintf() was only to pretty the integers up a bit and only show 2 places past the decimal. if you wanted these rounded to whole numers there are ways of doing that too, just let me know.
I hope I am taking the difference of the right two numbers. I was not quiet sure what you meant when you said you wanted it to read in the first and second numbersand then the third and fourth and so on..
Oh yeah and everything after __DATA__ is just the input data I used to parse. I created a filehandle in the actual script for easy processing but you can feed your filehandle to this routine however you get it (open() call etc..)