tmux の起動時セッションを自動化する tmuxinator いれた
開発用 Ubuntu VM はスリープっぽい保存はするけど、ローカルの Mac は落とさないといけない。で、毎回 ssh でウィンドウやペインごとに ssh つないだりするのはだるい。ということで tmuxinator いれた。
導入
いろいろある。特に ruby の開発してないし、適当にシステムグローバルにいれた*1。
tmuxinatorで一瞬で開発環境を起動する #Ruby #AdventCalendar #tmux #開発環境 - Qiita
# インストール gem install tmuxinator # .zshrc に設定 [[ -s ~/.tmuxinator/scripts/tmuxinator ]] && source ~/.tmuxinator/scripts/tmuxinator
で、つくる。ひな形やサンプルがあるのでだいたい簡単にできる。
# デフォルトの alias
mux new my_project
設定はこんなかんじにした。コマンドの連結がシェルの文法なのか独特の yml なのか、それともできないのかはよくわからない。実際動いてない。けどまあ、とりあえず複数 ssh でつなぐだけできるからいい。
# ~/.tmuxinator/my_proj.yml # you can make as many tabs as you wish... project_name: my_proj project_root: ~/ socket_name: tabs: - VMvim: ssh dev - VMterm: layout: main-vertical panes: - ssh dev - ssh dev - ssh dev - my: cd ~/work
これだけなら簡単
256 色対応
vim で 256 color 対応しようとすると「ターミナルソフト」「シェル」「screen/tmux」「vim」のすべてが対応していないと色が反映されない。で、いつもは tmux -2 で起動してたけど、mux を通すとできない。alias tmux = 'tmux -2' したりとかしたけど、結局以下に至った
- iTerm2 のターミナル設定を xterm-256color
- vim は t_co=256 してある
- .tmux.conf で set-option -g default-terminal screen-256color
ちょっとつまづたいのは、xterm-256color ってターミナルの設定してるのに tmux 側では screen-256color なんだね。とか。そういうあたり。あとは github の issue あたりをみて cli_args で -2 とか設定するとかしてたけど、いらなかった。
まあ
自動化はよい
Django アプリのダミーデータを大量投入するスクリプトをかく
モデルのフィールドが変わったり名前変わったりしそうだし、開発初期だと sqlite でサクっとつくって壊したりする。というときでも、とりあえずサイトを動かしたりするためになんらかのダミーデータを大量投入する必要はある。で、つくってたりした。
データ量としては10モデル x 10 とかつくれればよかったから多くはないけど、外部キーの組み合わせでよしなにやる必要があるので結果的にはとりあえず50個とか200個とかの単位でつくった。
人に聞いた
いろいろ
- python manage.py shell で for でぶんまわす
- Emacs あたりで生 SQL かいてコピペする
- むしろ Emacs からそのまま流す
- mysql workbench なるものがつかいやすいらしい
とかなんかまあなんかいろいろあったけど、とりあえずまだ sqlite だしまあ for でぶんまわした。生SQLをかくのはだるそうだし、ORM であわせたほうが楽っぽい気がしたし。
from django.utils.timezone import now from myproj.models import MyModel for i in xrange(1, 50): MyModel.object.create(name="name{0}".format(i), create_time=now())
まあこんな感じでゴリゴリ連番でつくっていった
のはいいけど
最初の一回はどうにか1時間くらいでつくったのはいいけど、モデルかわったり、外部キーでいろいろつくらないといけなかったからやっぱりスクリプトにした。やってることはだいたい上記なんだけど、どうしたらラクにできるかと。
python のスクリプトにすればいいだけだった
そりゃそうだったんだが、要は make_sql とか作って python manage.py shell の中で import make_sql make_sql.main() とかすればよかっただけだった。以下はサンプル。
# coding: utf-8 if __name__ == '__main__': main() def main(): make_user() make_author() make_book() def make_user(): for i in xrange(1, 30): User.objects.create( name="name{0}".format(i), email="email{0}@email.com".format(i), is_delete=False) # あとは外部キーとかたくさんコピペしながら条件付けしてつくっていく ...
# django でのシェルにはいって python manage.py shell # インポートして import make_sql # 流す make_sql.main()
Django でページング
よくある話、ページングしたかった。で、実際そういう機能がある。前は djang-pagination っていうのをつかったことがあったけど 1.3 くらいから使えなくなったとか、また、まあ別にそんなに難しい話でもなさそうだったので普通にフレームワークの機能で実装した。
日本語 1.0::ペジネータ (paginator) — Django v1.0 documentation
公式 1.5::Pagination | Django documentation | Django
最初から英語でみてたけど、英語のほうがサンプルコードが充実していてよい。
概要
- Paginator クラスにクエリセットとページ指定をしてインスタンスにして
- paginator.page(page)で実際のページを表示させる
基本はこれだけ。
ちなみに
以下にかくことをそれっぽくいい感じにお手軽に提供してくれるのが django.views.generic.ListView (class base view) ですね
サンプル
公式にあるサンプルに自分の理解でコメントをつける。
# 必用なものをとりこむ from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger def listing(request): # ページング対象にしたいオブジェクトをすべて取得しておく contact_list = Contacts.objects.all() # Paginator でインスタンスにする。この場合 25 件づつページングする paginator = Paginator(contact_list, 25) # クエリストリングで page の値を受け取る page = request.GET.get('page') try: contacts = paginator.page(page) except PageNotAnInteger: # int じゃなかったらとりあえず 1 ページ目に返す contacts = paginator.page(1) except EmptyPage: # 範囲外ならこの場合最後に飛ばす contacts = paginator.page(paginator.num_pages) # 辞書で渡してやる return render_to_response('list.html', {"contacts": contacts})
素の render_to_response だと RequestContext をつつんでくれないかもだからそこらへんは自分でよしなにする。今回は Class Base View で DetailView とかの中で get_context_data で context に上書きするような形にしていたので特に意識しなかった。
で、テンプレート
<!-- 普通に for で回して表示させる --> {% for contact in contacts %} {# Each "contact" is a Contact model object. #} {{ contact.full_name|upper }}<br /> ... {% endfor %} <!-- ページングの処理 --> <div class="pagination"> <span class="step-links"> {% if contacts.has_previous %} <!-- ここでクエリストリングにページをわたしてやる。 --> <a href="?page={{ contacts.previous_page_number }}">previous</a> {% endif %} <span class="current"> Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}. </span> {% if contacts.has_next %} <a href="?page={{ contacts.next_page_number }}">next</a> {% endif %} </span> </div>
難しいことはやってないんだけどもう一度いうと
- paginator オブジェクトがページング全体の情報を持っている
- pages = paginator.page(page) みたいにして pages オブジェクトにオブジェクトの配列にして返してやってつかったりする
- そのために ?page= というように request.GET の辞書につめこんでいる
という流れになっている。なので、 urls.py とかでうけとってよしなにしようとか paginator オブジェクトの中とは別で pages でオブジェクトを生成する必要があるっていうあたりがハマりどろだった。
まあ
思えばはじめて Django というか Web アプリケーションフレームワークさわったちょうど2年前くらいはページングの実装とか自分でがんばってたなーとかうまくいかないなーとか*1、思い出した。素直にドキュメント読んで使えるレベルになっただけ、2年前とは変わったのかなぁ、なんて。
*1:それで django-pagination をつかった
vim で python 開発するとき pyflakes + PEP8 = flake8 が便利
補完とかは Python 開発で便利な jedi-vim いれてみたらたしかにライフチェンジングだった - AtAsAtAmAtArA とかみよう。
PEP8 する必要があった
今まではシンタックスだけの pyflakes だけしてた。PEP8 はある程度守ってるけど80行折り返しと行間については多少自分のやり方でまあいいかなって思ってからだ。でも今回は PEP8 準拠でやろうってことになった。ということで vim-pep8 いれようとしたらなくなってて、 flake8 ってのに統一されてた。
flake8 ってなに
pyflakes + PEP8 つまりシンタックスチェックと python 的なコーディングルールの両方をパッケージにしたもの。
flake8 2.0 : Python Package Index
vim でつかう
vim-flake8/ftplugin/python_flake8.vim at master · nvie/vim-flake8 · GitHub
Using syntastic with vim (and a vim bug on OSX) - Statisfactory
自分の場合 syntactic + pyflakes でやってるのでいろいろ試行錯誤した結果 pyflakes-pathogen + vim-flake8 に落ち着いた。なんか公式だと「vim-pathogen でやってね」ってあるけど、自分は NeoBundle だし、じゃあ vim-pathogen いれて pyflakes-pathogen やめたりしたら syntactic でシンタックスが自動化されなくて微妙だったからこうした。
sed + awk をすこしさわった
dotinstall で sed と awk の講座が出たから*1せっかくなのでやってみた。思えば grep | sed しか知らないくらいだし、awk なにそれこわいという状態だし。
sed入門 (全10回) - プログラミングならドットインストール
AWK入門 (全13回) - プログラミングならドットインストール
sed(gsed)
GNU sed を使うため、Mac の場合は gnu-sed をインストールする必要がある。
引数
- f file
- e exec
- これは省略可能
- i repalce
- n
- あんまりわかってないけど sed -n 'p' file みたいに p するときに他のを出力しない的な
パターンスペース
アドレスに対してコマンドを実行する。記号はだいたい vi 準拠っぽい感じ
# not 3!d # それぞれ指定 1d;4d # 範囲 1,3d # 末尾 $d # 正規表現っぽいけどちょっと正規表現じゃない操作 /hoge$/d
- p = 表示
- a = apppend
- i = insert
- y = copy
まあ vi 準拠なので馴染みやすい
ホールドスペース
パターンスペースの裏でよしなにする。正直難しかったし使わなさそうでだるかった。
- パターンスペースのバックグランドで動作する
- hでhold
- gでget
- x で excahge(交換)
awk(gawk)
引数と実行
- f file
- コマンドラインでは '{}' で実行(""はだめ)。文字列リテラルは "hoge" で文字列連結は space で
概要
行指向スクリプト。レコードに対してフィールドを操作する。行志向スクリプト, Cっぽいらしい。
特殊引数
- $0,1,2で参照 $0 は全体
- NR は行番号
- NF はフィールドの数
文法
大きく分けて処理としては3つになる
- BEGIN {...}
- something(条件など) {...}
- something(条件など) {...}
- something(条件など) {...}
- END {...}
BEGIN でよしなに初期設定とかできる。デリミタ(FS(Field Separator))とか、RS でフィールドの区切りとかなんとか。
あと比較演算子と論理演算子とかもある。 (pattern) || (pattern) {command} 比較演算子には正規表現もある(~)。if 的条件もある NR < 5 とか。
関数
文字列、数値、システムコール、配列、辞書とかそれっぽいものがひととおりある。
まあ
シェルスクリプトだるいですね。そりゃシェルスクリプトだるくて Perl つくったのうれしいね。がんばってパースするのやだ。でも zsh とかで使えるかも、しれない。たぶんつらぽよくてきっとやらない。
*1:ちょうどこの記事をかいたとき