パーフェクトPythonを読んだ

5年くらい前に

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


なかなか良い本だったと思う

Phantom.js終了していた

東証の適時開示情報閲覧サービスをチャンネルにして自動チェックさせたら便利なんじゃないかと昔のスニペットを探し出してきてコーディングしてたら、Chromeがheadlessに対応していてPhantomjsは終了になったようだ。

なので、Seleniumからはheadless chrome使うべし的な感じだったので、ちょっと試してみた。ハマったのはchromedriverをDLしてPATHの通ったところに置く必要があったということ。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.binary_location = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
options.add_argument('--headless')
options.add_argument('--disable-gpu')
driver = webdriver.Chrome(chrome_options=options)
driver.get('https://www.google.co.jp/')
print(driver.title)

東証開示情報チェックプログラムもphantomjs->chromeに変更するだけで動いたので良かった

Fluent Python

最近気になっている本

ProductName Fluent Python ―Pythonicな思考とコーディング手法
Luciano Ramalho
オライリージャパン / 6264円 ( 2017-10-07 )


昨日のmarkdown2pptxのスニペットをもう少しちゃんとしてrepoで管理するようにしました。

昨日のこれをちゃんとコマンドライン化してmishima.sykのrepositoryにあげておいたので適当にいじってください。

まともに動くようになったらpypiにでもあげようかなと思いますがとりあえず動かしたい場合にはgit cloneしてから

python setup.py install

で、md2pptxというコマンドが使えるようになるのでmd2pptx --helpで使い方を確認してください。

もともとのmarkdownの記法ではクラス属性とか渡せないんだけど、Attribute_list を使うとよろしい感じだったのでそうしています。

  • power pointのlayoutを指定する
  • テキストボックスのareaの位置、大きさを指定する
  • 画像の位置、スケールを指定する

あたりの情報はこれを使えばなんとかなるのではないかと。

markdown2pptx

風邪をひいたようです。自覚症状ないから気づかなかった。

こんな感じで如何?handle_dataメソッドでタグの情報持てないから、ちょっと考えた。HTMLパーサーよりはXMLパーサーのほうがやりやすい気もする。

from markdown import Markdown
from html.parser import HTMLParser
from pptx import Presentation

class MyHTMLParser(HTMLParser):
    def __init__(self):
        super(MyHTMLParser, self).__init__()
        self.prs = Presentation()
        self.tags = []
        self.slide = ""

    def handle_starttag(self, tag, attrs):
        if tag == "h1":
            slide = self.prs.slides.add_slide(self.prs.slide_layouts[0])
            self.slide = slide
            self.tags.append(tag)
        elif tag == "h2":
            slide = self.prs.slides.add_slide(self.prs.slide_layouts[1])
            self.slide = slide
            self.tags.append(tag)
        elif tag == "h3":
            self.tags.append(tag)
        else:
            print("Encountered a start tag:", tag)

    def handle_endtag(self, tag):
        pass

    def handle_data(self, data):
        if len(self.tags) > 0:
            tag = self.tags.pop()
            if tag == "h1":
                self.slide.shapes.title.text = data
            elif tag == "h2":
                self.slide.shapes.title.text = data
            elif tag == "h3":
                p = self.slide.shapes.placeholders[1].text_frame.add_paragraph()
                p.text = data
            else:
                print("Encountered some data  :", data)

    def close(self):
        self.prs.save("sample.pptx")

def md2pptx(md_txt):
    md = Markdown()
    parser = MyHTMLParser()
    parser.feed(md.convert(md_txt))
    parser.close()

sample_md = '''
my sample slide
===============

title of a Content slide
------------------------

### this paragraph
### that paragraph
### the other paragraph

another title of a Content slide
------------------------

### this paragraph
### that paragraph
### the other paragraph

'''

if __name__ == '__main__':
    md2pptx(sample_md)

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)

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

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