ラベル 開発メモ の投稿を表示しています。 すべての投稿を表示
ラベル 開発メモ の投稿を表示しています。 すべての投稿を表示

2012年11月12日月曜日

WELL512a, WELL1024a を Pythonで実装

前回の続きです。

前回のコードは、元にしたプログラムがゲーム用に最適化されちゃっていて、もとの論文と比較しにくかったので、乱数生成部分を書き直しました。

WELL512a と WELL1024a, はC版と同じ結果が返ることを確認しています。
それ以外は、たぶん動くけど未検証なので、コメントアウトしてあります。
(誰か検証してください!)

あと、jumpahead()は、未実装にしました。seed()使って下さい。
本来の意味だと、数学的に離れた位置にジャンプするべきなのですが、
やり方がわからないんで、前はseed()を使ってお茶を濁してました。
これは、かえって混乱のもとなのでやめました。

2012年11月8日木曜日

WELL512aをPythonで実装してみる

擬似乱数生成法「WELL」の512ビット版をPythonで実装してみました!

このアルゴリズムは、まだマイナーのようですが、
有名なメルセンヌ・ツイスタ(Pythonの標準の乱数生成アルゴリズムでもあります)より新しく、より乱数の性質が良いとされているアルゴリズムです。

WELLについては、以下のサイトのメモがまとまっています。
http://lt140.blogspot.jp/2010/05/well.html
http://en.wikipedia.org/wiki/Well_equidistributed_long-period_linear

2012年6月15日金曜日

Sphinxのファイルの拡張子とか

うーん。Sphinxのファイルの拡張子って、.rstと.txtのどっちが良いんだろう?
Sphinxを仕事で使うようになって、いろいろモヤモヤとしてきたので、整理してみます。


2012年6月9日土曜日

開発進捗(06/06)

MTG-GUILDですが、開発から1年以上たっている割には進捗悪いんです。
余暇を利用して開発しているので、予算0円、納期未定なので、ずるずる進行なのは想定内ではあるのですが・・・。

もうちょっとなんとかしたいので、現状を整理してみました。

2012年5月16日水曜日

Python で unicode型を 継承した場合のはまりどころ



元ネタはこちらの記事です。

お題:


以下のようなクラスを定義しています。

class TestUnicode(unicode):
    def __init__(self, x):
        print x

このクラスは、キーワードを指定しないとインスタンスを作成できますが、
キーワードを指定してインスタンスを作成するとエラーになってしまうようです。

>>> a = TestUnicode('a')
a
>>> a
u'a'
>>> b = TestUnicode(x='b')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'x' is an invalid keyword argument for this function

なぜキーワードの指定の有無で挙動が変わってしまうのでしょうか?


2012年4月3日火曜日

GoogleAppEngin(Python2.7)で、NDBによる非同期アクセスをお試し中(その2)


ndbについて、ほとんど何も知らないのに、なんとく格好が良いから使い始めてしまっているのですが、翻訳したり軽く使ったりしている中で、なんとなく中身が見えてきました。

標準のdbモジュールとの差異は、主に以下の3つです。
  • 自動的なキャッシュ機能による処理の高速化
  • プロパティの整理(構造化されたプロパティの使用等)
  • 非同期処理の連鎖や並列実行

2012年3月7日水曜日

Eclipse で PEP8のチェックを行う方法


 ウィンドウ(W)→設定(P)→PyDev→エディター→コード解析→pep8.py
にて、「警告」もしくは「エラー」を選択

これでOK.(orz)

【頑張ってunittestに組み込んだのはなんだったんだ・・・。


Windows7 + Eclipse 3.7.2 + PyDev 2.4.0 で動作確認しました。


<環境構築メモ>
Pleades 3.7.2 の Platform(JREあり)をダウンロードして解凍。

ヘルプ→新規ソフトウェアのインストールで、
を追加インストール

2012年3月5日月曜日

webtestで日本語を使うときの注意点

GAE の ローカルのユニットテストにwebtestというパッケージを利用しているのですが、日本語関連でちょっとはまってしまったので、書きます。


from webtest import TestApp
app = TestApp(testtarget_app)
app.get('/')
app.post('/search', {'title': u'sample検索文字列'}

ってやると、エラーは起きないのですが、文字化けします。
非ASCII文字は?に変換されちゃうんですよね。


2012年2月20日月曜日

自動テスト時にPEP8コーディング規約をチェックさせる

unittestを自動テストでまわす時に、PEP8をコーディング規約をチェックさせてます。
この手の規約を守るのは面倒くさいのですが、
Eclipse(PyDev)に特化させることで かなり効率が上がったので、紹介します。

まず、【ここ】を参考にして、PEP8チェックをunittestに組み込んでみました。

それだけだと芸が無いので、テスト結果の出力形式をPyDev用に編集しました。

PyDevは、トレースバックのログから、エラー箇所へのリンクを作りますよね?
これはログの出力結果のパターンから リンクを生成しているように思えたので、PEP8のログを整形してトレースバックログに似せてみました。
(この辺、Pythonは改造が簡単で良いですね)

すると、トレースバックのログと同様に、PEP8に違反したところへのリンクができました!
これで、PEP8違反箇所の修正が、かなり簡単になります。

以下、ソースです

2012年2月13日月曜日

成長の軌跡:PythonでSingleton実装


昔書いたコードを見直しすると、むずむずしてきて面白いですね!
Python で Singletonを実現するためのコードの変遷を書きます。


2012年2月8日水曜日

SyntaxHighlighterを入れてみました

Google先生も古い情報ばかり教えてくるので、探し出すのに結構かかったのでメモ。

設定方法:

SyntaxHighlighter を Blogger で使えるようにするには、
以下のサイトを参考に設定すると良いです。

SyntaxHighlighterのグーグルBloggerでの使い方
http://yksmtmks.blogspot.com/2011/05/syntaxhighlighterblogger.html

SyntaxHighlighter 3.0 on Blogger
http://kenmemo.blogspot.com/2011/05/syntaxhighlighter-30-on-blogger.html

 Yet Another How To Use SyntaxHighlighter in Blogger with Autoloader
http://ywafield.blogspot.com/2011/03/yet-another-how-to-use.html

この一文
SyntaxHighlighter.config.bloggerMode = true;
なくても動くみたいですが、いちおう入れてます。

使い方のメモ:




エンコードはここが便利:
www.netyasun.com/syntaxhighlighter/source-escape.html

英語の読み書きを訓練するのが一番大事な気がする今日この頃です・・・。

2012年2月7日火曜日

GoogleAppEngin(Python2.7)で、NDBによる非同期アクセスをお試し中


以下のサイトで、GAE/PのNDB(Next DB module)モジュールについて知りました。
https://sites.google.com/site/copypesouko/--manyuaru/datastore-plus-tutorial-ja
(ただ、今は【ここ】の情報が最新らしいですね)


全然ドキュメント読めていないのですが、(Python創始者のGuidoがせっせこ作っている)GAE/Pのデータストアで非同期アクセスを行う為のモジュールらしいですね。
(他にもコンテキスト処理?とかいろいろ出来るらしいけれど難しそうなので読んでません)

非同期にアクセスできるようにということは、
  • 複数のテーブルへのアクセスを並列実行できるので、反応を改善できることがある。
    (とはいえ、高価なデータストアに頻繁にアクセスする設計は間違っている気がします)
  •  書き込み結果を待たずにレスポンスを返せる。たとえば、ブログの更新のように、書き込みにほぼ成功するような更新なら、反応を早くできる。
    具体的には、データストアとMemcacheへの更新を並行して実施することで、データストアへの書き込みを待たずにキャッシュを使って更新結果を参照させることができる。
といったような効果を期待できますね!

ただ、この新しいモジュールではkey_nameを使えません(!)


from google.appengine.ext.ndb.model import (Model as _NdbModel,
                                            transactional)


class Model(NdbModel):
    u"""google.appengine.ext.db.Modelの動きを真似るラッピング
        ぶっちゃけ、こんなラッピングはしないほうが良いと思います
    """

    def __init__(self, **kwds):
        _kwds = kwds.copy()
        key_name = _kwds.get('key_name')
        if key_name != None:
            _kwds['id'] = key_name
            del(_kwds['key_name'])
        NdbModel.__init__(self, **_kwds)

    @classmethod
    def get_by_key_name(cls, key_name, **kwds):
        return cls.get_by_id(id=key_name, parent=kwds.get('parent'))

    @classmethod
    @transactional
    def insert_or_fail(cls, id_or_keyname, **kwds):
        u"""挿入して挿入された値を返します。
            キー重複は、何もせずにNullを返します。全然非同期じゃないし、動作未検証です。
        """
        entity = cls.get_by_id(id=id_or_keyname, parent=kwds.get('parent'))
        if entity is None:
            entity = cls(id=id_or_keyname, **kwds)
            entity.put()
            return entity
        return None


  • google.appengine.ext.dbをgoogle.appengine.ext.ndbにすると新しいモジュールでなんとなく動く(だいたいのAPIは上位互換)
  • key_nameとidの区別がなくなって、key_nameを使っていたところはidを使うようにAPIが変更されている
  • 普通にput()とかすると、これまでどおりの処理が行われる(全然非同期じゃない)
  • 非同期処理を行う場合は、
    k1 = Key('モデル名', id)
    f1 = k1.get_async() # これで、値の取得が開始される
    <何か処理をする>
    a1=f1.get_result() # 取得結果を受け取る

    ということらしいです。(key_nameが無くなったことを知るだけで2時間くらい消費してしまった・・・。へこみました)

    確かに、自動でidを振られた場合と 自分でkey_nameを指定した場合で、使うメソッドが違うのは格好が悪いので、このほうが良いですね。

    だから、上の例みたいなラッピングはしないことがお勧めです(!)
    普通にget_by_idで統一しましょう。


2012/02/25 追記:
あれ、でも別にNDB使わなくても、昔から非同期でデータストアにアクセスできるんですね・・・。
GAE/PのAsync Datastore APIの使い方


その他の追加の機能(yeildで非同期アクセスの結果を受け取る書き方や、taskletsとか)や、設計上の不合理、新バージョンを押し付けない、ってのがメインなんですね・・・。


うーん?別にそんなにNDBにこだわる必要もないような?

2012/03/05 追記:
ここの記事見るより、こっちを見ましょう!
http://najeira.blogspot.com/2012/02/google-app-engineapindb.html

2012年1月12日木曜日

GAE Python 2.7のテスト環境の構築について考えてみる

今のGAEだと、

from google.appengine.ext import testbed

とかからで、必要なスタブを読み込んでいけばいいんですね。

プロダクション環境のビッグテーブルを使ってテストしなくちゃいけないほどハードなテストはしないよていなので、GAETestBaseは移植しないことにしました。

gaeunitみたいな、プロダクション環境でテストを動かす仕組みはあったほうが良い気がしますね。
今の案では、

  • ローカル環境:unittest + testbed + webtest + BeautifulSoupでテスト。
  • プロダクション環境:Seleniumでテスト
かな。

Python2.7の環境なら、unittestで、かなりいけるはず。noseとかいらないかもしんない。
webtest と BeautifulSoup は リクエストを投げて帰ってくるレスポンスの内容をテストする為にいるはず。


アプリのバージョンでnamespaceを分けるようにすれば、アプリを公開後もプロダクション環境でテストを走らせることは可能なはず。

ただ、そうした場合、バージョン間のデータのコピーとかを簡単にできるように環境を整えるのと、Seleniumのテスト開始時にデータストアを初期化するような仕組みがほしくなりますね。

んー面倒だから、プロダクション環境でのテストは後回しかな。
TDDで開発するには、ローカル環境でテストできれば十分だし。


2012年1月5日木曜日

GoogleAppEngineでjinja2を使う


jinja2は日本語のドキュメントの出来が良いし、Sphinxでも使えるので、個人的にテンプレートエンジンとしては一択だと思っています。
GAE/P 2.7では一部のサードパーティのライブラリも使えるのですが、そこにjinja2も含まれています。使用する場合は、こんな感じの記述をapp.yamlに加えましょう。

libraries:
- name: markupsafe
  version: latest
- name: setuptools
  version: latest
- name: jinja2
  version: latest

バージョン指定を推す流派もありますが、私は新しいもの好きなのでlatestを推します。問題がおきたらバージョンを指定すれば良いんじゃないかと。

追加するライブラリはjinja2だけでも良いけど、パフォーマンスとかを考えるとmarkupsafeは入れたほうが良いんじゃないかと。
ローカルで動かす場合は、SDKには上記のライブラリはないので、入れとく必要ありますね。
といっても、setuptoolsは入れているでしょうから、
easy_install jinja2
easy_install markupsafe
ってやるだけでしょうけど。

テンプレートを毎回ロードするのが嫌なので、ロードしたテンプレートをグローバルな辞書に登録してキャッシュさせているのですが、jinja2はデフォでキャッシュ機能があるらしいので、あんまり意味ないのかな?
(デフォのキャッシュにはサイズに制限があるそうだけれど、その制限はどれくらいなのか、また、制限を解除できるのかは、もうちょっと調べよう)


あと、全然話は変わりますが、2.5で使っていたGAETestBaseとか、GAEUnitとかは、Python2.7の環境だと動かないみたいですね。参考にしながらテスト用のフレームワークもどきを揃えてみるかなぁ。
そういうのがないと自動テストとかきつくてやっていられないと思うのだけれど・・・、料金改定でみんなGAE/P使ってないのかな?

2011年12月10日土曜日

開発進捗(12/10)

Pytho2.5のままだと将来的にきつそうなので、Python 2.7で頑張ることにしました。
(OrderdDictも欲しかったし)

Python2.5のときは、フルスクラッチで フレームワークを作ってました。今回はまた1から作り直しますが、前回とは違って、なるべくwebapp2を利用することにします。
あんまり開発に時間をとれないんだから、些細なことには拘らずに、手早く作ることをめざします。

今のところwebapp2で気にくわないのは、routerのところと、そこから先のハンドラの部分なので、そこをいじればいけるかなと。

htmlのレンダは、昔は日本語のドキュメントがあるフレームワークがみあたらなくてきつかったので、自作してました。でも今はjinja2の日本語のドキュメントあるので、jinja2で良いかな。Sphinxでもjinja2が標準ですしね。
本当は、前の自作のと比べるとimport が重くなりそうなので、jinja2を使うのはちょっと嫌です。でも、動的な遅延インポート+ハンドラのキャッシュで、レンダリングには ほとんどパフォーマンスは要求されないはずなので、手を抜くことにしました。

環境の再構築はだいたい完了。
当面の目標は検索画面の作成ですね。

タスク1:検索先のマスタの作成
  1. Mechanizeで とりこみたいデータを取り込むようにする
    →例外的なところを除けば取り込めるようになった。例外部分は後回しにしよう
  2. 取り込んだデータをもとに、辞書を定義するpythonスクリプトを出力するモジュールを作る
    →これから着手
タスク2: 検索用のフォームの作成

そういや、webapp2 についての記事が微妙に人気みたいですね。
googleの検索でひっかかりやすいので、一番ページビューがあります。
webapp2については、googleの公式には日本語のドキュメントがないので、困っている人もおおいのかな?
でも英語わからなくても、Python語がわかるなら、webapp2は頑張れば使えますよ!

2011年12月8日木曜日

GAEの課金額の変更について

課金額の変更ですが、あんまりいっぱいGAEを使っていなかったので、だいぶ乗り遅れてました。

今更情報収集したのですが、
を整理すると、こんな感じですかね。
  • CPU利用時間ではなくインスタンス時間で課金。
    Front Endのインスタンスは、のべ28時間分OK。
    つまり1インスタンスだけなら、24時間無料枠でOK!
    BackEndは別に9時間分の無料枠がある。
  • 課金モードにすると、最低でも月9$かかる
  • データストアへのアクセスは高価。
    特に書込でインデックスがいっぱいあるとキツイ。
    エンティティのサイズはあんまり関係ないらしい。
  • 全体的に無料枠が激減。
    一人や家族くらいまでなら大丈夫だけど、一般に公開するとなると普通は課金が必要

無料で広告費を稼ごうかなぁとかおもっていた人(←私のことです)的には、残念な話ですね。

でもまあ、元々が安すぎたと思うので、仕方がないかなぁと思います。
特に、データストアへのアクセスは、インフラに負荷をかけていたと思うのでしかたないかなぁと。



考えられる対策としては、

データストアのチューニング:
  • Memcache をばりばり使う
  • なるべく大きいエンティティを使う (普通のDBみたいに正規化とかしない。親子は一つにまとめる)
  • インデックスは押さえる。なるべくキーを良く考えて設計し、そこに情報を詰め込む。
  • マスタ類は、コードにべた書きの辞書にする

インスタンス時間のチューニング:
  • Python 2.7 で スレッドセーフにして、1つのインスタンスで捌けるトランザクションを増やす
  • BackEndを有効活用する
  • 「Max Idle Instance」は「1(最小)」にする
  • 「Min Pending Latency」は「15s(最大)」にする

他にも良い方法を見つけたら思いついたら上に追記していきます。

2011年12月7日水曜日

IE9 と localhost

GAE SDK 1.6.0 がリリースされ、Python2.7がちゃんと使えるようになったらしいので、環境を再構築してみました。

以下、ポイント
  • Python2.5をアンインストールして、Python2.7のみの環境にしてからGAE SDKを入れたら、警告らしきものが出た。 (でも動くらいしい)
  • 私はWindows7の64bit版を使っているので、Python 2.7 も64bit版をインストール。しかし、PILモジュールは、64bit版に対応していないらしい?(インストールしようとするとエラーになる・・・)
  • Eclipseは、Pleades3.7(32bit)の一番軽いやつに、pydevを追加。
  • Windows7(64bit) + Python 2.7(64bit) + Pleades3.7(32bit) 上で、webapp2のHello worldは普通に動いた
  • でもSDKのバージョンのチェックの際に404エラーになっている・・・なんでか不明。
  • IE9だと、localhostを開くときもsmartscanが動いてしまうらしい。そのせいで、Eclipseでgae sdkをテスト実行しているときに、IE9でなかなか開けないという現象が発生した。
    GAE SDKからIE9を起動すると、IEの設定を一部オフにするらしく、普通に開ける。
    1時間近く無駄にして、大変な憤りを感じてしまったので、Chromeをインストールした。
IE9でも、互換モードにしたりプライベートモードにすれば、localhostを普通に開けるようになるのかも知れないのですが・・・、いちいち調べるのが嫌になったので試してません。

Eclipseだけ64bit対応じゃないので、いつか64bitにしたい気もする。
あとは、MySQLのインストールか・・・。できれば今晩チャレンジしたいな。

2011年11月25日金曜日

Python:半角で文字数を数える

なんとなく必要になったので、いろいろ調べて以下に落ち着きました。



def hankaku_count(text, wide_type_letters='WFA'):
    u"""半角で何文字かを数えます

    あいまいな文字を1文字で数える時は、
    wide_type_letters='WF'でお願いします。
    (デフォルトは2文字です)

    Example:
    
    >>> hankaku_count(u'テストtest')
    10
    """
    import unicodedata
    return (len(text) + 
            sum(1 for char in text 
                if ord(char) >= 256 and 
                   unicodedata.east_asian_width(char)
                   in wide_type_letters
               )
           )

# EOF


2011年10月25日火曜日

携帯サイトのセッション管理

携帯電話のセッション管理の面倒さは、ドコモの携帯がクッキーに対応していないことに起因している。(他のキャリアについては、パソコンとほぼ同じと考えていい)
新しい機種やスマホは、当然クッキーに対応しているのだけれど、古いドコモを切って良いのかどうかで迷い中。

ぶっちゃけ自分の携帯は、クッキーに対応しているので、古いドコモはとりあえず切って開発しようかな?
うん、そうしよう。

速さを重視して、データストアにまったく値を保存しないで、memcacheでセッション管理したら、memcacheの寿命が短すぎてまいった。端末のcookieにはセッションIDが残っているのですが、サーバ側はセッションIDやそれに紐づけられた変数が数分で消える。
memcacheのエントリの寿命は2週間を指定しているのに、すぐおちるのは、インスタンスが落ちるのと同じタイミングでmemcacheも落ちるということかな?
みんなcookieに保存するのもありだけど、改ざんテストにコストがかかるし、古いドコモに対応させようとするとURLクエリに保存しきれなくてきついはず。
ってことはやっぱりセッション管理にデータストアを使うしかないのかなぁ。
普通でつまらないけど、仕方ないかな。

2011年9月7日水曜日

webapp2! の続き

ビジネスロジックはいじらずに、あいかわらずフレームワークをいじってしまってます。

webapp2のハンドラの文字列によるインポートは、ちょっと誤解してました。
ディスパッチャでは別の使い方をしているので、私のフレームワークとは別物ですね。
webapp2は、全体にモジューラルな感じに作られていて、いじりやすそうですが、書き方が冗長すぎる気もします。webapp2を分解してもう少しインテグラルな方に作り直してみよう。
前回webappを分解して自分用フレームワークを作ってみた時は、GAEの仕組みを大分理解できましたので、今回もいろいろ勉強になりそう。

旧フレームワークの改善点:
・requestやresponseを、ハンドラオブジェクトの属性に保存しない(並列実行時にオブジェクトの属性が書き換えられる場合があることを考慮する)
・ディスパッチャからハンドラのgetやpostのメソッドを直接呼ばないようにする(ハンドラ側でセッションIDの管理を行ってから、getやpostを呼ぶようにする)。そうすることで、ハンドラごとにセッションを管理するかどうかを制御できるようにする。
・view部分をもう少し高速化できるようにする。(文字列の結合を減らせるようにする)

最近は仕事で少しだけpythonを使うようになっているのですが、2.7のほうが良いことがおおいので、GAEにもはやく2.7になって欲しいです。