Shizuoka.py #2をやりました

参加された皆様お疲れ様でした。

今回も内容が充実していて楽しかったです。次回は10月初旬-中旬を予定していますのでまたよろしくお願いします。個人的には後半のserverspec,ansible,パッケージングが勉強になった。あと現状はKivyよりはAlloyのほうがよさそうだなーってのがはっきりしたのでスッキリした。 ansibleのスライドは上がったら追記する。

私のスライド。元ネタをあたればもしかするとお目当てのものが見つかるかもしれません。

Flask入門

サンプルアプリがすぐにpyramid書き換えられてpull requestが送られたらしいw

フレームワークはWSGIとZopeの間のどこか。

パッケージングの今と未来

パッケージの話。いくつかPYPIに置いているので非常に勉強になった。それからpipでbitbucketから直接インストールする方法が便利だなぁと思った。

@ringtaroがじゃんけん大会でパーフェクトPythonをゲットして喜んでいたので、詳しいまとめを書くはず(多分)。

ProductName パーフェクトPython (PERFECT SERIES 5)
Pythonサポーターズ
技術評論社 / 3360円 ( 2013-03-05 )



安東米店にいった

ちょっと気になるものがあったので、静岡駅から安東二丁目まで歩いていって米屋さんでカミアカリを買ってみた。

1373149936

今日のドラムンベース(130629)

radrがTwitter API1.1に対応したらしいが、先週Traktor-SongNameServerというものを見つけたのでこちらに乗り換えた。

traits   => [qw/OAuth API::RESTv1_1/],

って変更だけで動くし。

ログとっているのでperlからsqliteにアクセスするかTraktor-SongNameServerをPythonで書きなおしてリアルタイムで収集するようにしたい(今はプレイリストをXMLにエクスポートしてそれを読んでる)

djutil1

ついでに、曲の雰囲気をコメントに入れているので、配色イメージを参考にしてノードに色つけすればいいか。そうすれば選曲をもっと楽しめるはず。

ProductName 配色イメージワーク
小林 重順
講談社 / 1680円 ( 1995-02-15 )


Darkling Sky / Barefoot
Electric Smile / Dom & Roland
Inspired By Insane / Fade
Cant You See / Optiv & CZA
Right Here / Ulterior Motive
Dead Hollywood / Royalston
Whatever (Mefjus Remix) / Optiv & BTK
Circles / Enei featuring Sam Wills
The Chant / Mikal
Boshoven / Nymfo & June Miller
Marka (feat. Strategy) / Dub Phizix & Skeptical
Run / Spinline
We Are One (NuLogic Remix) / Logistics
Rich Kids / Hamilton
Boiler Room / Ben Fawce & P Fine
We Become One (feat. Foreign Beggars & Craze) / Calyx & TeeBee
Posers / Breakage
To Fly / Eastcolors & Enei
Ice Block / James Marvel & Shimon
This City (12 Mix) / LSB feat Sian Sanderson
Liberation / Enei & Emperor
Midnight Nation / Optiv
Chubrub / Various Artists
Temper / Ed Rush & Optical
Roxy / Nymfo & State Of Mind
Sleepless (B-Complex remix) / New Zealand Shapeshifter
Hide Your Tears Because We Are In Heaven / Unquote

来週はShizuoka.py #2です

楽しく二回目もやることになりました。静岡Pythonistaの熱い気持ちがシナジー的な何かを産んで、サーバーサイド(構成管理も含む)からフロントエンドまで含むバランスの取れた発表が集まりました。

ランチは清水港みなみのマグロ丼などオススメですね。

maguro

というわけで、今回も楽しくやれればいいなーと。

pychembldbでつくるChEMBLウェブサービス

Flaskpychembldbを使えばChEMBLウェブサービスみたいなのは簡単に作れるよと、朝の30分くらいを使ってちょっとやってみた。

pychembldbはSQLAlchemyのラッパーなので、Flaskのほうではルーティングを設定して、ハンドラ関数用意すればいいだけ。特にFlaskはJSON化する関数が用意されているのでJSONで返すのはラク。

@app.route("/chemblws/compounds/<chembl_id>")
def compound_by_ChEMBLID(chembl_id):
    compound = chembldb.query(Molecule).filter_by(chembl_id=chembl_id).one()
    result = {...}
    return jsonify(result)

という感じでDictionaryを用意してxmlかjsonに変換して返せばいいので、とりあえずChEMBLIDを与えると対応する化合物情報を返すAPIを実装してExamplesに用意してみた。

自前でサービスを用意することのメリットは

  • 外部に情報が流れない
  • レスポンスが速い
  • 沢山投げても怒られない

ということの他に

  • 自分たちの用途に合わせて 拡張できる
  • データベースのスキーマをきちんと理解できる

という部分もあるかなと思います。例えばChEMBLウェブサービスにはジャーナルのdoiから構造リストを返すというAPIは存在しないけど、project毎にジャーナルをまとめていたりするときにはそういうAPIが用意されていると便利かもしれませんよね?

最初、ウェブサービスが返す情報は固定なのかなと思い、決め打ちで用意したのだけど、CHEMBL1CHEMBL2で返ってくるjsonのキーが違うので、valueが存在するのものをすべて返しているのかな。

もう少しちゃんと出来たらきちんとテストを書こう。

CHEMBL1

{
    "compound": {
        "acdLogd": 7.67, 
        "acdLogp": 7.67, 
        "alogp": 3.63, 
        "chemblId": "CHEMBL1", 
        "knownDrug": "No", 
        "medChemFriendly": "Yes", 
        "molecularFormula": "C32H32O8", 
        "molecularWeight": 544.59, 
        "numRo5Violations": 1, 
        "passesRuleOfThree": "No", 
        "rotatableBonds": 2, 
        "smiles": "COc1ccc2[C@@H]3[C@H](COc2c1)C(C)(C)OC4=C3C(=O)C(=O)C5=C4OC(C)(C)[C@@H]6COc7cc(OC)ccc7[C@H]56", 
        "stdInChiKey": "GHBOEFUAGSHXPO-XZOTUCIWSA-N"
    }
}

CHEMBL2

{
    "compound": {
        "acdBasicPka": 6.52, 
        "acdLogd": 2.09, 
        "acdLogp": 2.14, 
        "alogp": 2.11, 
        "chemblId": "CHEMBL2", 
        "knownDrug": "Yes", 
        "medChemFriendly": "Yes", 
        "molecularFormula": "C19H21N5O4", 
        "molecularWeight": 383.4, 
        "numRo5Violations": 0, 
        "passesRuleOfThree": "No", 
        "preferredCompoundName": "PRAZOSIN", 
        "rotatableBonds": 4, 
        "smiles": "COc1cc2nc(nc(N)c2cc1OC)N3CCN(CC3)C(=O)c4occc4", 
        "species": "NEUTRAL", 
        "stdInChiKey": "IENZQIKPVFGBNW-UHFFFAOYSA-N", 
        "synonyms": "CP-12299,Minipress,Minizide,PRAZOSIN,Prazosin"
    }
}

今週末は第3回入門機械学習読書会です

優先トレイと回帰分析の章をやります。

懇親会はどこにするかは決めていないですが、それほど人が多くなければPhotoに寄って、ソビって帰るというプランが(自分のなかで)固まりつつある。

ProductName 入門 機械学習
Drew Conway
オライリージャパン / 3360円 ( 2012-12-22 )


ちなみに、scikit-learnでも回帰分析してみました。

MMPで発表してみたら結構レスポンスが多くて楽しかった

先週はgWT絡みで、今週はMMP絡みの発表をしてきた。それぞれ独立している仕事ではあるのだけど、プロジェクトの大いなる流れというかストリームというかそんなやつをきちんとコントロールしたいというのがそもそもの動機だったりするのでそういう意味ではつながっていると思います。

あと、いくつか質問をうけたので答えられるものはここに記しておきます。

sdfからgspのコンバートってどうすんの?

openbabelのPythonラッパーを入れていればここに書いてるスクリプトで動くと思います。結合情報をアトム情報を吐き出せばいいだけなので他のツールでも同様にやればいいはずです。速度が気になる場合はsdfパーサーを書かなければいけないので面倒かも。

個人的にはpygwtというsdf2gsp gsp2sdfを後ろで面倒見てくれるモジュールを作りかけなので、出来たらgithubにあげておくかもしれません。

pychembldb

chembldbのpythonラッパーです。pypiにもあげてあるのでeasy_installとかpipでインストール出来ます。16には対応していませんが、そのうち対応します。

イントラでrestfulなウェブサービスを作る場合(といってもGETに対応させるだけでしょうが)にはFlaskを使うのがお手軽かなと思います。chemblのAPIに対応させるのはそんなに難しくないですね。

そういえば、創薬系の中でPythonでウェブサービスつくるハンズオンでもやりつつ沼津のタップルームで地ビールがぶ飲みしたいなとかそういう話をしていたことを思いだした。

Shizuoka.py #2をやります

7/6@静岡です。

snake

前半はフロントエンドな話、後半はサーバーサイド(サーバー管理的な)の話になっています。

前半は、みんな大好きパターン認識から、Pythonで書いてjavascriptにコンパイルするっていう話と、Pythonでスマホアプリを作っていくという夢が広がる系の話ですね。

後半はサーバーの管理を楽にする構成管理ツールの使い方という実務的な内容になる(のかな?)個人的にansible,fabric(+cuisine), envassertの使い分けをいまいち理解していないので楽しみなトコロ。

タイムテーブルに若干余裕があるので、入門的な話を入れたいのだけど、もし聞きたい話があればATNDのコメント欄にでも書いておいて貰えれば。もちろん「発表したい」も歓迎です。

python-pptxで表をつくってみた

python-pptxがテーブル対応していたので早速使ってみた。これはヤヴァイ、スクリプトで自動化したら快適になりそうな予感がする。

が、いまのとこ6行以上を指定するとファイルが出力できない模様。

test_table

from pptx import Presentation
from pptx.util import Inches
from pychembldb import *

prs = Presentation()
title_only_slidelayout = prs.slidelayouts[5]
slide = prs.slides.add_slide(title_only_slidelayout)
shapes = slide.shapes

shapes.title.text = "10.1016/S0960-894X(01)80693-4"

rows = 6
cols = 6
left = Inches(0.5)
top = Inches(1.5)
width = Inches(8.0)
height = Inches(0.8)

tbl = shapes.add_table(rows, cols, left, top, width, height)

tbl.columns[0].width = Inches(2.0)

tbl.cell(0, 0).text = 'inchi_key'
tbl.cell(0, 1).text = 'activity'
tbl.cell(0, 2).text = 'HBD'
tbl.cell(0, 3).text = 'HBA'
tbl.cell(0, 4).text = 'PSA'
tbl.cell(0, 5).text = 'MWT'

for journal in chembldb.query(Doc).filter_by(doi="10.1016/S0960-894X(01)80693-4"):
    for assay in journal.assays[:1]:
        for i, activity in enumerate(assay.activities[:5], 1):
            tbl.cell(i, 0).text = activity.compound.molecule.structure.standard_inchi_key
            tbl.cell(i, 1).text = str(activity.published_value)
            tbl.cell(i, 2).text = str(activity.compound.molecule.property.hbd)
            tbl.cell(i, 3).text = str(activity.compound.molecule.property.hba)
            tbl.cell(i, 4).text = str(activity.compound.molecule.property.psa)
            tbl.cell(i, 5).text = str(activity.compound.molecule.property.mw_freebase)

prs.save('test.pptx')

追記 130605

というわけでSHizuoka.py #2も楽しいよと、ちょいと宣伝しておきます。

入門機械学習の線形回帰をscikit-learnでやってみる

5.2のウェブアクセス数予測の節でRのコードは以下のようによくあるもの

> lm.fit <- lm(log(PageViews) ~ log(UniqueVisitors), data = top.1000.sites)
> summary(lm.fit)

Call:
lm(formula = log(PageViews) ~ log(UniqueVisitors), data = top.1000.sites)

Residuals:
    Min      1Q  Median      3Q     Max 
-2.1825 -0.7986 -0.0741  0.6467  5.1549

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)         -2.83441    0.75201  -3.769 0.000173 ***
log(UniqueVisitors)  1.33628    0.04568  29.251  < 2e-16 ***
---

これをpandas+scikit-learnでやってみる。プロットするのでipython -pylabで起動しておく。

from sklearn import linear_model
import pandas as pd
import numpy as np
top_1k_sites = pd.read_csv("top_1000_sites.tsv", sep="\t")
scatter(np.log(top_1k_sites["PageViews"]), np.log(top_1k_sites["UniqueVisitors"]))
clf = linear_model.LinearRegression()
clf.fit(np.log(top_1k_sites[["UniqueVisitors"]]), np.log(top_1k_sites["PageViews"]))
clf.coef_        # array([ 1.33627803])
clf.intercept_ # -2.834409473735672

個人的にRの表記の仕方(y ~ Xみたいな)のほうに慣れているのでscikit-learnのfit(X, y)という書き方は最初ちょっと戸惑った。

以下はscatter(np.log(top_1k_sites["PageViews"]), np.log(top_1k_sites["UniqueVisitors"]))で表示される散布図

plot

ProductName 入門 機械学習
Drew Conway
オライリージャパン / 3360円 ( 2012-12-22 )


PythonScriptでHandlebarsを扱う

PythonScriptでhtmlテンプレートを使いたいなぁと思ったのでHandlebarsを使ってみた。

pythonscript with handlebars

index.jade

!!! 5
html
  head
    meta(charset='utf-8')
    meta(name='viewport', content='width=device-width')
    title Handlebars demo
    link(rel='stylesheet', href='stylesheets/app.css')
    script(src='javascripts/vendor/custom.modernizr.js')
  body
    .row
      .large-12
        h2 PythonScript with Handlebars
        hr
    script(src='javascripts/jquery.js')
    script(src='javascripts/handlebars.js')
    script(src='javascripts/pythonscript.js')
    script(src='javascripts/jquery.py.js')
    script(src='javascripts/app.py.js')
    script(src='javascripts/foundation/foundation.js')
    script
      $(document).foundation();

app.py

テンプレートをhtmlのscriptから取れなかったのでベタ書きした。あと",'の扱いが0.7.4でおかしくなってる。

source = "<h3>{{title}}</h3><div>{{body}}</div>"

template =  JS("Handlebars.compile(source)")
title = "ひげひげひげ"
body = "セクシーコマンドー外伝"
data = JS("template({title:title,body:body})")
J("body .row ").append(data)

ちょっと試した感じではラップすればjavascriptを意識せずに使えそう。scriptタグでテンプレートが読み込めない問題は困るが。

ProductName セクシーコマンド外伝 すごいよ!!マサルさん(1) [DVD]

バンダイビジュアル / 3243円 ( 2001-01-25 )