Sep 15

FBModel 以下のクラスでは、親子関係を作る事が出来るらしい。

というわけで、どうやるかというと、子供にしたい FBModel の Parent 属性に 親にしたい FBModel を代入するだけ。

FBModel.Parent = FBModel

これは簡単だね!

Tagged with:
Sep 03

前に書いた、職場のモーション担当の人が MotionBuilder用に Python を覚えるという事で
自分がサンプルコードを書いてそれを見ながら、モーション担当の人が、あーでもない、こーでもないといじっております。

しかし、これ日本語の資料殆どないね。

元々Pythonが出来る人じゃないと、難易度が凄い高い。
しかも、日本人でPython出来る人って少ないから、更に難易度高そう。

他にも、MotionBuilder用に Python 覚えたい人いるかもしれないので、サンプルなんぞを。

選択されている Component の名前表示 スクリプト

from pyfbsdk import FBSystem

for lComp in FBSystem().Scene.Components:
    if lComp != None and lComp.Selected:
        # MotionBuilder 2009
        print lComp.LongName
        # MotionBuilder 7.5
        #print lComp.ShortName

バージョンによって、名前の参照方法が違うみたい。
LongName は、 FBModel 以下の階層に存在していて、 Unique name and namespace.
Name は、FBComponent 以下の階層に存在していて、 Unique name.

で、選択されているComponentを取得する方法はもう一通りある。

from pyfbsdk import FBModelList, FBGetSelectedModels

sels = FBModelList()
FBGetSelectedModels(sels, None, True)

for s in sels :
    # MotionBuilder 2009
    print s.Name
    # MotionBuilder 7.5
    #print s.ShortName

# 追記
MotionBuilder 7.5 と 2009 で挙動が違ったので報告。

FBSystem().Scene.Components

で、取得するコンポーネント一覧が 2009 だと FBModel オブジェクトを返していたのに
7.5 だと、 FBComponent オブジェクトを返してくる。
FBModel は FBVector3d などの情報を持っているけれど、 FBComponent は持っていないので
処理に必要な情報が足りなかった。

というわけで、バージョンによって微妙に挙動が違う。

MotionBuilder 使っている職場の人の話だと、2009 は、Pythonスクリプト強化とラグドール機能の追加がメインらしいけれど
Pythonスクリプト組める人が少ない上に、ラグドールは殆ど使っている人が居ないらしいので、操作系が使いやすい 7.5 の方が良いのだそうな。
という訳で、7.5 向きのスクリプト情報が多くなるかも。

Tagged with:
Nov 01
Pythonで、HTTP Requestを作成するのに、URLEncode(URIEncode)をしようとして、Unicodeで文字列を受け取って、変換かけようと思ったら、
UnicodeDecodeError
が発生して、は!?なぜに!?と思ったので調べてみた。
どうにも、urllib.urlencode は、Unicodeには対応していないらしい。
import urllib
urllib.urlencode(
{'title': "火目の巫女", }
)
と書いた場合、"火目の巫女"の部分は、Unicode扱いなんだけれど、これがUnicodeDecodeErrorを投げてくれる。
'ascii' codec can't encode characters in position 0-1
こんなエラーが出るっぽい。
ということで、以下の様に、str型に変換してあげる。
import urllib
urllib.urlencode(
{'title': "火目の巫女".encode('utf-8'), }
)
いや、参ったねこいつは。三時間くらい、あれ~?なんじゃこりゃ!?とか悩んでた・・・w

Tagged with:
Mar 04

前回は、Liteの話だったんだけれど、今回は正規版を入れて操作してみることにした。
前回 >>> openSUSE 10.3 に Navicat-Lite を入れてみた。
なんで Navicat 使ってるの?っていうと、MySQLの公式サイトで配られている専用のGUIツールが使えないからだ・・・ShiftJISとかEUC_JPとか関係なく、マルチバイト文字にかなり弱いので、非常に怖い。特に、Webシステムなんて、お客さんの大事なデータをデータベースに入れる訳だし、仕事であれを使うのはきついんだよね。
ということで、職場の人に教えてもらったNavicatを使っていたんだけれど、Linux版もあるということで、お、それはいいね!!普段Linuxで開発しているし、ありがたい。ってことで入れてみている訳だったり。
ってことで、製品版のインストールもメモしました。
ま、殆ど lite と変わらないけれどね〜
wiki: Navicat
とりあえず、製品版という事で色々出きるようになっています。
Liteでもそうなんだけれど、各操作をファイルとして記録しておいて、後で再現出来るのも大きいかも・・・
Data Synchronization はそのまんまデータベース単位で同期取ってくれます。
これはあくまでも同期なので、片方にしか無いテーブルに関しては何もしないみたい。
それでも、データ同期をボタンぽちぽちでやってくれて、一応Transaction使ってのPreviewもあったりするので
各開発サーバ間で、テストデータをやりとりしたり、ステージングサーバにデータを入れるのに良いかも。
これはまあ、ダンプでコピーしまくるよりも、簡単に共有するためのツールかな。
で、もっと面白いのが Structure Synchronization.
これは,データベース同士の構造を合わせてくれるって意味そのまんまで、足りないテーブルを追加したり、多いテーブルを削除したりまでしてくれる。
こんな感じで情報もその場で見られるのと、SQL の選択も出来たりするので、中々芸が細かいなぁ・・・
screenshot
で、これの何が良いのかっていうと、Django の Database の部分ってちょっと欠点があって
運用中のサーバに対して、データ構造の変更を行う場合、 models.py を変更しただけじゃ、データベースの構造までは買えてくれないんだよね。
models.py の Model Class を変えた上で、ALTER文を自分で書いて走らせないといけない。
詳しくはこちらをどうぞ。
The Django Book: Making Changes to a Database Schema
で、こういう場合一々SQLを自分で書くのはミスもあるだろうし、手間もかかるし結構大変。
なので、Navicat のこの機能を使うと中々便利なのです!!
どう使うかというと、新しいデータベースを作って一旦Django の接続先をそちらへと変更する。
その後に、python manage.py syncdb を行い、真新しいスキーマーを作成してもらう。
その後、新しいデータベーススキーマーから、古いデータベーススキーマーへ、 Structure Synchronization を行えば良いのだ。
なんて便利なんだろう!!
って、最後は Django の話になっちゃったけれど、Django + MySQL の開発に Navicat は中々良いかもしれないぜ(・・
っていう話でした。

Tagged with:
Feb 28

Python 2.4 から decorator (デコレーター)使えるらしい。
それに伴って、Django みたいなフレームワークでは、decorator を使う機会が出てきているので、覚えておきましょう。
ってことで、軽くメモ。
これって、Java でいう annotation(アノテーション)でしょう。
使い方も殆ど一緒だし。
ただ、Javaの方が色々出来る気がする。まあ、これからに期待かな?
簡単に言うと、function を装飾するための機能です。
装飾というだけあって、指定された属性に意味を追加するのに使う場合が多いです。
decorator.py
module の中のコメントに大体説明は書いておいたけれど
function を上書きするための機能みたいなものです。
機能を追加してみたり、 wrapper 関数で上書きしたりと、まあそんな感じのもの。
サンプルだと、DecSmp1 は、組み込み decorator で、static method を作ってます。
DecSmp2 は、自作の超簡単な decorator で static method を作ってます。
まあ、余り大した事してないけれどね〜
こういうのは、大きなシステム作るときに落になるように作るものであって、普通は余り自作しないんじゃないかなぁ〜
どうしても、関数に共通の加工を加えたい。っていう場面に出会ったら、自分も自作はするだろうけれど・・・
ん〜 Django だと、フィルターやタグを自作するときにこれを使います。
それの解説書こうと思っていたんだけれど、リポジトリ整理していたら時間がなくなった・・・w
いや、まだいけるか!? 明日金曜じゃん!! 急ぎの仕事もないし・・・うへへ
ってか、こんなこと書くと部長に仕事入れられそうだww
入れられて困る事はないんだけれど・・・

Tagged with:
Jan 31

さて、先日お伝えした様に我が家のmod_pythonがたまにRuntimeErrorの例外を出すということだったのだが、原因が判明した。
http://www.python.jp/doc/contrib/modpython/pyapi-interps.html
こちらに書いてある内容から考えるに、Apacheのpreforkを使って複数プロセスで処理をしている場合、それぞれのプロセスが独立したサブインタプリターを生成しているっぽい。そして、その間では名前空間は共有出来ないから
RuntimeError: instance.__dict__ not accessible in restricted mode
という内容の例外が出るに至るわけだ。
解決方法としては

    PythonInterpreter main_interpreter

と、.confファイルに書けば良いだけだ。
http://www.python.org/doc/current/api/initialization.html
ここを見るに、独立したPythonのサブインタープリターを作成する。ってあるんだけれど、それぞれのプロセスが独立しているなら、どうして他のプロセスの持っているインスタンスにアクセスしようとするんだ?
ってことだよ。
どういうPythonコードが原因で、mod_pythonで動かしたとき、そういうエラーが出るのかがまだ謎。
もうちょっと調べないとだなぁ・・・普通に、PythonInterpreter main_interpreter と書けば解決されるのは分かったんだが
どのコードがいけないことしてるんだよ!!って分からないと余り解決になってないような。
今日は眠いのでまた今度ソース見てみよう。
なんか、ルーターか光の回線終端装置がお亡くなりになったみたいで
帰ったらネットにさっぱり繋がらなくなっておりました。
う〜ん、ルーターは三カ月くらいツケっ放しだったんだけれど、やっぱりたまに再起動しないとダメなのかな。
1万以下のやつだからね・・・
ルーターにはアクセスできるけれど、ローカルネットワークも死んでいたんだよね。
う〜ん、インターネットだけなら分かるけれど、イントラネットもってなると、ルーターだよなぁ

Tagged with:
Jan 30

今思ったんだけれどさ、みんな検索する時は、 “django 入門” とかで検索する訳じゃん。Pythonもさ。
でも、自分のエントリーって全部やろう!!なんだよね。ま、いいか?w
硬いのは嫌いだしね~
ってことで、Djangoのcontributeの一つのadminに付いてやります。これはちょっとしたCMSちっくです(・・
最初に、
INSTALLED_APPS = (
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.sites’,
‘django.contrib.admin’,
‘redhawk.task’,
)
のように、’django.contrib.admin’を追加します。
次に、
python manage.py syncdb
を実行。admin権限のユーザーを作成するか訊いてくるので、作成します。
次に、redhawk.task.modelsにこんなことをしてみます。
python manage.py 192.168.11.40:8000
でサーバ起動。IPアドレスとポート番号は自分の環境にあわせて選んでください。
この場合、アクセスするURLは、

http://192.168.11.40:8000/admin/

になります。

上の様な画面が出るはずなので、ぐりぐり弄くりまわしてみましょう。
で、色々物足りないと思うので、こんな物を追加してみる。
models.py
公式ドキュメントや、本では
def __str__(self)
となっているかもしれないが、最近のバージョンでは
def __unicode__(self)
が推奨となっている。
まあ、どの言語にもよくあることで、__str__はasciiで__unicode__はユニコード企画に変換してくれる訳ですよ。
datetimeに__unicode__がないのは、__str__だけで事足りるからかな?
Rubyは日本人が作っただけあって例外なのかな?使ったことないから分からないけれど、そう聞いたことがある。
さて、これをすると、Objectが、printに渡されたときに、自動的に__unicode__の戻り値が表示されるようになるわけだ。
前のバージョンのままでは、User Objectと表示されていただろうが、これでUser.nameが表示されるので誰だか分かる。
更に、admin画面をカスタマイズ!!こんな事をしてみよう。

更に色々カスタマイズできるけれど、これまたアプリを作りながら見ていったほうが良いと思うので
サンプルアプリつくりながら色々出しておこうかなと。

Tagged with:
Jan 20

大事な話が抜けていた。
そう、ドキュメントだよ!!
Pythonのドキュメントは簡単に使う事が出来るので、非常に便利。
まず、基本。
pydoc time
で、timeモジュールのドキュメントを見ることが出来る。
更に、これはビルトインモジュールだけでなく、自前のライブラリにも使える。
例えば、自分が以前に作った、cnclass.pyのドキュメントを見たいと思ったら
pydoc cnclass
とすればいい。ここで驚きなのが、継承、引数、戻り値に関しては自動生成してくれる。
ドキュメント文章は、メソッドの宣言の下に書くと、それが追加される。
例えば、
class MyClass:
    ”"”
    Base Class for other classes in this module
    ”"”
    def printer():
        ”"”
        print attribute
        ”"”
        print x
という感じに書くと、pydoc できちんとドキュメント文字列も表示される。
きちんと、インデントを揃えるのを忘れてはいけない。
IDLEの中であれば、helpを使って見ることもできる。
この場合は、きちんとimportを事前に行う必要性がある。
また、__doc__属性にも、ドキュメントは入っている。
import time
help(time)
print time.__doc__
といった感じ。
読むためのツールとしてはGUIのもあるので、そちらを使うのもいいだろう。

Tagged with:
Jan 19
Pythonの例外処理来ました!!
例外処理を初めていじったのはC++だったけれど、なんじゃこりゃ?こんなの要るのか?ifでいいよ。ifで。って最初思った。
でも、Javaを使ってみて、例外処理のありがたさが分かった。
Javaは特に、Eclipseがあると例外処理に関しては覚えやすかった。最初viで書いていたので、面倒なだけだったし・・・
おかげで、今PythonをIDLEとかviで書いているんだけれど、例外処理の有り難味が分かるよ。
C++はそれほどクリティカルな物でない限り、例外処理は要らないけれど
JavaもPythonも例外処理は、乗用するので、覚えておきましょう。
C++いじってたのは昔なのと、最近のソース余り見てないから、今だとC++でもかなり使っているのかな?
まず、最初に言っておこう。
Python2.5から、try/except/else/finallyが一緒に使えるようになった。
それまでは、
try/except
try/finally
のペアしか使えず、elseはどちらのペアにも使えたらしい。古いバージョンのPythonは弄ってないのであくまでもらしいで。
2.5だと気にしなくていいので、特に注意する必要性はないけれど、古いバージョンで動かさないといけなくなる場合もあるかもなので
一応、頭に止めておいたほうがいいかも。
更に言っておこう。
文字列例外は使うな。クラス例外を使うのだ。
Javaの例外がそうだけれど、例外にツリー構造を持たせる方向性にPythonが進んでいる。
C++の場合は、言語標準ではなく設計するときに例外もクラスとして設計するような・・・なんで、こいつだけ違うんだ?w
まあとにかく、Pythonでは文字列例外は将来的になくなるということだ。
詳細はこちら。PEP 352 PEP 348
また、Javaでは関数、クラスの外に例外を投げる時は、throwsが必要だけれど、Pythonの場合はそれが要りません。
なので、どいつがいつ例外を出すのかが、Javaと違い明確じゃないです。
その結果、例外がトップレベルまで飛んでしまうと、プロセスを終了してエラーメッセージを出します。
そこが一番注意するところかな。例外処理に関しては、elseがある事以外は、Javaの方が明らかに使い勝手が良いです。
まあ、exceptだけを書けば、全ての例外をキャッチできるのと、2.5以降なら、except BaseExceptionでも全ての例外をキャッチできる。
複数の例外をキャッチするときは、tupleとしてつなげるみたい。
except (TypeError, IndexError):
pass
という感じ。
さて、今回の例外サンプルはこちら。
exception.py
""" exception sample program """
class MyClass:
pass
class MyClassException(BaseException):
def __init__(self):
BaseException.__init__(self)
self.message = "MyClassExceptionMessage"
def tryexcept(cls):
try:
c1.attr
except AttributeError, data:
print data
else:
print "else"
finally:
print "finally"
if __name__ == "__main__":
print "--- 1st step ---"
c1 = MyClass()
tryexcept(c1)
print "--- 2nd step ---"
c1.attr = "value"
tryexcept(c1)
print "raise --- String Exception ---"
myExcept = "Error"
try:
raise myExcept, "exception data"
except myExcept, data:
print data
print "raise --- Class Exception ---"
myClsExcept = MyClassException()
try:
raise myClsExcept
except:
print myClsExcept.message
print "--- assert AssertException ---"
myException = MyClassException()
try:
assert False, "assert error message"
except AssertionError, data:
print data
python exception.py での実行結果はこちら。
--- 1st step ---
MyClass instance has no attribute 'attr'
finally
--- 2nd step ---
else
finally
raise --- String Exception ---
exception.py:33: DeprecationWarning: raising a string exception is deprecated
raise myExcept, "exception data"
exception data
raise --- Class Exception ---
MyClassExceptionMessage
--- assert AssertException ---
assert error message
python exception.py -O で実行すると、最後の行の assert error message がなくなります。
上から解説していくと、1st step 2nd step が、try/except/else/finallyの動きを表示したやつです。
ソース見れば直ぐに分かるかと。
最初に言ったように、StringExceptionを投げると一応注意書きが出ます。これは注意なので、処理は止まりません。
次に、BaseExceptionを継承して作った例外クラス。これは、pydoc BaseException で調べてみて、BaseException.messageが標準であるので、それを上書きしてます。公式サイトの英語のドキュメントとかも探してみたんだけれど、使い方が載っていないんだよね。まあ、見つけたらそのうち追加で書きます。
で、最後のassert statementは、
__debug__
というフラグがTrueの時だけ実行されます。これは、-O オプションを付けて実行すると、Falseになります。
また、assertの最初の部分は評価式を書き、結果がFalseの時に例外が投げられます。例外の形は、AssertionErrorで固定みたい。これも、探してみたんだけれど、イマイチ説明が少ない・・・その後ろにはデータを送るといった具合。
例外処理はこんなところかな。
これで、Pythonの基本編はお終い。次からは、標準ライブラリをやりたいけれど、そういうのは実際にアプリケーション組みながらの方が覚えられるので、そうしようかな。マルチスレッドだけは、別にやりたいけれどw
だって、Webアプリ作っていて、マルチスレッドってそんなに使わないような。今なら、Ajaxでそれっぽい事も出来る訳だし。
Tagged with:
Jan 12

Pythonでは、statement(命令文)と、expression(式)を明確に分けて使わないと、結構はまるかもしれない。
逆に、そこを理解していれば、Pythonの構文は馴染み易くなると思う。
簡単に説明すると
expressionはstatementになるが、statementはexpressionにはならない。
例えば、if は statement だ。
そして、if の中には、expressionを書くことができる。
if x == 0
といった感じだ。x == 0 は明らかに、expressionと言える。
では、これはどうだろうか。
if x = 0
これは、PythonではSyntax Errorになる。何故か?
x = 0 は、expressionではなく、statementだからだ。
このことにより、C言語では、
if ( x == 0 )
と書くとき、誤って
if ( x = 0 )
と書くのを気をつけないといけないが、Pythonでは、文法的に認められないので、この問題を回避できる。
まあ、自分は
if ( 0 == x )
と書くようにしてるけれどね。リテラルに、変数・リテラルは代入できないので。
ついでに、printは現在statement扱いだ。これは、printに()がいらないので、関数ではなくstatementだと分かる事ができる。
このことに寄って、現行のPython(2.5)までではprintの使える場所が限られていて、結構面倒だったりする。
Python3000からは、printは関数になるので、色々な場所にかけるようになるわけだ。
これは、関数やメソッドの場合、statementとして扱う事ができるからだ。
普通はありえない使い方だけれど、こんな事ができる。
L1 = [1,2,3,4]
if print L1 == 0:
File ““, line 1
if print L1 == 0:
^
SyntaxError: invalid syntax
となるが
def printer( value ):
    print value,
if printer(L1) == 0:
    print ‘zero’
[1, 2, 3, 4]
とまあ、こんな感じ。
単純に、expression書くべきところに、statementは書けないんだよ!!って事なんだけれど
関数・メソッドの呼び出しは、expressionとして解釈されるからなのです。
また、statement扱いすることも可能。
だって、
printer( L1 )
なんて、statementそのままじゃん!!
っていう感じですね。
ま、以下のコードは当たり前に大抵の言語できるけれど、きちんと、statementとexpressionを分けて考えて
関数・メソッドは、どちらにもなるから。と理解していないと、Pythonは変なところではまるかもしれない。ということかな。
def ret( value ):
    return value
if ret(1) == ret(1):
    print ‘eq’
eq

Tagged with:
preload preload preload