コンピュータやソフトウェアのあれこれ@道民(&元道民)
python
第20回北海道開発オフに参加してきた
1月 19th
[python][メモ]GAE on virtualenv
1月 10th
virtualenv上でGAEのdev_appserver.pyを動かそうとNo module named cgiが出たりしますが、これはdev_appserver.pyがos.pyが入っているディレクトリ以外からモジュールをロードしないようにサンドボックスを作っているからです。virtualenvな環境だとos.pyはローカルの環境にありますが、それ以外は通常のPythonのpathにあるものを使おうとするため制約に引っかかります。
で、見た感じこの辺で昔直した(?)みたいですが、これだと手元の環境では .pyc が作られた場合に、 os.__file__ がシンボリックリンクではなく .pyc という実ファイルを指してしまい、うまく動きませんでした。
ってことで、もう一ひねりしてこんな感じ。
これで手元のOS Xでは、うまく動かすことができました。ただし、SITE_PACKAGES 変数は手を付けてないので、 --no-site-packages してない環境では、サンドボックスが破られてしまいます。SITE_PACKAGES には複数の値を入れられない構造なので、まともに直すのであればこの辺にも手を付ける必要がありそうです。
なお、本家のIssueの方では違うパッチが提案されてます。
[python][メモ]Import hooks 内で投げた例外
1月 9th
class MyImporter(object): def find_module(self, fullname, path=None): return self def load_module(self, fullname): raise ImportError("failed") import sys sys.meta_path = [MyImporter()] import datetime
だと「ImportError: failed」になって、
class MyImporter(object): def find_module(self, fullname, path=None): raise ImportError("failed")
だと「ImportError: No module named datetime」になって、
class MyImporter(object): def find_module(self, fullname, path=None): raise Exception("failed")
だと「Exception: failed」になるのは、find_module でImportErrorを上げた時だけ特別扱いされてるってことでしょうか。PEP-302には "If find_module() raises an exception, it will be propagated to the caller, aborting the import." としか書かれてないみたいですけど。
1/9追記
import.c をざっくり追った感じだと、load_packageやimport_submoduleの中で、find_module内で上げられたPyExc_ImportError は捨ててるっぽいですねー。で、return Py_None してることからわかりますが、 load_module から None を返した場合もこれと同等の挙動になります。ただし、これも PEP-302 的には未定義なので、やるべきじゃないんでしょう。
static PyObject *
import_submodule(PyObject *mod, char *subname, char *fullname)
{
..略..
fdp = find_module(fullname, subname, path, buf, MAXPATHLEN+1,
&fp, &loader);
Py_XDECREF(path);
if (fdp == NULL) {
if (!PyErr_ExceptionMatches(PyExc_ImportError))
return NULL;
PyErr_Clear();
Py_INCREF(Py_None);
return Py_None;
}
..略..
m = load_module(fullname, fp, buf, fdp->type, loader);
..略..
return m;
}
なお、path_hooks を実行した際に上げられたImportError はget_path_importer 内で捕捉されて無視されています。これはPEP-302 に書かれている通りの挙動ですね。
[python][GAE]Re: TransactionとEntity Groupについての理解
12月 26th
TransactionとEntity Groupについての理解で言及されていたことを試してみたのですが、どうも微妙に違うような?
つまりTransaction内では、(多分Keyに関する操作がある場合には)暗黙のうちに「Key.from_path(u'UserAccount', u'tagomoris')を親とするEntity Groupに対する操作」として扱われている、ということだろう。
このエントリの add_useraccount() が動作するのは、get_by_key_name に成功した場合は u = UserAccount.get_by_key_name(name) のEntity Group のみをTransaction 内で触っていることになり、get_by_key_name に失敗した場合は u = UserAccount(key_name=name, fullname=fullname) のEntity Group のみへの操作となるからな気がします。参照するEntity Groupと作成するEntity Groupは確かに別物で、Transaction内で同時に触ることができないってのも真なのですが、この例の場合だと参照と作成は同時に起きないってのがミソでしょう。
ということで、以下のようなコードを書けば、"Cannot operate on different entity groups in a transaction"となります。
def make_shadow(body_name, fullname): u = UserAccount.get_by_key_name(body_name) if u is None: raise db.Rollback u = UserAccount(key_name=u.key().name() + "_shadow", fullname=fullname) u.put() return u user = UserAccount(key_name="hiratara", fullname="Masahiro Honma") user.put() new_user = db.run_in_transaction(make_shadow, "hiratara", "Shadow Honma")
BadRequestError: Cannot operate on different entity groups in a transaction: (kind='UserAccount', name='hiratara') and (kind='UserAccount', name='hiratara_shadow').
[Python]psycopg2でhstoreをdictにマップ
12月 10th
hstoreというのはcontribにはいっているkey-valueデータ型です。
psycopg2の2.3.0以降では、hstoreをPythonのdictにマップできるそうです。
ところでhstoreの前にARRAYはどうなってるのと思ったらサポート済みの様子。
>>> import psycopg2
>>> conn = psycopg2.connect("")
>>> cur = conn.cursor()
>>> cur.execute("select %s", ([1,2,3],))
>>> cur.fetchone()
([1, 2, 3],)
cursor.mogrify()で実際に発行されるクエリを確認できます。
>>> cur.mogrify("select %s", ([1,2,3],))
'select ARRAY[1, 2, 3]'
タプルをROWにはできるけどその逆はできないのかもしれない。
>>> cur.mogrify("select %s", ((1,"foo"),))
"select (1, E'foo')"
>>> cur.execute("select %s", ((1,"foo"),))
>>> cur.fetchone()
('(1,foo)',)
さて、hstoreを使うには、DBにhstoreをインストールした上で、psycopg2.extras.register_hstore()を実行します。これを実行した時にhstoreのoidを取りにいっている様子。
>>> import psycopg2.extras
>>> psycopg2.extras.register_hstore(cur)
>>> cur.execute("select 'a => 1'::hstore")
>>> cur.fetchone()
({'a': '1'},)
>>> cur.mogrify("select %s", (dict(a=1, b=2),))
"select hstore(ARRAY[E'a', E'b'], ARRAY[1, 2])"
>>> cur.execute("select * from each(%s)", (dict(a="foo", b="bar"),))
>>> cur.fetchall()
[('a', 'foo'), ('b', 'bar')]
あとEventletを使ったLISTEN/NOTIFYのサンプルもありましたが理解してないのでリンクだけ貼っておきます。
[python]今日は「帰ってきた Python Workshop 2010/12」の日です
12月 8th
ケータイの予備バッテリーは2つ持ってきたのにケータイを忘れましたが、気を取り直して出席します! ハッシュタグは#pw1012みたいです。
Session 01. mixiアプリとGoogle App Engine
mixiプラットフォームについて / 山下さん
- mixiはPerlの会社・・・Pethonについては別の方に
- 個人デベロッパーにも近日公開予定
- developer.mixi.co.jpも参照
- PC、モバイル、スマートフォンに対応
- mixiプラットフォームの利点 → ユーザを集めやすい
- 1ヶ月で40万ユーザとか1週間程度で200万ユーザとか
- ユーザ登録不要、ユーザによる宣伝
- Activity, Voice, Invite, Request, Message などのAPIの存在
- mixiアプリの構成
- Application ProxyとMedia Cache Proxyがある
- 1000万〜数億PV/日 (200-500 req/sec) → 普通のサーバだときつい
- インフラ構築支援サービス
- GAE, IDC Frontier, DSAS, NIFTY Cloud, GMO INTERNET などなど
App Engine for Mixi Apps / 松尾さん
- アクセスにばらつきがある → 時間によるアクセスの波、人気が出るか
- 人気が出なかった場合は、コストが0で済む!
- アクティブなアプリが15万、開発者が10万、PVは10億PV/日、最高実績1600QPS
- ポテンシャルは、この10倍いけるはず
- Quota → お金により増えるものと、増えないものがある
- 増えないもの → リクエスト、発信・受信帯域、CPU時間
- ただし、どうしても困った場合は松尾さんに連絡をすればなんとかなるみたい
- スケールのために気をつけること
- 必要最低限のことだけする → 1000msルールが守れないと、インスタンス数が抑制される
- データストアコンテンションを避ける
- Task Queueとmemcache をうまく使う
- DBオペレーションにデッドラインを設定 (mixiアプリの制約を避けるため)
- 「Best practices for writing scalable applications」を参照
- GAE1.4出たよ!
- ロードマップ
- 30秒以上走らせることができるバックグラウンドサーバ
- レイテンシィよりアベイラビリティを優先する設定が増える(メンテ時とかも書き込みが可能になる)
バスキュールについて / 田中さん
- mixiアプリ『華麗なる女優たち』
- GAE + Pythonを利用
- 65万人以上登録、DAUは10万以上、ピークは200-300req/sec 1000-1500万/日
- 開発 → 経験のあるパートナーが居なかったが、頑張ってもらった
- トラブル事例1: 404 not found が大量発生
- ImportError により、不完全なインスタンスが立ち上がっていた
- @shin_no_suke さん → @tokibito さん → コンソールの開発により、解決
- トラブル事例1: 突発的にLatencyが悪くなる
- 「JOIN停止」問題。3分間に10秒以上のタイムアウト1000件以上
- 松尾さんにお願いし、解決。HTTP QUEのタイムアウトを10秒から7秒に下げた
- GAEのメリット
- スケーラビリティ → mixi Xmas 2010 は 1週間で200万人。普通に動いている
- コスト → 1000万リクエスト = 100ドル。1ヶ月30万円程度
- まとめ: ユーザにはドキドキ、我々はウキウキ
- 松尾さんより補足
- 404エラー → Dead line excidate errror?? が起きたときに、モジュールのインポートが終わってしまうのが原因。1.4では改善されている
- レイテンシーの問題も1.4ではほぼ解決しているはず。しかし、mixiアプリでは松尾さんへ連絡してタイムアウトを下げた方がベター
Session 02. Harvester - CG映像制作用ジョブディスパッチシステム / 齊藤さん、石川(@yusukei)さん
- デモ → DIVA 2ndのオープニング映像 (Ustream非公開)
- 80名ほどのチームで、ソフトは7名。インハウスのツールを開発
- CG業界ではPythonが使われている
- Maya, Houdini, Cinema4D, Blender, Nuke への組込
- C++に続き、2位。3位以降はMEL、JS、Ruby
- ジョブディスパッチとはなぜ必要?
- 制作にCPUリソースが必要 → 1:30+3:30の映像で、820日とか
- 多数のサーバで分散処理
- レンダーファーム → レンダリング用のサーバ群、140ブレード(1300CPU)、100TB
- 服や髪のシミュレーションなどにもサーバの作業が必要
- エンコード、ベイクにも
- サーバ群を有効利用するために必要
- Havesterの歴史
- 初期バージョンは、定期的再起動が必要(cronを利用していた)
- バージョン2で安定
- バージョン3は、PushからPullへ設計変更
- Havesterの構成
- クライアント → Manager(mod_wsgi) → worker
- 通信はJSON
- Python2.6ベース。ManagerはLinux、workerはWindows
- SQLAlchemy, MySQLdb, mywin32, memchached, paste, zope など
- 特徴(1): サーバの区分けを台数ではなく割合で設定する
- 問題 → 台数固定だと、空いてるサーバが有効利用されない
- 空いているときは割合を超えて利用。混み始めると自動調整
- 特徴(2): タグにより、特定ノードへ振ることができる
- OSの種類や、ソフトのライセンスの問題などがあるため
- 特徴(3): ジョブテンプレートにより、新しいアプリケーションへの対応が簡単
- ExtJSによるGUI → WEB経由の利点がある
- ユーザがクライアントアプリを入れなくていい
- クライアントを強制的にバージョンアップできる
- クライアントのワークステーションにもサーバを建てている → mod_proxyで逆向きに再リクエスト
- APIはJSONベース → デバグしやすい、HTTPは安定している、ExtJSとの相性
- ただし、トランザクションしにくいのは、HTTPの欠点
- ドキュメント
- WSGIのミドルウェアにより実現
- →WEBからAPIドキュメントを見られる。直接APIを呼び出してテストもできる
- 運用面 → GUIからの再起動、Zabbixとの連動で監視
- 苦労話: レンダラーがメモリを使い尽くすと、Pythonがメモリを使えなくなる
- コネクション時のアロケーションが問題。事前にアロケーションできればいいのだが、そこまでpythonインスタンスを制御できなそう
- MySQL周りの性能低下
- JOSNのサイズの肥大化 → Apache の deflate が効果的
- WindowsのWMIが安定しない
- time.sleep で interrupt call backの発生(スレッド周り?) → win32のsleepで凌ぐ
- CPUコアが多過ぎる問題 → 特定のアプリが立ち上がらなかったり、十分な性能が出なかったり
- 予定 → PullとPush やはり両方したい、電力管理など
- 質疑応答
- Q. 実際にどんなタスクを設定するのかを見たい
- A. クライアントアプリに組み込まれている。
- Q. ユーザはタスクがどう分割されるかは考える?
- A. 考えなくてよい。依存関係などもツールが解決する
- Q. マシンの割合の単位は? ロードアベレージとかCPU時間を見る?
- A. 台数ベース。
Session 03. Pythonのここがイケてる、イケてない / 司会:郷田まり子さん
自己紹介
- Java : 庄司嘉織さん(@yoshiori) → ドワンゴのプレミアム会員になってね!
- Perl : 松野徳大さん(@tokuhirom) → 5年前はPythonのイベントでも話してた
- PHP : 小泉守義さん(@moriyoshi) → 蓮舫に2位ではいけないのかと言われた系をやってます
- Ruby : 高橋征義さん(@takahashim) → IT系の電子書籍でPythonの原稿くれる人募集
- Python : 西尾泰和 さん(@nishio) → 一番使っていた言語は自然言語
Pythonのイケてるとこ
- @yoshioriさん
- インデント
- END=falseとかけばENDも使える
- Javaと比べるとすべてがPythonの方がいい
- ダックタイピング、インタプリタ
- 0、空の文字、空の配列がfalseになる
- @tokuhiromさん
- インデントくらいしかない
- Pythonの人がPerl使うときはAcme::Pythonicを使うといい
- メソッドの定義をいじりやすい
- blessが要らない
- インタプリターのコードが(Perlより)読みやすい
- 略語を覚えなくていい
- 標準ライブラリが多い (PerlはHTTPクライアントもない。次くらいには入る)
- @moriyoshiさん
- Python嫌い、Ruby最高
- 標準ライブラリの充実
- PHPでも多いのでは?? → 標準関数が多いだけでまとまりがない
- ドキュメントが充実 (PHPには劣るが)
- @takahashimさん
- RubyはRailsのための言語として見られることが多い。それ以外の分野はPythonが普及
- GAEへの対応
- Rubyは英語っぽいDSLが流行過ぎ。Pythonではないのでは? しっかりしてるイメージ
- @nishioさん
- インデント
- Javaは静的言語だからIDEサポートが嬉しいのではないか
- 「IDEの素晴らしさで言語的なものではない」
- IDEも含めての言語では?
- 「個人的にはEclipse最強。静的・動的型付けは、IDEの違いではなく、性質ではない」
Pythonはここがイケてない
- @takahashimさん
- インデント
- 本の表紙の蛇が女性に辛い → 「萌え擬人化すればいいのでは?」 → 女性には買いにくい
- 見た目は大事。RoRはサイトのかっこよさにも勝因がある
- @moriyoshiさん
- インデント
- テンプレート言語として見ると非常によくない → HTMLに混ぜると、インデントが・・・
- 「式だけで書けば、インデントフリーです!」
- @tokuhiromさん
- 正規表現リテラルがない (import re, match) → 「欲しい」
- @yoshioriさん
- Python3で後方互換を捨てたのだけど、 len とか str がOOPじゃない
- 予約語が少ないってのが嘘っぽい (trueとか覚えなきゃいけないし)
- Noneがちょっと・・・nullとかnilがいい
- 「lenとかstrはシンタックスシュガー」
- 「予約語は少ないほどいいってもんじゃない。C++とか」
他の言語について
- @nishioさん
- PHPは@moriyoshiさんがハックしてくれるのがいい
- PHPによって、数学の良さを学べる
- 「PHPは、a == b, b == c → c == a が成り立たないことがあるという仕様」
- Perlは、動的スコープと静的スコープの切換えが楽。
- 「my, local」
- 「動的スコープはいるの?」「グローバルだとマルチスレッドで困る」
- Javaはまともなスレッドがある。 util.concurrent とかもよい
- 「RubyやPythonではマルチコアを有効利用できない」
会場より
- Q. Pythonのselfはどうなの? めんどうくさい
- A. めんどうくさいです
- selfのせいで、引数の数が合わないときのエラーメッセージがわかりにくい
Session 04. ライトニングトーク
Python sf / 小林さん
- 計算ソフトとL.L.のお話
- Python sf → ワンライナーでの計算
- 3+4の計算の例
- 数値微分、ベクトル積などを実装
- 複素数のtanの分布関数を表示させる例
- 元利均等払い → 等比級数
- Python sfでの計算のデモ
遷移図生成ツールblockdiagの紹介/ @tk0miyaさん
- 遷移図 → 画面を箱、遷移を矢印 → visioで作るの大変
- 追加、削除が大変
- ずれる
- Excelのバージョンの問題、Sphinx は画像になる・・・
- blockdiag
- テキスト → PNGとSVG
diagram {
A -> B -> C;
D -> E;
}
- SVNで管理しやすい
- 自動的にレイアウト
- 日本語対応
- PyPIにあるよ
- 色、装飾なども可能
- 矢印へのlabel付け、分岐など
- デモ: WEB上でできる画面
- group化
- Sphinx 用のプラグインもある
- 今後 → ノード形状の切換え、レイアウトエンジン、遷移図以外への対応
- →画面設計書にも
SciPy-Japan 2011 Project / Bertrandさん
- NumPy, SciPy を日本でもやりたい
- カンファレンスは、欧米だけでなくインドでも開かれている
- どんな内容がいい?
- 日英の両語で
- キーノート、トーク、スプリント、懇親会
- まずはボランティアを集める → PyJUGの忘年会、scipy-japan@googlegroups.com、IRC で #scipyjapan@chat.ap.freenode.net (12/15の21:00より)
[Ruby][Python]static website generatorっぽいソフトウェアを集めてみた
11月 12th
結構沢山ありますね。実際試したりとか全然してません。下のリストの中ではざっと見た感じ nanoc が有名っぽい。
sphinxもよく使われてますが、こっちは document generator みたいなタグ付けされて、Javadoc や Doxygen の仲間と分類されていることが多いようです。
Ruby
- nanoc: a Ruby site compiler that generates static HTML » home
- Webby :: Webby
- StaticMatic
- tdreyno/middleman - GitHub
- jekyll
- Home | webgen - static website generator
- benschwarz/bonsai - GitHub
Python
- Markdoc Documentation ? Index
- Hyde - A Python Static Website Generator
- Blogofile
- jek / blatter / overview ? Bitbucket
- Tahchee
Haskell
まだまだ沢山ありそうです。
- Any recommendations for a static site generator ? : Python
- web development - Best Static Website Generator - Stack Overflow
別レイヤですが、Markdown とか Textile みたいな軽量マークアップ言語の一覧は wikipedia が便利
最終更新日付を更新するPythonスクリプト
10月 22nd
Twitter を CouchDB にぶち込みつつける
1月 11th
Twitter の Streaming API を叩いて,CouchDB に入力し続ける。
久しぶりに python 書いた。
まだ空気が読めてない感。どう書けば素敵なんだろーなー。