Perlコーディング初心者質問スレ Part 55
レス数が950を超えています。1000を超えると書き込みができなくなります。
0001nobodyさん
2007/05/30(水) 11:34:01ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。
お勧めサイトは >>2-10
前スレ http://pc11.2ch.net/test/read.cgi/php/1171102883/
過去ログ倉庫 ttp://user.ftth100.com/mirrorhenkan/perl/
0889nobodyさん
2007/09/02(日) 00:23:50ID:???## IP の範囲やサブネットから IP の最小値と最大値を10進数で返す
sub getipminmax{
my($ip) = $_[0] || "";
my(@retip) = (0, 0);
# $ip に数字、/、- 以外があればエラーリターンする
if($ip =~ /[^\d\.\-\/]/){ return @retip; }
# - か / で分割する
if($ip =~ /\-/){ # IP の範囲
my ($ipaddr1, $ipaddr2) = split(/\-/, $ip);
$retip[0] = &ip2dec($ipaddr1);
$retip[1] = &ip2dec($ipaddr2);
}elsif($ip =~ /\//){ # サブネット
my ($ipaddr, $subnet) = split(/\//, $ip);
my $subnetdec = (2 ** 32) - (2 ** (32 - $subnet));
my $ipaddrstart = &ip2dec($ipaddr) & $subnetdec;
$retip[0] = $ipaddrstart;
$retip[1] = $ipaddrstart + (2 ** (32 - $subnet)) - 1;
}else{ # 単一の IP
$retip[0] = &ip2dec($ip);
$retip[1] = 0;
}
return @retip;
}
0891nobodyさん
2007/09/02(日) 01:22:15ID:???質問です。
ユニークな6〜8文字の英数字文字列があるのですが、この文字列を他の文字列(英数字10文字)にしたいんですが、
それもユニークにしたいんです。
ならべく元の文字列がわからないようにしたいんですが、何か方法はありますでしょうか?
ユニークな文字列は5万行ぐらいあります。
0893nobodyさん
2007/09/02(日) 01:33:55ID:???0894nobodyさん
2007/09/02(日) 01:38:33ID:???2行目は初期化してるだけ
3行目は
111.222.333.444 という IP をループさせないで素直に書くと
(111 * 256 * 256 * 256) + (222 * 256 * 256) + (333 * 256) + 444
となります
これじゃ見た目がアレなのでループで回す関係上基準値というか初期値を定義してるのが3行目です
0895nobodyさん
2007/09/02(日) 01:40:06ID:???じゃぁ初心者じゃないあなたが書いてみてください
参考にしたいです m(_ _)m
>>890
ここまで書いておいてアレですが IP アドレスが指定する範囲に収まってるかどうかチェックするような
perl モジュールがあったはずです
0897nobodyさん
2007/09/02(日) 01:54:25ID:???既存のハッシュ関数を元に自分で作りなさい。
MD5とかSHA1も中身は乱数表でクルクルさせてるだけだから。
0899nobodyさん
2007/09/02(日) 02:10:43ID:???それは知ってたけど、0から書いて10進にする過程を勉強したかったからそういったコードを期待したのだが・・・
0900nobodyさん
2007/09/02(日) 02:18:02ID:???0902nobodyさん
2007/09/02(日) 13:00:20ID:???ここは初心者が初心者に答えるスレですね
0903nobodyさん
2007/09/02(日) 15:05:41ID:???0904nobodyさん
2007/09/02(日) 18:56:16ID:???PHPやRuby Java はすんなり理解できるのに Perl は納得いかないことばかりだ・・・
0905nobodyさん
2007/09/02(日) 19:05:01ID:???2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
まずどういう部分が納得いかないでわからないでいるのかを書かないと教えてもらえないよ
0906nobodyさん
2007/09/02(日) 19:35:56ID:???んー、>904に特に意図は無いんじゃねーのかな。
質問スレに書くべきことかどうかはともかく。
良し悪しは別として、Perlは怠慢・短気・傲慢の方向に進化した言語だから、
他言語から入って来たような人だと違和感があってもおかしくないっしょ。
0907nobodyさん
2007/09/02(日) 19:39:57ID:???>Perl ってなんでこんなに複雑なんだ?
これじゃなきゃ、CPANにあるような膨大なモジュールを作り出せないよ
0908nobodyさん
2007/09/02(日) 20:30:52ID:???0909nobodyさん
2007/09/02(日) 21:26:57ID:???0910nobodyさん
2007/09/03(月) 16:56:41ID:EmlGMulIリファレンスも渡さずに呼び出し先が$_を変更する事はできますか?
0911nobodyさん
2007/09/03(月) 17:11:15ID:???やってみたら判るだろ?
perl -le '$_= 1 ;sub { $_=2}->(); print $_ '
0913nobodyさん
2007/09/03(月) 17:29:35ID:???perl -le '$_= 1 ;sub { local $_=2}->(); print $_ '
0914nobodyさん
2007/09/04(火) 00:51:54ID:???0917nobodyさん
2007/09/04(火) 06:15:03ID:???A:「映画館でいいんじゃね?」
914:「コンドームも持たずに何やってんだボケ!!」
、、、くらいに>>914はズレてんなあ。QもAもコンドーム持ってっか
どうか会話内容からは分からんのに。それどころかmy知ってるし、
使ってる可能性の方が高いのに。
0918nobodyさん
2007/09/04(火) 07:00:37ID:???0919nobodyさん
2007/09/04(火) 08:23:01ID:???0920nobodyさん
2007/09/04(火) 12:41:44ID:???use strict, warningsは使わないよ
こんなの使って喜んでるうちは素人だね
0923nobodyさん
2007/09/04(火) 14:03:30ID:???use strict, warningsは使わないよ
こんなの使って喜んでるうちは素人だね
0925nobodyさん
2007/09/04(火) 14:17:32ID:???use strict, warningsは使わないよ
こんなの使って喜んでるうちは素人だね
0926nobodyさん
2007/09/04(火) 14:19:02ID:???0927nobodyさん
2007/09/04(火) 17:09:14ID:???use strict, warningsは使わないよ
こんなの使って喜んでるうちは素人だね
0928nobodyさん
2007/09/04(火) 21:03:16ID:???0929nobodyさん
2007/09/04(火) 22:18:58ID:???子は一定の処理を行い、またforkして孫をつくる。forkしたあとはexit。
孫も処理を行い、exitする。
これをやると、たまに500内部サーバーエラーが起きるんだけど、
理由がわかりません。
forkする際には、どちらも$|=1、標準出力は閉じています。
0930nobodyさん
2007/09/04(火) 23:04:14ID:???0931nobodyさん
2007/09/05(水) 01:30:11ID:???何処に居る!!
0932nobodyさん
2007/09/12(水) 18:15:02ID:w11eoBjq何か数学系の関数を提供してくれるモジュールがありますでしょうか?
また、自分でやる場合は結局階乗も以下のようにすることになるのでしょうか。
sub kaijo{
my $n = $s = shift;
for(1..($n-1)){ $s *= $_ }
return $s;
}
組み合わせ関数も自分で書くしかないんでしょうか。
あんまり軽く仕上げる自信がないですが。
0933nobodyさん
2007/09/12(水) 18:16:00ID:???0934932
2007/09/12(水) 18:30:54ID:w11eoBjqsub kaijo{
my $n = shift;
for(1..($n-1)){ $n *= $_ }
return $n;
}
sub niko{
my $n = shift;
my $m = shift;
return &kaijo($n) / ( &kaijo($m) * &kaijo($n-$m) ) ;
}
print &niko(14,2);
とりあえずヒマなので自分で書くのならという事で試しに書いてみました。
何千っていう計算をさせてみようかなって思ったのでちょっとした重さの違いが大きな差につながるかなとおもてまうsが。
採点かアドバイスか。何か下さい。
>>933
階乗ってべき乗使ってできるんでしたか?
すいません調べてみます。
って云うのは仕事上、多用しています♪@三女ウコン
0936932
2007/09/12(水) 19:01:36ID:w11eoBjqmy $n = shift;
for(1..($n-1)){ $n *= $_ }
return $n;
}
sub combin{
my $n = shift;
my $m = shift;
return ($n==0 or $m==0 or $n==$m) ? 1 : fact($n) / ( fact($m) * fact($n-$m) ) ;
}
エクセルに名前倣いました。
それと僕の勘違いで二項係数全然いりませんでした。
別の質問をさせてください。
my @array = qw/1 13223 46 4 29 3/;
こういう風に配列に数値が入ってる場合の、総和を出したい時はどうコーディングするのでしょうか?
@array[0..2]の分の総和
@arrayの総和
など確率のプログラムなので、
@arrayは数千の要素数
それを0と1の総和0-2の総和、0-3の総和のように最後までやってifでわけたいところがあるのですが。
0937932
2007/09/12(水) 19:02:25ID:w11eoBjqありがとうございます。
三乗根の計算ですね。
0938nobodyさん
2007/09/12(水) 19:08:56ID:???0939932
2007/09/12(水) 19:18:07ID:w11eoBjq具体的なコードを教えてもらってもいいでしょうか?
僕もmapあたりでかっこよくいけると思ったのですが、なかなかそうもいかないというか、
思いつかないんです。
sub sum{
my $a;
foreach(@_){ $a += $_ }
return $a;
}
で、こんなの書いてみました。
いちいち変数を使うあたりがいやです。変数を使わなければmapでも出来るのか?
とか思いますが。
0940nobodyさん
2007/09/12(水) 19:45:29ID:???0941nobodyさん
2007/09/13(木) 02:52:57ID:???0942nobodyさん
2007/09/13(木) 04:53:33ID:???0943nobodyさん
2007/09/13(木) 05:20:26ID:???って外部モジュール使うって
意味だったんだね。
0944nobodyさん
2007/09/13(木) 08:08:01ID:???「変数使わない」って結構大変だし、それで上等だと思うけど?
print eval join '+' , @arr ;
>>943
・・・釣り?
0945nobodyさん
2007/09/13(木) 20:30:12ID:QEyk4I0D$form =~ m/([++,,、、。。__\// ])/)
正規表現で上記のような記号を抽出しようとすると、
どうもうまく抽出されません。
たとえば「?」が半角の。になってしまいます。
文字コードはjcode::sjis2euc(\$form)で事前に
EUCにしておりますが(ソースコードもEUCです)、
何か対策等ございましたらご教示いただきたく思って
おります。
宜しくお願いいたします。
0946nobodyさん
2007/09/13(木) 20:53:20ID:???ことになる
あと、日本語EUCと言えども文字の並びによっては別の文字と同じ文字コードパターンがきて
文字の境目が部分だけでは判断できにくくなる
対策としては先頭から1文字ごとに分割して判断するのが素直なやり方
0947nobodyさん
2007/09/13(木) 21:15:58ID:???0948nobodyさん
2007/09/13(木) 21:53:49ID:???アドバイス感謝です。
できないことがわかりましたので、早速以下に変えてみました。
報告とさせていただきます。
-------------------------------------------------------
my $form_length = length($form);
for (my $i = 0; $i < $form_length; $i++) {# 文字を1文字ずつ処理(日本語対応)
my $form_substr = substr($form, $i, 1);
if ($form_substr =~ /[\x80-\xff]/) {
$form_substr = substr($form, $i++, 2);
}
if(($form_substr eq '+') ||
($form_substr eq '+') ||
($form_substr eq ',') ||
($form_substr eq ',') ||
($form_substr eq '、') ||
($form_substr eq '、') ||
($form_substr eq '。') ||
($form_substr eq '。') ||
($form_substr eq '_') ||
($form_substr eq '_') ||
($form_substr eq '/') ||
($form_substr eq '/') ||
($form_substr eq ' ') ||
($form_substr eq ' '))
{
&error_out();
last;
}
}
0949nobodyさん
2007/09/13(木) 22:06:55ID:???ifでくくるにしてもgrepなりfirstなりで検索するとか
ハッシュテーブル使うとかすりゃいいのに・・・
if (grep{ $_ eq $str } @mojilist) {
if ($mojilist{$str}) {
$pat = join '|', mapquotemeta @mojilist
$form =~ m/($pat)/
0950nobodyさん
2007/09/13(木) 22:12:41ID:???足りない部分は想像力で補ってくれ
if (grep{ $_ eq $str } @mojilist) {
・・・
%mojilist{$str} = map { ($_=>1) } @mojilist;
if ($mojilist{$str}) {
・・・
# このやり方はすごく効率が悪い
$pat = join '|', map { quotemeta $_ } @mojilist;
$form =~ m/($pat)/;
0951nobodyさん
2007/09/14(金) 14:13:47ID:???Perl言語を用い、fpingの出力ファイルから、
ラウンドとリップ時間のみの数値列を出力するプログラムを作成せよ。
という宿題がでました。
何から手をつければいいかわからない状態なので、もしよかったら教えてもらえないでしょうか?
0953nobodyさん
2007/09/14(金) 20:30:20ID:???> 足りない部分は想像力で補ってくれ
エスパー能力を要求する回答者イラネ
0954nobodyさん
2007/09/15(土) 13:34:20ID:???0955nobodyさん
2007/09/15(土) 16:49:52ID:iajdiFDwループ回数を増やすほど理論値に近似しますのでできるだけ増やしたいですが、
あまり増やして、数十分も処理を続けられると困ります。
ループ1回あたり何秒かかるのか。
もしくは1秒で何回ループさせられるのかを調べるコードを教えてくだしあ。
0957955
2007/09/15(土) 17:03:02ID:iajdiFDw早速ありがとうございます。
英語読めないんですがperldocちょっと読んでどうやらtimethisでできそうな気が。
でやりましたら、
error 0.168701171875 at (eval 6) line 40.
なんて表示されました。
どういうエラーでしょうか。
my $code = q{コード};
timethis(1,$code);
って感じでやってみました。
「コード」内で別モジュールを使ったり、コード内にない自作関数を使ったりするのはありですよね?
それともrequirやuseもコード内でやるべきですか?
イマイチうまくいきません。でもあと少しっぽいのでもう少しだけアドバイスお願いしまうs。
0958955
2007/09/15(土) 17:05:33ID:iajdiFDwdie
をコメントアウトしてやりなおしたら
Illegal division by zero at (eval 6) line 47.
こんなエラーにかわりました。
改善策わかりますでしょうか?
0959955
2007/09/15(土) 17:06:51ID:iajdiFDwもうちょっと挙動を調べて又きまう。
0960955
2007/09/15(土) 17:24:13ID:iajdiFDw0961nobodyさん
2007/09/15(土) 21:08:38ID:???0962nobodyさん
2007/09/15(土) 22:37:55ID:???0963nobodyさん
2007/09/15(土) 23:36:16ID:???事をみつけてはコーディングしてみています。
複雑なループ処理等になってくると全てがきっちり動いてるのか確認大変ですね。
今なにをやっているかという具体的な中身を視覚化してくれるモジュールなどあるのでしょうか?
自分で「よし、まずはこの変数の動きをチェックしてみよう」みたいな事をやっていくのにも限界があるなと思うこのごろです。
0964nobodyさん
2007/09/15(土) 23:40:09ID:???0965963
2007/09/15(土) 23:47:45ID:???確かエラーを見つけるものですよね?
エラー修正はそこまで苦労しないのです。
普通に何行目あたりに構文エラーがあるなどとわかりやすいですし。
問題は動いてるけど、この出てきてる数値が果たして本当に合っている数値なのかってことです。
それのコードの検証作業を補助してくれるものはないのかなと思ったのですが。
以前にフローを視覚化するなんとかがあるとかないとかって聞いたことがあります。
Perlではなかったかもしれませんが。
実際はもっとわかりやすく、実際に動かした時の逐一の動作を見せてくれると楽だな。と。
0966nobodyさん
2007/09/15(土) 23:49:53ID:???0968nobodyさん
2007/09/16(日) 00:05:24ID:???追加書き込みでログ保存するサブルーチン書いて
&func("\$val=$val");
って書いていけば簡単にできると思うが
0969nobodyさん
2007/09/16(日) 00:18:53ID:???まぁ、プログラム作ってる最中っていうより、プログラムできあがったけど
なんか動作があやしいって時に使うもんだけど。
自分がテストやんなくていいなら使わないか。。。
0970nobodyさん
2007/09/16(日) 02:17:16ID:???とりあえず、perlデバッガなら、w 変数名 と c だけ覚えておけば、
変数をヲチできるよ。
大体は、print文や、ログの事後解析で事足りるから、
デバッガは殆ど使わないな。
0971nobodyさん
2007/09/16(日) 03:26:56ID:???よく多重のハッシュを使うから、これがないとね。
0972nobodyさん
2007/09/16(日) 07:21:24ID:y2OdqWq5print (sort{$a<=>$b}@list)[0];
これで上手くいきません。並べ変えた0番目の要素を表示したいのです。
別配列に一旦入れるのは避けたいです。
確かナイスな方法があったような気がするのですが思い出せません。
お願いします。
0973nobodyさん
2007/09/16(日) 07:33:41ID:???0974nobodyさん
2007/09/16(日) 07:43:09ID:y2OdqWq5すっげえ男前。
忘れてたのとは違うやり方だけどナイスですね。
しかしどういう理屈でしょうか?
[0..1]とかも使えちゃいましたし。
プラス演算子がおかれると何故配列として認識してもらえるのでしょうか。
print(式)
0976nobodyさん
2007/09/16(日) 07:52:15ID:y2OdqWq5回りくどい。
0977nobodyさん
2007/09/16(日) 08:32:37ID:???scalar() と似たもんだ。
print scalar ( (sort{$a<=>$b}@list)[0] ) ;
print + (sort{$a<=>$b}@list)[0] ;
配列スライス出力時に、+, scalar 共に使うのも良くない。
print + ( sort{$a<=>$b}@list)[0..2] , qq{\n};
print + ( sort{$a<=>$b}@list)[0..2] . qq{\n};
print scalar ( ( sort{$a<=>$b}@list)[0..2] ) , qq{\n};
print scalar ( ( sort{$a<=>$b}@list)[0..2] ) . qq{\n};
きちんと挙動確認して使うならいいかもしらんが後に読みなおした時
(もしくは他の人が読んだとき)に混乱するのは必至。
、、、が深くは突っ込まんでくれ。理解はしている(つもり)だが、
素人の説明を鵜呑みにするのはイクナイ。ここらへんは本とかperldocとか
読んでくれ。
これだとなんなんで。も一つ
printf "%d\n", sort{ $a <=> $b } @list ;
こっちは配列の中身が整数であることを「保証されない」時痛い目に
合うこと受け合いさ。
0978nobodyさん
2007/09/16(日) 09:19:49ID:???しかしいつも思うのだがO(n)で求めることができる最小値をO(n*log(n))はかかるソート使って求めるのは抵抗あるなあ。組み込みだからよっぽど長いのくわせない限り十分速いのはわかるのだが
0979nobodyさん
2007/09/16(日) 10:19:55ID:y2OdqWq5すいません。ありがとうございます。
print \(sort {$a<=>$b} @array);
こうすると配列のリファレンスができると思ったらできない。
それで思い出したけど、
print [sort {$a<=>$b} @array]->[0];
これが以前よく使っていた方法でした。これなら配列スライスも安全に
print @{[sort {$a<=>$b} @array]}[0..1];
とできますし。
()の中に配列が入ってるのに[0]でインデックス指定できるかできないか。
+をつけるとできる。scalar()の中に書くとできる。
>>978
その優先順位によって何が行われるんですか。
\()で配列リファレンスができなかったのは\の方が優先低いから先に3つのスカラーが出てきちゃった?
+()だと+が優先高い。。。で、+の優先が高いと何故にインデックス指定ができる?
0980nobodyさん
2007/09/16(日) 11:12:25ID:???0981nobodyさん
2007/09/16(日) 11:47:48ID:???0982nobodyさん
2007/09/16(日) 13:00:23ID:???根本的に間違ってますから
0983nobodyさん
2007/09/16(日) 14:12:00ID:???my @get = @_;
sort @get;
return $get[0];
}
print root 1,2,3;
普通は
print &root(1,2,3);
と書くでしょうし、それが一番わかりやすいですが、括弧なしで書いた場合は一体いくつまでをサブルーチンの引数と解釈されるんでしょうか?
0984nobodyさん
2007/09/16(日) 14:27:19ID:???挙動は変らんよ。与えられたリストを全部もってく。
print root 3,4,5, print q{hoge} ;
なんてマネしたら当然1 が返る(sort の行をきちんと機能させた場合)
がそれは、
print &root( 3,4,5, print q{hoge}) ;
と同じわけで本来の挙動だ。
お前さんが prototype の事を質問しているのだとしたら全く別の話。
0985nobodyさん
2007/09/16(日) 14:35:03ID:???http://perldoc.jp/docs/perl/5.6.1/perlfunc.pod
> 括弧を使うときには、単純な (しかし、ときには驚く結果となる)
> 規則が適用できます: 関数に見えるならば、それは関数で、
> 優先順位は関係ありません。
0986nobodyさん
2007/09/16(日) 14:42:55ID:???コーディングとちょっと違うかもしれませんがお願いします。
test.plを実行すると自分のパソコンのスペックで15分くらいかかります。
ファイル操作とか何もしない、コード内完結型?のコードなので、処理をさせてる間
他の作業をパソコンでしたいのです。
簡単に言うとtest.plの完遂を待ってる時間に2ちゃんねるでもして暇をつぶしたいのです。
なので30分かかってもいいので、test.plのCPUやメモリの最大使用率を通常の1/2にしたいのです。
可能でしょうか?
0987963
2007/09/16(日) 15:21:39ID:???う〜ん。なんか伝わってないような。
例えばsort関数が何をしているか視覚化して初心者に説明しなさい。
ってな時にsort関数のコードを渡せば自動で視覚化してくれるモジュールがあればなってことです。
自分でsort関数と同じ関数を作って、そこにごちゃごちゃと視覚化のためのコードを書くのは、
簡単な関数の時にしか「簡単じゃん」とは思えないですよね?
いや、簡単だというならsort関数の視覚化をこの場でやってもらえればいいんですけどね。
my @col = (4,6,2,98,2,1345,22);
この配列をsort関数がどういう手順でどういう事をしてるかを目で見えるようにするコードを「簡単に」どうぞ。
レス数が950を超えています。1000を超えると書き込みができなくなります。