日記帳だ! with Tux on Libserver

二度目の大改造!! 日記帳…か?を継承し、より柔軟でパワフルなBlogに変身しました。

RSSに対応しています。リンク・コメント・トラックバックは自由にしていただいてほぼ問題ありません。
RSS購読方法、僕のリンク・コメント・トラックバックについての考えを読むことをおすすめします。

JavaScriptを有効にし、Cookieを受け入れ、以下のブラウザを使うことで完全なコンテンツが楽しめます。
Mozilla Firefox 3.0(Get Firefox)・Opera 9.6・Safari 3.2・Lunascape 4/5(Gecko)・Lunascape 5(WebKit)
Internet Explorer 7/8とそれを使うIEコンポーネントブラウザ(Lunascape・Sleipnirなど)

<< 過去

それは正規表現ならお手軽だ

Excelで R162 とか PC21 とかなってる文字列をアルファベットの部分と数字の部分に分解したいということで相談を受けた。

けど、VBA含めてもExcelではあんまりいい方法が思いつかないんだよなぁ。

職場で使っているテキストエディタならば、わりと簡単に対応できるよと返答した。


このテキストエディタには正規表現での検索・置換機能がある。

これで ([A-Z]+)([0-9]+) → \1\t\2 と置換すればよいのだ。

([A-Z]+)([0-9]+)はアルファベット1文字以上、数字1文字以上が連続して現れることを表す正規表現、

置き換え後の文字列の中で \1 とすれば最初の括弧の中身、\2とすれば2番目の括弧の中身の意味になるので、

その間をTabで区切ってあげれば、あとはこれをExcelにでもペタっと貼ってやればいいわけだ。

「手動でやる必要があるが、確かに手軽だ」ということで、とりあえず目標は達成された。


自分の仕事でもテキストエディタで正規表現置換をするのはよくやっている。

僕は 2016-12-16 → 2016.12.16 のように数字の区切り文字を差し替えるのによく使っている。

このケースでは (\d{4})-(\d{2})-(\d{2}) → \1.\2.\3 と置換すればOKだ。(\d と [0-9] は同じ意味)

単純な置換では他の部分に影響が出てしまう。なので、こうやって正規表現で指定することをやるわけだ。

PerlとかPHPとかでたくさん正規表現を使っていたから、正規表現を書くのは慣れっこだ。


このときはExcelの組み込み関数にしても、VBAにしても正規表現は使えないものだと思ったけど、

VBAでは一応は正規表現が使えるらしい。

正規表現によるマッチング (Office TANAKA)

VBScript.RegExpオブジェクトをVBAで呼び出すというやり方をするらしい。

Internet Explorerに依存するらしいが、まぁWindowsならばあまり問題は無いだろうと。


Excelで文字列処理はけっこうやるんだけど、LEFT,MID,RIGHT関数で文字数指定で切り貼りするのがほとんどだ。

例えば 4C513135 36322020 とかなっているメモリダンプがあって、

最初8ByteはASCIIコードで表記された文字列なので、これを文字列に戻すとなれば、

=CONCATENATE(CHAR(HEX2DEC(MID(A3,1,2)),CHAR(HEX2DEC(MID(A3,3,2)), ... ,CHAR(HEX2DEC(MID(A3,16,2)))

のようにMID関数で2文字ずつ切り分けて、HEX2DECで16進数を解釈させて、CHARで文字コードから文字にして、CONCATENATEで戻すと。

こんな長い式を書くのはアホらしい気もするが、一回書いてしまえばあとは使い回せるから割に合うと。

ちなみにPerlだとこれに相当するのは join('',map{chr(hex)}(m/[0-9A-F]{2}/g)) で何Byteでも対応できる。

文字数を数えれば済みそうな仕事もPerlでは正規表現を使って簡単に書けるし、こっちの方が楽だと。


VBAで正規表現を使う方法も一応はあるというのは新しい発見だったが、息を吸うように使えるほど手軽なものではないのも確か。

正規表現なら簡単にできるんだという場合はまずテキストエディタに頼るのが得策だろう。

なかなか職場で使えるツールも限られますからねぇ。(cf. Excelがどこでも使えるからVBAはうれしい )


Author : hidemaro
Date : 2016/12/16(Fri) 21:11
Perl・PHP・Ruby・Python | Comment | trackback (0)

Scilabではハンガリアン記法も無意味ではない?

「最近、Scilabでのシミュレーションプログラムを作る人も増えたが、この機会にソースコードレビューを行ってノウハウの共有を行うべきだ」

と先日、指導教員が言ってきて、ごもっともだという話で、今日、レビューを行ったが、

思いの外、時間を食われてしまった。

学生それぞれが自分が使うために作り、再利用を想定していなかったということで、可読性がよくなかったと。

各自、多少なりともソースコードの掃除をしたのに、それでもなかなか。


指導教員が書いたC++のソースコードを見ると、変数の名前の頭に型を表す文字が書いてあることが常だ。

double型の変数がd_Fooになってたりそういうの。あんまり詳しく覚えてないけど。

これ、ハンガリアン記法とか呼ばれる物で、昔、Microsoftが好んで使っていて、

MFCなんかはそういう記法が使われているので、見たことあるひともいるかな。

ただ、最近ではそういうのを使うことってあんまりないと思うんだよね。

だってIDE(統合開発環境)で変数名を確認すれば、その変数の型なんて一瞬で分かるし。

最近では型推論なんてものもありますしね。C#のvarだとかC++11のautoだとか。

記述から型が自明であれば、型の名前を省略できると。

System.Collections.Generic.Dictionary<System.String,System.String>とかクソ長い型名を書かなくても、自明なら省略できると。

それでも、IDEはvarが実際にはどんな型であるのは判定して表示してくれるわけで、いやはや便利な時代になりました。


そんなわけでC++などで型名を表す文字を変数名に付けることは無意味と思っているのだが、

Scilabの場合、必ずしも無意味とは言いがたい事情もある。

というのもScilabには型という概念がなくて、全ての変数が行列だから。

それぞれの変数がスカラー(1x1行列)か1次元行列か2次元行列か区別することは重要であると言える。

行列にスカラー倍していたと思ったら、行列同士のかけ算だったとかなると目も当てられないことになることがある。

確かにそれはそうだ、と今日のレビューで思ったのだ。


今年の春頃に研究室内でのScilabでの変数名に付ける文字について相談していた。

スカラーが s_XX 、1次元行列(ベクトル)が v_XX 、2次元行列が m_XX とか。

画像を表す行列は特別に im_XX にしようとか、そういうことも決めていた。

ただ、僕が今使っているソースコードはその規則が決まる前に書いたものが元になっているので、

積極的に直す気が起きなかったのだ。あまり好きじゃなかったのもある。


ただ、そういうのを自分のソースコードに適用しようとすると、3次元以上の行列が出てくるので、これはどうするんだという話になった。

Scilabで3次元以上の行列はハイパー行列と呼ばれている。

数学では3次元以上の行列は扱わないから、行列同士のかけ算や逆行列が定義できないということで特別扱いを受けているのだと。

逆に言えば3次元のハイパー行列も4次元のハイパー行列も扱いはそんなに変わらないのだとも言える。

じゃあハイパー行列の変数に付ける文字はどうしようか。いろいろあったが h_XX ということに落ち着いた。

個人的には mm_XX を推してたのだが、まぁhyper matrixならhだろということになった。別にそれでもいいけどね。


スカラーまでいちいち変数に文字を付けるのはアホらしい気もするのだが、

ベクトル・2次元行列・ハイパー行列の区別はしっかりやりたいなと。

あとは特別な行列として画像とフィルタかな。

そういうことを今回のソースコードレビューで思ったのだった。


Author : hidemaro
Date : 2014/12/15(Mon) 23:53
Perl・PHP・Ruby・Python | Comment | trackback (0)

ラプラシアンフィルタ単独は残念

今度、研究室でScilabでの画像処理について実習を行うことになっていて、

ここ最近はそのための教材を作っている。


画像処理といえば線形フィルタ、線形フィルタといえばまず移動平均フィルタだよね。

ということで、

imSmoothed=imfilter(double(imIn),ones(5,5)/25);

ということで、まずはこれをやりましょうと。

それでラプラシアンフィルタをやって、ゼロクロス点を調べて、輪郭抽出しようと。

ついでに二次元FFTを使ってフィルタ前後の画像の周波数スペクトルを比べてみようと。


それじゃあ次にラプラシアンフィルタを実行してみるかと。
imLaplacian=imfilter(double(imIn),[1,1,1;1,-8,1;1,1,1]);

一番基本的なやつだね。これでゼロクロス点調べたら輪郭が出てくるぞ!

と思ってやってみたのだが、出てきた輪郭が汚い。

それで思い出した。ラプラシアンフィルタを単独で使うとノイズまで強調されて大変だから、

平滑化してからラプラシアンフィルタをかけることが多いんだった。

というわけで移動平均フィルタとの組み合わせでいい感じに輪郭が求まった。

実習のときには実際にやってみて、ラプラシアンフィルタ単独の弱点を確認してもらってから教えよう。


去年の実習の内容を元に、いろいろ要望を踏まえて教材を作り直してるわけだけど、

去年の実習はいきなりガウシアンフィルタを作らせるということで、それはいらないのではという意見があった。

確かにそうだと思ってやってたんだけど、ガウシアンを使ってたときにはこういう問題なかったんだよね。

というのもDoGフィルタ、すなわちガウシアンフィルタの差分をかけてたから。

DoGフィルタってバンドパスフィルタになってるから、ノイズの輪郭は出ないようになってたんだ。


平滑化フィルタをかけてから、ラプラシアンフィルタをかけるのもいいけど、

ラプラシアンフィルタに平滑化フィルタをたたみ込んだフィルタを使っても一緒のことだ。

LoGフィルタはLaplacian of Gaussian、ということでまさにそういうことをやっているわけだ。

なぜガウシアンと組み合わせることが肝心かということを知る上では、ラプラシアン単独で失敗することはかえっていいのかもしれない。

実用面ではLoGフィルタとか、それに似たDoGフィルタとかの方がいいのかもしれないけど。確かに特性はいいし。


Author : hidemaro
Date : 2014/06/17(Tue) 23:42
Perl・PHP・Ruby・Python | Comment | trackback (0)

Cythonを使うほどのことはある?

今日はB4向けのScilab講習があったんだけど、

その例題の中に、Scilabのforと行列演算の比較があった。

ちょうど1年前ぐらいに話題にしたが、Scilabというのはいまどき純粋なインタプリタらしく、

ループさせると構文解析まで繰り返すためか途端に遅くなる。

Scilabでは速いとされる

それゆえに非効率に思えても無理やり行列演算で書いた方が早いという特徴を持っている。

というかScilabはともかく、売り物であるところのMATLABも似たようなものらしいし、それはいかんよなぁ。


PythonやRubyではあらかじめコンパイルするから、forで極端に遅くなるようなことないはず。

という話をしていたら、PythonをCに変換することでさらなる高速化を実現する方法があるとのこと。

うーん、確かに高速化できるだろうけど、そこまでして高速化するメリットってなによ。

そんな疑問はあったものの、調べてみたら、どうもCythonというもののことを言っていたようだ。


Cythonの概略を言えば、PythonのコードをCに変換してネイティブコードを作るものだが、

厳密にはCythonというのはPythonとは異なる言語らしいのだが、Pythonのコードはそのまま使えるようだ。

Cythonを使うことで高速化するためのポイントは型指定を行うことらしい。

動的な言語では変数の型が動かしてみるまでわからないので、ここにオーバーヘッドがかかってしまう。

けどこれはlong型とかわかってれば、それで高速なコードが生成できると、それがCythonを使うメリットらしい。

なるほどなぁ。


しかし、どこでCythonを使うかというのは1つ問題である。

基本的にはPythonのモジュールを作るために使われるものなのかなと思うんだけどね。

Cに変換して、それをコンパイルというのは、それなりに時間のかかる処理だろうから、一回切りのプログラムでそれはもったいない。

最初のコンパイルはあっさり、けど動作はそこまで速くないというのがLLだと思うんだよね。

Cと同じぐらい早いよと言われても、そのために最初にかかる時間が増えてはどうしょうもないという意見もあるだろう。

それでも計算時間が気になる場合には有効な方法と思うので、気になる人は調べて使ってみればいいと思う。


ところで、PythonやRubyではforで極端に遅くなることはないと書いたが、実際にRubyで試してみた。

s=0;
for i in 1..10000000
  s+=i
end

s=(1..10000000).inject(:+)

上と下で10回実行して所要時間を比較してみた。

すると上の平均が4.21[s]、下の平均が2.94[s]、まぁこんなもんならforで極端に遅くなっているということはなさそうね。

この2つで大きな差が出る環境はやっぱりおかしいんだ、とそういうことを改めて記して終わる。


Author : hidemaro
Date : 2014/05/07(Wed) 23:35
Perl・PHP・Ruby・Python | Comment | trackback (0)

区切り文字に悩めばエスケープに悩まない

最近、ちまちまPerlでスクリプト書いてたんだが、

区切り文字を何にするかでちょっと悩んだところがあったのでそのことを。


Perlというのはおもしろいもんで、正規表現やら文字列やらの区切り文字を自由に選ぶことが出来る。

正規表現の区切り文字には / が使われることが多い。

s/\/read\.php\/(\d+)/\/$1.html/g

いちいち/をエスケープしないといけないので、ディレクトリを書くときとか、HTML・XMLの要素を書くときとかに不便する。

けど必ずしも/を使わないといけないわけではなくて、任意の記号を使えるので、

s|/read\.php/(\d+)|/$1.html|

と、/以外の文字を使えば、/についてはエスケープする必要が無くなり簡単に表記できるようになる。

マッチの場合は、/を使う場合は /\t/ のように書けるが、これは m/\// のmを区切り文字に/を使う場合に限り省略できているだけだから、

/以外を使うときは m|/| などと書く必要がある。

あと ()や[]や{}など、括弧については m(/) や s[/read\.php/(.+)/][/$1.html] のように前後を対応させて使う。

qw(a b c d) のように使われているのはよく見ると思うけど、mやsでも同様のことだ。


けっこう僕は | を使うことが多くて、僕の書いたPerlのソースコードを見ると頻繁に使っているのが見て取れるだろう。

HTMLを入出力に使う時、いちいち / をエスケープするのは能率が悪いからね。

ところが | は正規表現では並列検索、すなわち or にあたるメタ文字でもある。

なのでそんなときは | は避けなければならない。普段はあまり問題にならないんだけどね。

それじゃあ # を使おうかなと思ったんだが、ちょうどURLの部分をいじくる正規表現で、 foo.html#bar のような表記とかぶってしまう。

うーん、じゃあ $ はどうだろう、と思ったんだが、これは $1 だとか変数の$とかぶってしまう。

じゃあ [] は? と思ったけど、これは正規表現だと [a-z] のような表記とかぶる。

{} は? と思ったんだが、運の悪いことに今回の置換処理には $foo{$3} とハッシュを使っているから使えない。

それで結局採用されたのは % 、こんなの区切り文字に普通は使わんぞと思って書いてた。

もう1つ、@という案もあって、これかなとも思ったんだが、% の方が区切り文字としては見た目がよいということでこちらが選ばれた。


そんなこと考えるぐらいなら / を使って /をエスケープしとけよ、なんて言われるかもしれないが、見にくくなるから嫌いなのよね。

ただでさえ . など正規表現で意味のある文字をエスケープしないといけないのに、それ以上なんてたまったもんじゃない。

普段は / か | でほとんど事足りて、それでもだめなら # あたりでなんとかなることが多かったんだけどなぁ。

今回は本当に運が悪かったが、納得のいく表記法が思いついてよかった。


正規表現を書くときの区切り文字のことには気を使うが、あまり気を使わないのが文字列を書くときの区切り文字だ。

Perlでは文字列の表記には '' と "" を使うのが普通だ。""だと変数、エスケープ文字が展開され、''だと展開されない。

それでよく、

'<a href="'.$list[0].'">'.$list[1]."</a>\n"

と、 '' と "" を巧妙に使い分けて、""の中に " が出てこないように書くことが多いんだが、

よくよく考えてみると、

qq|<a href="$list[0]">$list[1]</a>\n|

のように書けば、エスケープのことを気にせず書けるんだよな。

あまり文字列中での変数展開を使い慣れてないというか、後でこう書けば簡単だったなと思うんだけど、

ついつい文字列を連結させて書いてしまいがちで、なんとも残念。


もちろん変数でなければ文字列中に書いても展開できないから、

substr($date,0,4).'年'.substr($date,4,2).'月'.substr($date,6,2).'日'

のような場合は、文字列の連結で書く必要がある。

けど、こんな場合でも、

"@{[substr($date,0,4)]}年@{[substr($date,4,2)]}月@{[substr($date,6,2)]}日"

と変数展開をフル活用して書く方法もある。こういうのを特に好む人もいるんだろうが。

僕はもともと文字列の連結で書くことが多い人なので、こういう書き方はほとんどしない。

もっとも、このようなことをするのに素直なのは、

my ($y,$m,$d)=(substr($date,0,4),substr($date,4,2),substr($date,6,2));
"$y年$m月$d日"

と一旦変数に収める方法なのは言うまでもない。横着者はこういうのすっ飛ばして書きがちだが。


Perlで区切り文字を自由自在に変えられるということはあまり知られていないのかもしれないが、

うまく使えばエスケープが必要な場面がぐっと減り、書きやすく読みやすくなる。

これはPerlの大きな長所だと思っている。Rubyでもこういう書き方はできないから。

まぁ逆に言うとPerlに堪能な人でないとなにを書いてるのかわからなくなるという問題もあるのだが。

僕もこの機能を完璧に使いこなせているとは言いがたいが、なかなか便利なものだ。

これはめんどくさい! と思ったときには使ってみるとよいだろう。


Author : hidemaro
Date : 2013/12/30(Mon) 22:49
Perl・PHP・Ruby・Python | Comment | trackback (0)

Pythonの考えるprintのあり方

研究で既存の技術について調べるため、OpenCVを試しに使ってみた。

コンピュータビジョンのライブラリとして著名なOpenCVだが、

実は実際に使うのは初めてだった。


OpenCVを使ってプログラムを書くために標準で使える言語にはC・C++・Pythonがある。

C・C++はともかく、Pythonがあるのが特徴的だ。

もちろんそれ以外の言語でも別にライブラリを持ってくれば使える。JavaでもC#でもRubyでも。

まぁけど、とりあえず試しに使うのならお手軽のはPythonだよね。

というわけでPythonをインストールしてPythonからOpenCVを使ってみることにした。

Python用のモジュールをPythonのlib/site-packagesフォルダにコピーすれば、

import cv

img=cv.LoadImageM('foo.png')

とかすれば使える。


それでとりあえずはOpenCVに付いてきたサンプルのスクリプトを動かしてみるか……

と思ったらいきなりエラーが出た。

そのエラーの出た原因はOpenCVとは関係ない部分だったから驚いた。

調べてみたらPython 2用のコードをPython 3で動かしたのが原因だったようだ。

そもそもOpenCVのライブラリはPython 2での使用を前提としているようだったからPythonを入れ直すことにした。

そしたらちゃんと動いたんですけどね。


そのエラーが出た部分はこんな文だった。

print "OpenCV Python version of edge"

なにがおかしいんだ? と思われた方も多いかも知れない。

Python 2はこれで正しいので、こういう書き方をしている人は多いんじゃないかな。

これがPython 3から通じなくなった。


Pythonでは関数はかならずカッコを付けて呼び出すことになっている。

PerlやRubyでは foo("bar"); とも foo "bar"; とも呼び出すことが出来るのだがPythonはそこはしっかり決めている。

あれ? じゃあなんでprintはカッコなしでも動くんだろ?

実はPython 2までのprintは関数ではなく構文という扱いだった。なのでこれでよかった。

末尾に改行がいらないときは print文の最後にカンマを付ければそれでよかった。

とにかくPython 2までのprintはかなり特殊な扱いだった。


これがPython 3になりprint構文は廃止されprint関数で置き換えられることになった。

関数の呼び出しはかならずカッコを付けるから、

print("OpenCV Python version of edge")

と書くことが求められるようになった。

これがOpenCVとは関係なく発生したエラーの原因だ。


関数として一貫性を持たせるためとはいえ、これまで親しまれていた表記を廃止したというのはいかにもPythonらしい。

Pythonの思想を表した言葉にこんなものがある。

There should be one―and preferably only one―obvious way to do it

「あることをやるのに誰もが望ましいと考える方法は1つであるべきだ」なんて意味ですね。

Perlの"There's more than one way to do it"とは対称的だ。

このprint構文のprint関数への置き換えもこの流れに沿ったもので、

printも関数のルールに従うのが筋だとPythonの人は考えているようだ。

そのために過去のコードの互換性を無くすのはどうかと思ったが。変換スクリプトはあるらしいけどね。


Author : hidemaro
Date : 2013/06/07(Fri) 23:48
Perl・PHP・Ruby・Python | Comment | trackback (0)

Scilabでは速いとされる

研究室でのScilabの演習で画像処理をやっていたのだが、

その中でガウシアンフィルタを生成する処理を書いていた。

そこでScilab流のやり方を聞いたのだが、一般的なプログラミング言語では非効率に見えるやり方がScilab流だそうで。


一般的なプログラミング言語の例でやればこんな風になるよね。

gaussian=zeros(size,size);
for i=1:size
  for j=1:size
    gaussian(j,i)=exp(((j-size/2)^2+(i-size/2)^2)/2/s);
  end
end
gaussian=gaussian/sum(gaussian);

forでループ回して計算するよねって。

最後に総和が1になるように正規化してるが、これはsumを使ってやれば簡単なので、そこはScilabらしい書き方だが。


ところでScilabではこれよりもこう書いた方が速いそうだ。

[Y,X]=ndgrid(linspace(-size/2,size/2,size),linspace(-size/2,size/2,size));
gaussian=exp((Y.^2+X.^2)/2/s);
gaussian=gaussian/sum(gaussian);

ずいぶんコンパクトにできている。

なにをしてるかという話だが、ndgridを使ってsize×sizeの行列を2つ生成している。

これでYは –size/2からsize/2の Y座標の入った行列、XにはX座標の入った行列が生成される。

この2つの行列を使って、各要素で exp((x^2+y^2)/2/s を計算させると。各要素へのべき乗は .^ で書けて、

expに行列を入れれば各要素にexpが適用される。

Scilabは行列が基本だからこう書けばたちまち計算が出来てしまう。


やってることは一緒で、後者の方がコンパクトにできていることがわかる。

ただ、実際の処理を考えてみると、X,Yといった行列を一旦生成する必要があり、後者の方が計算量は多いように思える。

それでもforを使うより、行列の計算に落とし込んだ方がScilabでは速いらしい。

実際、もうちょっと重い処理、具体的にはゼロクロス点の検出で比較してみると20倍ぐらいの速度差があったようだ。

なんでだ?


調べてみるとこんな記述がひっかかった。

タイトルの通りです。Scilabに限らずインタプリタ処理をする言語では,ループ計算は遅くなります。

(Scilabの使用法3-ループ計算は遅いので,できるだけ使わない (琉球大学 理学部 物質地球科学科 物理系 NMR物性研究室) )

計算が重いのではなく、構文解析が重いのだという。

確かに純粋なインタプリタならforループではループごとに構文解析→実行の処理を繰り返す必要がある。

それに対して、行列の計算で書けば、計算はともかく、構文解析は一度行えばそれでよい。

計算量が少々増えても、forで構文解析を延々と繰り返すよりもましということらしい。


ただ、インタプリタ型の言語と紹介されることも多い、Perl・Ruby・Pythonなどは、

実行するとき、まずコンパイルを行ってからプログラムを実行している。

ユーザーはコンパイルを意識することはないが、内部的には コンパイル→実行 の流れを踏んでいるわけだ。

コンパイルといってもネイティブコードを生成するようなものではなくて、中間コードを生成する処理なんだけど、

構文解析はコンパイル時に1回やるだけで済むし、最適化を施すこともできる。

とにかく、実行前にコンパイルする方がずっと高速に動作できるので、インタプリタ型の言語と紹介されるものもそうなっていることが多い。

だから、インタプリタ型の言語だからforループが遅いというのは一般的には正しい説明とは思わないが、

事前にコンパイルを行わず、本当に逐次的にソースを読み実行する場合は確かに正しい。


Scilabでは高速とされる記述では、とにかく行列を山ほど生成することになる。

なのでメモリ消費が激しいそうだ。

ScilabじゃなくてMATLABの話だが、大量のデータを処理するときメモリが足らなくて困っていると言っている人がいた。

Cで書けばメモリ不足の問題は解決するが、しかしMATLABのライブラリが使えず、特にGUIの面で不便が生じる。

そういうわけで困っていたようだが。


行列計算への強さ、ライブラリの充実を求めてScilabを使うわけだが、

プログラミング言語として見たときの弱さがこういうところに現れていたのかなと。

確かに便利なんだけど、処理が遅くてやってられないとか、処理できるデータ数が限られるとか、

そういうことになるぐらいなら、Perl・Rubyだとか賢い言語を使うか、Cで書いてネイティブコードでガシガシ動かすのがよいように思える。

Scilabでプロトタイプを作って、場合によっては他の環境に動かすと、そういうことも考慮に入れるべきかなと。

Scilabで関数1つでできていたことを、自分で記述する必要もあるかもしれないけど。


Author : hidemaro
Date : 2013/05/22(Wed) 23:53
Perl・PHP・Ruby・Python | Comment | trackback (0)

Dropboxからスクリプトへ

自分で書いたテキストデータを読み込んで、これをHTMLで整形して表示するようなスクリプトを書いて使っていたのだが、

データを書き換えるたびにいちいち更新してアップロードしなおすのがめんどくさかった。

なんとかこの手間を省いて、簡単に更新できるようにならんか、

というところでDropboxを活用する方法を思いついた。


サーバー上にHTMLに整形するスクリプトを配置して、

この入力データをDropboxからダウンロードしてくるようにすればいいわけだ。

これならDropboxと同期しているPCならどこからでも編集できて、

サーバーに更新しろと指示を与えるだけで、どこでも更新することが出来る。

これはかなり便利そうだ。


どうやってDropbox使うのがいいのか?

以前Mechanizeを使ってDropboxにバックアップを取るスクリプトを書いたが……(参考 : Dropboxにバックアップデータを投げつける )

もうちょっと簡単な方法はないか、と思って調べてたら、こんなものが。

WebService::Dropbox

DropboxにApp登録をして、それで使うようだ。

というわけでDropboxにApp登録してみた。

My apps (Dropbox)

ここでアクセス出来る範囲をApp folderかFull dropboxか選ぶ。

App folderが推奨のようだが、単にそのアプリで使うファイルを置いておくだけならこちらの方がいいでしょうね。

このアプリからはAppsフォルダ以下に作られるそのアプリ専用のフォルダだけアクセス出来る。


では次にユーザー認証、といっても1人しか使わんので簡単に。

use WebService::Dropbox;
my $dropbox = WebService::Dropbox->new({
    key => '...', 
    secret => '...' 
});
print 'Access this URL:',$dropbox->login('http://hdmr.org/'),"\n";
<STDIN>;
$dropbox->auth;
print 'access_token: ',$dropbox->access_token,"\n";
print 'access_secret: ',$dropbox->access_secret,"\n";

loginでコールバックのURLを指定して認証用のURLを得る。

これにアクセスして認証をしたら、戻ってきてaccess_token,access_secretを得る。

これを保存しておけばOK。

認証を行うとAppsフォルダ以下にそのアプリ専用のフォルダが出来る。

今回はここに読み込むテキストファイルを置いておいた。


あとは実際に使うだけ。

データをダウンロードしてくる方法はこんな感じ。

$dropbox->access_token('...');
$dropbox->access_secret('...');
$dropbox->root('sandbox');

my $fh_get = IO::File->new('temp.txt','>');
$dropbox->files('input.txt',$fh_get)  or die $dropbox->error;
$fh_get->close;

認証して得たaccess_token,access_secretを指定する。

そしてrootでsandboxを指定する。アプリ専用のフォルダを使う場合はこうしておかないといけない。

あとは受け取るファイルを開いてそのオブジェクトを渡してダウンロードしてくる。

わりに簡単に使えるなと思った。


あとはこのスクリプトをWebから指示を出して動かせるようにしておけば、

どこからでもDropboxのデータを編集して更新できる。

これは便利だ。

Dropboxの使い道というのもいろいろあるな、と今回作って感じた。


Author : hidemaro
Date : 2012/11/29(Thu) 23:45
Perl・PHP・Ruby・Python | Comment | trackback (0)

入力データをソースコードに書くと

Perlで入力データを入れるとき、ついついめんどくさがって、

my $foo=<<EOF;
(データ)
EOF 

なんてヒアドキュメントで書いてしまうことがよくある。


ソースコードの中に直接データを書き込むのはどうなんだという話だが、

まぁ使い捨てのプログラムだし、スクリプト言語だし、まぁいいかとは思っている。

とはいえ、ヒアドキュメントでテキストデータを1行ごとに分けるには、

my @line=split($foo,/\r\n/);

とかしなきゃいけないんだから、ファイルを1行ずつ読み出した方が結局は楽なのかも知れない。


しかし、ヒアドキュメントというのは便利なもんだ。

C#では、

foo=@"abcdefg
hijklmnop";

といったように @"~"とすれば複数行の文字列を簡単に書けるが、そうでもなければ1行しか書けないもんね。

まぁもっともC#で複数行の文字列を書くためにこれ使ったことはなかったような気がするけど。


Author : hidemaro
Date : 2012/10/22(Mon) 23:13
Perl・PHP・Ruby・Python | Comment | trackback (0)

Rubyでシリアル通信

研究でFPGAと開発用コンピュータとの画像データの通信にRS232Cを使うことにしたのはよいが、

通信を行うプログラムを作らないといけない。

Cで書くのもめんどくさいし、やっぱりRubyかなって。


Perl好きの僕だけど、そういや研究室にはPerlを導入してないんだよな。

Rubyは導入したんだが……なんでPerlじゃなくてRubyを入れたんだろ。

シミュレーションなどのために画像データやらの前処理・後処理を行う必要があって、

その処理を手っ取り早く実現するにRubyでスクリプトを書いて使っている。

ソフトウェアで画像をガリガリ処理する時はCでプログラムを書いているんだけど、

文字列を処理したりするのは明らかにRubyの方が楽ですから。スピードも要求されないところだし。


そのRubyでシリアル通信をするためにはruby-serialportを使えばいいようだ。

Ruby-serialport

導入方法は、

$ gem install ruby-serialport 

とするだけ。RubyGemsは便利だなぁ。

ただしUNIX系OSに限る。


WindowsでもMinGWをダウンロードしてインストールしておけば、Gemsでコンパイルしてくれるから普通は問題ないんですよね。

ただ、厄介なのはこれがシリアル通信を扱うところで、どうもMinGWにそのためのライブラリが入っていないらしい。

コンパイルが失敗するもんだから調べてみたらどうもそういうことだったらしい。

じゃあWindowsの人はどうすればいいんだよと。


それで調べてたのだが、世の中にはすでにコンパイルされたものがあるらしい。

GAINER/memo01 (千秋ゼミ)

ここにあるruby-serialport-0.7.0-mswin32-gem.zipをダウンロードしてきて、

gemファイルのあるpkgフォルダで、

> gem install serialport-0.7.0-x86-mswin32-60.gem

とすればすぐにインストールが完了した。

多分、正攻法ではMinGWにここで使ってるライブラリを持ってきてインストールしてとなるんだろうが、

このgemファイルを使えば簡単に導入できる。これはありがたい。


それで使い方だけど、

reuire 'rubygems'
require 'serialport'
sp = SerialPort.new("COM4",38400);
sp.write("foobar")
sp.read_timeout=1000;
puts sp.read

だいたいWebサイトに書いてあるとおりなのだけど。

timeoutを適当に設定しておかないと固まってしまうので必要な設定なのかなと。

配列のデータを書き込みたいときはpackで文字列に変換してから投げる必要があるのかな。

逆に読み込む時はunpackで配列にしてやってと。


あまり資料が充実しているとは言えないが、送信・受信が一通りできれば不便はないだろう。

導入さえできてしまえばRubyから簡単に使えるのでなかなかいいものかなと思った。

ちなみにActivePerlには標準でWin32::SerialPortというライブラリが入っているようで簡単に使えるようだ。

さすがActivePerlだな。


Author : hidemaro
Date : 2012/10/10(Wed) 23:55
Perl・PHP・Ruby・Python | Comment | trackback (0)

Tools