Могу ли я преобразовать этот Perl Script, чтобы он читался из файла? - PullRequest
0 голосов
/ 25 ноября 2011

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

my (@vals, $med);
@vals =(12, 23, 34, 21, 66,66, 34, 87);
print "UNSORTED: @vals\n"; #sort data points 
@vals = sort(@vals); 
print "SORTED: @vals\n"; #test to see if there are an even number of data points 
if( @vals % 2 == 0) { #if pair then: 
$sum = $vals[(@vals/2)-1] + $vals[(@vals/2)]; 
$med = $sum/2; 
print "The median value is $med\n"; 
} 
else {                       #if odd then: 
print "The median value is $vals[@vals/2]\n"; 
} 
exit;

Могу ли я как-то это преобразоватьзаставить его читать данные из файла из нескольких столбцов и вычислять медиану для выбранного столбца?например, набрав ./median.pl 1 column_numbers.tbl в команде оболочки.Я пробовал это, но файл data.txt имеет только один столбец

my (@vals, $med, $sum1, @numbers, @sorted);
open (COLUMN, "< data.txt") || die "Can not open file : $! ";
my @not_sorted = <COLUMN>;                  
close (COLUMN);
@sorted = sort { $a <=> $b } @not_sorted;  
if (@vals % 2 == 0) {  
$med = ($sorted[int($N/2)]);             
print "MEDIAN = $med\n";
}
else {  
$sum1 = $vals[(@vals/2)-1] + $vals[(@vals/2)]; 
$med = $sum1/2;
print "MEDIAN = $vals[@vals/2]\n";
};

Спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 26 ноября 2011

В принципе, я согласен с TLP по этому вопросу, но, поскольку я не нашел других вопросов по SO, которые меня интересовали в данный момент:

#!/usr/bin/perl

use strict;
use warnings;

my $index = shift;
my $filename = shift;
my $columns = [];

open (my $fh, "<", $filename) or die "Unable to open $filename for reading\n";

for my $row (<$fh>) {

    my @vals = split/\s+/, $row;
    push @{$columns->[$_]}, $vals[$_] for 0 .. $#vals;
}

close $fh;

my @column = sort {$a <=> $b} @{$columns->[$index]};

my $offset = int($#column / 2);
my $length = 2 - @column % 2;

my @medians = splice(@column, $offset, $length);

my $median;
$median += $_ for @medians;
$median /= @medians;

print "$median\n";

Это работает при условии, что данные разделены пробелами. Первый аргумент - это номер столбца с 0 индексами, а второй - допустимое имя файла.

Если вы новичок в Perl, я должен заметить, что массивы в скалярном контексте возвращают количество элементов, как в my $length = 2 - @column % 2; и $median /= @medians;.

0 голосов
/ 25 ноября 2011

Вас интересуют остальные колонки?Если нет, просто игнорируйте их.

Этот фрагмент программы считывает строку из файла, а затем помещает нужный столбец в массив @medium_array.Поскольку большинство людей считают первый столбец столбцом № 1, а Perl считает его столбцом № 0, я добавил смещение под названием COLUMN_OFFSET.

Основная часть работы выполняется с помощью этой строки.:

push @medium_array, (split " ", $line)[$column_for_medium - COLUMN_OFFSET];

В этой строке используются команды push и split.Не двигайтесь дальше, пока не поймете, что делает эта строка.

Эта программа может использовать более эффективную проверку ошибок параметров.Пользователь запрашивает столбец больше, чем количество столбцов в файле?Что делать, если в файле нет столбца?Что делать, если файл не существует?Все эти вещи должны быть добавлены и проверены в этой программе.

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

use strict;
use warnings;
use autodie;

use constant {
    COLUMN_OFFSET => 1,    #Incase you want to number cols from 1 instead of 0
};

# Read in the command line parameters

my $column_for_medium = shift;
my $file_name         = shift;

# Some sort of parameter checking

if (not defined $file_name and not $column_for_medium =~ /^\d+$/) {
   die qq(You must have two parames: "Column Num" and "File Name");
}

open (my $array_file, "<", $file_name);
my @medium_array;
while (my $line = <$array_file>)   {
   chomp $line;
   push @medium_array, (split " ", $line)[$column_for_medium - COLUMN_OFFSET];
}       
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...