昨日のperlshを改造してみた。
fr,fw,fa,lsという便利ツールを追加してみた。
frはファイル名を指定するだけでファイルを配列に展開してくれるもの。
PHPのfile関数に相当するやつね。いちいちopenするのがめんどくさいから作ってみた。
fw,faはファイル名と配列を指定すればファイルに上書き・追加するやつ。
lsはディレクトリ名を指定したらファイル一覧が得られるやつ。
ただ、本当は`dir /b C:\foo`とか逆クオートで書けばよさそうな気がするんだよね。
けど/bのオプションをうまく認識してくれないし、\(バックスラッシュ)があるとおかしくなるし。
その辺の都合もあって、ls ‘C;\foo’;とすればいいのを作ったと。
こうすればかなり便利になりそうです。
あと、複数行モードで打ち間違えたとき、clearと打てば、スプールを空にして、複数行モードから出れる。
それと、返り値を@ANSと$ANSという変数に入れて使えるようにしてみた。
そうそう、せっかくだからbinフォルダ内のbatファイルを見ながらbatファイルだけでいいのを作ってみた。
perlsh.bat.bz2
これを展開して、パスの通ったフォルダに置くだけ。
ちなみにこれ自体も正当なPerlスクリプトですよ。初めに変なのが入ってるじゃないかと思うかも知れないけど、
p @rem;としてみればよくわかると思う。おもしろい仕掛けですね。
さて改めていろいろやってみますかね。
> @ls1=ls 'C:\Music';;
> @ls2=ls 'C:\Music0';;
> foreach(@ls1){ s/\.wma$//; }
> foreach(@ls2){ s/\.mp3$//; }
> foreach $e1(@ls1){ foreach $e2(@ls2){ if($e1 eq $e2){ $e1=""; $e2=""; } } }
> grep(!/^$/,@ls1)
> grep(!/^$/,@ls2)
=> 'tmp'
空行は省略させていただいた。
こんな具合に2つのフォルダのwmaとmp3が一致してるか比較すると。tmpフォルダだけ余計にあるようですね。
> sub f{ sqrt(1- $_[0]**2); }
> f(0.5)
=> '0.866025403784439'
> $delta=1/1000;
> $s=0;
> for($x=0;$x<1;$x+=$delta){ $s+=f($x)*$delta; }
> $s
=> '0.785888866727756'
> $s*4
=> '3.14355546691103'
> $mypi=$ANS
> use Math::Trig
> pi
=> '3.14159265358979'
> abs($mypi - pi)/pi*100
=> '0.0624782884881649'
あまりにしょうもない返り値も省略した。中心角90度の扇形の面積を数値積分で求めてるんですね。
サブルーチンの定義もできますし、あまりつかわないforループですが、当然こんな風に使えます。
piを取ってくるのに、use Math::Trigとしても通る。いやすごいですね。
1000分割するだけで、誤差率0.06%ってどうなんだろうかね。まぁまぁいい線いってるのかな。
> @lines=fr('C:\root\実験\コンデンサ放電\r5.txt');;
> @datas=();
> foreach(@lines){ _
* @data = split( /\s+/,$_);
* push(@datas, [$data[0],$data[1],$data[2]*1e-3 ] );
* }
*
> $si=0; $sv=0; $svs=0; $sis=0;
> $first=shift(@datas)
=> ['0','10','0.0019']
> ($lastt,$lastv,$lasti)=@$first;
=> '0''10''1900'
> foreach(@datas){ _
* ($t,$v,$i)=@$_;
* $delta=$t-$lastt;
* $si+=($lasti+$i)*$delta/2;
* $sv+=($lastv+$v)*$delta/2;
* $sis+=($lasti**2 + $i**2)*$delta/2;
* $svs+=($lastv**2 + $v**2)*$delta/2;
* ($lastt,$lastv,$lasti)=@$_;
* }
*
> $si
=> '0.0992'
> $sv/5e3
=> '0.0986'
> $sis*5e3
=> '0.505275'
> $svs/5e3
=> '0.4998688'
かなり昔の実験で、コンデンサを放電させて電気量とエネルギーを測定する実験。
なかなか作るの難しかったけど、こうやって試しながらやっていって、成功したのををplファイルに落とせばいいと。
台形を作って積分するという方法で、わかりやすくていいですね。
さて、$siと$sv/5e3の結果は電気量。理論値は0.100[C]みたいだから、なかなかいい具合ですね。
$sis*5e3と$svs/5e3はエネルギ、こちらも0.500[J]とまぁまぁいい線行ってますね。
当時はPerlなんて使ってなかったから、計算できるソフトを探したもんだが、
実はこの方法なら表計算で簡単に計算できるし、さらにかっこつけてPerlで計算できると。
まぁこれをやってるとき、単位がmAなのを忘れててとんでもない数値が出てきたけど、最後に補正してもよかったか…
見ての通り、@linesから@datasに変換するときに補正するようにしたけど。
レポートをサボるためにPerlは作られたとよく言われます。
正直これでレポートがサボれるのかよくわからんのだけど…
しかしTeX使ってる人なら確実にサボれるよな。
CSVファイルをTeXのフォーマットに落として、GnuPlot通したり…
そのあたりのことは僕は表計算でやってるけどさ。
Perlを自分の手のように、足のように使うためにperlshは便利ですね。
今、ちょっとしたテキストファイルの、行頭がスペース1つから始まってるのの行数を調べたけど、
> $data = <* (テキストファイルをひたすらはりつけ)
* EOF
*
> @lines = split /\n/,$data
> grep /^ [^ ]/,@lines
> @ANS+0
返り値は省略した。果てしなく返り値が表示されてへこんだから。
まぁこんな風に簡単に調べられる。もちろん@ANSを@linesに代入しておいてから、
@lines+0で行数調べて、frで書き出してもいいし、いろいろできる。
これのためだけにスクリプト書くのめんどくさいからねー。