Reputation:
So I have this code which takes input and output file from command line, then writes a certain output to the output file (Only the relevant portion shown here due to privacy issues):
use strict;
use warnings;
use autodie;
# check that two arguments have been passed
die "usage: $0 input output\n" unless @ARGV == 2;
my $infile = shift;
my $outfile = shift;
open my $in, "<", $infile;
open(DATA, $in);
open my $out, ">", $outfile;
my %DEF = (
I => [ qw( P Pl P.P P.Pl Pl.P Pl.Pl P.P.P P.P.Pl P.Pl.P P.Pl.Pl Pl. +P.P Pl.P.Pl Pl.Pl.P Pl.Pl.Pl ) ],
II => [ qw( E P.E Pl.E P.P.E P.Pl.E Pl.P.E Pl.Pl.E ) ],
III => [ qw( E.P E.Pl P.E.P P.E.Pl Pl.E.P Pl.E.Pl E.P.P E.P.Pl E.Pl.P + E.Pl.Pl ) ],
IV => [ qw( E.E P.E.E Pl.E.E E.P.E E.Pl.E E.E.P E.E.Pl E.E.E ) ]
);
# Hash table/dictionary for all the groups
my @rank = map @$_, @DEF{qw(I II III IV)};
my %rank = map { $rank[$_ - 1] => $_ } 1 .. @rank;
my @group = map { ($_) x @{ $DEF{$_} } } qw(I II III IV);
my %group = map { $rank[$_ - 1] => $group[$_ - 1] . "_" . $_ } 1 .. @group;
sub rank {
$rank{ $a->[2] } <=> $rank{ $b->[2] }
}
my %T;
sub oh {
map values %$_, @_;
}
sub ab {
my ($b, $a) = @_;
[$b->[0], $a->[1], qq($a->[2].$b->[2]), qq($b->[3]<-$a->[3])];
}
sub xtend {
my $a = shift;
map { ab $_, $a } oh @{ $T{ $a->[0] } }{@_};
}
sub ins {
$T{ $_[3] //= $_[1] }{ $_[2] }{ $_[0] } = \@_;
}
ins split /,\s*/ for <DATA>;
#ins split /,\s*/ for $filename;
ins @$_ for map { xtend $_, qw(P E Pl) } (oh oh oh \%T);
ins @$_ for map { xtend $_, qw(P E Pl) } (oh oh oh \%T);
for (sort { rank } grep { $_->[1] eq 'Q' } (oh oh oh \%T)) {
print $out "%-4s: %20s, %-8s %6s\n",
$_->[0],
qq($_->[0]$_->[3]),
$_->[2],
$group{ $_->[2] };
close $in;
close $out;
}
The problem is that it isnt writing anything to the output file.
perl program.pl input_file output_file
Due to certain reasons I want to read in the input file in format, so that cant be done away with.
Please help
input_file
M19,Q,P,
M31,M19,Pl,
M420,M31,E,
M421,M31,E,
M33,M31,E,
M438,M33,Pl,
M445,M33,E,
M437,M33,E,
M444,M33,E,
M73,M33,E,
M552,M73,Pl,
M553,M73,Pl,
M569,M73,E,
M549,M73,E,
M550,M73,E,
Upvotes: 1
Views: 169
Reputation: 126762
The major problems I can see are these
The line open(DATA, $in)
is meaningless. I presume you want to test your program with data from the DATA
file handle, in which case you want
my $in = \*DATA;
You are closing both file handles inside the final for
loop. That means only one line will ever be written to the output, and thereafter you will get the warning
print() on closed filehandle
You are using print
with a format. You need printf
instead
This variant of your program fixes these things, and produces some output. Is it what you expected?
use strict;
use warnings;
use autodie;
# check that two arguments have been passed
# die "usage: $0 input output\n" unless @ARGV == 2;
my ($infile, $outfile) = @ARGV;
# open my $in_fh, '<', $infile;
# open my $out_fh, '>', $outfile;
my $in_fh = \*DATA;
my $out_fh = \*STDOUT;
my %DEF = (
I => [ qw( P Pl P.P P.Pl Pl.P Pl.Pl P.P.P P.P.Pl P.Pl.P P.Pl.Pl Pl. +P.P Pl.P.Pl Pl.Pl.P Pl.Pl.Pl ) ],
II => [ qw( E P.E Pl.E P.P.E P.Pl.E Pl.P.E Pl.Pl.E ) ],
III => [ qw( E.P E.Pl P.E.P P.E.Pl Pl.E.P Pl.E.Pl E.P.P E.P.Pl E.Pl.P + E.Pl.Pl ) ],
IV => [ qw( E.E P.E.E Pl.E.E E.P.E E.Pl.E E.E.P E.E.Pl E.E.E ) ]
);
# Hash table/dictionary for all the groups
my @rank = map { @$_ } @DEF{qw(I II III IV)};
my %rank = map { $rank[$_ - 1] => $_ } 1 .. @rank;
my @group = map { ($_) x @{ $DEF{$_} } } qw(I II III IV);
my %group = map { $rank[$_ - 1] => $group[$_ - 1] . "_" . $_ } 1 .. @group;
my %T;
sub rank {
$rank{ $a->[2] } <=> $rank{ $b->[2] }
}
sub oh {
map values %$_, @_;
}
sub ab {
my ($b, $a) = @_;
[ $b->[0], $a->[1], qq($a->[2].$b->[2]), qq($b->[3]<-$a->[3]) ];
}
sub xtend {
my $a = shift;
map { ab $_, $a } oh @{ $T{ $a->[0] } }{@_};
}
sub ins {
$T{ $_[3] //= $_[1] }{ $_[2] }{ $_[0] } = \@_;
}
ins split /,\s*/ for <$in_fh>;
close $in_fh;
ins @$_ for map { xtend $_, qw(P E Pl) } (oh oh oh \%T);
ins @$_ for map { xtend $_, qw(P E Pl) } (oh oh oh \%T);
for (sort { rank } grep { $_->[1] eq 'Q' } (oh oh oh \%T)) {
printf $out_fh "%-4s: %20s, %-8s %6s\n",
$_->[0],
qq($_->[0]$_->[3]),
$_->[2],
$group{ $_->[2] };
}
close $out_fh;
__DATA__
M19,Q,P,
M31,M19,Pl,
M420,M31,E,
M421,M31,E,
M33,M31,E,
M438,M33,Pl,
M445,M33,E,
M437,M33,E,
M444,M33,E,
M73,M33,E,
M552,M73,Pl,
M553,M73,Pl,
M569,M73,E,
M549,M73,E,
M550,M73,E,
output
M19 : M19Q, P I_1
M31 : M31M19<-Q, P.Pl I_4
M421: M421M31<-M19<-Q, P.Pl.E II_20
M420: M420M31<-M19<-Q, P.Pl.E II_20
M33 : M33M31<-M19<-Q, P.Pl.E II_20
Upvotes: 2