Posts on python

Python製WebアプリケーションフレームワークFlaskが思っていたよりパワフルで深い。

せっかくPython始めたのでWebアプリの一つでも作ってみたいと思い、この本を読みながらFlaskの使い方を勉強していたんですが、正直扱いづらいなぁ・・・と感じていました。 Pythonプロフェッショナルプログラミング 第2版posted with カエレバ株式会社ビープラウド 秀和システム 2015-05-21 Amazon楽天市場 ちょっと規模が大きくなると、Viewを機能ごとに複数のソースファイルに分けたり、機能ごとにテストを組みたくなってきて。 デコレータで手軽にroute設定できるのは利点なんですが、このappインスタンスを複数ファイルから参照するのは何か嫌だし。 from flask import Flask app = Flask("hoge") @app.route('/users/') def show_users(page): users = User.query.all() return render_template('users.html', users=users) if __name__ = "__main__": app.run(host="0.0.0.0", port=80)…

MNIST手書き文字機械学習。TensorFlowチュートリアルの前に、scikit-learnのSVMで復習する。

TensorFlowを手持ちのMacにインストールしてチュートリアルを写経...する前に、まずは復習がてらscikit-learnのSVMを使って分類してみようと思います。 久々ですっかり忘れてきているもので。 MNIST手書き文字イメージデータのダウンロード THE MNIST DATABASEからトレーニング用とテスト用の手書きイメージデータをダウンロードしましょう。 以下4つです。 train-images-idx3-ubyte.gz: training set images (9912422 bytes) train-labels-idx1-ubyte.gz: training set labels (28881 bytes) t10k-images-idx3-ubyte.gz: test set images (1648877 bytes) t10k-labels-idx1-ubyte.gz: test set labels (4542 bytes) 手で落としてgunzipしてもいいんですが、せっかくなのでpythonで書いてみます。 MNIST手書きイメージデータを扱うためだけのクラス ダウンロードしてgzip伸長する関数を書くと、こうなります。 …最初メモリを節約しようとgeneratorで書いたんですが、データ数が多すぎて処理が重くなったのでやめました^^; 代わりに、流行り?のasyncioを使います。 MNIST手書き文字イメージデータのDataFrame化 先ほどのクラスを使えば、手書き文字イメージデータをDataFrame化するのは簡単です。 from mnist_dl import…

matplotlibをOSXのpyenv仮想環境下で使用するには。

matplotlibを使いたかっただけなのに、まさかトラブるとは思っていませんでした…。 ちょと前まで普通に使えていたはずなのですが、そういえばSSD換装後にOSXを再インストールして以降、使った覚えがない。 pyenv環境下でmatplotlibを使用するためには色々と下準備が必要ということを今更知り、とりあえず解決したので、その備忘録です。 import matplotlibでいきなり警告 pip install matplotlibは何事もなく成功するのですが、import matplotlibでおもむろに警告が出力されます。 が、これは問題ありません。 フォントのキャッシュを作ってるのでしばし待てと。 OSX再インストール前にも表示されたかどうかは… うーん、記憶にない。 In [11]: import matplotlib.pyplot as plt /Users/takashi/.anyenv/envs/pyenv/versions/3.5.1/lib/python3.5/site-packages/matplotlib/font_manager.py:273: UserWarning: Matplotlib is building the font cache using fc-list.…

Python asyncioのソースを眺めていて、すっかり忘れていた '*' (アスタリスク) 1個が示す意味。

これです。 __init__の引数に '*' (アスタリスク) が1個、ポツンとありますよね。 class Queue: """A queue, useful for coordinating producer and consumer coroutines. ... """ def __init__(self, maxsize=0, *, loop=None): if loop is None: self._loop = events.get_event_loop() else: self._loop = loop self._maxsize = maxsize # Futures. self._getters = collections.deque() # Futures. self._putters = collections.deque() self._unfinished_…

太陽光チャージコントローラ TS-MPPT-60 のステータス取得用Pythonパッケージを作ってみた。

自作した自家発電機の状態を監視するシステムの根幹部分をどうやって作ったか、の記録。 コントローラがブラウザに返すhtml/jsをリバースして作ったんですが、一応メーカのエンジニアに問い合わせてOK頂いたので、安心して公開することにします。 まずはチャージコントローラ選別 「発電状況を外部から取得できるコントローラ」って、意外と少ないんです。少なくとも個人で手が出る価格帯の範囲では。 外部から取得できないなら、センサー類を自前で揃えて自作するしかないのだけど、家電が使える容量のシステムだと流す電流量が多いので、それに耐えるセンサーとなると… コストが嵩むことになります。そもそも入手できないかも…。 そこでこのTristar社製チャージコントローラTS-MPPT-60です。 日本円で10万円程度にも関わらず、標準でEthernetポートを備えている上、HTTP経由でバッテリ電圧、太陽光パネル電圧、充電流量、放電流量、ヒートシンク温度に至るまで様々な情報を得ることができる、お得感満載な製品です。 太陽電池充放電コントローラー TS-MPPT-60posted with カエレバ 電菱 Amazonで調べる楽天市場で調べる この情報を収集する手段を用意し、収集したデータをXivelyといったクラウド上のデータベースに記録してグラフ化したい、というわけです。 Tristar社製 TS-MPPT-60 API仕様 TS-MPPT-60から得る情報や、その取得方法の仕様はTriStar-MPPT Modbus specification documentを見れば分かるよと、Tristar社のエンジニアの方が教えてくれたんですが… 結構な文量な上、まさに「仕様書」って感じで読みづらい。 ならば、ブラウザ経由でチャージコントローラにアクセスした際に参照するJavascriptソースを解析した方が、目的達成には近道。 のはず。 発電状況取得方法の検証 ということで、…

vimのテンプレート機能でコーディングを3倍楽にする方法。

コードを書き始めるとき、毎回同じことを書くのは時間の無駄ですよね。 典型例がソースコードのライセンス条文だったり、HTMLの雛形タグだったり、Markdownの章立てだったりすると思います。 .vimrcを設定する vimであれば、こんな風な設定を.vimrcに書いといて、テンプレートとなるファイルを${HOME}/.vim/templateに置くだけで無駄を省くことができます。 autocmd BufNewFile *.py 0r $HOME/.vim/template/python.txt autocmd BufNewFile *.md 0r $HOME/.vim/template/markdown.txt autocmd BufNewFile *.uml 0r $HOME/.vim/template/plantuml.txt plantumlソーステンプレートを作成する 特にオススメなのがplantumlソースのテンプレート。 こんな形で予め網羅的に書いといて、.vimrcと一緒に適当なVMSにpushしておくと良いです。 ' sequence diagram @startuml hide footbox actor Foo1 boundary Foo2 control…

ちょっとしたコマンドラインツールをpythonで作る時に便利なargparseのテストで気をつけるべきこと。

ちょっとしたコマンドラインツールをpythonで作る時に便利なargparseなんですが、位置引数ありparserが出す例外をテストするコードを書いて初めて知ったことがありました。 そのメモ書きになります。 位置引数とは argparseの公式ページにも載っている通り、コマンドライン実行時に必須となる引数のことです。以下引用。 位置引数は次のように作成します: >>> >>> parser.add_argument('bar') parse_args() が呼ばれたとき、オプション引数は接頭辞 - により識別され、それ以外の引数は位置引数として扱われます: >>> >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('-f', '--foo') >>> parser.add_argument('bar') >>> parser.…

呼び出し規約とは?stdcallとはなんぞや?という話。

昔WindowsCEプラットフォームで製品開発していた時も、素のWin32APIを叩いてテストアプリを作ったりしていたけれど、今思うとあまり理解しないままに使って作っていたんだなぁ…と、今更ながら思う。 ARMで言う所のeabiみたいなもんか。関数を呼び出すということ - Web/DB プログラミング徹底解説 https://t.co/Bb6Nw5icCO @sharethisより— takashi ando (@takashi7ando) 2016年10月27日 上のリンク先、「関数を呼び出すということ」なんて超基本じゃん!などと思うなかれ、かなり深いところまで掘り下げて解説されています。 最も具体的で身近な例としては、「Win32APIと標準Cライブラリとでは、スタックの巻き戻し方が違うんだよ」という点です。そうだったんだ!と、目から鱗でした^^; そんな__stdcallの規約、大元の情報は以下のMicrosoft本家ページに記載されています。 Win32APIの呼び出し規約 Cライブラリはこちらです。 Cライブラリの規約__cdecl ちなみに、上記の規約ページでも触れていますが、スマホなどの組み込み機器で確固たる地位を築き上げたARMプロセッサは、インテルのx86プロセッサとは全く異なるCPUなので、当然規約も違います。 検索したら、ARM社ではなく、なぜかMicrosoft の解説ページがトップに出てきたんですが… そのままリンク貼っちゃいます^^; ARM ABI 規則の概要 なんでこんなもん調べだしたのかというと… 今後仕事でWindows上で動かす業務効率化するスクリプトを書く機会が増えそうで、…

DIYガイガーカウンタ製作日記その3。

DIYガイガーカウンタ製作日記その2の続き。 事あるごとに線量計で家の周りを測るの、メンドくさいんですよね。 勝手に計測してくれて、リアルタイムに自動的にグラフ化してくれて、線量が上限の閾値を超えたら警告してくれる線量計があると、楽に安心して生活できるなぁ…。 リアルタイムに可視化した空間線量データ そんな動機で作り始めて、リアルタイムに可視化するとこまで完成。 Safecastにデータ提供するだけだと、他の大量の観測データに埋もれてしまうのと、特定地点の線量の増減がよく分からないので、お馴染みXivelyを使います。データ量によらず無料なのが良い。 KeenIOのライブラリを使うと簡単に綺麗なグラフが描けるんですが、月当たりの送信可能データ量上限が決まっているので、今回は泣く泣く諦めることに。 コードの解説 Xivelyにデータ送信する部分のコードは以下です。実際は自前のevent trigger/handlerを間に挟んでいますが、送信部のみ抜粋しました。 class XivelyEventHandler(IEventHandler): """ The instance should be registered to event trigger for data update. This uploads any data to xively cloud service. Args: api_key: API key ID provided by xively.…

DIYガイガーカウンタ製作日記その2。

DIYガイガーカウンタ製作日記その1の続き。 前回はSparkfun製ガイガーカウンタから得たcpm値をuSv/hに変換してprintするとこまでだったので、今度はこれをSafacast API経由でSafecastサーバに送信してみます。 検討は過去記事空間放射線量データを公開しているSafecast。REST API経由で定点観測データを自動送信するには?でほぼ完了しているので、あとは組み合わせるだけです。 import requests from datetime import datetime from serial import Serial # Sparkfunガイガーカウンタを接続したシリアルポートを開く port = Serial("/dev/tty.usbserial-AK05C8NQ", baudrate=19200) while True: # cpm値の部分だけ抜き出す cpm = int(port.readline().decode("ascii").split()[0]) # uSv/h換算 usv = cpm * 0.00812 print("{:.2f}[uSv]".format(usv)) # 計測した線量値をSafecastのHPから登録する際のやり取りをgoogle chromeでキャプチャした結果を使う data = { "measurement[…