1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
use strict;
use warnings;
use feature qw(say signatures);
no warnings 'experimental::signatures';
use List::Util qw(sum);
my (%cost, %month);
while (<>) {
chomp;
s/^(\d{4}-\d{2})-\d{2}/$1/; # YYYY-MM-DD -> YYYY-MM
my ($month, $category, undef, $cost) = split /\t/;
$month{$month} = 1;
$cost{$category} = {} unless $cost{$category};
&check_consistency($cost{$category}->{$month}, $cost, $month, $category);
$cost{$category}->{$month} += $cost;
}
my @category = sort(keys %cost);
my @month = sort(keys %month);
say join("\t" => "Month", @category, "Out", "In", "Total");
for my $month (@month) {
my @cost = map { $cost{$_}->{$month} // 0 } @category;
my $out = sum(grep { $_ > 0 } @cost) // 0;
my $in = sum(grep { $_ < 0 } @cost) // 0;
my $total = sum(@cost) // 0;
say join("\t" => $month, @cost, $out, $in, $total);
}
# 月毎にカテゴリーのコストの正負が一貫していることをチェックする
sub check_consistency($sum, $cost, $month, $category) {
!defined($sum) || $sum >= 0 == $cost >= 0
or die "$month の $category カテゴリーのコストの正負が一貫していません";
}
|