Yesterday I posted a short Perl solution to a problem given by Kees de Koster in the Dutch newsgroup nl.comp.os.linux.programmeren. My solution was met by Koos with:
AAAAARRRRGHHHH!!!! 'dorie John, hou daar nu eens me op!
(Damn John, stop doing that). So when Kees posted more information on his problem and his own solution written in Perl, I couldn't resist to call the Perl solution in my reply the "Koos special of the day".
An example of new input data, as given by Kees:
ChartPath=/home/sircrow/Qtstalker/data/Stocks/AAB
0=Plugin=HorizontalLine|Name=0|Value=19.9431|Plot=Main Plot|Color=#0055ff
19940103000000=8.15,8.36,8.13,8.33,2893070
19940104000000=8.35,8.35,8.26,8.26,4084400
19940105000000=8.33,8.33,8.28,8.3,5622470
20050218000000=21.16,21.28,21.08,21.16,6017510
20050221000000=21.17,21.19,20.82,20.88,6842220
BarType=0
CHARTOBJECTS=0
Plugin=Stocks
Symbol=AAB
Title=AAB
Type=Stock
Which, according to the same posting, when a factor of 4 is used for multiplication, should result in the following output:
ChartPath=/home/sircrow/Qtstalker/data/Stocks/AAB
0=Plugin=HorizontalLine|Name=0|Value=19.9431|Plot=Main Plot|Color=#0055ff
19940103000000=32.6,33.44,32.52,33.32,723267
19940104000000=33.4,33.4,33.04,33.04,1021100
19940105000000=33.32,33.32,33.12,33.2,1405617
20050218000000=84.64,85.12,84.32,84.64,1504377
20050221000000=84.68,84.76,83.28,83.52,1710555
BarType=0
CHARTOBJECTS=0
Plugin=Stocks
Symbol=AAB
Title=AAB
Type=Stock
Moreover, from the solution Kees had made I understood that only if the value in front of the = character was greater than 19000000000000 action should be taken. Besides, the number in the last column should divided by the given factor and turned into an int. So my Perl solution became:
#!perl -spaF[=,]
next unless $F[0] > 19000000000000;
$_ = "$F[ 0 ]=" . join ',', (
map { $_ * $factor } @F[ 1..4 ]
), int( $F[ 5 ] / $factor ) . "\n"
Again, the first line of the Perl program does most of the work. The -s switch enables rudimentary
switch parsing on the command line after the script name but before any filename arguments.
I used it to pass the value of the factor, for example
-factor=4
sets the value of $factor to the number 4.
The -p switch works similar to the -n switch (see: Using Perl to process fields) put it does
an additional print;
, ie it prints the value contained in the $_ variable.
And like with the previous Perl solution
the -a switch is used in combination with -F to split each line on either the , or the = character.
In the actual code I first test if the value of the first column is greater than 19000000000000. If not, then move on (and the -p switch makes sure that the input is copied 1:1 to the output). The next line multiplies the values in the 2nd up to and including the 5th column, and does the integer division on the 6th. A join is used to glue the values together, separated by commas.
The Perl program should be called as follows:
program -factor=n file > out
In order to make sure my Perl program gave the desired output, I piped the output to md5sum and compared it with the md5sum I calculated from the result given by Kees.
kees-sol2.pl -factor=4 kees-in-2.txt | md5sum
e800ee35c08e70b4ceae4e4096e77013 *-
md5sum kees-out-2.txt
e800ee35c08e70b4ceae4e4096e77013 *kees-out-2.txt
Since the MD5 digest of the program is identical to the output given by Kees it's safe to assume that the Perl program I wrote works correctly.