python-amazon-product-api doesn't work

ここ2,3ヶ月python-amazon-product-apiが動かなくなっていて、仕様かなんか変わったのかなーなんて放置していたんだけど。

手元の開発環境ではあっさり動いたので、なんだかなーと原因追求したところ、さくらVPSのほうの時間がズレていた。

というオチ。

今は動くので、これからも精力的にアフィリエイトポチポチ貼りたいw

Jupyterの本が出ていた

買うかどうかは中身見てから決める。

ProductName PythonユーザのためのJupyter[実践]入門
池内 孝啓
技術評論社 / ?円 ( 2017-09-09 )


PygamessのバックエンドをOpenbabelからRDKitに変更しているところ

今の会社がRDKitを使っていたり、gamessで計算したエネルギーとか軌道係数をそのままRDKit+Pandasに持っていけると都合が良かったりするので、バックエンドをRDKitに変更しようとしている。

とりあえず、このコミットでtotal energyが出るようになった。

久々にコードの修正していて、 なんじゃ、この書きなぐったようなコードは? と感じたのでもう少し綺麗に書き直したい。

>>> from pygamess import Gamess
>>> from rdkit import Chem
>>> from rdkit.Chem import AllChem
>>> m = Chem.MolFromSmiles("CC")
>>> m = Chem.AddHs(m)
>>> AllChem.UFFOptimizeMolecule(m,maxIters=200)
0
>>> g = Gamess()
>>> g.input(m)
' $contrl runtyp=energy scftyp=rhf mult=1  $end\n $basis gbasis=sto ngauss=3 $end\n $system mwords=30  $end\n $DATA\n6324\nC1\nC      6.0     -0.7593407291    0.0107048487   -0.0162273112 \nC      6.0      0.7593414912   -0.0107048029    0.0162270652 \nH      1.0     -1.1594363804   -0.1004995560    1.0135868837 \nH      1.0     -1.1131931576    0.9732198527   -0.4420381632 \nH      1.0     -1.1342180646   -0.8246918478   -0.6443526878 \nH      1.0      1.1342169299    0.8246865647    0.6443564239 \nH      1.0      1.1594357587    0.1005043120   -1.0135855392 \nH      1.0      1.1131941519   -0.9732193715    0.4420333286 \n$END\n'
>>> nm = g.run(m)
>>> nm.GetProp("total_energy")
'-78.302511907400003'

なんでGamessなんて使うかというと光毒性予測モデルのようなHOMO-LUMOギャップとか励起状態が効いてくるような現象を予測しようとした場合それなりの計算してあげないといけないからね。

Gene symbolでpubmed検索をする

Gene symbolでpubmed検索をしたい場合には[sym]というオプションを付ければいいらしい。

あとはeutilに投げればXMLが返ってくるのでXPathでゴニョればいい。

例えばトポイソメラーゼIIでガン関連の文献がいくつあるかを調べたい場合にはこんな感じ。

import requests
from urllib import quote_plus
import xml.etree.ElementTree as ET

base_url = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&term="
query = "TOP2A[sym] AND Cancer"

url = "{0}{1}".format(base_url, quote_plus(query))
r = requests.get(url)

root = ET.fromstring(r.content)
print root.find("Count").text

手元のファイルをサーバーに送ってさらにサーバーでシンボリックリンクを張る(Pythonで)

Windowsの共有フォルダはCIFSを使ってLinuxにマウントすればいいということをちょっと前に知って、それ以来Windowsの共有フォルダを監視しつつ、ゴニョゴニョするようなサービスを幾つか作っている。メリット・デメリットはあるけど、ウェブブラウザのフォームを頑張るよりも楽なタスクも結構あるのではないかなと思う。

でクライアントのLinuxマシンから共有ディレクトリをマウントしておいて、適当なトリガーでフォルダの中身を漁って必要な情報をサーバーのデータベースに登録したり、ファイルをpushしたりするのはscp使えばなんとでもなって、pythonでやるんだったらparamiko使うのが普通だと思うんだが、送るファイル名に整合性がなくてシンボリックリンクを張ってキレイな別名をつけたくなった。

ま、sshからln -sっぽいことすればいいのかなと思ったら違った。sftp使うみたい

ssh = SSHClient()
ssh.set_missing_host_key_policy(AutoAddPolicy())
ssh.connect(host)
scp = SCPClient(ssh.get_transport())

scp.put(source, dest)
sftp = ssh.open_sftp()
sftp.symlink(dest, symlink)

最後の二行でシンボリックリンク張ってます。

ところで、最近コードのエントリあげてないなと思ったので調べたら、全然書いてないじゃないか…

「Pythonではじめる機械学習」は結構いい本だと思う

2ヶ月くらい前に出たscikit-learnの本で、発売後直ぐに読んで感想書いてなかった。

内容としては交差検定のやり方が丁寧に説明されていてよかったのと、色々なアルゴリズムのパラメータを振るとどういう挙動を示すのかがきちんと説明されていて非常によかった。

そもそもscikit-learn自体が理論的な背景を知らなくても簡単に機械学習をできるようにするパッケージなんで、こういう本は実務的には非常にニーズがあるんではないでしょうか?

とりあえず、機械学習の素養はないけどRF,SVMとかつかってみたいんだよねっていう人には間違いなくオススメできると思います。

それから理論の本だと、パラメータ調整の話とか、トレーニングセット、テストセットの分け方とかそういう話は基本的に書いてないんで、汎化モデルを作る際にどういうところに気を使ったらいいかとか勉強になりますし、こういうデータの分け方はディープラーニングでも一緒なので知らないのであれば本書で一通り押さえておくと良いでしょう。

一方で理論的なことはほとんど書かれていないので、ちゃんと勉強したい人はPRMLをオススメします。僕は三周くらいはしたはず、そして、あの頃は実装Rで書いてたんやなーとしみじみした。8,9 年前の話なんか…

そういえば、この前のMishima.sykでModern Rっていう言葉を初めて聞いたわ。

pexpectとclickで劇的ビフォーアフター

何故か最近GAMESSでFMOを計算することに全力を注いでおりまして。

GAMESSでFMO計算を行う場合にはfmoutilという便利ツールを使うことが多いのだが、これは対話的な環境の上にデフォルトというものが用意されていないので、毎回毎回手打ちしないといけない。

それから、きれいな複合体データでないと上手く動かない(途中に欠損があると駄目)とか実践で使っていく場合には色々と不都合があるので、今は自分用の 超便利有能空気読みすぎpython版のプリプロセッサ をガシガシ書いている。

で、ヘッダーチェックのためにfmoutilをすごい重宝してるんだけどなんせ毎回手打ちで1日何十回も対話していると流石に疲れる。

pexpectclickを使ってこんな感じに実行できるようにしてみた。

$ ./fuu --help
Usage: fuu [OPTIONS] IFILE

  Create FMO Input

Options:
  -o, --ofile TEXT         output option (default: fmo.inp)
  -n, --node INTEGER       node option (default: 4)
  -c, --core INTEGER       core option (default: 8)
  -m, --memory INTEGER     memory option (default: 48000)
  -w, --wavefunction TEXT  wavefunction option (default: RHF)
  -b, --basis-set TEXT     basis set option (default: STO-3G)
  --help                   Show this message and exit.

コードは至ってシンプルなのにモダンなfmoutilに生まれ変わって満足

#!/usr/bin/python
import pexpect
import click

bs = {"STO-3G": 1, "3-21G": 2, "6-31G": 3, "6-31G*":4, "6-311G*":5}
wf = {"RHF": 1, "DFT": 2, "MP2": 3, "CC": 4, "MCSCF": 5}

@click.command(help="Create FMO Input")
@click.argument("ifile")
@click.option("--ofile",  "-o", default="fmo.inp", help="output option (default: fmo.inp)")
@click.option("--node",  "-n", default=4, help="node option (default: 4)")
@click.option("--core",  "-c", default=8, help="core option (default: 8)")
@click.option("--memory",  "-m", default=48000, help="memory option (default: 48000)")
@click.option("--wavefunction",  "-w", default="RHF", help="wavefunction option (default: RHF)")
@click.option("--basis-set",  "-b", default="STO-3G", help="basis set option (default: STO-3G)")
def cli(ifile, ofile, node, core, memory, wavefunction, basis_set):
    c = pexpect.spawn("./fmoutil")
    c.expect(".*") #   Enter Job # :     1. Generate FMO input data for GAMESS
    c.sendline("1")
    c.expect(".*") #   Enter Input PDB File(s) :
    c.sendline(ifile)
    c.expect(".*") #   Enter Output File : 
    c.sendline(ofile)
    c.expect(".*") # 1> How many computer nodes do you want to use ?
    c.sendline("{}".format(node))
    c.expect(".*") # 1> How many CPU cores does each node have ?
    c.sendline("{}".format(core))
    c.expect(".*") # 1> How much memory does each node have (in megabyte) ?
    c.sendline("{}".format(memory))
    c.expect(".*") # 1> Choose runtyp (1:energy, 2:gradient, 3:geometry optimization)
    c.sendline("1") 
    c.expect(".*") # 1> How many layers do you want to define (1-5) ?
    c.sendline("1")
    c.expect(".*") # 1> Choose wavefunction type (1:RHF, 2:DFT, 3:MP2, 4:CC, 5:MCSCF)
    c.sendline("{}".format(wf[wavefunction]))
    c.expect(".*") # 1> Enter basis set (1:STO-3G, 2:3-21G, 3:6-31G, 4:6-31G*, 5:6-311G*)
    c.sendline("{}".format(bs[basis_set]))
    c.expect(".*") # 1> Do you add diffuse functions on COO- groups ? (1:yes, 2:no)
    c.sendline("2")
    c.expect(".*") # 1> Enter the desired n-body expansion (2 or 3) ?
    c.sendline("2")
    c.expect(".*") # 1> Would you like to perform the pair analysis (PIEDA) ? (1:yes, 2:no)
    c.sendline("1")
    c.expect(".*") # 1> Would you like to print Mulliken charges (1:yes, 2:no) ?
    c.sendline("1")
    c.expect(".*") # 1> Would you like to produce a cube file with the total electron density ? (1:no, 2:standard, 3:sparse)
    c.sendline("1")
    c.expect(".*") # 1> Whould you like to use PCM ? (1:yes, 2:no)
    c.sendline("2")
    c.expect(".*") # 1> Enter fragment size (1:1res-per-frg, 2:2res-per-frg)
    c.sendline("1")
    c.expect(".*") # 1> are S-S bonded CYSs combined to one ? (1:yes, 2:no)
    c.sendline("1")
    c.expect(".*") # 1> is GLY combined to the neighbor ? (1:yes, 2:no)
    c.sendline("2")
    c.expect(".*") # Enter Job # :
    c.sendline("")
    c.close()

if __name__ == "__main__":
    cli()

以上、clickの提供でお送りしました☆

あと、clickで--helpしたときにデフォルトの値も表示させたかったんだけど、やりかたわからんかった。誰か知ってたら教えてください。尚、オプションにchoiceを入れてないのは僕の怠慢ですw

半自動スクレイピングに最適なファイル形式、それがmht

reCAPTCHAみたいな画像認証が組み込まれていてロボットも弾くようになっているサイトだけど、どうしてもスクレイピングしたいから、マニュアルアクセスでページを保存してスクレイピングのプログラムにまわしたい、さらにその際に表示されている画像も一緒にとりたいというなかなか難しそうな課題に取り組んでいた。

IEで保存すると(完全とかいうオプション選ぶんだっけ?忘れた)フォルダに画像ファイルとかまとめて保存してくれるんだけどスクレイピングにまわすの不便というか、ウェブサービスにしたいからuploadしやすいファイル形式がいいなぁと調べていたらIEだとmhtという形式で保存できるということに気がついた。

調べたら相当前からあったらしい。

そして単一のファイルでMIMEなのも便利なところ。

RFC 2557 は、MHTMLは電子メール以外のプロトコル (HTTPやFTP) でも一度に転送出来ることや、完全なHTML文書のアーカイブとして保存出来ることを示唆している。

unpackの実装見てみたら、emailモジュール使ってunpackしていた。まぁそうだろうなと。

そこまでわかればスクレイパーをサクッと書いてやりたい仕事は終了した。

もう、半自動スクレイピングは怖くないw

あとmhtをそのままメールで送ったらアクセスポリシーがとか画像の表示を許可しますか?とか言われなくていいんではないかと思ったけどどうなんだろう?

Python Testing読みなおそうっと

pygamessをopenbabelからRDKitに依存させるように書き換えてるんだけど、pyvowsのサイトにずっとアクセスできなくてnoseでいいじゃんってなってさっきpyvowsで書いてたテストを削除した。

pychembldbもunittest使ってるしpyvowsとはサヨナラだな。

そして、色々忘れていてあれなのでPython Testingを読み直すことにした。バッグが更に重くなるけど仕方ない。

ProductName Python Testing: Beginner's Guide
Daniel Arbuckle
Packt Publishing / ?円 ( 2010-01-19 )


pythonのformatでfloatの正負の記号を無視して揃える

ドットの前にスペース入れるらしい。解決するのに大分かかったのでメモ

>>> print "{:.1f}\n{:.1f}".format(1.0, -1.0)
1.0
-1.0
>>> print "{: .1f}\n{: .1f}".format(1.0, -1.0)
 1.0
-1.0