Re: script assistance please
by hippo (Archbishop) on Feb 19, 2015 at 21:47 UTC
|
Some guidance, as requested:
- use strict
- use warnings
- indent your code to improve legibility
- ... and maybe some whitespace within the lines might help too
- comment your code liberally
- use the 3-argument form of open
- check your return values from open()
- use lexical filehandles
- don't assign to @_ without good reason
- go through the (rest of the) Basic debugging checklist
If you do all that, you'll be in a much better place to determine where you are going wrong.
| [reply] [d/l] |
|
|
I'm out of votes for the day, but if I could, I would ++hippo for each of the following items from that checklist which were part of my troubleshooting steps:
1, 3, 4, 7, 10
I would further point out that things I had either intended to do, or would have done with my own work, include:
1, 2, 3, 4, 5, 6, 7, 9, 10
The only item missing is #8, and I don't use those merely out of habit -- but I do ensure every handle is unique globally, which is a less foolproof system, but due to my own rigorous adherence to my own standards, has never failed me in a few decades of using Perl. :-)
| [reply] |
|
|
| [reply] [d/l] |
|
|
|
|
|
Re: script assistance please
by marinersk (Priest) on Feb 19, 2015 at 21:43 UTC
|
Made the following changes:
- Added strict to aid in debugging;
- Slight reformat for readability:
#!/usr/bin/perl
use strict;
$moyr="12/2014";
$,=" ";
open(IN,"<COS_SGA_xref.txt");
while(<IN>) {
chop;
@_ = split(/ /);
$csga{$_[0]}=$_[1];
}
open(IN,"<cc.txt");
open(OUT,">new_cc.txt");
for($i=0;$i<9;$i++) {$_=<IN>;}
($mo,$yr)=@_ = split(/\//,$moyr);
while(<IN>) {
chop;
@_ = split(/ /);
$created=pop(@_);
($mocr,$day,$yrcr)=@_ = split(/\//,$created);
if($yrcr.$mocr >= $yr.$mo) {
$cc=$_[1];
$cc =~ y/C_//d;
splice(@_,3,1);
shift(@_);
print OUT $created,@_,$csga{$cc};
print OUT "\n";
}
}
__END__
Now for the errors:
D:\PerlMonks>test1.pl
Global symbol "$moyr" requires explicit package name at D:\PerlMonks\t
+est1.pl line 5.
Global symbol "%csga" requires explicit package name at D:\PerlMonks\t
+est1.pl line 11.
Global symbol "$i" requires explicit package name at D:\PerlMonks\test
+1.pl line 15.
Global symbol "$i" requires explicit package name at D:\PerlMonks\test
+1.pl line 15.
Global symbol "$i" requires explicit package name at D:\PerlMonks\test
+1.pl line 15.
Global symbol "$mo" requires explicit package name at D:\PerlMonks\tes
+t1.pl line 16.
Global symbol "$yr" requires explicit package name at D:\PerlMonks\tes
+t1.pl line 16.
Global symbol "$moyr" requires explicit package name at D:\PerlMonks\t
+est1.pl line 16.
Global symbol "$created" requires explicit package name at D:\PerlMonk
+s\test1.pl line 20.
Global symbol "$mocr" requires explicit package name at D:\PerlMonks\t
+est1.pl line 21.
Global symbol "$day" requires explicit package name at D:\PerlMonks\te
+st1.pl line 21.
Global symbol "$yrcr" requires explicit package name at D:\PerlMonks\t
+est1.pl line 21.
Global symbol "$created" requires explicit package name at D:\PerlMonk
+s\test1.pl line 21.
Global symbol "$yrcr" requires explicit package name at D:\PerlMonks\t
+est1.pl line 22.
Global symbol "$mocr" requires explicit package name at D:\PerlMonks\t
+est1.pl line 22.
Global symbol "$yr" requires explicit package name at D:\PerlMonks\tes
+t1.pl line 22.
Global symbol "$mo" requires explicit package name at D:\PerlMonks\tes
+t1.pl line 22.
Global symbol "$cc" requires explicit package name at D:\PerlMonks\tes
+t1.pl line 23.
Global symbol "$cc" requires explicit package name at D:\PerlMonks\tes
+t1.pl line 24.
Global symbol "$created" requires explicit package name at D:\PerlMonk
+s\test1.pl line 27.
Global symbol "%csga" requires explicit package name at D:\PerlMonks\t
+est1.pl line 27.
Global symbol "$cc" requires explicit package name at D:\PerlMonks\tes
+t1.pl line 27.
Execution of D:\PerlMonks\test1.pl aborted due to compilation errors.
D:\PerlMonks>
I will start debugging this, but you should also.
Holler if the above error messages don't make sense to you.
| [reply] [d/l] [select] |
|
|
| [reply] [d/l] [select] |
|
|
| [reply] [d/l] [select] |
|
|
|
|
|
|
Marinersk, thanks for your reply. I hope this works out.
Sample data
COS_SGA_xref.txt
195003 COS
195010 COS
500512 COS
500511 COS
520536 COS
550551 COS
550625 COS
560119 COS
cc.txt
01/31/2015 Dynamic List Display 1
Controlling Area C2
Date 01/01/1900 To 12/31/9999
Cost Center All Cost Centers
Cost Ctr Description CoCd Profit Ctr Person Responsible Created on
6 PCS<>PCS MAIL CLOSED per B. Middleton 301 6000 Garrity, T. 05/24/2004
30 COST CENTER 000001 170 112 Mac Crawford 08/30/2004
50 150BS - Balance Sheet C/C-(No RT) 150 112 Mac Crawford 08/16/2004
60 COST CENTER 000001 160 112 Mac Crawford 08/16/2004
60 COST CENTER 000001 170 112 Mac Crawford 08/16/2004
70 COST CENTER 000001 170 112 Mac Crawford 08/16/2004
71 COST CENTER 000001 170 112 Mac Crawford 08/16/2004
74 COST CENTER 000001 170 112 Mac Crawford 08/16/2004
76 COST CENTER 000001 170 112 Mac Crawford 08/30/2004
77 COST CENTER 000001 170 112 Mac Crawford 08/30/2004
78 COST CENTER 000001 170 112 Mac Crawford 08/30/2004
80 State of NY 351 112 Bob Achettu 02/09/2006
80 State of NY 301 112 Bob Achettu 02/09/2006
| [reply] |
Re: script assistance please
by karlgoethebier (Abbot) on Feb 20, 2015 at 14:45 UTC
|
use strict;
use warnings;
use feature qw(say);
use Data::Dump;
Split (if you really need it):
my $moyr = "12/2014";
my ( $month, $year ) = split /\//, $moyr;
say for ( $month, $year );
Building the hash:
my %csga;
while (<$in>) {
my @record = split /\t/;
chomp @record;
$csga{ $record[0] } = $record[1];
}
close $in;
dd \%csga;
Skipping headers when reading a file:
open( my $in, "<", q(cc.txt) ) || die $!;
while (<$in>) {
next if $. <= 8;
# print;
}
close $in;
Best regards, Karl
«The Crux of the Biscuit is the Apostrophe»
| [reply] [d/l] [select] |
|
|
Hmm, for skipping a header, I usually prefer to do it before entering the main loop. For example:
open( my $in, "<", q(cc.txt) ) || die $!;
$useless_header_line = <$in> for 1..8;
while (<$in>) {
# print;
}
Two reasons for that. It is more self-documenting. If my file has 500 million lines (and, yes, I am commonly dealing with such file sizes), I do not like the idea to make a useless test so many times. The test is pretty fast and has probably relatively limited impact of performance, but, still, it is still against my sense of economy or ecology.
| [reply] [d/l] |
|
|
while (<>) {
last unless (/^#/);
}
procline;
while (<>) {
procline;
}
continue {
if (eof) {
while (<>) {
last unless (/^#/);
}
procline;
}
}
| [reply] [d/l] [select] |
|
|
#!/usr/bin/env perl
use strict;
use warnings;
use Benchmark qw ( :hireswallclock cmpthese timethese );
our $file = qq (huge.file);
our $amount = 1_000_000;
sub karl {
our ( $file, $amount );
open( my $in, "<", $file );
while (<$in>) {
next if $. <= $amount;
1;
}
close $in;
}
sub laurent {
our ( $file, $amount );
open( my $in, "<", $file );
my $useless_header_line = <$in> for 1 .. $amount;
while (<$in>) {
1;
}
close $in;
}
my $results = timethese(
10,
{
'karlgoethebier' => 'karl',
'Laurent_R' => 'laurent',
}
);
cmpthese($results);
__END__
karls-mac-mini:monks karl$ perl -e 'print qq(Lorem ipsum kizuaheli\n)
+for 1..50_000_000;' > huge.file
karl-mac-mini:monks karl$ ls -hl huge.file
-rw-r--r-- 1 karl karl 1,0G 21 Feb 17:24 huge.file
karls-mac-mini:monks karl$ wc -l huge.file
50000000 huge.file
karls-mac-mini:monks karl$ ./1117372.pl
Benchmark: timing 10 iterations of Laurent_R, karlgoethebier...
Laurent_R: 65.9521 wallclock secs (63.43 usr + 2.34 sys = 65.77 C
+PU) @ 0.15/s (n=10)
karlgoethebier: 127.837 wallclock secs (124.90 usr + 2.55 sys = 1
+27.45 CPU) @ 0.08/s (n=10)
s/iter karlgoethebier Laurent_R
karlgoethebier 12.7 -- -48%
Laurent_R 6.58 94% --
"...relatively limited impact of performance"
This is relative. It is like it is ;-)
Thanks for your reply and best regards, Karl
«The Crux of the Biscuit is the Apostrophe»
| [reply] [d/l] |