たけっぱ横丁

the technical document for Vim(Editor), Natural Language Proecssing(NLP) tools and Programming(Python, Ruby, C++ etc).

Wantedlyの春インターンに行ってきた話

Wantedly Spring Internに行ってきました. 企業に話を気軽に行ってみる!、というテーマのもとWantedlyというサービスを展開されています. 面白そうなサービスと思っていたこともあり SNSで流れてきたイベントページを見て, 気軽に行ってみようという感じでWantedlyに行ってきました.

やったことは以下です.

  • 1日目

    • Wantedely会社説明
    • 仲社長による Zoops講義 & 実践
    • チームによるアイディアソン
  • 2日目

    • セットアップ講義
    • エンジニア訪問
    • HTML/CSS/React.js 講義+演習
  • 3日目

    • Wantedlyにおける開発の取り組み講義について
    • チーム開発(新卒採用ページの改修)
    • Demo Day

Wantedly という会社は非常に面白かったというのが感想です. というのは, 会社内部の情報が会社内で非常にオープンな会社でした. 会社の情報を全てgithubで管理することで非常にフラットな組織構成になっていました. Wantedlyの社員は あらゆるプロジェクトの進行や現在のコード, issueを見れるようになっていました. 人事の人もgithubを使えるというのはほんと凄い話です.

機能のマイクロサービス化という話は考え方として非常に面白かったので良かったです. 僕は大学院生のなので研究をメインでやっているのですが、この考え方というものを研究にも導入したくなりました。 最近は書いたコードをgithubに投稿するというのが 最近の流れとしてよくあるのですが やっぱりコードが動かない、環境構築ができない といったようなことがよく起こるので そこから一歩先に!ということで, マイクロサービス化というのはすごく良い流れなのかなと思いました.

アイディアソンで優勝して, Wantedlyパーカーもらえたのは嬉しかったです!

3日間でDSPを作った話 (サイバーエージェント主催 アドテクコンペ レポート)

f:id:tkngue:20160303071419j:plain

縁あって, サイバーエージェント(以下CA)さんのアドテクコンペ 開催概要 に参加してきた.

DSP(Demand-Side Platform)を開発したので、せっかくなので報告をしたいと思う。 だいたい 3人1チームで組んで開発.

3日工程のうち最終日は作った, DSPでみんなで勝負する時間なので 実質2日でDSPを作った.

以下は一番SimpleなDSPのコード

Simple DSP Server for AdTech Competition 2016. To ...

DSPの雛形自体をつくるのは難しくなく、ちょろっと書いたコードで十分リクエストを裁けた.

DSPで最低限必要な機能というのは

  1. SSPからのリクエストを受け取る(エンドポイントを用意する)-
  2. SSPに応答を返す.
  3. SSPからの報告を受け取る

これだけなので 上みたいな脊髄反射でいいなら, 今回の要件である2000QPSぐらいを1~2台で余裕で裁けた.

ただ, もう少し複雑なロジックをDSP内に組もうとすると いろいろ問題になってくるので, そこが各チームで各々の工夫どころ, ということになる.

システムの構成で 皆が目指したところは 大きく差は無く 以下の記事の図のシステム構成がとても丁寧だ. CyberAgentさんのアドテクコンペで特別賞頂いた話

次回もあるならば, もっともっと盛り上がって欲しいと思うので
以下では このコンペの良さについて語れたらと思う.

続きを読む

高速に連番を作成する.

Vim で 連番を高速に生成する

連番の番号を降りたい時、 あなたはどうしているだろうか?

つまり以下のようなリストを作る時である。

  1. a
  2. b
  3. c
  4. d
  5. e

vim ではものすごく簡単にできる。

定番な作り方:マクロを利用する

書籍等を確認していると, マクロを利用し, 連番を打つようなものが割と定番だったりする。

例えば以下のような形.

:let i=0
qqi<C-R>=i<CR><ESC>:let i=i+1q
10@q

この操作方法の問題点は,正直マクロを打つのが面倒くさいこと

部分選択を利用し連番を打つ

Vimでは選択範囲に対して<C-A>,<C-X>で選択範囲中の数字の増減が可能である。 範囲選択中にoコマンドを押すことで, 選択範囲のカーソル位置を反対方向に持ってくることができる。 これを利用し, 以下のような操作で連番が可能である。

一番早い方法:g CTRL-A コマンドを使う

さて、ここまで長々と書いてきたが一番てっとり早いのが以下の方法だ

f:id:tkngue:20151218042837g:plain

選択範囲に対しg <C-A>を押す. なんとこれで連番が作成されてしまうのである。

Completed snippet featureを使ってみる

Shoug/neosnippet.vim に Completed snippet featureなる実験的機能が追加された. Implemented completed snippet feature

早速使ってみようと思い, 色々見てみるが 使い方が docみてもhelp見てもわかんねーなーと思って

Lingrを検索したらあった.
http://lingr.com/room/vim/archives/2015/08/23#message-22336910

Shougo
使い方は簡単。
補完候補を確定したら、それをトリガーに候補を展開するだけ。
汎用的な仕組みなので、neocompleteだけでなく、deoplete や他のオムニ補完にも対応。
戻り値の補完はしません。ただの引数補完用途なので。
miosnippet の実装を分析しました。
neocomplete が持っている前回の補完情報を利用して、
スニペット複数動的に生成するようですね。
ただ、スニペットの生成が手動なのがつらいところか。
補完関数によって細かくカスタマイズできるのは筋が良さそう。

これでもいまいち要領を得なかったので 仕方なしにソースコードを読む.

  1. v:completed_item が必要. CompletedDoneイベントの発生時に補完した要素がどのような属性であったかを 記述するVimの定義済み変数の模様.

動作としては以下のような感じ. 入力して展開すると test_func| -> test_func(arg1, arg2) しかも arg1とarg2がそれぞれplace-holderになるという動作.

このsnippetを自動的に作成してくれるのが このcompleted snippet feature. snippetの生成のタイミングは補完関数で変換候補の関数のが入力された時 そのタイミングで自動的にoneshotのsnippetが作成されるようだ.

便利ではあるので うまく使えるように各種設定したいところ

激アツの6日間!TechCAMP オオサカ編 レポート

pic1

8月初旬にCyberAgentさん主催のTechCAMP オオサカ編に 参加させていただきました.
サイコーにアツい6日間を過ごさせいただいたので
報告も兼ねまして, TechCAMPの魅力について語らせていただきます.

他参加者もインターンについてまとめてくれてます.あわせてどうぞー!

TechCAMP オオサカとは

TechCAMP(オオサカ・キョウト編)

TechCAMPはスマートフォンタブレットで楽しめるアプリケーション制作を体験する短期集中型インターンシップです。 オオサカ編、キョウト編ともに、地域にちなんだテーマをもとに課題の解決、技術面での創意工夫に挑戦していただきます。

インターンでは, 会社側から提示されたテーマを元に
2人1組になって Android/iOSアプリを作成するというものでした.

今回は合計で5チームでの競い合いです.
そのお題はこちら

エンジニアが「ハマる」アプリを創出せよ

ハマるの定義とはなにか? エンジニアがハマるってなんなんだ?!
エンジニアエンジニアがほしいもの をつくる.
TechCAMPならではの お題だったように思います.

TechCAMPの魅力 その1: 男女 10: 0の圧倒的熱量

まずは こちらをみて頂きたい.

こちらが同時期開催されていたという TechDesignCAMP...
TechDesignCAMP

この目から流れる水は一体何なんだ...

CyberAgentの敏腕イケメン人事「おざまさ」さん曰く 「動物園」 .

しかしながら,
「おざまさ」さんによる選ばれたメンバーは 最高につきるメンバーでした!
技術もさることながら 開発にかける熱量というのは凄まじかった

朝から晩まで, そして時には晩から朝まで開発, 開発, 開発!

みんなガンバる から 僕もガンバれる.
みんなガンバった から 最高の6日になる!!

互いにいい刺激を与えあえる そんな環境でした.

TechCAMPの魅力 その2: イケメン人事・メンター陣の圧倒的サポート

このエンジニア10人を支えるサポート体制は 余念がありませんでした.
2日目の初日には 「ハマる!アプリの作り方」という題目で講義をいただきました!
ハマるアプリの作り方講座!

要望や意見を言うと そこで速攻で意見が反映されました.
Slackを導入したり, デュアルディスプレイを要求したり...
(BGMにAWAが使えるのは CyberAgentさん ならですよ!)

「ここを〜こういうふうにしたいんですけど, 何が一番いい方法ですかね」という
疑問に関しては メンターさんにすぐ答えていただけました.

Android開発は数年前にやってから離れてて, 開発中にカンを取り戻すというような状態でしたが
おかげさまで開発を一気に進めることができました.

開発の佳境には ヒレカツサンドの差し入れは 本当に嬉しかったです...!

TechCAMPの魅力 3: 友情・努力・勝利

昨年までは3人1チームだった開発体制は 今年は 2人1チームでの開発でした.

2人というのは 開発力的にも 何をやるにしても すごーく限られる人数です.

アイディアの段階から「何を作って」, 「何を捨てるのか」.
ここは各チームともシビアな選択を迫られたように思います.
僕らも 「見た目はいらねぇぇ」 ということで
完全に見た目は捨て 開発を行いました. (結局,この場ではこれが功を制しました)

2人1チームの体制で
最初は僕がバックエンド, 相方がフロントエンドの担当だったはずが
真ん中には 僕がバックエンドエンド, 相方がフロントエンド
最後には 僕がフロントエンド, 相方がバックエンド
と 非情にフレキシブルに開発を行いました.
(付き合ってくれた本当に相方には感謝です)

相方の技術者としての圧倒的 熱意

こうして過ぎた6日間はあっという間でした.
ここで書くには 長すぎるぐらいに 濃密だったのですが

きたる最終発表には 2時間前には 互いにデモの動きを確認し, よしこれでイケる! と思っていたのですが
予想外のミスで実際のデモでコケるという痛手...

相方は 動いていたはずのデモが動かなかったことが 何より悔しい模様で
僕も驚いたのですが デモ再チャレンジを敢行 (技術者としての全てをかけるとまで言いました).

執念のデモ再チャレンジ

おざまさ(8月12日)

優勝チームはデモがうまくいかなかったことが悔しくていきなり再度デモ。動いてよかった!そして普通にほしいわこれ。

http://7gogo.jp/lp/tK0SOhMR1UoWkVIvojdMdG==/3488

トークアプリ755からの投稿

結局 こう言っていただけたのも相方の執念とも言うべき情熱が 伝わったからこそではないでしょうか?

終わりよければ全て良し, ということで結果的に 優勝 と評価をいただいたのは本当によかったです.
結果発表後には審査員・メンターの方々から チームごと個々に講評をいただけるという
最後まで まさに至りつくせりな状況でした.

他のチームのアプリをもっと見たかったなーというのはあります.

たった6日間という短い期間でしたが すごく濃密な期間を過ごすことができました.
それもこれも 一緒に参加したTechCAMPメンバー
指導いただきましたメンター, 支えてくれた人事のおざまさ さん
そして6日間付き合ってくれた 相方のおかげです.

ほんと感謝でした!

本日は TechCAMPキョウト の 報告日らしい! 一体どんなものができたのか 気になります!

officeからの脱却作戦

Officeでブイブイ言わせていた俺も, 今じゃUnixの虜. もはやgitとvimが使えないファイルは触りたくないと拒否反応がでる始末さ.

読者はこんな経験ありませんか?

中古で買ったPCで一番はじめにやるのはWindows OSのアンイストール

ヒャーハー

すっかりコンソールの住人になってしまった. あの頃の僕が見たらきっと泣くだろう.

それでも突き進むしかない,薔薇の道じゃない茨の道.

officeからの脱却作戦1 - office 関連フォーマットをテキストに変換する

docx, xlsx, pptxなどの各種形式は オープンな規格に沿って記述されているため
変換ツールによりテキストに簡単に変換できる.

ここでは Apache tika を紹介する. 様々なフォーマットで書かれたファイルをテキスト等に変換してくれる便利ツールだ! jarファイル を ダウンロードし

java -jar $HOME/.local/src/tika-app-1.8.jar file.docx

とすれば, テキストを出力してくれる. この出力内容を各種ソフトウェアで表示するようにすれば, 大きなの問題は解決する.

パスの通る範囲にtikaというファイル名で
以下のようなファイルを作ってしまえば 非常に便利だ.

#/bin/sh
java -jar $HOME/.local/src/tika-app-1.8.jar $@

vim で テキスト読み込みを可能にする

OpenOfficeは辛い... vim で 読めれば ひとまずは問題はないんだ…

ということで, docx, xlsx, pptxをvimで開くときは tikaによってテキストだけを表示する

以下のautocmdを.vimrcに追加しよう.

augroup office_format
    autocmd!
    autocmd BufEnter *.{docx,xlsx,pptx,ppt,doc,xls}  set modifiable
    autocmd BufEnter *.{docx,xlsx,pptx,ppt,doc,xls}  silent %d
    autocmd BufEnter *.{docx,xlsx,pptx,ppt,doc,xls}  silent %read !tika --text %:p 
    autocmd BufEnter *.{docx,xlsx,pptx,ppt,doc,xls}  set readonly
augroup END

vimでOffice関連書式を開こうとすると, BufReadやFileReadが発生しないため
BufEnterでひとまず代用している(情報募集).

これで編集はできないが, ファイルは読み込めるようになる.

git で 差分を表示する

Officeフォーマットだってgitで管理したい!!

gitで困るのが差分を出力できないファイルだ. 差分を表示できなければなんのためにバージョン管理しているか分からない.

でも大丈夫. git は そんな問題を解決する素晴らしい機能を備えている. textconv属性だ! c.f. 7.2 Git のカスタマイズ - Git の属性

ファイルに対する適切なコンバーターを設定してやることで git diff が どんなファイルでもできるようになる. こんな最高な機能があったなんて!

必要な設定は

  1. 拡張子に対するグループを設定してやる
  2. グループに対する操作を設定する

の2つである.

.gitattirubtes に 以下を追加しよう.

; .gitattirubtes
*.docx diff=office
*.xlsx diff=office
*.pptx diff=office
*.xls  diff=office
*.doc  diff=office
*.ppt  diff=office

.gitconfig には 以下の設定を追加だ.

[diff "office"]
    binary = true
    textconv = "tika --text"

これでgit diff で officeやらの変更が見れるようになる. もちろん blame で誰がどの文章を追加したかわかる. 最高だな!

同様の要領で pdfやら画像ファイルも vim, gitで開けるぞ!

markdown, latexファイルでOfficeファイルを作る.

いくら自分がOfficeから卒業したいからと言って
Officeと無縁の生活ができるわけではない.

Officeファイルでくれ,と言われることもあるとおもう そんな時は pandoc でだいたい解決できる.

sudo apt-get install pandoc

latexを使えば, 論文だってスライドだって書ける. reveal.jsを使えば, javascriptの知識を活かした動的なスライドだって書ける!!

君の眼前に広がる世界は広い

参考文献

git diff で Office ファイルの差分を見る Pandocの比較的簡単なインストール方法

Nested tmux向け.tmux.conf

Remote Server に 作業用のtmuxを常駐している.

僕の環境では,

自宅PC -> Remote server -> 各種サーバ

とつなげることが多く, Remote serverにtmuxを常駐させることによって 作業状態を保存して置けるのが, かなり嬉しいのでtmuxをネストして使うことが多い.

しかしながら ネストしたtmuxでのprefixの使い分けが 苛ついてて仕方ないので, ネストしたtmuxをシームレスに使える設定を考案.

以下に述べようと思う.

Nested tmux向け設定

まずtmux では以下の設定でC-qにprefixを付け替えられる.

set-option -g prefix C-q

ネストしたtmuxでは, 以下の様に設定してやれば C-s がネストしたtmuxのprefixになる.

bind -n C-s send-prefix

しかしながら prefixの使い分けは, 非常にややこしく操作ミスも大きいくせに リスクが大きい.

よくあるのが, 中のtmuxのpaneを昨除しようと思ったら, 外側のtmuxのペインを削除し, tmuxごと消えてしまうということ, またその逆も然りである.

従ってネストした時には, 今のprefixが ネストしたtmuxのprefixであると直感的操作ミスも少なくなるだろう.

ということで, Nested tmux 向けに以下のように設定を行うことで解決. 僕はCtrl+矢印でウィンドウの移動を行っているので, その移動の際にsshのチェックを行うだけである

bind -n C-q send-key C-q
bind -n C-Left  run-shell 'tmux previous-window; \
        tmux if-shell "$is_ssh" " \
            set-option -q prefix C-s " " \
            set-option -q prefix C-q "'
bind -n C-Right  run-shell 'tmux next-window; \
        tmux if-shell "$is_ssh" " \
            set-option -q prefix C-s" "\
            set-option -q prefix C-q; unbind C-s"'

以上の設定はtmux1.8のみで動作を確認している

VimとTmuxをシームレスに移動する

VimとTmuxをシームレスに利用するためのプラグイン.

今日は, tmux + vimユーザならば入れておくべきであろう vim-tmux-navigatorをご紹介させていただきます.

vim-tmux-navigator

このプラグインを入れるとシームレスにtmuxとvimを移動できるようになります 私はCtrl+hjklで, vimのバッファを移動できるように設定しているのですが

このプラグインを入れることで, 同じキーでvimのバッファだけでなく tmuxのペインも移動できるようになります.

正直かなり便利です.

preview

Install

NeoBundleを利用しているならば
.vimrcに以下の設定を追加しましょう

NeoBundle 'christoomey/vim-tmux-navigator'

Configuration

# Smart pane switching with awareness of vim splits
is_vim='echo &quot;#{pane_current_command}&quot; | grep -iqE &quot;(^|\/)g?(view|n?vim?)(diff)?$&quot;'
bind -n C-h if-shell &quot;$is_vim&quot; &quot;send-keys C-h&quot; &quot;select-pane -L&quot;
bind -n C-j if-shell &quot;$is_vim&quot; &quot;send-keys C-j&quot; &quot;select-pane -D&quot;
bind -n C-k if-shell &quot;$is_vim&quot; &quot;send-keys C-k&quot; &quot;select-pane -U&quot;
bind -n C-l if-shell &quot;$is_vim&quot; &quot;send-keys C-l&quot; &quot;select-pane -R&quot;
bind -n C-\ if-shell &quot;$is_vim&quot; &quot;send-keys C-\\&quot; &quot;select-pane -l&quot;

C-hjklに限らず 自由にマップが可能です.

 nnoremap <silent> {Left-mapping} :TmuxNavigateLeft<cr>
 nnoremap <silent> {Down-Mapping} :TmuxNavigateDown<cr>
 nnoremap <silent> {Up-Mapping} :TmuxNavigateUp<cr>
 nnoremap <silent> {Right-Mapping} :TmuxNavigateRight<cr>
 nnoremap <silent> {Previous-Mapping} :TmuxNavigatePrevious<cr>

Advanced Configuration For Nested tmux

僕はtmuxをローカルPC と リモートPC で それぞれ立ち上げているため, tmuxをネストして利用することが多いです.

以下のような設定を加えると ローカルのtmuxとvim, リモートのtmuxとvimの4つでシームレスに移動が可能になります!

is_vimorssh='echo "#{pane_current_command}" | grep -iqE "(^|\/)g?(view|n?vim?|ssh)(diff)?$"'
bind -n C-h if-shell "$is_vimorssh" "send-keys C-h" "select-pane -L"
bind -n C-j if-shell "$is_vimorssh" "send-keys C-j" "select-pane -D"
bind -n C-k if-shell "$is_vimorssh" "send-keys C-k" "select-pane -U"
bind -n C-l if-shell "$is_vimorssh" "send-keys C-l" "select-pane -R" 
bind -n C-\ if-shell "$is_vimorssh" "send-keys C-\\" "select-pane -l"

Python3対応のMeCab(using subprocess)

Python3対応のMeCab

言語処理をされているかたならば,ご存知のMeCabですが
公式で配布されているパッケージがPython3に対応していなくて困ったことになります.

以下の記事では, python2のパッケージをpython3用に書きなおして pipで配布されているようです.

python3対応MeCabの紹介

インストールは非常に簡単で以下のいちコマンドで

pip install mecab-python3

これで今までのMeCabがPython3でも使えるようになりました.素敵!!

......

で終わるとなんだかつまんないですよね.

いつも思うことなのですが, こういうパーサー系のライブラリを使おうとすると,
その仕様を理解するのが色々面倒です.

出力を自分で直接パースしてしまうのが早かったりします.

またMeCabに限らず他のパーサをPythonで利用する時には結局自分でラッパーを書くしか無いので
パーサー系をラップするPythonを書くのは一度書いておくと何かと楽です.

Pythonでパーサーをラップする

ということでsubprocessを利用して, パーサをラップしたコードを書いてみました.

以下は分かち書き用のMeCab parserを抜き出したものです. コード全体はこちらです.
python3でも使えるように書かれています.

python2でsubprocessを利用するときの注意として,
Popen.communicate(input=None)には注意です. バッファサイズが小さいと入力によっては例外が投げられます.

python2でもtimeoutが設定できればよいのですが, (python3では設定できます)
無いので実装する際には, デットロックがかからないよう注意してください.

※例えば, 何もwriteしてない状態で, read()等を呼び出すとデットロックになります.

#Mecab implements for Python using subprocess
class MeCab():

    def __init__(self, opts=['-Owakati']):
        self.opts = opts
        self._process = subprocess.Popen(
            list(itt.chain(['mecab'], opts)),
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            universal_newlines =True,
        )

    def parse(self, iterable):
        for line in iterable:
            self._process.stdin.write(line+'\n')
            output = self._process.stdout.readline()
            yield output.strip().split()

parser = MeCab()
print next(parser.parse(['すもももももももものうち']))
# >>> ['すもも', 'も', 'もも', 'も', 'もも', 'の', 'うち']

こういうのひとつ書いておくと, あとで他のパーサでも書きやすいので何かと楽です.

pyenv+virtualenvでPythonの仮想環境を作る

Pythonでの開発と仮想環境

開発者ならば至極当然のように使っている仮想環境.
この記事では,なぜ仮想環境を利用するのかを始めとして, Pythonでの仮想開発環境を導入まで述べたいと思います.

なぜ仮想環境なのか

簡潔に言うと, こっちのマシンでは動いたけど,あっちのマシンでは動かないよー

という状況を解決しやすくするために使います.
そもそも配布するようなプログラムを書くときには公開しないプログラムでも心がけるべきですが,

"この環境が整ったマシンでは必ず動く"

という状況設定をして開発する必要が有ります.
なぜなら, ここがわからないと誰もその動かし方がわからないですし
複数人で開発するときに同じ環境を整えないと, まともな開発を進めることはできません.

ではどうやって, 現在の環境を把握するか ということになりますが

新しい開発を行うたびに新しい環境を用意する

というのが答になります. そして,それを実現するのが仮想環境です.

仮想環境を使うことのメリット

  • 開発プロジェクトの依存関係が明確になる.
  • 開発環境とテスト環境の分離が簡単
  • 利用している環境とプロジェクトの環境を簡単に切り離すことができる

pyenvとvirtualenvにおける仮想環境の導入

Pythonで仮想環境を導入するためのツールがvirtualenvとなります. それに併せてよく利用されるのがpyenvになります.

これらの関係が若干わかりにくかたので, 簡単な図を用意しました

overview

pyenv

ひとえにPythonといっても色々なPythonがあります.

その複数のバージョンのPythonを管理するのが
pyenvです

公式のPythonパッケージだけでなく 科学計算用のパッケージ(numpy, scipyなど)付属のAnaconda等もサポートしています.

virtualenv

Pythonの仮想環境化のツール. Pythonのライブラリなどの環境などをプロジェクトごとに作れる.

端的に言ってしまえばプロジェクトごとのpipができるようになります.

Pythonのバージョンを指定して仮想環境を構築することも可能だが
そのためにはそのPythonバイナリを予めインストールしておく必要がある.
pyenvがそれをサポートするツールということになります.

virtualenvwrapper

virtualenvを使いやすくするためのツール. virtualenvを利用した仮想環境の作成, 削除やフックの設定が容易になる.

pyenv-virtualenvwrapper

pyenvとvirtualenvを組み合わせたツール このPythonのバージョンで仮想環境をつくりたいっといったことが簡単に実現できます.

その他 参考サイト

VIRTUALENVについて - 今日のPython