SQLAlchemyのmany-to-manyのsecondaryにunique制約をかけたい

同じ外部キー同士の組み合わせが重複して登録されないようにしたい。Objectでチェックするよりはデータベースに任せたかったのでこんな風にしてみた。

patents_tags = db.Table('patents_tags',
     db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')),
     db.Column('patent_id', db.Integer, db.ForeignKey('patent.id')),
     db.UniqueConstraint('tag_id', 'patent_id', name='tag_patent')
)

ちなみに単に複数の属性をuniqueにしたいんだったら__table_args__を使えばよろしい。

ProductName Essential Sqlalchemy
Rick Copeland
Oreilly & Associates Inc / 2556円 ( 2008-06 )


PyJadeでenumerateしたりstrしたい

僕はJade派なのでPythonでもJadeを使うわけだが、jadeテンプレートのなかでゴニョゴニョしたい時にハックっぽいことをしないといけないのは何とかならんかなぁと思っている。

enumerate

配列のインデックス値が欲しい時

for elm in ary
  i = ary.index(elm)

とやっている。

str

Intを文字列にしたい時str関数が使えないので

elm.id.__str__()

とやっている。

pythonの組込み関数使えると嬉しいんだけど、やり方あるのかな?

ChEMBLのデータにアクセスしたくなったらSQLAlchemyを使うとよい

ローカルに構築したChEMBLにアクセスする場合には生のSQLじゃなくてSQLALchemyを使ったほうが楽だ。その場合にはMetaDataのrelflectをTrueで。

from sqlalchemy import create_engine, MetaData

db = create_engine('mysql://user:password@localhost/chembl_14?charset=utf8&use_unicode=0')
metadata = MetaData(bind=db, reflect=True)

table = metadata.tables['target_dictionary']
stmt = table.select(table.c['organism'] == 'Homo sapiens')

for r in stmt.execute():
    print r.chembl_id, r.pref_name

ChEMBLって、生物種を正規化してないのね。パフォーマンスの問題かな?

ProductName Bioinformatics Programming Using Python
Mitchell L. Model
Oreilly & Associates Inc / 5075円 ( 2009-12-23 )


Pythonとかのちょっとしたスクリプトをforeverでデーモン化する

pythonでちょっとしたクローラーを書いて終夜で流したい時に、夜中に落ちたりすると時間がもったいないので、死んでも生き返るようにしておきたいことがある。

追記121203

はてブで指摘された通り

forever start -c python crawler.py

で良かった。ドキュメントにちゃんと書いてあった。


node.jsで書いた場合にはforeverが使えて便利だが、他の言語で書いた場合にはchild_processで子プロセスにして呼び出せばいいので、javascriptをちょっと書いておけば、PythonでもPerlでもHaskellでもなんでも使える。

でもjavascriptを毎回書くのは(忘れるし)面倒なのでforever用のjavascriptを出力するスクリプトをpythonで書いてみた(foreverizeっていう名前)。

#!/usr/bin/env python

import sys

js_str = """var spawn = require('child_process').spawn;
var app   = spawn('{}', [{}]);
app.stdout.on('data', function(data) {{
  console.log('stdout: ' + data);
}});

app.stderr.on('data', function(data) {{
  console.log('stderr: ' + data);
}});

app.on('exit', function(code) {{
  console.log('exit code: ' + code);
}});
"""

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print "Usage: {} [command]".format(sys.argv[0])
    else:
        command = sys.argv[1]
        options = ""
        if len(sys.argv) >= 2:
            options = ",".join(["'{}'".format(op) for op in sys.argv[2:]])
        print js_str.format(command, options)

使い方は簡単

foreverize python crawler.py > crawler.js
forever start crawler.js

これで、デーモン化されて夜でも安心。

ApressのEbooksDailyDealをGmailに送る

Nexus7を購入してから次の2つの電子書籍のDailyDealにはよく目を通すようになった。

ApressのほうはGoogle Readerでうまく更新されなくてちょっと困ったので、毎朝Gmailに送るようにしてみた。

import requests
import feedparser
import smtplib
from email.MIMEText import MIMEText
from email.Header import Header
from email.Utils import formatdate

EMAIL = 'your_account@gmail.com'
PASSWORD = 'your_password'

def sendmail(subject, body):
    msg = MIMEText(body, 'plain', 'utf-8')
    msg['Subject'] = Header(subject, 'utf-8')
    msg['From'] = EMAIL
    msg['To'] = EMAIL
    msg['Date'] = formatdate()

    s = smtplib.SMTP('smtp.gmail.com', 587)
    s.ehlo()
    s.starttls()
    s.ehlo()
    s.login(EMAIL, PASSWORD)
    s.sendmail(EMAIL, EMAIL, msg.as_string())
    s.close()

if __name__ == '__main__':

    r = requests.get("http://www.apress.com/index.php/dailydeals/index/rss")

    if r.status_code == 200:
        d = feedparser.parse(r.content)
        e = d.entries[0]
        sendmail(
            u"[APRESS DailyDeal] {}".format(e.title),
            u"{}\n\n{}".format(e.summary, e.links[0].href)
            )

ちなみに本日のディールはProtect Your Wealth from the Ravages of Inflationという本で僕は想定読者ではなかった。

people who have reached a level of financial stability and whose income is greater than monthly expenses.

Emacsでコード補完にJediを使う (Python)

昨日ac-python入れてみたんだけど、@kozo2jediがいいと教えてもらったので、早速使ってみた。

なんも考えないで設定すると/usr/bin/pythonを見ているようで、import errorが起きていたので、JEDI:SOURCE-DIR/env/bin/python に/usr/local/bin/pythonのシンボリックリンク張って解決

それから

(add-hook 'python-mode-hook 'jedi:ac-setup)

がうまく動かなかったので、jedi:setupのほうからC-tabで補完させて使っている。

それから下の順番で読ませないと動かないのはpackage.elのせいなのかなぁ。

;; jedi
(add-hook 'python-mode-hook 'jedi:setup)
(setq jedi:setup-keys t)
(require 'jedi)

候補が表示されるのはac-pythonと似たような感じ。

jedi

引数が表示されるのはかなり便利だ。Flaskのmodelとか引数の順番結構忘れるので。

jedi

ac-pythonで補完リストが表示されない(Emacs24)

pythonのモジュールの補完が出来ればいいなぁと思い、ac-pythonを入れてみたのだけどwindowに補完候補が表示されない。

Pythonのバッファを開いてみると、以下のようにemacs.completeによって補完候補がきちんと 返されている。

ac-python

動的略語展開(M-/,C-o)のほうで拾えるのでそんなに困らないんだけど、理由がわからないのでちょっと気持ち悪い。

Google Driveで別刷りを管理するというアイデア

既にFacebookでつながっているのであれば文書共有はDropboxを利用するのが便利だろうけど、ポスターの別刷りの配布みたいな用途にはGoogleアカウント経由で認証できるGoogle Driveのほうがいいよなと思った。

ポスターの端のほうにでもアクセス用のURLをQRコードにして印刷しておけばいいだけだしね。

Nexus7を買ってから、電子書籍購入率が急激に上がったのだけど、epubの管理にGoogle Driveを使っていて便利さを実感しているので、Sphinxでつくった文書はEpubでもダウンロードできるようにしておくのがいいだろうなと。

SphinxでMSWord(docx)ファイルを出力する

sphinx-quickstart でスキャフォールドを作成したら、sphinx-docxbuilderエクステンションを使えるようにするためクローンする

mkdir exts
cd exts/
hg clone https://bitbucket.org/haraisao/sphinx-docxbuilder

conf.pyの15-30行目あたりを編集

sys.path.insert(0, os.path.abspath('exts'))

# -- General configuration -----------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'

# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 
extensions = ['sphinx-docxbuilder']

Makefileにdocx用の設定を追加

docx:
    $(SPHINXBUILD) -b docx $(ALLSPHINXOPTS) $(BUILDDIR)/docx
    @echo
    @echo"Build finished. now you can process the docx file. $(BUILDDIR)/docx."

文書を作成してみる

make docx

おお!

sphinxでdocx

業務の文書をMSWordで提出しないとだめいうカルチャーの会社は多いと思うが、文書がフォルダに収められた後に、実際に再利用されるのを見たことがある人は少ないはず(探すの面倒だし)。

そういう場合にはReSTで書けるWIKIなんかを使うと常に参照できるうえに必要に応じてレポーティング出来ていいよねと思うのだが。僕はそういうスタイルでやっていたが超快適だった。

この快適さをmoin2+Sphinxで再現したい。

三島Haskell無名関数の会

主催者がHaskellerではないので「三島Haskell無名関数の会」と銘打ってますが、正確には三島λerの会です(嘘です)。

というわけで、Haskell (とPython)でおおいに盛り上がりましょう。

λ.ΣπとかいうHaskellとPythonを主軸にした地域コミュニティでもつくるかっていう話をしてこようっと。