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(こっちは組み込みのメソッド)

みえないラムダが見えてきたヨ(あと括弧)。

SICPのおともにpythonインタプリタとかperlshとかmochikitのインタプリタなんかを併用すんだけど。

mapで遊んでみるわけだ、

perlだと

main[118]$ @numbers = (1,2,3,4,5)
main[120]$ map $_+5 , @numbers
6
...
10

なわけで、pythonだと

>>> numbers = [1,2,3,4,5]
>>> map(lambda (x): x +5 , numbers)
[6, 7, 8, 9, 10]

さて、SICPでググルとすぐに目に飛び込んでくる『計算機プログラムの構造と解釈』についてに引用されている、あのフレーズを思い浮かべる。

弟子が尋ねた。「先生、私は先生がカッコをまるで魔術師の ように扱っているのを常々敬服しています。どうすれば先生のようになれ るのでしょうか?」 師「えっ? カッコ? あ、そうか。そんなものもあったな。いやあ、 すっかり忘れておったわ」

perlだと忘れてるどころか、そもそも括弧もないしラムダもないわけだ。でさらに、YAPC2006でのバベルの話が頭をよぎった。

つまり最近lispが楽しいのはperlのせいに違いないと。

ProductName 計算機プログラムの構造と解釈
ジェラルド・ジェイ サスマン,ジュリー サスマン,ハロルド エイブルソン
ピアソンエデュケーション / ¥ 4,830 ()
在庫あり。

しかし、SICP in other languagesにperlがないですな。

pythonのスコープではまる

ちょっとはまった。結局オブジェクト作って解決しといたけど気持ち悪いので少し調べた。(でも未解決)

クロージャでカウンタを考える。Open Source WEBを参考に

perlだと

sub make_counter {
  my $c = $_[0] || 0;
  return sub { $c++ }
}

gaucheだとこんな感じ

(define (make-counter n)
  (let1 c n
    (lambda () (inc! c))))

でもpythonだとだめなの

def make_counter(n):
    c = n
    def counter():
        c = c + 1
        return c
    return counter

スコープの洗礼をうけた。参照できても代入できないのでglobalにする必要が。

def make_counter(n):
    c = n
    def counter():
        global c
        c += 1
        return c
    return counter

ctr = make_counter(5)
ctr()
ctr()

Traceback (most recent call last):
  File "C:\home\kzfm\test.py", line 10, in <module>
    ctr()
  File "C:\home\kzfm\test.py", line 5, in counter
    c += 1
NameError: global name 'c' is not defined

とかいってglobalでも駄目だ。

ビューティフルコード

最初サンプルみたときにはちょっと理解できなさそうだったので保留にしてたけど、bioperlとかpythonの話が面白そうだったのでポチッた。

ProductName ビューティフルコード
Brian Kernighan,Jon Bentley,まつもとゆきひろ
オライリージャパン / ¥ 3,990 ()
在庫あり。

jythonでopsinを使う

jythonがmacbookにインストールできなかったのでとりあえずlinuxで。

といってもgcjだとエラーを吐くので、sunのjavaをインストール。 ここみて設定。alternativeコマンドを使うとjavaの共存ができるのね。いままで、シンボリックリンクを上書きしてたのでめんどいなーと思ってたけど、これだとらくちん。

jythonをインストールしたら、あとはopsinのjarを落としてきてクラスパスに通す。

>>> import uk.ac.cam.ch.wwmm.opsin as opsin
>>> opsin.NameToStructure().parseToCML("4-iodobenzoic acid").toXML() 

二行でIUPAC名がCMLに。 すばらしい。

jrubyの例もある。

ちなみにjrubyはmacbookにさくっと入って、この例の通りにやれば動いた。

perlで同じ事をやる場合にはInline::Javaを使ってやればいいけど、Javaのライブラリを有効に利用するのはJavaで実装された言語処理系がやっぱ楽だ。

オープンソースで始めるゲノム・プロテオーム・メタボローム解析

perl,python,Rでオームな解析をするための本。ツールやデータベースの説明が主なので、ハウツーな感じではなくて、インフォマティクス側からみたバイオロジーとかケミストリーのサービスとかツールのレビューに近い感じかも。

個人的には5章のケモインフォのとこと、9章のRの章が面白かった。

codereposのコミット権をいただいた

codereposのコミット権をいただいたので早速設定した

emacsのあたりで。

それから来年はちょっとまじめにprocessingをやりたいところなので/lang/processingになにかコミットできたらいいなぁと。

Inline::Python

Inline::Pythonのバージョンがあがったのでmacbookに入れて遊んでみた。

generatorが使いたかったのだけど、nextを呼ぼうとすると

Can't call method "next" without a package or object reference at test.pl line 3.

と怒られてしまうのであった。

perlでOASAライブラリを使いたい

Inline::Pythonを使うだけ。お手軽

use Inline Python => <<'END';
import pybel
def draw_png(smiles,file):
    mymol = pybel.readstring('smi',smiles)
    mymol.draw(filename=file, show=False)
    return True
END

draw_png("CCCc1ccccc1OC","xxx.png"); 

TODO: あとでクックブックに追加しておく

ケモインフォクックブックはじめました

bioinformaticsの学習道路はそこそこ充実している。

でも、chemoinformaticsだってオープンソースで色々できるし、独学でも結構いけるよ!なんて思うんだけど情報が足りないなぁと思った。

というわけで、ちょっと小道でも。

ケモインフォクックブック

特にperl,pythonでちょっとした化学情報をいじるコードをクックブック形式で書いていけたらなぁなんて思ってる。

週に一回くらいは更新するつもりで。