23112010 Python
どんな本かな?と思い、目次を眺めてみたら、なかなか面白そうだった。
Magnus Lie Hetland
Apress / ¥ 4,294 ()
近日発売 予約可
23112010 Python
どんな本かな?と思い、目次を眺めてみたら、なかなか面白そうだった。
1-3章読んだ。
どちらかというと、リファレンスっぽい。
あと1章は正誤表がないと動かすことができないので、これを見ながら。
Kayはこれからというか、ソースコードをちょっと眺めはじめたくらい。
結局、自分でなんかつくってみないと覚えないわなという、当たり前の結論に達したので、なんか作ってみようと思ったのであった。
flask-gae-skeletonとかも試さないといけない。
19112010 Python
最近寒いですね。昨晩は御殿場のうえのほうで雪が降って、ノーマルタイヤなのに道凍ってたらどうしようかなぁと。ちょっと悩んだけど、結局高速道路で帰った。((((;゜Д゜)))ガクガクブルブル
さて、これはチャーチ数で2^2=4、2^4=16を計算し、「w」を16個出力します。(grass.elのぺえじから)
((;゜Д゜))((;゜Д゜))(((;゜Д゜)))(((;゜Д゜)))((;゜Д゜))(((;゜Д゜)))(((;゜Д゜)))(((;゜Д゜)))((;゜Д゜))(;゜Д゜)((;゜Д゜))(((;゜Д゜)))(((;゜Д゜)))((;゜Д゜))((;゜Д゜))(((;゜Д゜)))((;゜Д゜))((;゜Д゜))((;゜Д゜))(((;゜Д゜)))((;゜Д゜))((;゜Д゜))((;゜Д゜))((;゜Д゜))((;゜Д゜))(((;゜Д゜)))((;゜Д゜))((;゜Д゜))((;゜Д゜))((;゜Д゜))((;゜Д゜))((;゜Д゜))((;゜Д゜))((;゜Д゜))
$ ./gkbr.py church.gkbr
wwwwwwwwwwwwwwww
最近計算論を読んでいて、型なしラムダ計算の実装としてgrassを追っかけていたら思いついたので書いてみた。
Python実装のデバッグ出力には大変世話になった。先人のコードが読めるというのは素晴らしい。
あと数式でラムダ計算を眺めると外から見た感じになって理解を深めるのに良いですな。
でもこの本は難しい。2章までは読んだけど、3章はわからん。
#!/usr/bin/env python
# -*- encoding:utf-8 -*-
"""
gkbr.py - Gkbr interpreter
2010-11-19
- Modified by kzfm
---- Original Grass --
grass.py - Grass interpreter
http://www.blue.sky.or.jp/grass/
Copyright (C) 2008 NISHIO Hirokazu. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
History:
2008-06-06
- Tlanslated to python by NISHIO
2007-10-02
- Follow the latest changes of the definition of Grass.
- by UENO Katsuhiro
2007-09-20
- First version by UENO Katsuhiro.
"""
from copy import deepcopy
import sys
import re
import codecs
RELEASE = 0
ONLY_RETURN = 40
DEBUG = 50
DEBUG2 = 60
LOGLEVEL = RELEASE
NUMERICAL_OUTPUT = False
def log(level, *msg):
if level <= LOGLEVEL:
print "\t".join(map(str, msg))
def Struct(*keys):
class _Struct(object):
def __init__(self, *values):
self.__dict__.update(zip(keys, values))
return _Struct
Machine = Struct("code", "env", "dump")
class Value(object):
def __repr__(self):
return self.__class__.__name__
class Insn(object):
pass
class App(Insn):
def __init__(self, m, n):
self.m = m
self.n = n
def eval(self, m):
f, v = m.env[-self.m], m.env[-self.n]
f.app(m, v)
def __repr__(self):
return "App(%(m)d, %(n)d)" % self.__dict__
class Abs(Insn):
def __init__(self, body):
self.body = body
def eval(self, m):
m.env.append(Fn(self.body, deepcopy(m.env)))
def __repr__(self):
return "Abs(%s)" % self.body
class Fn(Value):
count = 0
name = ""
def __init__(self, code, env):
self.code, self.env = code, env
Fn.count += 1
self.count = Fn.count
def app(self, m, arg):
m.dump.append((m.code, m.env))
m.code, m.env = deepcopy(self.code), deepcopy(self.env)
m.env.append(arg)
def __repr__(self):
if self.name:
return self.name
return "Fn%d" % self.count
ChurchTrue = Fn([Abs([App(3,2)])], [Fn([],[])])
ChurchTrue.name = "CTrue"
ChurchFalse = Fn([Abs([])], [])
ChurchFalse.name = "CFalse"
class CharFn(Value):
def __init__(self, char_code):
self.char_code = char_code
def app(self, m, arg):
if self.char_code == arg.char_code:
ret = ChurchTrue
else:
ret = ChurchFalse
m.env.append(ret)
def __repr__(self):
return "Char(%s)" % self.char_code
class Succ(Value):
def app(self, m, arg):
m.env.append(CharFn((arg.char_code + 1) & 255))
class Out(Value):
def app(self, m, arg):
if NUMERICAL_OUTPUT:
sys.stdout.write("%d(%c)" % (arg.char_code, arg.char_code))
else:
sys.stdout.write(chr(arg.char_code))
m.env.append(arg)
class In(Value):
def app(self, m, arg):
ch = sys.stdin.read(1)
if ch == "":
ret = arg
else:
ret = CharFn(ord(ch))
m.env.append(ret)
def eval(m):
while True:
if not m.code:
if not m.dump: break
ret = m.env[-1]
m.code, m.env = m.dump.pop()
m.env.append(ret)
log(ONLY_RETURN, m.env)
else:
insn = m.code.pop(0)
insn.eval(m)
return m.env[0]
InitialEnv = [In(), CharFn(ord("w")), Succ(), Out()]
InitialDump = [[[], []], [[App(1, 1)], []]]
def start(code):
return eval(Machine(code, deepcopy(InitialEnv), deepcopy(InitialDump)))
def parse(src):
code = []
src = src.replace(u'(((;゜Д゜)))','W').replace(u'((;゜Д゜))','w').replace(u'(;゜Д゜)','v')
src = re.subn("[^w]*", "", src, 1)[0]
src = re.sub("[^wWv]", "", src)
for s in re.split("v+", src):
if not s: continue
a = re.findall(r"w+|W+", s)
a = map(len, a)
arity = 0
if s[0] in "w":
arity = a.pop(0)
if len(a) % 2 != 0: raise RuntimeError("parse error at app")
body = []
for i in range(0, len(a) - 1, 2):
body.append(App(a[i], a[i+1]))
for i in range(arity):
body = [Abs(body)]
code += body
return code
def run(src):
start(parse(src))
def run_stdin():
sys.stdin = codecs.getreader('utf_8')(sys.stdin)
src = sys.stdin.read()
run(src)
def run_from_file():
with codecs.open(sys.argv[1], 'r','utf_8') as f:
run(f.read())
if __name__ == "__main__":
if len(sys.argv) > 1:
run_from_file()
else:
run_stdin()
18112010 Python
こう書いてもいいのか。
def Struct(*keys):
class _Struct(object):
def __init__(self, *values):
self.__dict__.update(zip(keys, values))
return _Struct
なるほど。
上巻読み終えたけど、この本はグラフ理論のさわりをおさえるのにちょうどいい難易度だ(難しすぎず、かといって平易すぎもしない)
X Yを任意の集合とする。直感的には、関数fとはXの各元にYの元を一つだけ割り当てる何かである
という記述とその次のページからの関数合成とp.36の関数合成の集合のイメージでHaskellの関数合成のイメージがかなり強く沸いた。
次数列定理って面白いなと調べたら、Havel-Hakimiアルゴリズムというらしい。perlで書いてあったので、pythonでかいてみた。
def hakimi(deg):
deg.sort()
n = len(deg)
m = deg[-1]
if m == 0: return True
if m < 0: return False
if m > 0 and n == 1: return False
new_deg = []
for i,v in enumerate(deg[:-1]):
if i+1 < n-v:
new_deg.append(v)
else:
new_deg.append(v-1)
return hakimi(new_deg)
if __name__ == "__main__":
print [1,1,1,2,2,3,4,5,5]
print hakimi([1,1,1,2,2,3,4,5,5]) # True
print [2,2,2]
print hakimi([2,2,2]) # True
print [3,3,3]
print hakimi([3,3,3]) # False
木の章もおもしろかった(符号化アルゴリズムとか)。
クラスカルのアルゴリズムやヤルニークとボルーフカのアルゴリズム(プリムのアルゴリズム)は読みなおした。そっちに興味がわくようだったら、最短経路の本がより深いのでよいかも。
4色定理はいわんとしていることは分かるが証明の過程をきちんと理解しているとは言いがたい。確か図書館に四色定理の本が置いてあったので今度借りてみるかな
これは評判通りの良書。
最初のほうはさらさら読めて、僕は7章からが面白かった。
7章では関数とは何か?ということが集合から説明されていく。有限関数の表現の仕方とか一対一対応とか。
8章はlamdaから始まって継続の話でこれは面白いがさらっと流れる。継続とは何かということは良く考えないと出てこないかも
9章はコラッツの問題,アッカーマン関数が出てきて最後にY-combinator
pythonで書いてみた( fact(5) )。
(lambda g: (lambda f: g(lambda arg: f(f)(arg)))
(lambda f: g(lambda arg: f(f)(arg))))
(lambda f: lambda n: (1 if n<2 else n*f(n-1)))(5)
10章はSchemeを実装する話で、Javaなんかで実装したことがあるが、こっちのほうが環境の動きというものがよくわかった。
8,9,10は色々分かっている人向けかな。でもちょっとは知っていればかなり理解が進むし、深まり度も高まってオススメかも。
Izu.R #0お疲れ様でした。いつもは22時前には寝るのだけど、2時半くらいまで起きてコード書いてた。たのしす。
今回が初めてで、Rらしく発表+LT的なほうがいいのか、ハッカソン的なもののほうがいいのか、わからなかったうえに初めての宿という不安はあったが、とりあえず集まってみて様子見しようという感じでしたが、蓋を開けてみれば、楽しい会になってくれて良かった。
次回もやる方向で考えているので、興味があれば。
今回のキーワード
pythonで書かれたワークフロー管理ツール。@bonohu さんに初期の導入のあたりを教えてもらいながら。みんな、ほとんどこれいじってたような。
ちなみにmacportsのpythonだと依存関係トラブリまくってうまく動かないので、潔く/usr/binのを使えという結論に落ち着いた。
これはもう少しいじる。次回にはなんか成果物をもっていきたいかな。
これはよい。あとで内容をきちんと把握する。あの、ユーザー会は一定の確率で面白い内容出てくるからよいです。面白さを面白いと感じるためには、面白さに対して感度をあげる努力を怠るとダメですな。
きっかけは覚えてないが、MADの方向に行ってきた。
ついでに、一人ふぁぼ界に引きずり込まれてた。
みんなのPythonは良書ですよね。
そういえば、前日の二次会でもPython利用者率を上げていこうという結論で落ち着いた(Pythonistaの中で)
openbabelで荒く構造立ち上げて、その後量子化学計算で精密化して、Mulliken Chargeとか楽に求めたいこと多いので、サクサク出来るようにラッパー欲しかったので書いてた。 ファイルの読み込みとかよくわからんバグが出ててはまったが、なんとか動くとこまでいった。
あとはもう少しちゃんと書いてクックブックにでもあげとく。
import openbabel as ob
from tempfile import mkstemp, mkdtemp
from os import removedirs, unlink, system, environ
import re
import os.path
import string
from random import choice
def randstr(n):
"ランダムなファイル名を生成するため"
return u''.join(choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in xrange(n))
class Gamess(object):
def __init__(self):
self.tempdir = mkdtemp()
self.gamess = "/Users/kzfm/gamess/rungms"
self.jobname = ''
self.cwd = os.getcwd()
def calc(self, mol):
self.jobname = randstr(6)
obc = ob.OBConversion()
obc.SetInFormat("gamout")
gamin = self.write_file(mol)
gamout = self.tempdir + "/" + self.jobname + ".out"
os.chdir(self.tempdir)
os.system("%s %s> %s 2> /dev/null" % (self.gamess, self.jobname, gamout))
# エラーが出たのでstringを渡したらなおった
# TypeError: in method 'OBConversion_ReadFile', argument 3 of type 'std::string'
new_mol = ob.OBMol()
s = open(gamout).read()
next = obc.ReadString(new_mol, s)
os.chdir(self.cwd)
unlink(gamin)
unlink(gamout)
return new_mol
def header(self):
h = """ $BASIS GBASIS=STO NGAUSS=3 $END
$CONTRL SCFTYP=RHF RUNTYP=OPTIMIZE $END
$STATPT OPTTOL=0.0001 NSTEP=20 $END"""
return h
def write_file(self,mol):
obc = ob.OBConversion()
obc.SetOutFormat("gamin")
gamess_input_file = self.tempdir + "/" + self.jobname +".inp"
gamess_input_str = obc.WriteString(mol)
h = self.header()
ng = gamess_input_str.replace(" $CONTRL COORD=CART UNITS=ANGS $END",h)
with open(gamess_input_file, "w") as f:
f.write(ng)
return gamess_input_file
def __del__(self):
#print "remove " + self.tempdir
removedirs(self.tempdir)
if __name__ == '__main__':
g = Gamess()
obc = ob.OBConversion()
obc.SetInFormat("mol")
mol = ob.OBMol()
next = obc.ReadFile(mol,"test.mol")
newmol = g.calc(mol)
print [obatom.GetPartialCharge() for obatom in ob.OBMolAtomIter(newmol)]
GAMESSに関しては動く環境をもっているのが前提なので、そこをやりたい場合はこの本が良いです。
29102010 Python
今日の朝、時計をもっていないことに気づいて。
import sys,os
import Growl
import threading
def timenotify(notify_string):
image = Growl.Image.imageFromPath("/Users/kzfm/.tw_growl/kzfm.png")
g = Growl.GrowlNotifier(applicationName='Timer', notifications=['Watch'])
g.register()
g.notify(
noteType='Watch',
title="GrowlTimer",
description= notify_string,
icon=image,
sticky=False)
if __name__ == "__main__":
t1 = threading.Timer(600, timenotify, args=["10分経過しました"])
t2 = threading.Timer(1200, timenotify, args=["20分経過しました"])
t3 = threading.Timer(1500, timenotify, args=["25分経過しました。そろそろまとめ"])
t4 = threading.Timer(1800, timenotify, args=["30分経過しました。発表終了"])
t1.start()
t2.start()
t3.start()
t4.start()
やっつけスクリプト
12102010 chemoinformatics work Python Mercurial Sphinx
SAR News No19に寄稿しました。この号はSVM,RFとかの統計手法を使ったSARから可視化とかグラフっぽい処理とか、ToolKitを使ったプログラミングとか、日本ではあまり見かけない内容なので面白いのではないでしょうか?
余談ですがハッカソンっぽい場もあるので、ちと書いてみるか(または飲んでみるか)という方がいれば連絡を下さい(まだ空きあります)。僕はOpenBabelを使ってGAMESSの量子化学計算で構造最適化をするラッパーを書く予定にしています。それかHaskellのchemoinformaticsライブラリのソース読んでます。
さて、今回の原稿を書くのにSphinxを使った。これ最高ですな、EPubも出力できるし、超便利。ただ、今回は原稿の提出がwordだったのでwordの行間調整したりとかよくわからない部分で難儀したけど(word嫌い)。でも履歴管理の仕組み(変更モードって言うの?)はメールでやり取りするときに便利だったけど。
あとバージョン管理はMercurialを使った。Gitに比べてwebアクセスが簡単に設定できたのでチョイス、あと文書管理だとそんなに複雑な操作しないし。
09102010 chemoinformatics Python network cytoscape
以前、おもむろに思いついたLeadOptimizationのシミュレーターで、networkxはgml出力できてCytoscapeでimportすればいいじゃんということに気づいてヤル気が出た。
ついでにコードもちょっと直して、活性はpIC50とかそういうレンジにしてみて、μMオーダーから上げていくようにした。
エッジは世代を表していて、黄色から緑にむけてすすんでいく。ノードの色は活性を表していて黒から赤になるにしたがって活性が向上する。最初の方は活性が振れるけど段々向上していって安定するようにしてみた。
リードホッピングとは選択されなかったより良い未来を選択しなおすことであるとするならばそのような希望はLO初期のあたりに存在すると思うのだ。
以下、書いたコード
from random import random
import networkx as nx
class Branch(object):
"""LeadOptimization flow
potency: pIC50 or such
weight : range for activity
"""
count = -1
@classmethod
def inc_count(cls):
cls.count = cls.count + 1
return cls.count
@classmethod
def get_count(cls): return cls.count
def __init__(self,potency,weight):
self.id = Branch.inc_count()
self.potency = potency
self.weight = weight
self.activity = self.potency + self.weight * random()
def make_child(self,num_childs,potency,weight):
return [Branch(self.potency + self.weight * (random()-0.5)*2,self.weight * 0.5) for i in range(num_childs)]
if __name__ == "__main__":
max_comps = 500 # total compounds
initial_branches = 1 # number of lead compounds
lead_potency = 5 # lead activity
generation = 0
G=nx.Graph()
heads = [Branch(lead_potency,2) for i in range(initial_branches)]
map(lambda b: G.add_node(b.id, activity=b.activity),heads)
while Branch.get_count() < max_comps:
new_heads = []
generation += 1
for branch in heads[:int(2+5*random())]:
for new_comp in branch.make_child(int(40*random()),branch.potency,branch.weight):
G.add_node(new_comp.id, activity=new_comp.activity)
G.add_edge(branch.id, new_comp.id, genneration=generation)
if new_comp.activity > 7:
new_heads.append(new_comp)
heads = new_heads
heads.sort(key=lambda x:x.activity)
heads.reverse()
nx.write_gml(G,"test.gml")