Как напечатать последнее значение моего вывода в perl? - PullRequest
1 голос
/ 03 марта 2020

Я написал скрипт, который впервые работает так, как я хочу: PI предоставит мой скрипт ниже. Единственное, что я должен был sh сделать, но у меня ничего не получилось, - это напечатать ТОЛЬКО последнее значение моего вывода.

use strict;
use warnings;
use feature 'say';

my $filename = '/home/Desktop/my_scripts/coordinates_based';

my $p;
my $i;
my $mikos = 0;
my $sum = 0;
my $count = 1;
my $mikos_thetika = 0;
my $mikos_arnitika = 0;
my $k = 1;
my @table = ();
my $final = 0;
my $neg = 0;
my $pos = 0;
my $size;
my $last_value = 0;

open(FH, '<', $filename) or die $!;

while (<FH>) {

    my ($n, $p, $a, $b) = split '\s+';

    chomp;
    $i =  1 if $p eq '+';
    $i = -1 if $p eq '-';

    for ($k..$n)
    {
        $mikos = $b - $a;
        if ($p eq '+')
        {
            $mikos_thetika = $mikos*1 ;
            $pos += $mikos_thetika;
        }
        else
        {
            $mikos_arnitika = $mikos*(-1);
            $neg += $mikos_arnitika;
        }

        $final = $pos + $neg;

        #chomp;
        #push(@table, $final);

        #$size = scalar @table;
        say $final;

        $k = $k + 1;
    }
}
close(FH);

Объяснение сценария: В результате вычисляется разница между $ b и $ a, и на основе $ p выведите разницу с - или + соответственно. И в конце выводит сумму этих разностей, но не в сумме, как я хочу, а в виде суммы ($ final) предыдущего значения с приходящим.

Я пробовал это:

1)  if ($k==$n) # $n is first column of my input file
    {$last_value =$table[$k];}
    say $last_value; # But it prints the same output.

2)  $size= scalar @table;
    $last_value = $table [$size];
    say $size; # prints the correct table size but not as value 
               # but as an entire sequence. For example 
               # if my table size is 5 it prints 1\n 2\n 3\n 4\n 5

3) # Also i tried the List library 
    use List::Util qw(sum);
    $last_value=sum($final);

входной файл:

$n $p $a $b   
1 - 852 1934
2 - 2020 3108
3 + 3212 3781
4 - 3917 4162
5 - 4263 4421

выходной файл после моего сценария

-1082
-2170
-1601
-1846
-2004

Желаемый вывод

2004

Ответы [ 2 ]

5 голосов
/ 03 марта 2020

У вас в основном такая ситуация, когда в конце каждой итерации вы что-то выводите. Вы продолжаете делать это, потому что не знаете, когда доберетесь до последнего элемента.

while( <FH> ) {
    say $_ ** 2;
    }

Вместо того, чтобы что-то выводить, сохраните результат для вывода позже. Когда вы столкнетесь с другим элементом, замените это значение. Когда вы исчерпали ввод, последнее значение, которое вы запомнили, - это значение, которое вы хотите вывести:

my $previous_output;
while( <FH> ) {
    $previous_output = $i ** 2;
    }

say $previous_output;

Или вы можете обмануть, сделав весь вывод и взяв только последнюю строку с помощью tail (или что-то подобное):

% perl script.pl | tail -n 1
2 голосов
/ 03 марта 2020

Ну, я взял на себя смелость очистить ваш код.

Пожалуйста, посмотрите, не найдете ли следующий фрагмент кода легче для чтения / понимания, чем ваш оригинал.

Он выполняет ту же цель / функцию, что и ваш исходный код, за исключением того, что ваш конечный результат выводится после того, как все данные обработаны непосредственно перед выходом из программы.

Примечание: zdim обратил мое внимание на то, что код может быть улучшено с split особый случай, if ... else ... КПД цикла ЦП (для очищенных входных данных) и в отношении кода пропуска заголовка (заголовок может отсутствовать или иметь другой формат). Хотя изначально я не намеревался улучшить кода, а только код читаемость , я считаю предложение zdim полезным изменением.

Примечание: входные данные очищены с помощью next unless /\d+ +[+-] +\d+ +\d+/;, что может показаться несколько необычным, поскольку обычно оно записывается как next unless /\d+\s+[+-]\s+\d+\s+\d+/; - для демонстрации цель одна и та же цель может быть достигнута разными способами. Я предположил потенциальные случаи несогласованности входных данных, когда поля данных могут быть разделены более чем одним пробелом (пользователь может настроить интервал для удобочитаемости). ' ' и \s весьма различны, так как сначала предполагается только '' (пробел), но '\ s' предполагает [\ f \ n \ r \ t]. perlre

use strict;
use warnings;
use feature 'say';

my $filename = 'coordinates_based';    # I run code in same directory as input file

my($k,$pos,$neg,$final);               # only necessary variables for computation 

$k = 1;
$pos = $neg = 0;                       # some variables initialization

open my $fh, '<', $filename
    or die "Could not open $filename: $!";

while (<$fh>) {                             # walk through file
    next unless /\d+ +[+-] +\d+ +\d+/;      # sanitize input data
    chomp;

    my ($n, $p, $a, $b) = split;            # see split doc for special case

    for ($k..$n)
    {
        if ($p eq '+') {
            $pos += $b-$a;   # thetika  (positive)
        } else {
            $neg -= $b-$a;   # arnitika (negative)
        }

        $final = $pos + $neg;

        $k++;
    }
}

close $fh;

say $final;                            # output result of computation

Выход

-2004
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...