Pythonはどうよ

朝の散歩の途中でふと面白い光景に出会った。家の新築工事現場なんだけど、やっと基礎工事が始まった ばかりの所だ。

整地のために、トラックに小型のパワーショベルを積んできたおじさんがいた。どうやって、荷台から ショベルを下ろすんだろう? 普通なら、荷台に斜めに板をかけ、そこを下らせると思うんだけど 、そんな板はどこにも無いんだ。

おじさんは、シャベルの先を大きく伸ばして地面に付け、そこを支点にして、パワーシャベルの 本体をかまわず、荷台から前進。当然、キャタピラーが荷台をはみ出して、空を切った所に、 シャベルの腕の張りを調整。キャタピラーの前面が地面、後面が荷台のふちにかかるように調整。 運転台から見れば、45度ぐらいの前のめりですよ。

その体制になったら、今度は運転席を反転。シャベルを荷台の方に持ってきて、今度は荷台に シャベルを置いて支点にした。この体制で、本体を後退。キャタピラーが荷台から外れた所に シャベルの腕を弱めて、キャタピラーを着地。

かくして、パワーシャベルは無事に地面の上へと移動しました。この間、1分ぐらいですかね。 絶妙な運転技術に、思わず拍手してしまいましたよ。こんな事って普通にやる事なんだろうか? バランスを崩せば、一発でシャベルの下敷きになってしまう事間違い無しだな。

きっと、講習所では教えてくれない、危険なすご技。今度、TV番組に投稿して、3万円をGetしようかな。 (ああ、いやしい! せめて、YouTubeぐらいにせいよ)

setup

前回ちょっとPythonを試してみた。pythonのserial機構を使ってみても、AA-30との通信は確立出来なかった けど、複素数の表現が何気においらの琴線に触れた。

MITの名物SICPも最近は Pythonで行われているそうだから、時代の進歩に便乗してみるのも悪くは無いな。(今は時代の寵児と言えば、 アンドロドイドですが、MACの焼き直しBy土台はJavaなんで、ご免蒙りますだ)

どうせPythonするなら、AA-30からのデータを吸い上げて、それをグラフ表示するぐらいの事はやりたいよね。 問題は、Pythonからグラフ描画ソフトであるgnuplotを簡単に制御出来るかだ。なーに、昔rubyでやったみたいに popen相当を使って、直接コントロールしちゃうって言う原始的な方法でもいいんだけど。

調べてみたら、Gnuplot.pyと言うのが有った。このページのinstallに 書かれている要件を満たす必要がある。Windows用のgnuplotを入れた。

一応gnuplotを起動して、動作確認。wgnuplotは起動すると、制御Windowsの文字サイズが小さくて見難い ので、右クリックしてフォントサイズを変更たらupdateしておこう。それから、helpは、ファイル形式が古過ぎて Windows7では表示出来ないと言われるので、案内に従って、M$サイトから旧式の表示プログラムを 取り寄せておこう。ま、gnuplotを素で使う事もないだろうけど。。。

次はNumPyを入れる。所が現在入れているPython3.2は新しすぎて対応していない。ソースから入れろと言う 声も聞こえてきそうだが、おいらは清く正しいWindowsユーザーです。Pythonのバージョンにこだわりは ないので、PyJUGへ行って、2系の最新版を入れた。

しっかりPythonを根元にしてるLinux等では、おいそれとバージョンを変えるなんて事は出来ないだろうから、 それに比べれば、おいらなんて気楽なものだ。最近、FreeBSDのportsもPython2.6 → 2.7 移行で大騒ぎの 毎日でしたから。。。

これでやっとgnuplot.pyを入れられる。えっと、入れ方は

python setup.py install

これをやる前に、pythonとgnuplotのPathを通しておかないといけないのね。

これで準備は整った。Windows用の開発環境 pywin32 も入れておこうか迷ったけど、こやつは行儀が悪くて Lib/site-packages の下を汚してくれるので入れるの止めた。その代わり、デフォでついている、IDLE(Python GUI) を使う事にした。

IDLEを起動すると、デフォのworking-dirが、Pyton 2.7の直下になってしまうんで、やだなと思った。変更 出来んか? WindowsのスタートメニューにあるIDLEのアイコンを右クリックして出てくるプロパティーから ショートカットタグを選んで、作業フォルダーに、任意の場所を設定すれば良いのね。いろいろ突いてみる ものだ。

リハビリには、オンライン ドキュメントあたりの チュートリアルとか、調べ物はライブラリレファレンスあたりが便利だ。

gnuplot.pyの試運転

おあつらえな demo.py が、Lib/site-packages/Gnuplotの中に入っている。こやつをダブルクリックすると pytonとgnuplotのコラボが始まるよ。2Dと3Dのデモが見られれば、インストールは成功だ。

ついでに、demo.pyを眺めておくと後が楽になるよ。更に余禄が有ったら、このdirの中の構成を見ておくと 面白いぞ。

test.pyは、あの人のお勧めだろうか。長いけど実行してみると面白い。gpで始まるやつは、それぞれの プラットフォーム用ね。java用があるって事はJthonにも対応してるのか。gp_win32.pyとかを開いてみると Windows特有のいやらしさが読めて、プチ気分が悪くなります。みんな泣かされてるのね。

試作品

そんじゃ、スクリプトを書いてみます。仕様は、前回書いたTeraTermのマクロを動かして、汚れたCSVファイルを 受け取り、それをSWRに変換しグラフ表示する事です。

手抜きして、これまた前前回に書いた、csvファイル からswrに変換するschemeのスクリプトを真似て、そこにgnuplotの呼び出しルーチンをくっ付けてみる事にします。

import cmath
import re
import csv
from numpy import *
import Gnuplot, Gnuplot.funcutils
import subprocess

def td(x):
    if re.match(r"^\d.*", x):
        return x

def getlog(csv_file):
    fd = open(csv_file)
    s = fd.readlines()
    fd.close()
    return filter(td, s)

def to_fz(f):
    return float(f[0]), complex(float(f[1]), float(f[2]))

def swr(fz):
    a = (fz[1] - 50) / (fz[1] + 50)
    return fz[0],(1 + abs(a)) / (1 - abs(a))

def main():
    subprocess.call(['ttpmacro', 'aa30.ttl'])     # aa30.ttl must be in teraterm-dir
    c = csv.reader(getlog('AA30.log'))
    fz = map(to_fz,c)
    dat = map(swr, fz)
    print(dat)
    g = Gnuplot.Gnuplot(debug=1)
    g.title('AA-30 SWR')
    g('set logscale y')
    g('set data style lines')
    g.plot(dat)
    raw_input('Please press return to end...\n')

# when executed, just run main():
if __name__ == '__main__': main()

前回のttpmacro用のスクリプトを、teratermのdir内に置いておく。そして、そいつをキックして、AA-30を 動かし、ログを取得する。 getlog()で、汚れたCSVもどきのログを読み込み、簡単なフィルターでCSVの行を濾過します。 後は、to_fz手続きで、(周波数, インピーダンス)と言う形式のタプルに変換。タプルが連なったリストを 元にSWRを計算し、gnuplotを呼び出しています。

gnuplotに渡すパラメータは、タイトル、Y軸をログスケール表示、折れ線グラフね、最後に データを渡して描画してねって感じです。

実行結果

>>> main()
[(6.55, 1135.0810071682176), (6.6, 4734.037788476731), ... (7.5, 1990.1239411943218)]
gnuplot> set terminal windows
gnuplot> set title "AA-30 SWR"
gnuplot> set logscale y
gnuplot> set data style lines
gnuplot> plot "c:\\users\\foo\\appdata\\local\\temp\\tmpokoknq.gnuplot" notitle
Please press return to end...

>>> 

Gnuplotのインスタンスを作成する時に、debugを有効にしているので、gnuplotとのやり取りが 表示されています。

6.55000019073 1135.08105469
6.59999990463 4734.03759766
6.65000009537 4541.42919922
6.69999980927 2117.97949219
6.75 486.25479126
6.80000019073 1265.88684082
6.84999990463 2387.61767578
6.90000009537 445.572723389
6.94999980927 2319.89306641
7.0 417.883728027
7.05000019073 433.850250244
7.09999990463 504.538299561
7.15000009537 458.767669678
7.19999980927 819.039245605
7.25 719.569763184
7.30000019073 453.882110596
7.34999990463 8171.71777344
7.40000009537 1627.5234375
7.44999980927 626.215454102
7.5 1990.12390137

上記は、gnuplotへ渡す為に作成された一時データファイルです。最近のgnuplotは、パイプ経由でも データの受け渡しが出来るように、wgnuplot_pipes.exe が、同梱されていますが、gnuplot.pyの 開発者達に人気が無いようで、採用されてません。

混同しちゃったぞ

さすがMITがSICPの後釜に据えただけあって、schemeと同様な感覚でプログラムを書ける。けど、はまった のは、関数から戻り値を戻す時(変な日本語だ事)、returnを明示してあげないといけない点。これには、 何度も泣かされたよ。

他でおややと思ったのは、エラーがスルーされる事。swrの手続きを書いた時、引数の型を間違えてしまった んだけど、エラーは出ず。結果も表示されずでした。複数を同時にリファクタリングしちゃったら、どこで ミスったかさっぱり分からなくなります。この点、肝に銘じておこう。

文字列から数字に変換する手続き(ruby風に言うと、str.to_f)を探し当てるのにちょっと戸惑った。 古いPythonだと、Cのライブラリーそのままで、atofが使えるらしいんだけど、3系へのブリッジバージョン では、駄目みたい。まあ、こんなのは一度苦労すれば忘れる事は無かろう。

csvモジュールの解説の部分を良く読まなかったけど、テンプレートを定義しておいて、csvを読み込む時に いきなり所望な型に変換出来るのかな。これが出来れば、CommonLispのリーダーマクロみたいで、面白いな。 なんて思っていたら、csvの方言を使った例が 出ていた。

参考資料

折角 numpyと言うのが入っているので、どんな事が出来るか概観しておく

機械学習 はじめよう

NumPyを使ってみる

FFTも出来るんか、面白いな。その他のPython一般にて

Lisp プログラマのための Python 入門

DreamPie 開発環境だとか。名前がいいね。

GNU Radio Pythonもやっぱり半田(接着剤)?