Memento memo.

Today I Learned.

NumPyの配列操作 - 条件に合う要素のみフィルタする処理の理解

積ん読消化中で、以前買った機械学習入門本を読んでいます。

データサイエンティスト養成読本 機械学習入門編 (Software Design plus)

データサイエンティスト養成読本 機械学習入門編 (Software Design plus)

前半部に基礎的な事項が簡潔にまとめられてて良い本です。 おかげで去年Courseraでやった内容を思い出せました。

本題

NumPy使っていて、以下の例での3行目あたりの処理で一体何が起きているのか分かってなかったのでメモ。

a = np.arange(10)
#=> array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
a[a<5]
#=> array([0, 1, 2, 3, 4]) <- !?!?

配列の indexing

配列のindexingは、配列に対してbool値でindexを指定すると True の要素だけ取り出せるやつです(本当はもうちょっと意味が広いです)。

a[np.array([True, False, True, False, True, False, True, False, True, False])]
#=> array([0, 2, 4, 6, 8])

配列の broadcasting

broadcastingは、配列の全ての要素に関数を適用するやつです。

a < 5
#=> array([ True,  True,  True,  True,  True, False, False, False, False, False], dtype=bool)

まとめ

a = np.arange(10)
#=> array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
a[a<5]
#=> array([0, 1, 2, 3, 4])
# 以下の2STEPに分解できる
bool_array = a < 5
#=> array([ True,  True,  True,  True,  True, False, False, False, False, False], dtype=bool)
a[bool_array]
#=> array([0, 1, 2, 3, 4])

データサイエンティスト養成読本 機械学習入門編 (Software Design plus)

データサイエンティスト養成読本 機械学習入門編 (Software Design plus)

「サーバ/インフラエンジニア養成読本 ログ収集〜可視化編」でFluentdがinstallできない問題

去年買って完全に積んでいた「サーバ/インフラエンジニア養成読本 ログ収集〜可視化編」を読み始めました。 最近お仕事で運用設計的なところ触ったりして興味湧いてきたのがきっかけです。

問題: 環境構築こける

fluentd周りでこける。Ruby古いとか言われる。

対応: td-agent2にした

td-agentはv1とv2があるらしいのでv2にしてみました。

本家側は書籍側とversion合わせる必要があると思うので適当にforkしました。

差分はこんな感じです。 github.com

対応方法これで合ってるのかよくわかりませんが、一旦動くところまで。

Neovimのpython_host_prog設定

新しくMBP買いました。Brewfile, dotfiles周りはある程度環境構築自動化できてるんですが、Neovim <=> python_host_progの連携とか何もしてないので少しずつscriptに落としていきたい。

とりあえずNeovimでPython呼べるようにshellを書きます。

zcheeさんの以下のwikiを参考にしました 🙏

github.com

こんな感じです

#!/bin/sh
# requirements:
# - pyenv
# - pyenv-virtualenv

python2='2.7.13'
python3='3.6.0'

eval "$(pyenv init -)"

# python2
pyenv install "${python2}"
pyenv virtualenv "${python2}" neovim2
pyenv activate neovim2
pip install neovim

# python3
pyenv install "${python3}"
pyenv virtualenv "${python3}" neovim3
pyenv activate neovim3
pip install neovim

echo "NOTE: Add following lines to 'init.vim'"
echo "let g:python3_host_prog=\$HOME . '/.pyenv/versions/neovim3/bin/python'"
echo "let g:python_host_prog=\$HOME . '/.pyenv/versions/neovim2/bin/python'"

あとは上記scriptの通りに init.vim に設定追記すればokです。

Ruby: Hash -> Structの変換

こんな感じで書けます

  def deep_struct(hash)
    foo = hash.values.map do |v|
      case v
      when Hash
        deep_struct(v)
      when Array
        v.map { |x| deep_struct(x) }
      else
        v
      end
    end
    Struct.new(*hash.keys).new(*foo)
  end

OOPっぽく書きたければHash, Arrayに deep_struct のようなメソッドを拡張するのもアリです

Hacktoberfest 2016 に参加してきた

Hacktoberfestなるものに参加して景品のTシャツを貰いました。あとステッカーも7枚ほど貰いました。

Hacktoberfest

hacktoberfest.digitalocean.com

GitHub上でのOSS活動を活発化するため(?)に10月に行われたイベントです。去年もやっていたようで、きっと来年もやると思います。

とりあえず任意のpublicリポジトリにPull Requestを合計4回送ると全クリでした。PR稼ぎに意味のないPRを送るのはNGらしいです(当たり前)。

PRの粒度は問われないので僕はいつも使ってるライブラリのドキュメント修正やソースのタイポ直したりと諸々しょぼいPRを6つほど投げました。

来年はもっと強いPRを投げられるように修行したいです。

サイバーマンデーのセールでPS4買って優勝した

サイバーマンデーが最高だった話です。技術ブログ要素ゼロ。

普通にPS4買う場合: 30,895円

PlayStation 4 ジェット・ブラック 500GB(CUH-2000AB01)

PlayStation 4 ジェット・ブラック 500GB(CUH-2000AB01)

今日買った場合: 27,976円 + マインクラフト!!!!!!!!

マインクラフトのせいでマイナス3000円みたいになってますね(そういうことではない)

!!!!!!!!!!!!!!!

というわけで100000回ポチりました。嘘。一回だけです。

FF15も買うぞ!(まだ買ってない)

最the高

Docker と node_modules と Volume Trick

Rails & Node.jsの構成で Docker環境を作ろうとしたらハマったのでメモ

現象

npm installを実行する Dockerfileを記述

...
RUN mkdir /app
WORKDIR /app
# npm install
ADD package.json /app/package.json
RUN npm install
...

カレントディレクトリを /app にマウントするdocker-compose.ymlを記述

version: "2"

# これは失敗
services:
  web:
    build: .
    command: bundle exec rails server -p 3000 -b '0.0.0.0'
    ports:
      - "3000:3000"
    working_dir: /app
    volumes:
      - .:/app

するとnode_modulesが消える

原因

考えてみれば当たり前なんですが、
「node_modulesが出力されたコンテナ内のワーキングディレクトリに対して、ローカルのカレントディレクトリをマウントしてしまっている 」ため、コンテナ内のnode_modulesが隠れてしまいます。

解決策

こちらに書いてありました。 volume trick と紹介されています。

jdlm.info

version: "2"

services:
  web:
    build: .
    command: bundle exec rails server -p 3000 -b '0.0.0.0'
    ports:
      - "3000:3000"
    working_dir: /app
    volumes:
      - .:/app
      - /app/node_modules # コンテナ内のnode_moduleをvolumesに登録

複数マウントの詳細な挙動は謎なんですが、マウントで隠されたくないものをvolumesに登録しておくとコンテナ内のものが読まれるようになるそうです。

ちなみにbundle installなどでも同様の問題が起き得ますが、bundlerの場合はinstall先を環境変数でワーキングディレクトリ以外のパスに逃がせるのでそっちの方が楽です。

Redisの有効期限系コマンド

redis-cliから叩いた場合のコマンドです

EXPIRE(key, seconds)

有効期限の設定(相対時間)

# key-valueを適当に設定
> SET ice "I'm melting..."
OK
# 有効期限を10秒にする
> EXPIRE ice 10
(Integer) 1
> EXISTS ice
(Integer) 1 # 10秒以内
> EXISTS ice
(Integer) 0 # 10秒以上経過

上記例はMULTIブロックを使わないとatomic性が保証されないので注意。

EXPIREAT(key, timestamp)

有効期限の設定(絶対時間)

timestampにはUNIX時間を指定します。redis-cli上ではTIMEコマンドで現在のUNIX時間が取得できます。

SETEX(key, seconds, value)

SET(key, value) + EXPIRE(key, seconds)のショートカット。

公式ドキュメント(SETEX – Redis)を見る限り、atomic性が保証されるので、 SET + EXPIREを使うよりこっちを使った方が良いみたいです。

> SETEX ice 10 "i'm melting..."
OK

TTL(key)

有効期限の残り秒数を表示

PERSIST(key)

タイムアウトを無効化

参考

7つのデータベース 7つの世界

7つのデータベース 7つの世界

VimConf 2016 に参加してきました

vimconf.vim-jp.org

VimConf 2016 に参加してきました。会場はmixiさんで、コーヒーが無限に飲めて最高でした。

vim-jpの中の人や普段お世話になっているプラグインの開発者の方と話せて楽しかったです。

印象に残った発表と感想書きます。全部は書けないので3つほど紹介します。ちなみに全部面白かったです。

Introduction to Vim 8.0

www.slideshare.net

日本一のVimコミッターのK.Takata さんの、Vim8.0についての発表でした。

Vimの歴史的な話や、Vimのpatchを書いてる開発者の多くが日本人、という話が印象的でした。

Vim scriptもいつの間にかLambdaやClosure等のモダンな機能が使えるようになっているそうです。Vim script書きましょう。 あと表記ゆれに注意しましょう。

発表の中で紹介されていた breakindent 機能は知らなかったのですが、便利そうなので今後使って行きたいと思いました。

(参考: Vim 8.0 で追加された機能 'breakindent' - Secret Garden(Instrumental)

Denite.nvim ~The next generation of unite~

暗黒美夢王こと、Shougoさんの Denite.nvim についての発表でした。

発表資料がVimのただのmarkdownだったのが前衛的でした。

とりあえずUniteは開発がつらいのでDenite使いましょう、ってことでした。

実際Deniteは超速くて感動するので使っていない方は導入しましょう。

Dark powered系プラグインは基本的にNeovimで前提ですが、Vim8もサポートするそうです。

今後のDark powered系のプラグインの構想?みたいなお話も聞けました。ちなみにNeovimもDark powered系プラグインもユーザは海外の開発者が多いそうです。

ShougoさんもzcheeさんもPython3書いてプラグインやdeopleteソース書いてるそうなので、VimmerはPython3書きましょう。

ちなみに他の発表ではGolang書きましょう、という話が多かったのでGolangも書きましょう。

vim-mode-plus for Atom editor

t9mdさんの、Atomプラグインvim-mode-plusの発表でした。

Atom上での単なるVimのエミュレートというわけではなく、 Atom上のvim-mode-plusならではの機能を実装しているそうです。

vim-mode-plusのdemoでVim Golf的なことをやっていたのですが、鮮やかなtext-editingでした。使いこなせればまさに思考のスピードで編集できそうです。

VimAtomの双方の特性を深く理解した上で、便利な拡張機能を実装しているようで、t9mdさんのこだわりを感じました。

詳細は上記のリンクの資料とチュートリアルをこなすのが良いと思います。自分も試してみようと思います。

その他

Vim8 vs Neovim だと圧倒的にVim8の方が多いみたいです。ちなみに私はNeovim派です。

gemを作ってrubygems.orgでリリースする

作ったもの

github.com

slash-force というかっこいい名前のgemを書きました。

Railsで特定のURLへとアクセスしたときに末尾にスラッシュを付けて強制的にリダイレクトさせるだけのプラグインです。

こんな感じでgemをリリースできました。

slash_force | RubyGems.org | your community gem host

gemの作り方

Gemの作り方まとめ 普通のgem編 - masarakki's blog を参考に。

  • bundle gem xxxxx -t でプロジェクトの雛形を作成
  • 適当に実装
  • gemspecのTODO部分を埋める

くらいです。

gemのリリース

curl -u shotat https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
  • bundle exec rake release を実行。

以上の手順でリリースが完了します。当初の想定の2兆倍くらい簡単なプロセスでした。

gem化のメリデメ

汎用的な機能のgem化のメリデメについて(私見)

メリット

  • プロダクトコード内の libconcern の肥大化を防げる
  • 車輪の再発明を防げる(gem自体が再発明でない場合に限る)
  • UTをプロダクトコードと完全に分離できる
  • 見知らぬ強い人がenhance, bug fixしてくれる可能性がある
  • 楽しい

デメリット

  • インタフェースの変更に大いなる責任が伴う
  • やりすぎるとプロダクトコード側が苦しくなる(謎gemに大量に依存する状況になるとつらい)