SWEet

A Software Engineer Is Eating Technologies

brew updateしたらなんかvimが動かなくなった

ある日 brew update したらvim

dyld: Library not loaded: /usr/local/opt/lua/lib/liblua.5.2.dylib
  Referenced from: /usr/local/bin/./vim
  Reason: image not found

/usr/local/opt/lua/lib/liblua.5.2.dylib がないと言われた。実際にパスに移動するとなかった。

ということで  bilibili-mac-client/liblua.5.2.dylib at master · typcn/bilibili-mac-client · GitHub からファイルをダウンロードして /usr/local/opt/lua/lib にmvしたら動いた。

それにしてもmacvimをよく止めるね

Contikiにおけるファイル分割してコンパイルの仕方とPROCESSによる並列実行

卒業研究で使ってるWSN用のOS、というより超巨大ライブラリのContikiというものについてメモしておきます。

Why

そもそも日本語のドキュメントは勿論、英語でのドキュメントもサンプルを動かしただけとかばっかで深いところに突っ込むにはソースコード読むしかないという現状だったのでもし他にこの分野に手を付ける人がいたらその助けになればいいなという思いと、自分で忘れないようにするために書いておきます。

Contikiとは

WSN用のOSです。マルチスレッドを標準でサポートしています。何を当たり前のことをと思うかもしれませんが無線センサネットワークとかの界隈ではリソースの都合上結構すごいことだったりする。

このOSで動くプログラムはC言語で書けます。これまた「今時C〜?古くない〜?」と言われそうですが、結構有名なWSN用のOS、TinyOSとかはnesCとかいうドキュメントは英語の本一冊のみという魔の言語で書かなきゃいけなかったりするので恵まれている方です。

あとCoojaというGUIシミュレータが付属しているので基本的には書いたプログラムをこのシミュレータでデバッグしながら開発することができます。 とりあえずContikiで動かすことができるもっとも簡単なプログラムを示します。

#include "contiki.h"
#include "stdio.h"

/*---------------------------------------------------------------------------*/
PROCESS(hello_world_process, "Hello world process");
AUTOSTART_PROCESSE(&hello_world_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(hello_world_process, ev, data)
{
  PROCESS_BEGIN();
   
    printf("Hello, Cooja\n");

  PROCESS_END();
}
/*---------------------------------------------------------------------------*/

お決まりのHello world!ですがこれだけでも結構なことをしています。 一行ずつ説明していきます。

  1. PROCESS(プロセス名, プロセス呼び出し時に出力する文字列)

    これは hello_world_process という名前のプロセス構造体を定義しています。第二引数は呼び出し時に標準出力に出力する文字列です。

  2. AUTOSTART_PROCESS(プロセス構造体のアドレス)

    センサー起動時にこのプロセスを自動的に起動します。これがないとセンサを起動しても何も起きません。 プロセスをコード上で任意に起動することもできますがそれは後述します。

  3. PROCESS_THREAD(プロセス構造体, イベント, データ) { ... }

    プロセスの実際の処理を記述する関数です。このPROCESS_THREADは他のPROCESS_THREADとは並列に処理されます。 イベントはセンサ本体のボタンなどが押されたときのシグナルを判定する時に使用します。 データはコード上でプロセスを起動した時に任意のデータポインタを渡すことができます。

  4. PROCESS_BEGIN() ... PROCESS_END()

    この間に書かれた処理が実行されます。 PROCESS_END()が実行されても完全にプログラムの実行が終わったわけではなく, バックグラウンドではセンサ毎に定義されているOSプログラムが存在して, 低電力モードなどへの移行を行っています。あくまでここに定義されたプロセスをベースとなるOS上で実行しているイメージです。

コンパイルの仕様

センサで動かすプログラムをContikiがコンパイルする際には全てMakefileでセンサーごとに独自のバイナリにコンパイルしていきます。 例えば、上の hello_world.cコンパイルする際にはMakefileはこのようになります。

CONTIKI_PROJECT = hello-world
all: $(CONTIKI_PROJECT)

CONTIKI = ../..
include $(CONTIKI)/Makefile.include

makeする際には make TARGET=... でTARGETに動かしたいセンサを指定します。

あとはhello-world.cにガリガリ書いていけばいいのですがある程度コードの規模が大きくなると1ファイルで管理するのは非常に面倒でした。 そこで他のヘッダファイルに定義した関数を別のcファイルで実装し、それを呼び出す場合は

MakefilePROJECT_SOURCEFILES += hoge.c fuga.c と定義します。 この時のディレクトリ構成はこんな感じです。

.
├── Makefile
├── README.md
├── fuga.c
├── fuga.h
├── hello-world.c
├── hoge.c
├── hoge.h
├── symbols.c
└── symbols.h

この時, fuga.c hoge.c を別階層のディレクトに配置すると, コンパイルしたファイルを参照できなくなりエラーが起こります。

別プロセスの呼び出し

では試しに hoge.hhoge_processを定義し, hoge.c に実装し, hello-world.c でボタンが押された時に hoge_process を呼び出す処理を書いてみます

hoge.h

#ifndef _HOGE_H_
#define _HOGE_H_

void start_hoge_process();
#endif

hoge.c

#include "contiki.h"
#include "stdio.h"

PROCESS(hoge_process, "hoge process");
PROCESS_THREAD(hoge_process, ev, data) {
    PROCESS_BEGIN();
    printf("hoge %d\n", data);
    PROCESS_END();
}

void start_hoge_process(void) {
    process_start(&hoge_process, (void *)100);
}

hello-world.c

#include "contiki.h"

#include "dev/button-sensor.h"
#include "dev/leds.h"


#include <stdio.h> /* For printf() */

/*---------------------------------------------------------------------------*/
PROCESS(hello_world_process, "Hello world process");
AUTOSTART_PROCESSES(&hello_world_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(hello_world_process, ev, data)
{
  PROCESS_BEGIN();
  SENSORS_ACTIVATE(button_sensor);
  printf("Hello, Cooja\n");

  while(1) {
    PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event &&
            data == &button_sensor);
    start_hoge_process();
  }
  PROCESS_END();
}

これによって hello-word.cコンパイルしてcoojaシミュレータで起動(センサーの種別は問いません)し、 センサのボタンをクリックするとログに hoge 100 と出力されるはずです。

ContikiのMakefileには独自のフラグが多くあるのでまた自分が何か見つけたらメモしておこうと思います。 私のContikiで開発中のリポジトリはこちらです。興味があったらContikiでプログラミングしてみてください。 そして私に知見をください。

github.com

contiki本体のリポジトリはこちらになります

github.com

wikiも一応あるにはありますが大体動かしつつソース読むのが手っ取り早いです。

それにしてもWSNの具体的なユースケースや規模がググっても全然出てこないので評価の仕様策定に苦戦中です。 辛い

HighSierraにアプデしたらvimが起動できなかった

macをHigh Sierraにアプデしたんですが、コンソールでvimを起動したらこんなメッセージが

dyld: Library not loaded: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/libruby.2.0.0.dylib
  Referenced from: /usr/local/bin/vim
  Reason: image not found

ググると先人さまの知恵がありました。

shinogasa.hatenablog.com

swiftfe0.hatenablog.com

とりあえず色々アプデする必要がある模様。

まずpythonをアプデしようとしたら

$ brew upgrade python
Updating Homebrew...
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/core, caskroom/cask).
==> New Formulae
avimetaedit           bedtools              cling                 clingo                docker-ls             envconsul             mrboom                raylib                sceptre
==> Updated Formulae
little-cms2 ✔       checkstyle          fail2ban            gitlab-runner       kontena             libuv               nghttp2             pyvim               shfmt               uncrustify
sbt ✔               clhep               firebase-cli        gmime               kotlin              libwps              nmh                 q                   sile                urh
abcm2ps             cmake               fish                gradle-completion   kubernetes-cli      lldpd               node-build          qca                 sip                 vcdimager
angular-cli         conan               fluent-bit          grails              kvazaar             mapnik              nuget               qscintilla2         skinny              wireguard-tools
arangodb            conjure-up          fn                  gx                  ldc                 mediaconch          ocamlbuild          qt                  sslyze              xonsh
armadillo           consul              fonttools           gx-go               libatomic_ops       mgba                opencbm             rancher-cli         stormlib            xxhash
aspcud              convmv              freetds             hana                libcddb             micro               overmind            rebar@3             swi-prolog          youtube-dl
aurora-cli          cppad               fwup                hivemind            libcdio             midnight-commander  paket               remake              swiftformat         zanata-client
awscli              docker              gauge               huexpress           libcouchbase        minio               pandoc              rocksdb             termius             zimg
azure-cli@1         docker-completion   gdnsd               ibex                libdivecomputer     miniupnpc           parallel            roswell             terragrunt
bacula-fd           efl                 gegl                iso-codes           libgosu             mockserver          passenger           rust                tgui
blink1              ejabberd            geoserver           jhipster            libhttpseverywhere  mono-libgdiplus     pegtl               scalariform         thefuck
bmake               erlang              geth                knot                libmaxminddb        mpd                 percona-toolkit     sdl2_mixer          tidy-html5
bwfmetaedit         etsh                ghc                 kobalt              librealsense        multimarkdown       plzip               sfk                 tippecanoe
bzt                 exim                git-annex           kompose             libsass             nativefier          pyqt                shairport-sync      traefik
==> Deleted Formulae
clasp                                                                                                gringo

==> Upgrading 1 outdated package, with result:
python 2.7.14
==> Upgrading python
Error: The following formula:
  python
cannot be installed as a binary package and must be built from source.
Install the Command Line Tools:
  xcode-select --install

なんかこけた

xcodeコマンドラインツールないよって言われたので xcode-select --install 実行 そしたらポップアップでウィンドウが出てきたのでそのままインストール

もう一回実行してちゃんとインストールされたか確認

$ xcode-select --install
xcode-select: error: command line tools are already installed, use "Software Update" to install updates

されてますね。

~ brew upgrade python
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (caskroom/cask).
No changes to formulae.

==> Upgrading 1 outdated package, with result:
python 2.7.14
==> Upgrading python
==> Installing dependencies for python: sqlite, openssl
==> Installing python dependency: sqlite
==> Downloading https://homebrew.bintray.com/bottles/sqlite-3.21.0.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring sqlite-3.21.0.high_sierra.bottle.tar.gz
==> Caveats
This formula is keg-only, which means it was not symlinked into /usr/local,
because macOS provides an older sqlite3.

If you need to have this software first in your PATH run:
  echo 'export PATH="/usr/local/opt/sqlite/bin:$PATH"' >> ~/.bash_profile

For compilers to find this software you may need to set:
    LDFLAGS:  -L/usr/local/opt/sqlite/lib
    CPPFLAGS: -I/usr/local/opt/sqlite/include
For pkg-config to find this software you may need to set:
    PKG_CONFIG_PATH: /usr/local/opt/sqlite/lib/pkgconfig

==> Summary
🍺  /usr/local/Cellar/sqlite/3.21.0: 11 files, 3.0MB
==> Installing python dependency: openssl
==> Downloading https://homebrew.bintray.com/bottles/openssl-1.0.2m.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring openssl-1.0.2m.high_sierra.bottle.tar.gz
==> Caveats
A CA file has been bootstrapped using certificates from the SystemRoots
keychain. To add additional certificates (e.g. the certificates added in
the System keychain), place .pem files in
  /usr/local/etc/openssl/certs

and run
  /usr/local/opt/openssl/bin/c_rehash

This formula is keg-only, which means it was not symlinked into /usr/local,
because Apple has deprecated use of OpenSSL in favor of its own TLS and crypto libraries.

If you need to have this software first in your PATH run:
  echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bash_profile

For compilers to find this software you may need to set:
    LDFLAGS:  -L/usr/local/opt/openssl/lib
    CPPFLAGS: -I/usr/local/opt/openssl/include
For pkg-config to find this software you may need to set:
    PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig

==> Summary
🍺  /usr/local/Cellar/openssl/1.0.2m: 1,792 files, 12.3MB
==> Installing python
==> Downloading https://homebrew.bintray.com/bottles/python-2.7.14.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring python-2.7.14.high_sierra.bottle.tar.gz
==> /usr/local/Cellar/python/2.7.14/bin/python2 -s setup.py --no-user-cfg install --force --verbose --single-version-externally-managed --record=installed.txt --install-scripts=/usr/local/Cellar/pytho
==> /usr/local/Cellar/python/2.7.14/bin/python2 -s setup.py --no-user-cfg install --force --verbose --single-version-externally-managed --record=installed.txt --install-scripts=/usr/local/Cellar/pytho
==> /usr/local/Cellar/python/2.7.14/bin/python2 -s setup.py --no-user-cfg install --force --verbose --single-version-externally-managed --record=installed.txt --install-scripts=/usr/local/Cellar/pytho
==> Caveats
This formula installs a python2 executable to /usr/local/bin.
If you wish to have this formula's python executable in your PATH then add
the following to ~/.bash_profile:
  export PATH="/usr/local/opt/python/libexec/bin:$PATH"

Pip and setuptools have been installed. To update them
  pip2 install --upgrade pip setuptools

You can install Python packages with
  pip2 install <package>

They will install into the site-package directory
  /usr/local/lib/python2.7/site-packages

See: https://docs.brew.sh/Homebrew-and-Python.html
==> Summary
🍺  /usr/local/Cellar/python/2.7.14: 3,325 files, 45.5MB

成功しました。

続いてvimのアップグレード

 ~ brew upgrade vim
==> Upgrading 1 outdated package, with result:
vim 8.0.1300
==> Upgrading vim --with-override-system-vi --with-python3 --with-lua
==> Installing dependencies for vim: python3
==> Installing vim dependency: python3
==> Downloading https://homebrew.bintray.com/bottles/python3-3.6.3.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring python3-3.6.3.high_sierra.bottle.tar.gz
==> /usr/local/Cellar/python3/3.6.3/bin/python3 -s setup.py --no-user-cfg install --force --verbose --install-scripts=/usr/local/Cellar/python3/3.6.3/bin --install-lib=/usr/local/lib/python3.6/site-pa
==> /usr/local/Cellar/python3/3.6.3/bin/python3 -s setup.py --no-user-cfg install --force --verbose --install-scripts=/usr/local/Cellar/python3/3.6.3/bin --install-lib=/usr/local/lib/python3.6/site-pa
==> /usr/local/Cellar/python3/3.6.3/bin/python3 -s setup.py --no-user-cfg install --force --verbose --install-scripts=/usr/local/Cellar/python3/3.6.3/bin --install-lib=/usr/local/lib/python3.6/site-pa
==> Caveats
Pip, setuptools, and wheel have been installed. To update them
  pip3 install --upgrade pip setuptools wheel

You can install Python packages with
  pip3 install <package>

They will install into the site-package directory
  /usr/local/lib/python3.6/site-packages

See: https://docs.brew.sh/Homebrew-and-Python.html
==> Summary
🍺  /usr/local/Cellar/python3/3.6.3: 3,359 files, 53MB
==> Installing vim --with-override-system-vi --with-python3 --with-lua
==> Downloading https://github.com/vim/vim/archive/v8.0.1300.tar.gz
==> Downloading from https://codeload.github.com/vim/vim/tar.gz/v8.0.1300
######################################################################## 100.0%
==> ./configure --prefix=/usr/local --mandir=/usr/local/Cellar/vim/8.0.1300/share/man --enable-multibyte --with-tlib=ncurses --enable-cscope --enable-terminal --with-compiledby=Homebrew --enable-luain
==> make
==> make install prefix=/usr/local/Cellar/vim/8.0.1300 STRIP=/usr/bin/true
🍺  /usr/local/Cellar/vim/8.0.1300: 1,424 files, 22.8MB, built in 1 minute 36 seconds

ちゃんと8.xでアップグレードされていますね。 しかし、依存関係で取ってきているのはpython3.6・・・ もしかしてpythonのアップグレード関係なかった・・・?

まぁとりあえず動いているので良しとしましょう。

VimConf2017に参ってきました

VimConf2017とは

  • vim唯一の国内でのカンファレンス
  • vimにパッチ送ってる人とかプラグイン書いてる人がセッションしてくれる すごい

Vimとは

言わずと知れたテキストエディタ

ちなみに僕の研究室でvim使ってるのは10人中2人とかでvimconf行くんだーって言ったら 「こわっ」「vim使いって怖いイメージある」「atom使えばいいじゃん」 と散々でした。解せぬ

セッションに対する感想

スライドとかは他の方達がブログでまとめてるので省きます。

Vim, Me and Community - haya14busa

vimに関わってきた5年間について

5年間でvimプラグインや本体にコミットしまくって某会社で働いているの本当にすごいなと思いました。 EasyMotionの紹介や開発の裏話を聞きましたが今まで使ったことなかったので導入してみようと思います。

goのバイナリをvimscriptで呼び出してjsonとかでやりとりすることでプラグインを作れるっていうのはvimscript触ったことない人にも良さそうだなと思って僕もなんか作ってみようかなとモチベが上がりました。

あとvimscriptにlambdaが導入されたということですがちょっと調べてみるとスクリプト言語としては普通に書けそうなのでこれもチャレンジしてみたい

The Past and Future of Vim-go - fatih

普段からGoを使って開発してるので本当に足を向けて寝られないレベルの神様みたいな人と思ってます。 vim-goがない開発環境を考えたくない。。。

内容はvim-goの今までと将来について

vim-goがパワフルな理由は上記のようにjob_startとかsystemでvimscriptでやるのは難しいところをgoで書いたツールを呼び出してるからというのがあるそうです。

vifコマンドとvafコマンドという関数の部分を選択するコマンドが今まで知らなかったし結構便利そうだったのでこれから使ってみようと思います。 donationのお話では「donationをもらうのは躊躇すべきではない。だって僕たちは自分の自由な時間を費やして価値を創造しているのだから」という言葉がとても印象的でした。日本の企業とかではソフトウェアに対する考え方が未だに軽いのでこういう姿勢は重要なのかなと思いました。

これからはデバッグAPIとか作って後方互換性とかも重視していきたいとのことでした

Talk Show - mattn_jp k_takata kaoriya

super viman god 3人による鼎談 この時にmattnさんを初めて見て

というツイートをしたら結構有名な人にリツイートやらお気に入りされて肝が冷えました。

印象に残ったvimのパッチやこれからどんな機能を作っていきたいかのお話でした。 その中でlspというワードがあったのですがこれがどんなものか僕は知らなくて調べてみたんですがいまいちよくわからなかったです。 どなたか噛み砕いて教えていただける方募集してます。

Creating your lovely color scheme - Cocopon

スライドの構成もさることながら「人生の33%はカラースキームを眺める時間で構成されている」というのに思わず納得させられてしまいました。 お話を聞いてると確かに自作のカラースキームを作るのはそこまでハードルが高そうではありませんでしたがラブリーなものにするのはセンスが問われるなーと思いました。

自分は普段molokaiを使っていますがこの綺麗なスキームを作るのに一体どれほどの時間をかけていただいたのでしょうか・・・ これからは色んなカラースキームを試してみながらコーディングしてみようかなと考えさせられた発表でした。

vim-mode-plus: The most ambitious vim emulator in the world - t9md

atomにおけるvimエミュレータパッケージの開発についてでした。 普段自分たちが使っているコマンドをatom上で再現するのがすごく面倒臭いってことがわかりました。 というか発表の内容がすごすぎてこんな感想ぐらいしか書けませんでしたすいません。

Vim and Compatibility - senopen

POSIX主義のお話でした。 なんというか発表する方の衣装もあってかなんか怖かったです。 でも発表内容は色々なところで動くものを作ること、後方互換性というものの重要さを改めて考えた発表でした。

後方互換性は色々なソフトウェアを使っていると「あって当然だろ!なんでないんだよ」と思うことがありましたが作ってる側からするとすごく大変なことだというのもわかっています。これとどう付き合って行くかはソフトウェアを開発してく上で非常に重要でしょう

neosnippet.vim + deoppet.nvim - ShougoMatsu

暗黒美無王ことShougoさんの発表でした。

こちらも普段から色んなプラグイン、僕の場合は主にdein.vimでお世話になってる方です。 内容はsnippetプラグインについてでした。

neosnippetは普段あまり使わないのですがneocompleteの方が開発を打ち切り、deocompleteでvim8などに対応していくということでこれからはdeocompleteに自分も移行しようと思います。やっぱり補完系はあるとコーディング速度とかtypoが減りますからね

How ordinary Vim user contributed to Vim - dice_zu

vimにどうやってコントリビュートするかのお話でした。 「vimは毎日ビルドするもの」 「大抵は運用でなんとかする」 「コントリビュートに必要なのは熱い情熱」

などなど様々な名言が生み出された個人的に一番面白かった発表でした。 やっぱりOSSにコントリビュートするならそのリポジトリのissueやpullreqをみてバグフィックスtypoなどの修正から手をつけるのがいいとのことでした。

そう言われると自分にもできそうという気になってきたので好きなライブラリとかのissueとかを眺めてる最中です

The new syntax highlighter for Vim - p_ck_

あのお寿司がステータスバーに流れるプラグインを書いた人の発表でした。

vimシンタックスハイライトは言語とかによると複雑な構文や一文が長い場合上手にハイライトされない場合がある。 なので独自のプラグインで完璧にハイライトしよというものでした。 ただ数万行のファイルを開くとvimが固まる模様。ただ、そもそも1ファイルに何万行も書くべきではないと思うのでそれは別にいいのではないかと思いました・・・

You've been Super Viman. After this talk, you could say you are Super Viman 2 -- Life with gina.vim - lambdalisue

なれる!Super Viman!ということでgina.vimというvim上でgitのコマンドを便利に使えるようにしたプラグインのお話でした。 なんでも結果を非同期でとってきているのでgit logとかを全部待つ必要がなくて高速に表示できるとかの工夫してるらしいです。すごい でも個人的にgitはSource Treeや生のgitで満足しているのでわざわざ使うかと言われると微妙なラインなのですよね・・・

まとめ

全部が全部内容が濃くて被ってないしすごく面白いカンファレンスでした。 僕はまだvimを使い始めて2年とかですがこれからもvimを使って開発しようというモチベが爆上がりの良いカンファレンスでした。 お金を払うのも普段ただでvimやそれに付随する沢山のプラグインを使わせてもらってるのでこれぐらい安いものだと思います。

これを機に自分もなにかvimに恩返しができたらなと思える素敵なカンファレンスでした。 開催していただいたスタッフの方達への感謝をここに述べたいと思います。本当にありがとうございました。また来年も楽しみにしています。

開発におけるdockerの利点とかその他諸々

インターン先での開発時はdockerを使って環境を構築することが多いです。

でも最近までdockerがなんたるかをwebで読んでもちんぷんかんぷんだったにも関わらず使ってると便利だなーって思えるようになりました。

でも環境構築するまでは結構苦労がありました。今回はdockerについて溜まった知見をメモしていこうと思います。

docker 概要

そもそもdockerとはなにものなのか。

一言で言えば 軽量なコンテナ型の仮想化環境

うーんわからない。

というわけで自分なりに解釈、要約してみます。

仮想化環境

仮想化技術で一番使ってるのが多いと思われるのはホスト型の仮想化技術。 これはよくある、「Linux上でWindows動かせるよ」とか、「Windows上でLinux動かせるよ」みたいなやつです。

こいつらはGUI上で他のOSのGUIでいじりたい時とかOS丸ごと動かしたい時は重宝するやつですね。

これに対して、Dockerのコンテナ型っていうのは、

一つのプロセスが独自の名前空間やリソースを持ってその中でアプリケーションを実行させる という感じだと思ってます。

例えば仮想化したWindowsGUI上でゲームしたい場合はゲーム以外にもWindowsっていうOS自体やそのOSの中でたくさんのプロセスが走ってます。Dockerの一つのコンテナはこのプロセス一つ一つに焦点を当てたもの。だから軽量でコンテナ型という文言があるのですね。

用途

なんでDockerが流行っているのか、何が便利なのか。自分なりにまとめてみます。

例えば以下のようなアーキテクチャのシステムを構築するとします。

f:id:kk_river108:20170617192844p:plain

ではこのWebサーバーでなんかWebアプリが動いてる、RailsでもDjangoでもなんでもいいです。 RedisやMySQLは別サーバーで稼働中。

ではこのWebアプリを開発するとして環境はどうすべきか。当然自分のPCにMySQLを入れて、Redisも入れて、ユーザー設定して。。。 とやっても全然いいです。

しかし、もし複数人で共同で開発する場合そういう風に環境を構築すると思わぬ齟齬が生まれる場合があります。 例えばポート番号が違うとか、ユーザーのパスワードが違うとか、ホスト名が違うとか。

開発環境を統一したい。新しい人が入って来てもこちらがわざわざ指示せずに開発環境をパッケージ化しておきたい。 そういう時にDockerは便利です。

Dockerは上記の図のWebサーバー、DB, inMemoryDBそれぞれをコンテナとして動かすことができます。

実際に構成がどのようになるかと言えば

  • 自分のPCのマシン 192.168.2.70
  • Gateway 172.0.0.1
  • Webサーバー 172.10.0.2
  • DBサーバー 172.10.0.3
  • Redisとか 172.10.0.4

Dockerはこれらを単一で走らせることもできますが、Docker-composeというものがあってこの構成をひとまとめに一括で起動することもできます。ネットワークの構成も自動でやってくれる優れものです。

簡単な環境構築の流れとしては

  1. プロジェクト直下に Dockerfile docker-compose.ymlを作成
  2. Dockerfileにはアプリのビルドプロセスを、docker-compose.ymlには各種サービスの起動手順を (詳しくはグーグル先生へ)
  3. docker-compose build でイメージを作成
  4. docker-compose up で起動

これが上手くいけば、他の人のPCでもプロジェクトのディレクトリをgitか何かで共有して docker-compose build docker-compose up みたいにするとすぐに開発環境が立ち上がります。DockerコンテナのIPアドレスは指定しないかぎり毎回ランダムですが自分のlocalhostポートと紐つけることができるので不便になることはありません。

図のようにAWSのサービスとかを利用する場合も環境変数等をファイルに記述し、鍵を読み込ませることもできます。環境変数ファイルはgitignoreとかで隠します。

ホスト名等もDockerでサポートしているサービスであれば基本的に面倒な設定いらずに統一できます。 Dockerfileを個別に作る必要もありません。

例:

Mysql ==> ホスト名: mysql
Redis ==> ホスト名: redis

docker-composeはプロジェクトのディレクトリ直下にdocker-compose.ymlを作成してdocker-compose upすると コンテナ群が起動します。

docker 便利です。

コンテナ内での作業

例えばMySQLへの書き込みをアプリでしていて実際に書き込まれているか見たい、なんて時もコンテナのシェルをすぐにいじることができます。

docker-compose exec -it sample_container_mysql_1 bash

と叩くとシェルに入れます sample_container_mysql_1 はコンテナ名みたいなやつで docker-compose psで確認できます

Webサーバーだけ再起動して動作確認したい。

docker-compose upでコンテナ群を起動して docker-compose down で落とします。

これらは全てのコンテナを操作するので多少時間がかかりますがWebサーバーのソース更新したからそこだけ、MySQLだけとかを再起動させる場合は

docker-compose restart web みたいにサービス名を入力すると単一的に再起動させることができます。最初知らなくて一々全部起動して、終了して、起動してを繰り返してました。

面倒くさいこと

マイクロサービスアーキテクチャが主流のなかでDockerは便利です。 しかし、この環境を作ること自体は結構面倒くさかったりします。docker-compose.ymlを何回も書き直してbuildしてイメージが増えすぎて消すのが結構面倒くさかったこともあります。

ある程度ネットワークや構築するシステムのアーキテクチャを知っている必要はあるのかなーって思いました。 あと自分でちょろーっと簡単なアプリ開発!なんていう時は必要ないかもしれません。AzureやGAEやHeroku使った方が早いと思います。

大きなシステムとしてその内部の一部を開発する時とかの環境構築として便利だと私は思ってます。

何事もケースバイケースですね。まだまだdockerは勉強中なのでこれからも使うかと思います。

またなんかあったら纏めてみようかな・・・

大学生活+αの振り返り

こんにちは。最近書くネタがなくてどうしようかと思い、でも月一更新はなんとか続けないと今後も続かないと思い、 「そういえば最近1年生や2年生の子にいつからプログラミングやってたかよく聞かれるなー」ってなって自分でもいつからこっち方面に進もうと思ったか曖昧だったので改めて思い返してみました。書くことが大事(戒め)

小学3年生

今思えばこの時に初めてパソコンに触った。目的は「ドラクエ5のブオーンの攻略方法を知るため」。父親が買ったMacBook(相当古いですが今でも家にあります)と「これみてひらがな打ちなさい」と言われ渡されたローマ字表片手にずっとGoogle先生と遊んでました。

小学4年生

確かこの頃近所に住む友達に面白フラッシュ倉庫を勧められてめちゃくちゃハマった気がします。Flash全盛期ってやつだったかと・・・ まだプログラミングとかには手を出してません。あと夏休みにポケモン大好きクラブにも登録して友達と一緒にミニゲームやってたりもしました。

小学5年生

特に進歩せずひたすらGoogle先生にゲームの攻略方法聞いてました。確かこの年はテイルズオブジアビスドラクエ8あたりだった気がする・・・

小学6年生

引っ越して環境が変わってなんかすごく辛かった年だった思い出です。確かここら辺でなんの映画か忘れましたがハッカーがターミナル画面をカタカタしてるシーンがあってそういうのにすぐ影響される僕は「あれ、どうやってやるの!?」って父に聞いた覚えがあるようなないような。この頃Windowsコマンドプロンプトを覚えてひたすら意味のない文字をガタガタ打ち込んでました。それでハッカーになった気でいたのです。

中1

なんか部活と塾で手一杯であんまりパソコンに触れた覚えがありません。この頃から受験という言葉に悩まされるようにになってた気がします。

中2

多感な時期です。この年か前の年かわかりませんがBloodyMondayというドラマが放映されました。ある意味これが僕の今後の人生を決定づけたといっても過言ではないぐらい大きい作品でした。

あらすじとしては天才ハッカーがテロリストから国を守るために戦うというもの、もうその主人公がかっこよすぎて一時期壁紙とかも真似したりしてました。 そして、そのドラマに使われている技術についてついにネットで調べるようになりました。主人公が使っていたのはUbuntuというOSだった。使用言語はPython(この頃プログラミング言語の種類なんて一つも知りません)という情報を頼りに、Ubuntuとは?Pythonとは?と必死に調べました。

その後ついにUbuntuをOSだと理解し、ディスクにイメージを焼いて起動し、Pythonをインストールして使うことができました。この時はかなり感動しました。

ただ、もっとかっこよくUbuntuを起動したいと思ってUSBからイメージを起動しようとしてPC(父の)のBIOS設定をいじっていたら元のOSが立ち上がらなくなってめちゃくちゃ怒られたのは少しトラウマです。

はてさて、この男はプログラミングを初めて経験したのですがなんとそこで満足、というか挫折しました。BloodyMondayの主人公がしていたようなプログラミングはどうやってするのだ!と一人途方に暮れていました。当然ですね。この頃はTCP/IPやサーバーという単語すら知らなかったのですからそもそも調べようがない。ですが、もうごく自然に僕の頭の中では将来こういう方面の仕事をしよう。他の仕事はありえないという考えになっていました。

中3

受験です。もうこの年はひたすら受験勉強です。といっても塾に通って勉強した気になっていただけなので学力は大したことなかったです。 まぁそれでも身の程を知らずに東工大の附属に推薦と一般受験どちらも受けて玉砕という哀れな結果になりました。それでも理工学系に強い学校に行くつもりはあって芝浦工大柏に受かりそちらに通うことになりました。ちなみに僕が一番得意なのは国語でした。 プログラミングの勉強はあれから「VisualStudio2005 で学ぶC++」みたいな本を買って貰ったのですがクラスの概念が理解できず挫折。早いですねー2回目の挫折w

高1

中学と同様に部活には入ったのですが大学受験する気は1ミリもありませんでした。「だって推薦で芝浦工大の情報工いければいいやん」という発想のもとテスト勉強もせず部活とゲーセン通いの日々でした。うーん思い返すと清々しいほどのクズですね。 この頃から今は廃刊になってしまいましたが白夜書房から発売されていた「ハッカージャパン」という本を買うようになりました。これ結構すごい雑誌でサンプルアプリをクラックしてみよう!とかゲームのバイナリを解析してチートコードを書こう!みたいなことが書いてあったんですよ。この頃CTFの存在を知りました(知っただけで参加するのは数年後)

高2

一番楽しい時期だと言われていますね。部活とゲーセンしか記憶がありません。楽しかったのでいいんですが。 プログラミングの方はこの頃すっかり頭から抜け落ちてました。ひたすら音楽ゲームの譜面を脳内でリピートしてた気がします。

高3

みんなが受験勉強してる中一人でのほほんとゲーセン通いを続けてのほほんと推薦に必要な最低限の勉強をしてました。 そんで推薦が決まってよーし大学に入った時のために勉強しておくかーと思ってネットで色々調べてもどれから手をつけていいかわからずすぐやめてゲームしてました。うーんクry

ここまで見るとろくに勉強してませんね。ぼんやりとした将来像しかなかった気がします。結局本格的にプログラミングを始めたのは大学からですし。逆にこんなのでも割となんとかなるってことですかね。

大学に入ってからは特に言うこともなく真面目に勉強するようになりました。自分がやりたいことだったし、自分でどうやって学べばいいかわからないところを「ああ!こういうキーワードで調べてこういうので勉強すればいいのか!」ってモヤモヤが晴れてすごく楽しかったですね。あとは知り合いの影響も大きかったと思います。大学1年の時は適当なサークルに入ってたんですけどその中で同じ学科の人から「こういうプログラミングしてるサークルあるんだけど入らない?」と誘われてそこに居た人たちに凄く良い刺激を貰いました。

ITの世界はすぐに新しいものが出てきて隆盛が特に激しい分野だと思っています。それでも僕はパソコンを触るのが好きだしプログラミングするのも好き。ロジックを考えて実装できた時なんかは一人で小躍りしますし、人にレビューを貰って一喜一憂することもあります。

このPCから繋がる全ての世界が僕は好きなのだと最近改めて実感するようになりました。と、いい感じに締めておきます。

途中からなんの話かわからなくなりましたがまあ良しとしておきます。文字数も稼げましたし。 にしても、改めて振り返ると初めて触れた言語Pythonだったんですね・・・(他人事)なんか今でもそれをガッツリ書いていると思うと多少は進歩が見られて嬉しいです。

では今回はこのあたりで筆を置かせていただきます。次の更新は6月中になんとか・・・

とりあえず機械学習を実践してみる方法

どうも、おばんです。

あ〜そろそろなんか記事書いてまとめておくか〜って思うと大体綺麗に1ヶ月経ってます。

突然なんですが最近一身上の都合(特に深い意味はないです)でpython機械学習を使う機会が増えました。

自分ではやろうやろうと思いつつも理論がワケワカメすぎたので敬遠していたのですが改めてやってみると機械学習の概念自体はそこまで難しくない(数学的な理論は置いといて)。むしろ難しさはもっと別の場所にある。

んでもって機械学習を理論はさっくりでいいからとりあえず手っ取り早く実践してソースからイメージを掴みたい。そういう時どうすればいいのか、意外としっかりまとめてるサイトがなかったので書いてみようと思います。 一応私の環境としてはMac,Pythonを用いています。

機械学習の定義

理論の話はさっくりとと言いましたが機械学習とはなんぞやぐらいはまとめておかないといけないのでそこはご容赦ください。 あと今回はDeepLeaningの話は今回はしません。ちょいと方針が違うので・・・ wikipedia先生によると、

センサやデータベースなどから、ある程度の数のサンプルデータ集合を入力して解析を行い、そのデータから有用な規則、ルール、知識表現、判断基準などを抽出し、アルゴリズムを発展させる。なお、データ集合を解析するので、統計学との関連が深い。
そのアルゴリズムは、第一にそのデータが生成した潜在的機構の特徴を捉え、複雑な関係を識別(すなわち定量化)する。第二にその識別したパターンを用いて、新たなデータについて予測を行う。データは、観測された変数群のとりうる関係の具体例と見ることができる。一方、アルゴリズムは、機械学習者として観測されたデータの部分(訓練例などと呼ぶ)を学習することで、データに潜在する確率分布の特徴を捉え、学習によって得た知識を用いて、新たな入力データについて知的な決定を行う[1]。

まぁ、つまりは沢山のサンプルデータから傾向とかを見つけ出して次のデータはこうなるはずだ!とか、

こういうデータはやばいデータなんだな!とかをコンピュータが判断できるようになるアルゴリズムを作ること って感じですかね

機械学習の分類

そんなすごそうな機械学習ですがいくつか種類があります。

  1. 教師あり学習 入力(データ)とラベル(答え)がある学習方法 (売上、株価の予測とかは大体これ)
  2. 教師なし学習 ラベルのない入力のみの学習 (データの分類分けとかに使われてるイメージ)
  3. 強化学習 よくわからんけど動的計画法(最大の報酬を得るための選択)みたいな感じ?

超アバウトです。でも詳しく書こうとするとどうしても専門的な手法とか数学の話が絡むので今回は省略。

主に使われる手法とかのキーワードは「線形回帰(未来予測)、K近傍法(分類)、ナイーブベイズ分類器(分類)、サポートベクターマシン(忘れた)」とか色々あります。

一番情報が多いのは教師あり学習です。なぜならデータさえあればあとはライブラリ使ってデータを突っ込むだけです。

必要な材料

python機械学習を始めるのに必要なものはすぐ揃えられます。仮に揃わなかったらStackOverflowにでも投稿すればいいんじゃないかな?(適当)

まずはPython 2.7でも3.5x系でもどっちでもいいですができれば3.5x系の方がいいかもしれません。インストールしましょう

さて、インストールが完了すればターミナルからpythonと叩けばインタプリタが起動するでしょう。

そこでprint('Hello world')と打って見事出力されればもう機械学習の世界はあなたを受け入れているでしょう。

ですが罠がもう一つあります。パッケージの管理です。どんなプログラミング言語でもパッケージ、ライブラリの管理は面倒臭いもの。

pythonではそれはpipというものが管理しています。それぞれのOSに合わせてpipをインストールしましょう。Macならbrew,Unixならapt-getかな。Windowsにそんなコマンドはない?bash_on_windowsunixコマンドが叩けるようになったらしいからそれを使えばいいんじゃないかな?

pipが入ったら pip install ~~~~コマンドでscikit-learn,numpy,pandasをインストールしましょう。scikit-learnは基本的な機械学習アルゴリズムが詰まった素晴らしいライブラリです。他にも沢山の機械学習ライブラリがあります。Tensorflowとかchainerとかね。numpyとpandasは言わずと知れた行列計算ライブラリと柔軟なデータ構造を実現するこれまた最高のライブラリです。

失礼、もう一つライブラリを忘れていました。それはmatplotlibです。これはグラフの描画ライブラリですがデータを可視化できるのでとても便利です。

さて、それらのインストールが済んだら実際に簡単なソースを動かしてみましょう

実践

import pandas as pd
import numpy as np

// データの読み込み wine = pd.read_csv("winequality-red.csv", sep=";") wine.head

// sklearn.linear_model.LinearRegression クラスを読み込み from sklearn import linear_model clf = linear_model.LinearRegression()

// 説明変数に "density (濃度)" を利用 X = wine.loc[:, ['density']].as_matrix() print(X) // 目的変数に "alcohol (アルコール度数)" を利用 Y = wine['alcohol'].as_matrix()

// 予測モデルを作成 clf.fit(X, Y)

// 回帰係数 print(clf.coef_)

// 切片 (誤差) print(clf.intercept_)

// 決定係数 print(clf.score(X, Y))

// 実際の値を与えてみての予測 result = clf.predict(0.9978) print("%s : %s" % (result,Y[0]))

// matplotlib パッケージを読み込み import matplotlib.pyplot as plt

// 散布図 plt.scatter(X, Y)

// 回帰直線 plt.plot(X, clf.predict(X)) plt.show()

scikit-learn で線形回帰 (単回帰分析・重回帰分析) – Python でデータサイエンス

上記のソースをお借りしたサイトです。少しだけ改変しています。 上をコピって実行すればライブラリさえあれば動くはずです。 これは何をしているソースかというとリンク先を読むとわかると思いますがワインの諸々のデータを読み込んで、試しに濃度からアルコールを予測してみよう的なことをしてます。

この予測に用いてる手法は線形回帰です。これは機械学習の数ある手法の中でもダントツでわかりやすい手法だと思います。 これを応用すれば売り上げの予測、アクセス数の予測、株価の予測とかもできるはずです。やってないのでわかりませんが。

処理に関してはコメント文そのまんまです。

機械学習の難しさ

さて、ソースを動かすだけならライブラリを使えば難しくはないことがお分かりいただけたでしょうか?

勿論、手法の方から自分でコーディングしてもいいと思います。それにはかなりの数学的知識とそれをコードに落とし込むプログラミング能力が必要にはなりますが・・・

そして実際に最近機械学習をやるようになって私が一番難しいと思っているのは何か。

それは データの調達、整形です。

今回のソースはあらかじめ用意されたデータを使っているのでとても綺麗で無駄がありません。 何か新しい分野に機械学習を利用したい!そういう人はいると思います。私も例外ではありません。しかし、新しい分野、たとえば日本の農業のこれからの総生産量を海外からの輸入量と比較しつつ予測するのに機械学習を用いるとなった場合はまず当然ですが日本の農業のデータが莫大に必要です。海外からの輸入データも必要でしょう。それはどこから入手しますか?農林水産省財務省?。まだ当てがある場合はいいです。そもそもまとめられていないデータを分析したいならまとめるところから始めなければなりません。

まとめたデータにノイズとなるようなデータが混じっていることもあります。それだけで学習器の精度は狂ってしまいます。コンピュータは人間より繊細ですからね優しく扱ってあげないといけません。

更に今まさに私が直面している問題ですが、データの定量化、評価です。機械学習で学習器に学習させるデータは全てを数値化する必要があります。 例えば学生のデータとして「170,50,男,性格に難あり」といった4次元の特徴ベクトルの集合の場合、男というベクトルは男女、しかないのであれば0,1に変換する必要があります。最後の備考的な項目はもっと評価するのが難しいです。定量化するのか、それとも独自のアルゴリズムで評価すべきなのか。

そこも考えるのがとても難しい。

ついでにデータの性質、傾向を学習させる前に自分でそれらを理解する必要もあります。なので統計や確率などの知識多少はあった方がいいのではないでしょうか。 データを理解すれば必要ではない項目、ノイズのようなデータもすぐにわかるようになるので学習器の精度向上にも繋がるでしょう

ですがとりあえず機械学習に触れるのであればライブラリに付属しているデータセットcsv) とかを使えばどういうものなのかはつかめると思います。

Pythonがわからない? 今すぐAmazonでOreillyの本を買うべきです。

今回の記事で機械学習の入り口が広がって(主に大学の関係者の方々へ)ついでに私に色々教えてくれるようになるのを願っています。

では今日はこのあたりで筆を置かせていただきます。次もなるべく早めに更新したいです