月別アーカイブ: 2007年12月

Python:関数の引数あれこれ

[pukiwiki]
PythonでLISPもどきを作る方法を思考実験。((Maximaで遊んでたら、なんとなく、こんなことのやりかたが気になったので。))

そのために必要そうな「あらかじめ引数の数が判ってない関数の呼び出しかた」の答えは、ちゃんとリファレンスマニュアルにありました。

-[[5.3.4 呼び出し (call)(Python リファレンスマニュアル):http://www.python.jp/doc/2.4/ref/calls.html#tok-argument_list]]
-[[3.2 標準型の階層 ->内部型 (internal type) ->コードオブジェクト:http://www.python.jp/doc/2.4/ref/types.html]]

判らなくて、調べるのに結構時間がかかったのでメモ。

。。。って、大晦日になにやってんだか。
—-
Pythonでも、関数名自体が関数へのポインタとして使えます。
_def f1(a,b,c):
_ print a,b,c
という関数があったとき、
_>>> f=f1
_>>> f1(1,2,3)
_1 2 3 #結果

では、変数fに入っている関数が、どのような引数を取るのか判ってない場合はどうしたらいいのか?たとえば、
_f=f1 ; arglist=[1,2,3]

関数のポインタと引数のリストがこのように変数で与えられた時には
_>>> f(*arglist)   #arglistの前にアスタリスク
_1 2 3 #結果
このように呼び出すことができます。”*”がキモです。

あらかじめ、関数定義側での引数名が判っていれば、引数リストを辞書で渡すこともできます
_def f1(a,b,c) : print a,b,c
_
_f=f1 ; d={“a”:1,”b”:2,”c”:3}
_
_f(**d) #  *が二つ
_
_1 2 3 #結果

—-
関数定義側で*や**を使うと、引数の数を自由にとることができます

_def f2(*arglist):
_ s=0
_ for x in arglist :
_ s+=x
_ print s

_>>> f2(1)
1
_>>> f2(1,2,3)
_6
_>>> f2(1,2,3,4,5)
_15
—-
_def f3(**d):
_ for k in d :
_ print k,”=”, d[k],” “,

_>>> f3(a=1,b=2,c=3)
_a = 1 c = 3 b = 2
_>>> f3(hoge=”fuga”)
_hoge = fuga

でもf3を変数名無しで呼び出すと
_>>> f3(1,2,3)
_Traceback (most recent call last):
_ File ““, line 1, in
_ f3(1,2,3)
_TypeError: f3() takes exactly 0 arguments (3 given)

さらにさらにこんなことをすれば、自由自在に引数を取れます。

_def f3(*arglist,**d):
_ for x in arglist :
_ print x
_ for k in d :
_ print k, d[k]

でも、普通に使う分にはIDLEなどで関数の引数の説明などが出なくなるなどのデメリットも。
—-
*関数の引数の数、デフォルト値を調べる
-[[3.2 標準型の階層 :http://www.python.jp/doc/2.4/ref/types.html]]

呼び出し可能型 (callable type) ユーザ定義関数 (user-defined function)より

“def hoge(a,b,c): pass #こんな関数があったら
hoge.func_defaults
#デフォルト値を持つ引数に対するデフォルト値が収められたタプル、デフォルト値を持つ引数がない場合には None

内部型 (internal type) ->コードオブジェクトより

hoge.func_code.co_argcount が固定引数 (positional argument) の個数。

—-
で、これをどういうときに使うのかといいますとー

Pythonのプログラムを、LISP風に構文木で書くときに使えるんじゃないかなーと。

PythonでLISPインタプリタを書くひとは居ない

_max(1,2,3,4,5)

たとえば、最大値を返す関数maxはこんなふうにリストに格納

_L=[max,1,2,3,4,5]
これを呼び出すときは
_>>> L[0](L[1:])
_5 #1~5の最大値は5

—-
またはこんな書き方も?

_L=[max,[1,2,3,4,5],{}]

これをPythonで実行するときは
_>>> L[0](*L[1],**L[2])
_5
—-
sin(x)**2+cos(x)**2は、こんな構文木に。

_from operator import add,mul
_[add,[mul,[sin,x],2.0],[mul,[cos,x],2.0]]

—-
三角関数の加法定理はこちらをカンニングしました。

[[三角関数(ウィキペディア):http://ja.wikipedia.org/wiki/%E4%B8%89%E8%A7%92%E9%96%A2%E6%95%B0#.E4.B8.89.E8.A7.92.E9.96.A2.E6.95.B0.E3.81.AE.E5.8A.A0.E6.B3.95.E5.AE.9A.E7.90.86]]

—-
_>>> from operator import add,mul
_>>> reduce(add,range(3+1))
_6 #1~3の合計
_L=[reduce,add,[range,10]]

構文木は、こうなりますが、実行しようと思うと、range -> reduceの順番に実行して、式を内側から展開する工夫が必要です。
。。。というか、これじゃ

-rangeの呼び出しなのか
-引数としてrangeのポインタを渡しているのか

の区別がつきませんよね。どうしよう?
_class exeObj : pass #マークアップ用オブジェクト
_L=[exeObj,reduce,add,[exeObj,range,10]]

で、リストを内側からwalkしてexeObjが無くなったらパース終了。。。遅そうだな。
_class exeObj:
_ __init__(self,f): self.f=f  #クラスの書き方、まだ憶えてないです。すんません。

_L=[exeObj(reduce),add,[exeObj(range),10]]

こっちのほうがいいかな?

*[[parser — Python解析木にアクセスする:http://www.m-takagi.org/docs/python/lib/module-parser.html]]
“parserモジュールはPythonの内部パーサとバイトコード・コンパイラへのインターフェイスを提供します。このインターフェイスの第一の目的は、PythonコードからPythonの式の解析木を編集したり、これから実行可能なコードを作成したりできるようにすることです。

私の守備範囲を超えております。自分でPythonなLISPインタプリタ書くよりは、バイトコードにコンパイルしてPythonに渡したほうがよさげではあるのですけれども。
*[[Programming/Python/LanguageServices:http://www.hanecci.com/pukiwiki/index.php?Programming%2FPython%2FLanguageServices]]
上記モジュールのサンプルコード
*Pythonで書かれたLISP処理系
メモメモ。

[[λ門 様々な LISP:http://homepage1.nifty.com/shota/lambda/variousLISPs.html]]より

**[[pylisp:http://www.biostat.wisc.edu/~annis/creations/PyLisp/]]

**[[Lisp in Python:http://www.ibiblio.org/obp/py4fun/lisp/lisp.html]]
**[[ Lython: Python用common lispフロントエンド:http://slashdot.jp/developers/04/02/15/1528254.shtml?topic=93]]

*[[最小のLISP(ウィキペディア LISP):http://ja.wikipedia.org/wiki/LISP#.E6.9C.80.E5.B0.8F.E3.81.AELISP]]
“最小のLISPは、以下に示す、Cや機械語で記述された関数だけを必要とする。
他のすべての関数は、効率良くではないが、これらの関数に置き換えて定義できるだろう。

へー。こうなってくると、Pythonにdefuncやlambdaなどに相当する”関数”も欲しいですな。(インチキするとしたら、evalやcompile使うのかしらん?)
*[[Lisp プログラマのための Python 入門:http://www.unixuser.org/~euske/doc/python/python-lisp-j.html]]
>Python にはマクロがない。 ~中略~
>Lisp なら、これと同等の構文木は (+ 2 2) である。この構文木なら誰にでも使えるが、 Python のこんな構文木をいじれるのは本当のエキスパートだけだろう。

Pythonプログラムを、構文木にしてから最適化しよう、という目論見は、私には難しそうです。”いや、最初からできるとは思ってませんでしたけれども。(汗)”

[/pukiwiki]

数式処理システムMaxima

[pukiwiki]
数式処理ソフトMaximaに ”これからチャレンジ” しようかな、ということで情報収集。

*[[Maxima公式サイト:http://maxima.sourceforge.net/]]
[[ダウンロード:http://sourceforge.net/project/showfiles.php?group_id=4933]]

*[[数式処理システムMaximaで楽をしよう:http://kougaku-navi.net/maxima.html]]
*[[Professional Maxima:http://www.muskmelon.jp/maxima/]]

*[[はじめてでもできる Maxima のインストール(Windows XP 編):http://www.interq.or.jp/mars/cherry/windows/maxima-install.html]]
*[[Maximaで遊ぼう:http://www.bekkoame.ne.jp/~ponpoko/Math/maxima/MaximaMAIN.html]]
*[[Maxima簡易マニュアル:http://www.bekkoame.ne.jp/~ponpoko/Math/maxima/ManualBook/ManualBook.html]]
*はじめてのMaxima I・O BOOKS
数学苦手だし、Mathematicaなどの数式処理ソフトは使ったことがありません。~
たまたまこちらの本を見かけたので読んでみました。

[[http://ecx.images-amazon.com/images/I/210XQBAD1AL.jpg:http://www.amazon.co.jp/exec/obidos/ASIN/4777512010/tamac-22/ref=nosim/]]

lispで書かれた数式処理ソフトMaximaの本。
なんですけれども、具体的な使い方、というよりは、どちらかというと、「Maximaが動くしくみの解説」です。実は、内容は、殆どよくわからなかったのですが(汗 面白かったです。

*数式処理ソフトの使い方を憶える、という数学の勉強のしかた
が、有りうるのかもしれない、という、甘い期待があって上記の本を手に取ったわけですけれども。。。

個人的には、中学、高校ぐらいの数学問題を解くチュートリアルをステップバイステップで解説した本が欲しいなぁと思いました。

< <追記>>
[[Professional Maxima:http://www.muskmelon.jp/maxima/]]
には、センター試験の問題をMaximaで解くチュートリアルが載ってました。少しずつやります~

*MaximaにVerboseモードが欲しい
この公式を当てはめて、こう変形しました、みたいな、途中の手順を全部表示してくれるモードがあると、数学の勉強には便利だよなーと思ったり思わなかったり。。。(ひょっとしたら既に有る?)
*「微積分なんて学校を出たら使わない」ならば。。。
最初からMaxima使ってズルすればよかった、と思った私。。。いや、私の高校時代には、こんなの無かったですけれども。

*Python compiler モジュールを見て、この本を思い出した

“>>> from compiler import parse ; compiler.parse(“y=x**2+2*x+1”)

y=x^2+2x+1なんて式をPythonでパースすると、
[/pukiwiki]

Module(None, Stmt([Assign([AssName('y', 'OP_ASSIGN')], Add((Add((Power((Name('x'), Const(2))), Mul((Const(2), Name('x'))))), Const(1))))]))

[pukiwiki]
こんなリストが返ってきます。Pythonの中では、こんなふうに表現されてるんすね。。。って、こんなのどこかで見たことが有ると思ったら、Maxima本。  Maximaも数式をリストに変換して格納しています。(多項式のCRE表現、というらしい。上記よりも、もっとLISPよりの書き方になってます)

数式処理ソフトと、コンパイラのパース、そりゃ、似たようなことをしてるんだから、似たよなことになるのはあたりまえ、って話もありますけれども。

で、コンパイラの最適化と数式処理つーのも、案外似通ったところが有るのかもしれない、などと思ったけど、よく判らず。

*MeCabつかってても思い出した
日本語も、
-形容詞、係り受け -> 係数 
-名詞 -> 項、 
-接続詞 ->演算子 と考えれば、

うまくやれば、一種の数式と捉えることもできる、のかしらん?
で、多様な定理を使って数式を変形するのと同じく、SVCとかSVOOみたく並び替えて英単語に置換すれば、翻訳ソフトになったりするのかしら?などと妄想してみたり。

似たような技術でも、分野ごとにいろんな使い方があるんですね。人間の科学技術とか文明って、複雑怪奇でよく判りませんけれども、意外に単純な小さな道具の積み重なりで成り立ってるのかも、などと思ったのでした。

*MeCabを使った日本語プログラミング
今回の話題とは関係ないですが、そういうのもアリなのかも、と、ふと思った。誰でも思いつきそうなので、既にあるかも。

*はじめての数式処理ソフト CD-ROM付(ブルーバックス)
ブルーバックスからもMaxima本が出ている模様
[[http://ecx.images-amazon.com/images/I/31u%2BDXnV6yL.jpg:http://www.amazon.co.jp/exec/obidos/ASIN/4062575604/tamac-22/ref=nosim/]]

。。。買ってみましたけど。。。ちょっと私には難しいようです。

ホントは、LISP苦手なので、[[Pythonな数式処理ソフト SAGE:http://www.sagemath.org/]]にチャレンジしようと思ったのですけれども、うちのマシンだとメモリが足りないようです。
[/pukiwiki]

ARToolKit

[pukiwiki]
*[[「攻殻機動隊」「電脳コイル」の世界を実現!ARToolKitを使った拡張現実感プログラミング:http://www1.bbiq.jp/kougaku/ARToolKit.html]]
世間ではずっと前に話題になってたようですけれども。

C用のライブラリなのでctypesでラッパーを書ける、かも。~~
すぐには触れないけど、将来やりたくなったときのためにメモ

ミックスド・リアリティよりも、Strata Foto3Dみた使い方(カメラによる3DCGのモデリング)は出来ないかしらん?というところに興味があります。
*[[拡張現実感プログラミングについての追加のはなし:http://kougaku.blog28.fc2.com/blog-entry-238.html]]
*[[Pythonの関数のポインタをCに渡す(ctypesで):http://ymasuda.jp/python/ctypes/tutorial_jp.html#id18]]
上記のサンプルをPython(ctypesモジュール)で書き直すときに必要。素直にCで書け、って話もありますけれども、Cの関数を順番に呼び出すだけならPythonでも速度は、えらく変わらんのです。~
ちょっとした処理を自前でやると、とたんに遅いですけど。。。

*[[PyARTK:http://mgldev.scripps.edu/projects/pyartk/]]
swigなラッパー。ちょっと敷居が高いんすよね。。。
*[[Suzanne on my desk:http://www.ash.webstranka.info/?p=36]]
PyARTKとGame Blenderとの組み合わせ例。
*[[USBカメラでカードを認識させる新機軸TCG「THE EYE OF JUDGMENT BIOLITH REBELLION ~機神の叛乱~ SET.1」:http://watch.impress.co.jp/game%2Fdocs/20071108/eoj.htm]]
*[[「THE EYE OF JUDGMENT 公式:http://www.jp.playstation.com/scej/title/eoj/]]
PS3用ゲームソフトのアレも同じような技術っすね。

//*[[:http://homepage.ntlworld.com/r.burke2/rab3d/tutorials/608/precision_modelling.pdf]]
[/pukiwiki]

Python日本語あれこれ。MeCab,zenhan.py,unichr

[pukiwiki]
//*[[グーグルの変な機能を見つけた。:http://d.hatena.ne.jp/pxl10666/20071225/p1]]
//*[[「インターネットマガジン」のバックナンバーがPDFで無償公開:http://internet.watch.impress.co.jp/cda/news/2007/12/25/17997.html]]

//—-
今朝は文章(google news)の読み仮名を取得 -> 音声合成してあそびました。

*MeCabをPythonから
オープンソース形態素解析エンジンMeCab (和布蕪)。~
windows版Pythonで必要なバイナリを配布してくださってるサイトを二つ発見。自力コンパイルは、よくわからなくて挫折。。。
-[[twist-bend coupling:http://twistbendcoupling.net/330/mecabpythonwindows]]
-[[takayanの雑記帳:http://neu101.seesaa.net/article/72349477.html]]
-[[MeCab(sourceforge):http://mecab.sourceforge.net/]]~
使うには、MeCab本体(DLL)にパスが通っている必要があります

—-
*[[全角/半角変換を行う Python モジュール zenhan.py 0.4:http://matatabi.homeip.net/blog/setomits/877]]
あとで試してみます
*[[perl, python & ruby – chr() vs. Unicode(404 Blog Not Found):http://blog.livedoor.jp/dankogai/archives/50696206.html]]
数字の全角半角変換や、単純な「かなカナ」変換程度ならord+unichrでいけるかしらん?python shellだと、

“print unichr(ord(“あ”.decode(“sjis”))).encode(‘sjis’)

で、文字 -> コード ->文字を一周。

“print unichr(ord(“1”)-ord(“0”)+ord(“0”.decode(“sjis”))).encode(‘sjis’)

*半角数字を全角数字に。
仮に半角数字 0123を全角にするとして、shell上では
//”pat= re.compile(r'([0-9])’)
“import re; print re.sub( r'([0-9])’,lambda x: unichr(ord(x.group(0))-ord(“0”)+ord(“0”.decode(“sjis”))).encode(‘sjis’),”0123″)

って書くとややこしいですけど、プログラムファイル中に書くときは、もう少しシンプルになる、はず。
—-
*全半英字、全角数字、かな、カナのみを透過する正規表現
“yomi=u”ユニコード文字列”
pat= re.compile(r'([^’ u”、。.ぁ-ん,ァ-ン,ー,0-9,a-z,A-Z,A-Z” r”])”,re.UNICODE)
yomi=pat.sub(r””, yomi)

これで、yomi中の漢字、半角数字、記号などを削除
//漢字も含めた正規表現を使えば、バイト数でなく、文字数をカウントする関数なども作れそう。このやりかただと遅そうですが。
*MeCabをパーサにして日本語プログラミング
誰でも思いつきそうなので、既にあるかも。係り受けも判定してくれる形態素解析ツールのほうがいいかな?
*[[日本語プログラム言語「なでしこ」:http://nadesi.com/]]
なでしこはMeCabとか使ってない、はず。

*[[ 国立国語研究所の言語コーパス整備計画はどうなるか:http://plaza.rakuten.co.jp/kugutsushi/diary/200712250000/]]

考えてみれば、ロボットに何がしかの命令を口頭で与えるのだって、「日本語プログラミング」に違いない、ですよね?

将来的には、今考えられてるよりも、重要な技術になるのかも

[/pukiwiki]

ZIP書庫内のjpegを表示(Pythonで)

昨日はモジュールzipfileやos.walk関数のチュートリアルを読んでおりました。で、適当に何かこさえよう、ということで、zip書庫中のjpegを表示する画像ビュアーを作ってみることに。

<<追記>>
・zipfileがファイルを開きっぱなしにするようなのでcloseする処理を追加。
・今回は単純なリストだけで十分なので、組み込み関数iterを使うように。iglobとか、os.walkなどのジェネレータを使うとiterじゃダメなんですけれども。
・2回目以降は最後にアクセスしたフォルダを表示
・えらく長くなってしまった。。。
続きを読む ZIP書庫内のjpegを表示(Pythonで)