I have written some code to print formatted arrays (first line = no of inputs, second line = max width of numbers). The star can be any sort of marker to differentiate some elements from the rest.
$ cat inp.txt
6
2
1 *
2
3
4
9
12 *
$ cat inp.txt | ./formatmyarray.pl
____ ____ ____ ____ ____ ____
| * | | | | | * |
| 1 | 2 | 3 | 4 | 9 | 12 |
|____|____|____|____|____|____|
$
fomatmyarray.pl
#!/usr/bin/perl
use warnings;
use strict;
my $spc = q{ };
my $und = q{_};
my $sep = q{|};
my $end = "\n";
my @inp = <STDIN>;
my $len = $inp[0];
my $wid = $inp[1];
chomp $wid;
sub printwall {
my($left, $middle, $l, $w) = @_;
for(0..($l - 1)) {
if ($_ == 0) { print $left; }
for(1..($w + 2)) { print $middle; }
print $left;
}
print $end;
return;
}
sub printchar {
my($left, $middle, $l, $w) = @_;
for(0..($l - 1)) {
if ($_ == 0) { print $left; }
my @temp = split ' ', $inp[$_ + 2];
my $star = 0;
if (($#temp) >= 1) { $star = 1; }
my $mid = sprintf "%d", (($w + 2) /2);
for(1..($w + 2)) {
if (($_ == $mid) && ($star == 1)) { print "*"; }
else { print $middle; }
}
print $left;
}
print $end;
return;
}
sub printnum {
my($left, $middle, $l, $w) = @_;
for(0..($l - 1)) {
if ($_ == 0) { print $left; }
my @temp = split ' ', $inp[$_ + 2];
my $format = join '', q{%}, $w, q{d};
my $num = sprintf($format, $temp[0]);
print join '', $middle, $num, $middle, $left;
}
print $end;
return;
}
printwall($spc, $und, $len, $wid);
printchar($sep, $spc, $len, $wid);
printnum ($sep, $spc, $len, $wid);
printwall($sep, $und, $len, $wid);
I already checked it with Perl::Critic but that will only tell me the syntactical problems (which I have already corrected). Are there any problems that you see with this code. Something an experienced Perl programmer would do differently?
Any comments or suggestions are welcome.
Several suggestions in here. Hope this is helpful.
use strict;
use warnings;
use Getopt::Long qw(GetOptions);
my $SPC = q{ };
my $UND = q{_};
my $SEP = q{|};
my $END = "\n";
main();
sub main {
# Try to keep run options and core input data separate from each other.
GetOptions('max=i' => \my $max_n);
# Parse input at the outset so that subsequent methods
# don't have to worry about such low-level details.
my $inp = parse_input();
# Prune the input array at the outset.
# This helps to keep subsequent methods simpler.
splice @$inp, $max_n if $max_n;
# Don't require the user to compute max width.
my $wid = determine_width($inp);
# The format string can be defined at the outset.
my $fmt = join '', $SEP, $SPC, '%', $wid, 's', $SPC;
# You can print both data and stars using one method.
print_border($inp, $wid, $SPC);
print_content($inp, $fmt, $_) for qw(star data);
print_border($inp, $wid, $SEP);
}
sub parse_input {
my @parsed;
# Using <> provides more flexibility than <STDIN>.
while (<>){
chomp;
my ($value, $star) = split;
$star = $SPC unless defined $star;
push @parsed, { data => $value, star => $star }
}
return \@parsed;
}
sub determine_width {
my $inp = shift;
my $wid = 0;
for (@$inp){
my $len = length $_->{data};
$wid = $len if $len > $wid;
}
return $wid;
}
# Because we did work at the outset to create a data structure
# that represents our goals conveniently, generating output
# is much simpler.
sub print_border {
my ($inp, $wid, $wall_sep) = @_;
print $wall_sep, $UND x ($wid + 2) for @$inp;
print $wall_sep, $END;
}
sub print_content {
my ($inp, $fmt, $mode) = @_;
printf $fmt, $_->{$mode} for @$inp;
print $SEP, $END;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With