プロが教えるわが家の防犯対策術!

Perlを始めたのですが、本や色いろんなサイトを見てもよく分かりません。
Aと言うデータを読み込んで最大最小・平均・標準偏差を求めたいです。
(1)どこが間違っているのか1部づつでもいいので詳しく教えてください。
(2)一つ一つの意味がちゃんとはつかめていないと感じるので流れを教えてください。



#!/usr/bin/perl
# 12345 STDIN
use strict; use warnings;

open ( FILEHANDLE , " < A " ) ;

my @Str=<STDIN>;

foreach my $Row (@Str ){
print $Row;
}


my $Minimum=$ARGV[0];
my $Maximum=$Minimum;
my $Sum=$Minimum;
my $temp=0;
my $i=1;
while ( $i < $Num_arg){
$temp=$ARGV[$i];
if ( $Minimum > $temp ) {
$Minimum = $temp;
}elsif ( $Maximum < $temp ){
$Maximum = $temp;
}
$Sum = $Sum + $temp;
$i++;
}


my $Average = $Sum / $Num_arg;


my $w =
foreach my $w(0..$#Numbers){
($Num_arg - $Average) ** / Num_arg;
}

my $Standarddivitation = sqrt ($w);

print "Average value = $Average \n";
print "Maximum Value = $Maximum \n";
print "Minimum Value = $Minimum \n";
print "Standard devitation = $Standarddevitation;

A 回答 (7件)

>>use Statistics::Basic qw(:all);


>>use List::Util qw(min max);
>
>>open my $fh, '<', 'A' or die;
>>my @data = <$fh>;
>>close $fh;
>say
>のところがよく分かりません。

use Statistics::Basic qw(:all);
use List::Util qw(min max);

というのは、それぞれモジュールを使うための宣言です。
qw(:all) というのはaverage などのモジュールにある関数をすべて使えるようにするためのものです。
qw(min max) というのはそのモジュールの min と max という関数だけ使います
という宣言です。

open my $fh, '<', 'A' or die;
my @data = <$fh>;
close $fh;

というのは三行まとめて、
'A' という名前のファイルをオープンして(失敗したら実行を終了)、
@data という配列変数に丸ごと読み込んで、
ファイルをクローズするということをしています。

say というのは pirnt とほぼ同じですが、尻尾に改行を自動的につけてくれます。




>say
    • good
    • 0

最後のところのPerl語、まんまですよ。


#!perl
open my $fh, '<', "A";
my @data = <$fh>;
close $fh;

my @sort_data = sort {$a <=> $b} @data;
print "min = $sort_data[0]\n";
print "max = $sort_data[$#data]\n";

my $anser = 0;
foreach my $i(@data) {
$anser += $i;
}
print "avg = " . sprintf "%.2f", $anser / scalar(@data);

標準偏差の計算はややこしいのでパスしています。
sakusaker7さんのようにモジュールを使えば、min,max,avgの他、標準偏差を出すと言うややこしい計算も、関数一つでやってくれます。
ActivePerlならppmでStatistics-Basicモジュールを入れないと動きませんが、それを除けばコピペで完璧に動くスクリプト書いて下さってますよ。
    • good
    • 0

自分で書いたものを読み返して反省したので……



内容を覚えてないのにおすすめするのはヒドイですよね。
「初めてのPerl」は定番だし、良い本だとは思うのですが、
アマゾンあたりでポンと買うのはやめてくださいね。
本屋さんで立ち読みして内容を確認してください。
もし買ったらボロボロになるまで読んでください。

# 最近は青いし……私が読んだころは赤い本だった(笑)。
    • good
    • 0
この回答へのお礼

>初めてのPerl
ですか。
探してみます。

とりあえず、この問題を解きたいので、これも教えていただけないでしょうか??

ありがとうございました。

お礼日時:2009/12/20 20:48

Perlは大規模で複雑な言語でもあります。

同じことを達成するのにも、
数多くの異なる方法が用意されています。
結果的に、初心者にとって習得が難しく、他人が書いたプログラムを
理解するのが難しい、といった面があります。
--「ミニマルPerl,Tim Maher著,オライリージャパン」より

Perlは、わかりにくく書こうと思えば、
いくらでもわかりにくく書ける言語です。
初心者は、あれこれと手をだすのではなく、
基本的なパターンを覚えていきましょう。

open(FH, '<A') or die "open: $!";
$sum = 0;
$cnt = 0;
while (<FH>) {
chomp($num = $_);
$sum += $num;
$cnt++;
}
close(FH) or die "close: $!";
$avg = $sum / $cnt;
print "Average value = $avg\n";

ファイル処理の基本はこんなところでしょうか。

どんな本を読まれたのでしょう。
Perlは長くつき合っていける言語です。
質のよい入門書を読んで基礎を固めましょう。
私がはじめて読んだPerl本は「Perlの国へようこそ」ですけど(古すぎる……)

最近、読み返してないので内容は忘れてしまいましたが、
オライリーの「初めてのPerl」がおすすめです。

# オライリーの本は、分厚くて値段も高いけど、
# きちんと学習しようとすれば、結局オライリーになると思う。
# 最近、翻訳のひどい本もあるけど……
    • good
    • 0

そもそも、Perl以外のプログラミング言語ならこの問題をこなせるのでしょうか?


Perlでの書き方がわからないのか、Perlであろうがなかろうがわからないのか。
多分後者なんでしょうね。
さらになんでPerlで標準偏差とかを求める話になって、急ぎで回答求めてるんでしょう。

#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';

use Statistics::Basic qw(:all);
use List::Util qw(min max);

open my $fh, '<', 'A' or die;
my @data = <$fh>;
close $fh;

chomp @data;
my $v = vector(@data);
say "Average :", average($v);
say "Standard deviation : ", stddev($v);
say "Max : ", max(@data);
say "Min : ", min(@data);
    • good
    • 0
この回答へのお礼

はい。そうです。
perlであろうとなかろうと分かりません・・・

>use Statistics::Basic qw(:all);
>use List::Util qw(min max);

>open my $fh, '<', 'A' or die;
>my @data = <$fh>;
>close $fh;
say
のところがよく分かりません。

もう少し詳しく教えていただけませんか??

ありがとうふございました。

お礼日時:2009/12/20 20:46

Aというファイルに、一行に数字が一つあるとします。

標準偏差はパスします。
最後は日本語を半ば放棄してPerl語になってますがご容赦を。

まず、@Strを読み込んだ後にファイルを閉じましょう。
print $Rowの部分は、print @Strだけで同じことがます。
次に@Strをソートして配列の最初(0)と最後($#Str)をprintしたら、最大最小値が出せます。
そしてforeach my $i(@Str)でmy $sum+= $iして、それをscalar(@Str)で割れば平均値が出ます。
    • good
    • 0
この回答へのお礼

標準偏差はあっているということでしょうか???
perl語のところは全く分かりません。

ありがとうございました。

お礼日時:2009/12/20 20:43

とりあえず、ぱっと見でおかしいな、と思うところ。



1.まず、データの読み込みをどのように行いたいのか不明です。ファイルから読み込みたいのか、引数で渡すのか、一つ一つ入力させるのか、どれか決めましょう。

2.
>open ( FILEHANDLE , " < A " ) ;
これは、ファイル「A」を入力ファイルとするのですが、コードの中では一切使われていないので意味の無いものになっています。


3.
>my @Str=<STDIN>;

>foreach my $Row (@Str ){
>print $Row;
>}

値を入力させてるようですが、その後使われていないので、何のためのものか不明です。


4.
>my $Minimum=$ARGV[0];
>my $Maximum=$Minimum;
>my $Sum=$Minimum;
>my $temp=0;
>my $i=1;
>while ( $i < $Num_arg){

いきなり$Num_argがでてきてますが、値が入っていないのでループ処理が思うような処理になっていないのでは?

5.
>$temp=$ARGV[$i];
>if ( $Minimum > $temp ) {
>$Minimum = $temp;
>}elsif ( $Maximum < $temp ){
>$Maximum = $temp;
>}
>$Sum = $Sum + $temp;
>$i++;
>}

一見まともなんですが、$iは1から始まっているのでARGV[0]の値は集計に使わなくていいのでしょうか?

6.
>foreach my $w(0..$#Numbers){
ここの$#Numbersもいきなり出てきてますね。値入ってますか?

7.
>($Num_arg - $Average) ** / Num_arg;
Num_argから$が取れちゃってます。
    • good
    • 0
この回答へのお礼

>ファイルから読み込みたいのか、引数で渡すのか、一つ一つ入力させるのか
>コードの中では一切使われていないので意味の無いものになっています。
>値が入っていないのでループ処理が思うような処理になっていないのでは?

$iは1から始まっているのでARGV[0]の値は集計に使わなくていいのでしょうか?

これらの意味がよく分かりません><

私はAから読み取った数字が全部$Numbersに入っていると思ったのですが、これは間違っているようですね・・・;;;

とりあえずどこが違うかがわかりました
ありがとうございました。

お礼日時:2009/12/20 20:41

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!