Perlで相補鎖を返す関数を短く書く
DNAは、相補的塩基対形成という性質があって、AとG、TとCとしか水素結合を形成することは出来ない。つまり、ATCCという塩基の相方の塩基は必ずTCGGとなる。これを出来るだけ短く書きたい。 がんばったら、 で5行で、実質の処理をしているのは1行になる。うーん、ループ使わずに一行にしたいがどうやればよいものか。
$rev .= $_ =~ /[aA]/ ? 't' : $_ =~ /[cC]/ ? 'g' : $_ =~ /[gG]/ ? 'a' : $_ =~ /[tT]/ ? 'c' : '' for split //, my $s = shift;
で、というか、splitの2個目の引数で変数定義しつつ渡せるのか。
1ツイートで相補鎖だす関数意外にむずい感じ
— yukke (@soh__i) 2013, 8月 21
my $s = $str =~ tr/AaTtGgCc/TtAaCcGg/r;
でよくねーか......なんで気付かなかったんだろ。。。
githubのwikiエンジン"gollum"の導入と細かい設定
gollumの特徴、良いところなど
- Markdown, MediaWiki, Textileなど大抵の記法で書ける。
- 基本的にgitリポジトリ一つで完結しており、MySQLなどのDBが不要で、簡単にprivate wikiを立ち上げられる。
- セットアップが非常に楽。
- gitで動いているので、バージョン管理や差分、コミットを遡ってrevertする、なんてこともWebのUIから簡単に操作できる。
- 全文検索も実装されている。
- ruby+sinatraで実装されているので、分かる人は拡張を簡単に書ける気がする。
導入
Python 2.5+ (2.7.3推奨)、Ruby 1.8.7+ (1.9.3推奨)とのこと。なのでpythonbrewなりrvmなりrbenvなりで新し目のpython+rubyを入れます。あとはgemからgollum本体をインストールします。
gem install gollum
rbenvのgemを使った場合は、~/.rbenv/shims/gollum
に入るはずです。
gollum --version => Gollum 2.4.13
使い方
- 適当なディレクトリにいって、
mkdir wiki && cd wiki git init gollum
で起動し、http://localhost:4567
からアクセス可能です。ポートは--port
で任意に変更可能です。
でもそれだけじゃあれなので今は、
gollum --mathjax --no-live-preview --config auth.rb 2>gollum.log &
としてデーモンっぽく起動させています。 mathjax.jsによってTex書式で数式を書くことができ、--configで外部の設定ファイルを読み込めます。
あとは、もうmarkdownですきなことを書いていけば宜しいという感じで。詳しくは、https://github.com/gollum/gollum/wiki を参考にしてみてください。コマンドラインから編集したりした場合は、ファイルをcommitしない限り、gollumには反映されません。
数式を書く
インラインの場合は、\\( \frac{x}{y} \\)
とか。そうじゃない普通の場合は、$$ \frac{x}{y} $$
と書く。数式(Mathjax)をデフォルトで使えるのは一部の人にはありがたいですね。
画像をはりつける
[[hoge.png]]
と書くと、オリジナルサイズで画像が表示されます。urlの場合も同じ記法で書くことができます。また、gollumの拡張として、[[hoge.png|heigh=400px]]
とかでサイズ指定、align=center
とかもできます。もちろん、markdown記法である![]()
も使えます。
ヘッダやフッタなど
ヘッダーやフッターは、_Footer.md
や_Header.md
というファイルを作って、コミットしてあげるとgollum側が勝手にそのファイルを全てのサイトに共通のヘッダやフッタとして認識してくれます。例えば、_Sidebar.md
に、_[[toc]]_
と書くことで、ページ内のTable of contentsを自動で生成することができます。(TOCは日本語も問題なく使えています。)ただ、日本語は文字化けしてそのままでは使えません(未解決)。
カスタマイズ
画像のアップローダー
gollumで一つ問題だったのが画像やpdfをリンクとして貼り付けたい、ということです。これは公式にサポートされていません。なので、~/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/gollum-2.4.13/lib/gollum/app.rb
に、
post '/upload' do if params[:file] new_filename = DateTime.now.strftime('%s') + File.extname(params[:file][:filename]) save_file = './upload_files/' + new_filename File.open(save_file, 'wb'){ |f| f.write(params[:file][:tempfile].read) } p "http://hoge.com/yukke/gollum/upload_files/", new_filename end end
とか追記してアップロードできるようにしておきました(http://yusukezzz.net/blog/archives/1388をそのまま参考にしました)。
wikiに認証をつける
パーソナルなwikiなので認証を付けたいです。apache.confで認証させてもいいのですが、gollumには--configというオプションを渡すことで簡単に認証をつけることができます。
module Precious class App < Sinatra::Base use Rack::Auth::Basic, "This is private wiki" do |username, password| [username, password] == ['yukke', 'passwd'] end end end
をauth.rbとかで保存しておき、gollum --config auth.rbとすることでBasic認証を簡単に実装できます。Rack::Auth::*には、
OpenIDによる認証するメソッドもあったりするので、twitterアカウントで認証させるなども出来そうです。あと、auth.rbに平文でpasswdを書くのはアレな気もするので、そのあたりは別のyamlを読むとかそういった工夫をすればよいかと。
ヘッダーをつける
なんとなく殺風景なデザイン(シンプルで良いのですが飽きる)なので、ちょっと変化をつけるためにカスタマイズすることも可能です。rbenvを使った場合は、~/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/gollum-2.4.13/lib/gollum/templates/
とかがgollumの検索や各ページのテンプレートになっています。今回、ヘッダを全てのページに付けたいので、この中のlayout.mustache
にちょこっとdivを付け足します。検索ページだけをカスタマイズするには、search.mustache
を編集すればよいでしょう。
<div id="cust-header-wrapper"> <div id="cust-header"> <h1>My gollum wiki</h1> </div> </div>
などと書きました。
ここに対応するCSSは、~/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/gollum-2.4.13/lib/gollum/public/gollum/css/gollum.css
ですが、custom.cssとか別のファイルにして読み込ませるようにしたほうが良さそうです。
#cust-header-wrapper { background: transparent url('header.png') top center repeat-x; height: 100px; } #cust-header { width: 85%; margin: 0 auto; text-align: left; } #cust-header h1{ padding: 1.1em 0 0 0; height: 80px; font-size: 50px; color: #eee; }
githubへpushする
apacheのDocument rootが例えば/var/www/html/だとすると、権限がrootやwwwになっているかと思います。そのままだと自分のgitの設定などが使えないので、gollum以下のディレクトリをroot権限ではなく、普段のユーザー権限に変更し、githubへpushできるようにしました。例えば、
#!/usr/bin/env perl use strict; use warnings; use Git::Repository; my $gollum_path = '/var/www/apache/users/gollum/.git'; my $git = Git::Repository->new(git_dir=>$gollum_path); my $status = $git->run('push', 'origin','master');
このようなperl scriptをcronで毎日1回回せば自動的にgithubへpushされ、バックアップ機能を果たすことができますね。
問題点
- 基本的に日本語(マルチバイト)が弱い、マルチバイトに対応?してないメソッドが呼ばれたりしてるところでwarningsが出たりするのですが、ruby力低すぎて直せなかった。なんとかしたい。
- ファイル名やディレクトリ名に日本語を使うと検索でgollumを巻き込んで落ちたり、必ずエラーを吐きます。
- 日本語でTOCを生成できなく、文字化けします。
追加したい機能
- もうちょっとマシなファイルアップローダー。画像のギャラリーから編集時に貼り付けるとかしたい。
最後に
gollum、dokuwikiとかmediawikiとかよりセットアップも楽だしシンプルで良いとおもうのだけどいまいち流行ってない気がするので売れてほしいですね。開発もけっこう盛んなようですし、watchしとくといいかもしれません。そう思いながらいろいろ細かいことも書きました。参考になれば。(大事なのは毎日ちゃんと記録をつけたりすることですが、、)
タイムトラッキングツールTogglの結果をR+ggplot2で可視化してみる
最近、Togglというサービスを使っている。Togglはタイムトラッキングツールみたいな感じで、何にどれだけの時間を使っているのかを記録するサービス。例えば、勉強した時間とか本を読んでいる時間とか、そういうのをログに残すことができて、励みになったり、さぼっているのが一瞬でわかると思った。習慣にしたい。
Togglのサイトを見ていたら、その結果のファイルはreport.csv
としてダウンロードできることがわかった。せっかくなので、Rで可視化してみることにした。1ヶ月とか、データが溜まってきたら傾向とかそういうのがわかるかもしれない。まだ4日。
というこで、ざくっとR+ggplot2を使って可視化してみた。
- ggplot2の
geom_bar()
のところで、geom_bar(aes(fill=toggl$Project)
としてあげることで、プロジェクトごとに色付けしてプロットしている。
ちなみに、report.csv
は以下のようなデータ構造になっている。
User,Email,Client,Project,Task,Description,Billable,Start.date,Start.time,End.date,End.time,Duration,Tags,Amount()
縦軸は経過時間、横軸に日付になっていて、4/5はちょっとさぼってしまったな、とかそういうのが把握できる。
Pie chartならこんな感じか。
とはいっても、togglはじめてまだ一週間も経っていないし、がんばって続けたい。なんというか、ライフハック!!!!という感じである。
config file in R
$HOME/.Rprofile
に書く。- .Last()と.First()は、起動時に読み込まれる特殊?な関数名。
- 起動オプションで、
R --quiet
とすると、startup messageがoffになる。
R>> sessionInfo() R version 2.15.3 (2013-03-01) Platform: x86_64-unknown-linux-gnu (64-bit) locale: [1] LC_CTYPE=ja_JP.UTF-8 LC_NUMERIC=C [3] LC_TIME=ja_JP.UTF-8 LC_COLLATE=ja_JP.UTF-8 [5] LC_MONETARY=ja_JP.UTF-8 LC_MESSAGES=ja_JP.UTF-8 [7] LC_PAPER=C LC_NAME=C [9] LC_ADDRESS=C LC_TELEPHONE=C [11] LC_MEASUREMENT=ja_JP.UTF-8 LC_IDENTIFICATION=C attached base packages: [1] stats graphics grDevices utils datasets methods base other attached packages: [1] BiocInstaller_1.8.3 colorout_1.0-0 loaded via a namespace (and not attached): [1] tools_2.15.3
R>> R.version _ platform x86_64-unknown-linux-gnu arch x86_64 os linux-gnu system x86_64, linux-gnu status major 2 minor 15.3 year 2013 month 03 day 01 svn rev 62090 language R version.string R version 2.15.3 (2013-03-01) nickname Security Blanket
perlでgnuplotの図を書く
Chat::Gnuplotを使う。オプションをハッシュで渡していくの感じで書きやすい。
pythonことはじめ
ちゃんとオブジェクト指向プログラミングを勉強したいなと思ったいたので、pythonを新しくやろうかなと思っている。rubyよりはpython書きたいっていう感じ。bioinformatics向けのチュートリアルやオライリー本もそこそこ充実している。それに、numpy、scipyといった最強なライブラリもあるし、matplotlibやRPyでグラフ書いたりR動かしたり出来るのも魅力的だった。というわけで、perlくらい書けるようになればなーって思っている。ことはじめということで、pythonbrewを使って、pythonをインストールした。
curl -kL http://xrl.us/pythonbrewinstall | bash [[ -s $HOME/.pythonbrew/etc/bashrc ]] && source $HOME/.pythonbrew/etc/bashrc source .zshrc pythonbrew install Python-2.7.3 pythonbrew switch 2.7.3 which python #=> /Users/yukke/.pythonbrew/pythons/Python-2.7.3/bin/python
コードはまだ書いていない。
perlのGetopt::Longを使った感想
perlのデフォルトのモジュールには、Getopt::Longが入っており、コマンドラインの引数処理を楽に書くことができるようになっている。
これまでは、自前でオプション名や引数の型チェックなどを書いていたが、いい加減べんりで楽な方法を使ってみることにした。
基本
ベーシックな使い方は、
#!/usr/bin/env perl use strict; use warnings; use Getopt::Long; GetOptions ('help|man' => \$HELP, 'in=s' => \$INFILE);
のようにオプションを渡していく。
perl $0 -in file.txt
のような使い方になる。help => \$HELP
だと、引数を要求せず単独で動く。|
を使うことで、複数の名前を使える。e.g. helpとh、versionとverなど。- オプションと値をハッシュにしたり、予め変数宣言のときにデフォルト値をセットしておくこともできる。
option名=s(strings)
で値に文字列以外が与えられた場合は、エラーを出力する(※プログラム自体はそのまま実行されるので注意)。=iはinteger、=fはfloatになる。このとき、=sで[0-9]をセットしても、文字列として数字が評価されるのでエラーにはならないことに注意。
これで、楽に引数やセットされる値はチェックできるが、--helpや--manをしたときは、ヘルプを表示してプログラムを終了させることや、実行に必須な引数が不足した場合にはdie()することなどは出来ない。
そこで以下のようにして書いてみる。
変なオプションが渡されたときは死のう
use Getopt::Long; ## Default value: my $HELP = undef; GetOptions ('help' => \$HELP) || die "Invalid options";
- これで、変なオプションが入った時には、dieするようになる。
--helpした時だけ、ダイイングメッセージ
my $HELP = undef; GetOptions ('help' => \$HELP); if ($help) { die "Usage: { something... }" }
- デフォルトでは未定義なので、--helpされるとdie()する。
オプションの数が足りないときは死にたい
use Getopt::Long; if (scalar @ARGV<1) { die show_help(); } sub show_help { my $help_doc = <<EOF; this is test program Usage: perl $0 [options] Options: --infile --help EOF return $help_doc; }
- Getopt::Longは面倒を見てくれない(たぶん)なので、普通に条件を書く。
- インプットファイルがないときは死にたいなども、デフォルトを
my $infile = undef;
としておいて、後でセットされているかをif文でチェックすれば良い。
感想
- やっぱり便利だった。もっと早くから使うべきだった。
- なんかいっぱい死にたいって書いた気がするけど、別に死にたいくないです。
- 最近、らーめん食べてない気がする。
おしまい。