use POSIX qw/strftime/; use strict; $|++; use constant Intervals => 20; my ($prev_time, $prev_val, $tmin, $tmax, $last_val, @curve); open my $data, "weightdata.txt" or die "weightdata.txt: $!\n"; while (<$data>){ chomp; next unless m{^\s*([\d/]+)\s+([\d.]+)}; my($m, $d, $y) = split /\//, $1; my $time_point = strftime("%s", 0, 0, 0, $d, $m - 1, $y - 1900); if (defined $prev_time){ my $slope = ($2 - $prev_val) / ($time_point - $prev_time); push @curve, [ $prev_time, $time_point, $prev_val, $slope ]; } ($prev_time, $prev_val) = ($time_point, $2); ($tmax, $last_val) = ($time_point, $2); } close $data; $tmin = $curve[0][0]; my $interval = ($tmax - $tmin) / (Intervals - 1); my ($prev_t, $val, $slope); for my $t (0 .. Intervals - 2){ my $calc_t = $t * $interval + $tmin; shift @curve unless $calc_t >= $curve[0][0] && $calc_t <= $curve[0][1]; ($prev_t, $val, $slope) = @{$curve[0]}[0, 2, 3]; printf "%2d: Weight on %s was %.1f\n", $t + 1, strftime("%F",localtime($calc_t)), ($calc_t - $prev_t) * $slope + $val; } printf "%2d: Weight on %s was %.1f\n", Intervals, strftime("%F",localtime($tmax)), $last_val;