PythonでShift-OR

ProductName Mastering Algorithms With Perl
Jon Orwant,Jarkko Hietaniemi,John MacDonald
Oreilly & Associates Inc / ¥ 3,263 ()
在庫あり。

Shift-ORってのはshiftしてORとって、どんどこどんどこと0を左送りにしていって最後まで0送りできた場合にパターンマッチ成功。最後がマッチしたかどうかは補数(一番左が0で残りが1)のANDをとって0が帰ってくるかどうかで判断するという文字列検索アルゴリズム。

#!/usr/bin/env python

def shift_OR_exact (T,P):

   text_length = len(T)
   pattern_length = len(P)

   if pattern_length > text_length: return -1
   if pattern_length == text_length: return 0
   if pattern_length == 1: return T.find(P)

   m1b = (1 << pattern_length ) -1
   table = [m1b] * 256

   mask = 1
   for i in range(pattern_length):
       table[ord(P[i])] &= ~mask
       mask <<= 1

   watch = 1 << ( pattern_length - 1 )

   for i in range(text_length):
       i = T.find(P[0],i)
       if i == -1: return -1

       state = m1b

       while i < text_length:
           state = ( state << 1 ) | table[ord(T[i])]
           if ( state & watch ) == 0:
               return i - pattern_length + 1

           if state == m1b: break
           i += 1

   return -1

if __name__ == '__main__':
   print shift_OR_exact("perlpypythonruby","python")
  • ビット演算はperlもpythonも似た感じ
  • perlのindexはpythonのfind(こっちは組み込みのメソッド)

iKnowの日々の記録をグラフに綴る

iKnow の進捗を Python で取得するというエントリをみつけたので、さらにmatplotlibでグラフ書くようにしてみた。これを一日の終わりにcronで実行すれば記録できる。

#!/usr/bin/env python

import urllib
from BeautifulSoup import BeautifulSoup
import re
from sqlobject import *
from pylab import *
from matplotlib.dates import MONDAY, WeekdayLocator
import datetime,os

# --- Configure --- #
mydb = '/home/kzfm/iknow.db'
mygraph = '/var/www/html/images/lf/iknow'
myname = 'kzfm'

myconnect = 'sqlite://' + mydb
sqlhub.processConnection = connectionForURI(myconnect)

class RecKnow(SQLObject):
    iknow_study = IntCol()
    iknow_finish = IntCol()
    dictation_study = IntCol()
    dictation_finish = IntCol()
    date = DateCol(default=datetime.date.today(), unique = True)

class Iknow:
    def __init__(self,username):

        b = BeautifulSoup(urllib.urlopen("http://www.iknow.co.jp/user/"+username))

        iknow = b.find('div',id="study_badge_div").find('script').string
        self.iknow_study = int(re.search(r"int_left.*?(\d+)", iknow).group(1))
        self.iknow_finish = int(re.search(r"int_right.*?(\d+)", iknow).group(1))

        dictation = b.find('div',id="dictation_badge_div").find('script').string
        self.dictation_study = int(re.search(r"int_left.*?(\d+)", dictation).group(1))
        self.dictation_finish = int(re.search(r"int_right.*?(\d+)", dictation).group(1))

def create_graph():
    iknow_study = [i.iknow_study for i in RecKnow.select()]
    iknow_finish = [i.iknow_finish for i in RecKnow.select()]
    dictation_study = [i.dictation_study for i in RecKnow.select()]
    dictation_finish = [i.dictation_finish for i in RecKnow.select()]
    dates = [date2num(i.date) for i in RecKnow.select()]

    mondays   = WeekdayLocator(MONDAY)

    fig = figure(figsize=(9,5))
    ax = fig.add_subplot(111)
    ax.plot_date(dates, iknow_study,      'co-')
    ax.plot_date(dates, iknow_finish,     'mo-')
    ax.plot_date(dates, dictation_study,  'yo-')
    ax.plot_date(dates, dictation_finish, 'ko-')

    ax.xaxis.set_major_locator(mondays)
    ax.autoscale_view()
    ax.grid(True)
    fig.autofmt_xdate()

    title('iKnow Daily chart')
    xlabel('Date')
    ylabel('Score')

    legend(["iKnow study", "iKnow finished", "dict study", "dict finished"])

    fig.savefig(mygraph)

if __name__ == '__main__':
    if not os.path.isfile(mydb):
        RecKnow.createTable()

    iknow = Iknow(myname)
    RecKnow(iknow_study=iknow.iknow_study,iknow_finish=iknow.iknow_finish,
           dictation_study=iknow.dictation_study,dictation_finish=iknow.dictation_finish)
    create_graph()

みんなのPython Webアプリ編はみんなのPythonの続編

今朝Amazonから届いたので早速読んだ。

ProductName みんなのPython Webアプリ編 [みんなのシリーズ]
柴田 淳
ソフトバンククリエイティブ / ¥ 2,604 ()
在庫あり。

そして一通り流し読みした感想としては、Pythonがはじめての言語で、Webアプリまで作れるようになりたいと考えているヒトには最強な選択肢かもしれんなーと。

HTTPサーバー構築からはじまって、CGIで、ほらーHTMLとコードが混在して読みにくくなっちまうだろ、だからここでTemplateシステムが出てくんだよとか、Webのシステムはデータベースが必要でSQLとか使うとさくさく感の流れが途切れるし気持ち悪いじゃろ、そこでO/Rマッパーの出番なんだぜといった、MVCフレームワークに至るまでの過程がスマートに追っかけられる内容ですな。

もし、コードが書けない人員がアサインされたら、みんなのPythonとWebアプリ編をセットで渡して、これ読んどけって言う、間違いなく。

僕は、みんなのPython Webアプリ(上級)編みたいなものをイメージして予約してしまったのでちょっと予想と違ったかなと。Appendixにあるような内容を深く掘り下げてるのかなと思ったんだけど、さすがにみんなのPythonの続編でそれはないかと。

年末にでもちゃんと手を動かしながら、がつっと読みますヨ。

化合物の最適化のグラフ表現

化合物の最適化の過程というもをグラフ表現にしてとっておけば、あとあと色々と使いまわせていいんじゃないかと思っている。

で、エッヂは化合物でいいとして、ノードは有向グラフで表したいが、部分構造を内包するかどうかで親子関係を決めるのがいいのか、それとも、時系列で古いほうを親にするのがいいのかそれとももっといいやり方があるのか悩ましい。

可視化は、Cytoscapeが丁度よさそうだったんだけど、Python から Graphviz を使うを見て、NetworkXというものがあるのを知った。

matplotlibで綺麗に出力できるし、これはなかなか楽しそうだ。

ExactMassを求める

そういえば多数の化合物からなるsdfからExactMassってどうやって計算したらいいのかね?と尋ねられて、

うーんそれはね、perlでChemistry::OpenBabelモジュールを使ってだなぁ、ごにょごにょとやればいいんだよ、ほら楽勝だろ。

とか言ってみたんだけど、別にpythonでもいいので書いてみた。

import openbabel as ob

obconv = ob.OBConversion()
obconv.SetInFormat("sdf");
obmol = ob.OBMol()

notatend = obconv.ReadFile(obmol, "test.sdf");
while notatend:
    print obmol.GetExactMass()
    obmol = ob.OBMol()
    notatend = obconv.Read(obmol)

たぶんPlutoだったら

from pluto import *

for mol in Molecule.readfile("test.sdf"):
    print mol.ExactMass

と書けるようになるはず。

でも今夜はOBChemTsfmとかいうクラスがねーとかいう謎の深みにはまりかけ、SWIGやらC++にやられっぱなしでそれどころじゃないのであった。

pythonのenumerate

enumerateなんて知らんかった

>>> for i in enumerate(range(5,10)):
...   print i
...
(0, 5)
(1, 6)
(2, 7)
(3, 8)
(4, 9)

plutoで結合をいじくる

こんな感じで。 titleとかはmol.title("newtitle")にしたほうがいいのかこのままでいいのか決めかねているのでそのうちちゃんと考える。

エタンをエチレンに変えてみた

>>> from pluto import *
>>> mol = Molecule.readstring("CC\tethane")
>>> mol.bond([1,2]).order(2)
>>> mol.title = "ethylene"
>>> mol.writestring()
'C=C\tethylene\n'

あとはmolecule同士のの結合とatomの追加と削除を実装すればよさそう

Pluto : Python module for chemoinformatics

PythonでもPerlMolみたいに化学反応を手軽に扱えるツールが欲しいなぁという欲求があったので書いてみることにした。PybelみたいなOpenBabelのラッパーだけど。

そういえば、PyMOLPyChemという、それっぽい名前は既に使われてるんですよな。

で、アトムにちなんでみた。

ProductName PLUTO (1) (ビッグコミックス)
浦沢 直樹
小学館 / ¥ 550 ()
在庫あり。

でも、国内しかわからなんだろうな。海外だとastro boyなんでしょ?まぁいいや。

>>> from pluto import *
>>> mol = Molecule.readstring("c1ccccc1O")
>>> mol.title = "phenol"
>>> mol.writestring()
'c1c(cccc1)O\tphenol\n'

とりあえず、readとwriteまではできた。SMARTSのクラスも作ってあるのだけどアトムばっか返ってきてボンドの返し方がよく分からん。

diels-alder反応ぐらいまで書けるようにするとこまではとっととやる。

py.testを試している

ここ数日unittest使ってみたんだけどなんかちょっと窮屈な感じがするのでもうちょっと楽にテストを書きたいなぁと思った。それから、自分ひとりで開発するときにはなんか変更を加えたタイミングでテストを走らせたいし、出来れば勝手に走るとうれしい。

そんな感じのテストのフレームワークはないかと探したところ、py.testにたどり着いた。ほぼ日本語化されたマニュアルもあった。

使い方は、例えばmodule.pyとtest_module.pyっていうファイルを作って

pytest -vf

と-fオプションをつけるとコマンドを実行したディレクトリを監視するようになって、ファイルが更新されるたびにテストが走るようになる(vは冗長モード)。

doctestもサポートしているらしいのでこれもあとで試してみる。

Paste = Pythonのmodule-starterみたいなもん

Python版のmodule-starterみたいなもんはないのかなとつぶやいたらPasteが使えることを教えてもらった。ありがとうございます。

しかしよりによってPasteがこんな風に使えるとは。

paster create -t pylons helloworld

pylonの組み込みコマンドの癖に-t pylonsってなんじゃそらとか思ってたのだけど実は組み込みコマンドじゃなかったという。

Pasteの使い方は

paster create mymodule

で対話的に入力していって答え終わると雛形完成。でディレクトリに移って

hg init
hg add
hg commit

までやるとあら不思議、分散リポジトリに管理されたPythonのモジュールスケルトンが数分で出来あがり。

ここまでやると、開発、実行(テスト)、リポジトリの管理がMeadowで全部出来るので楽チン。

あとsetuptoolsとか覚える