Не выводятся значения

У меня проблема с кодированием моей первой программы на Perl.

Здесь я пытаюсь получить максимальное, минимальное, общее и среднее значение списка чисел, используя подпрограмму для каждого значения и другую подпрограмму для вывода окончательных значений. Я использую «частное» для всех своих переменных, но я все еще не могу напечатать свои значения.

Вот мой код:

&max(<>);

&print_stat(<>);

sub max {

    my ($mymax) = shift @_;

    foreach (@_) {

        if ( $_ > $mymax ) {
            $mymax = $_;
        }
    }

    return $mymax;
}

sub print_stat {

    print max($mymax);
}

person Yasser Ḿ    schedule 08.07.2016    source источник
comment
В контексте списка <> читается до EOF (возвращая каждую строку, прочитанную как отдельную строку). Второе использование <> ничего не возвращает, так как первое уже считано в EOF. если вы хотите передать значения, возвращаемые при первом использовании <>, двум разным подпрограммам, вам нужно их где-то сохранить.   -  person ikegami    schedule 09.07.2016
comment
Совет: всегда используйте use strict; use warnings 'all';   -  person ikegami    schedule 09.07.2016
comment
Совет: никогда не используйте & перед вызовом подпрограммы (если только это не одна из крайне редких ситуаций, когда вы на самом деле хотите переопределить прототип подпрограммы).   -  person ikegami    schedule 09.07.2016
comment
Совет: используйте последовательную стратегию отступов!   -  person ikegami    schedule 09.07.2016
comment
Совет: вы получите меньше сюрпризов, если поместите код верхнего уровня после подопределений. А еще лучше, поместите завитки вокруг кода верхнего уровня.   -  person ikegami    schedule 09.07.2016
comment
Я очень люблю код верхнего уровня в начале скрипта. Помимо того, что я должен использовать круглые скобки вокруг всех моих аргументов функции (что я все равно предпочитаю делать), какие еще сюрпризы я открываю для себя?   -  person Grant McLean    schedule 09.07.2016
comment
Взгляните на List::Util, который имеет max, min, sum методов. В среднем всего sum / count. perldoc.perl.org/List/Util.html   -  person xxfelixxx    schedule 09.07.2016
comment
@GrantMcLean Все переменные верхнего уровня будут неявно включены в область действия ваших функций. Это может вызвать неожиданное поведение, например. если вы используете переменную $foo в своей функции, но забыли объявить ее, это обычно является ошибкой, но молча делает неверную вещь, если ваш основной код также использует переменную с именем $foo.   -  person melpomene    schedule 09.07.2016


Ответы (2)


Примерьте вот это:

use strict;
use warnings;

my @list_nums = qw(10 21 30 42 50 63 70);
ma_xi(@list_nums);

sub ma_xi
{
    my @list_ele = @_;
    my $set_val_max = '0'; my $set_val_min = '0';
    my $add_all_vals = '0';
    foreach my $each_ele(@list_ele)
    {
        $set_val_max = $each_ele if($set_val_max < $each_ele);
        $set_val_min = $each_ele if($set_val_min eq '0');
        $set_val_min = $each_ele if($set_val_min > $each_ele);
        $add_all_vals += $each_ele;
    }

    my $set_val_avg = $add_all_vals / scalar(@list_ele) + 1;

    print "MAX: $set_val_max\n";
    print "MIN: $set_val_min\n";
    print "TOT: $add_all_vals\n";
    print "AVG: $set_val_avg\n";

    #Return these values into array and get into the new sub routine's

}
person ssr1012    schedule 09.07.2016
comment
Пожалуйста, прокомментируйте перед голосованием - person ssr1012; 09.07.2016

Некоторые примечания

  • Используйте много пробелов, чтобы разместить свой код. Я привел в порядок код Perl в вашем вопросе, чтобы мне было легче его читать, не меняя его семантику.

  • Вы должны всегда use strict и use warnings 'all' в начале каждой программы Perl, которую вы пишете

  • Никогда не используйте амперсанд & в вызове подпрограммы. В этом не было необходимости или желания со времен Perl 4 более двадцати пяти лет назад. Любой учебник, который говорит вам об обратном, неверен

  • Использование <> в контексте списка (например, в качестве параметров вызова подпрограммы) прочитает весь файл и исчерпает дескриптор файла. После этого любые вызовы <> будут возвращать undef

  • Вы должны использовать chomp для удаления новой строки из каждой строки ввода

  • Вы объявляете $mymax в рамках подпрограммы max, но затем пытаетесь напечатать его в print_stat, где его нет. use strict и use warnings 'all' поймали бы эту ошибку за вас

  • Ваша подпрограмма max возвращает максимальное рассчитанное значение, но вы никогда не используете это возвращаемое значение.

Ниже приведена исправленная версия вашего кода.

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

Я также сохранил возвращаемое значение из max в переменной $max, а затем передал его в print_stat. Нет смысла пытаться снова прочитать файл и передать все эти значения в print_stat, как это делает ваш код.

надеюсь, это поможет

use strict;
use warnings 'all';

my @values = <>;
chomp @values;

my $max = max(@values);
print_stat( $max );

sub max {
    my $mymax = shift;

    for ( @_ ) {
        if ( $_ > $mymax ) {
            $mymax = $_;
        }
    }

    return $mymax;
}

sub print_stat {
    my ($val) = @_;

    print $val, "\n";
}



Обновлять

Вот версия, которая вычисляет всю статистику, которую вы упомянули. Я не думаю, что подпрограммы помогут в этом случае, так как решение короткое и код не может быть повторно использован.

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

use strict;
use warnings 'all';

my ($n, $max, $min, $tot);

while ( <DATA> ) {

    next unless /\S/; # Skip blank lines

    chomp;

    if ( not defined $n ) {
        $max = $min = $tot = $_;
    }
    else {
        $max = $_ if $max < $_;
        $min = $_ if $min > $_;
        $tot += $_;
    }

    ++$n;
}

my $avg = $tot / $n;

printf "\$n   = %d\n",   $n;
printf "\$max = %d\n",   $max;
printf "\$min = %d\n",   $min;
printf "\$tot = %d\n",   $tot;
printf "\$avg = %.2f\n", $avg;


__DATA__
7
6
1
5
1
3
8
7

выход

$n   = 8
$max = 8
$min = 1
$tot = 38
$avg = 4.75
person Borodin    schedule 09.07.2016
comment
Это еще больше меня запутало, потому что мне нужно было иметь подпрограмму для каждого значения, которое я ищу. Я многому научился из всех ответов, большое спасибо всем за вашу помощь. - person Yasser Ḿ; 12.07.2016