読者です 読者をやめる 読者になる 読者になる

vagrant使い方まとめ

vagrant

1.box取得

vagrant box add [**Box名**][**BoxのURL**]

上記のコマンドでboxを追加することができる。

DLするBoxはVagrantbox.esに記載されているのでこの中から選択して追加してやる

※追加したboxを確認する場合

vagrant box list

で確認することができる。

2.仮想マシンの作成

Boxの取得が完了したら仮想サーバーを作成してやる。 ※Vagrantoはサーバー単位でディレクトリを用意してやる必要があるので注意

サーバー用のディレクトリを作成したら移動を行い

vagrant init [**Box名**]

とすると現在いるディレクトリに"Vagrantfile"ファイルが作成される。 これが今作ったサーバーの設定ファイルとなる。

仮想サーバーの作成が完了したら

vagrant up

でサーバーが立ち上がる。

コマンド一覧

コマンド 内容
up 立ち上げ
halt 停止
status 状態
sleep スリープ
suspend スリープからの復帰
reload 再起動
destroy 削除

上記コマンドは

vagrant [コマンド]

の形で実行することができる。

vagrantで仮想サーバーを立ち上げる場合"Vagrantfile"とヒモ付されてるサーバーとなる。複数作成していた場合立ち上げたい対象を間違えないように気をつけよう!!

3.仮想マシンに接続

vagrant ssh

とすると立ち上げた仮想サーバーにvagrantユーザーでssh接続をしてのログインが行える。

4.ローカルネットワークでのアクセス

vagrantを立ち上げて色々と行った後にローカルネットワークでvagrantoにアクセスしたい場合"Vagrantfile"を編集してやる必要がある。 変更したいマシンの"Vagrantfile"を開いたら27行目のコメントアウトを解除してやれば同じ行に記載されているIPでアクセスが可能となる。

5.共有フォルダ

vagrantoは構築した時既に仮想マシン内の特定のディレクトリと"vagrantfile"があるディレクトリが最初から共有状態になっている。 共有されているディレクトリはルート直下の"/vagrant/" このディレクトリを外部公開ディレクトリに対してシンボリックリンクを貼ってやればファイル更新が楽になりそう。

試しに

vagrant ssh
cd /vagrant/
touch test.txt
exit
ls

とやればサーバーにログインして作ったファイルがホストOS側でも存在しているのが確認できる。(バージョン管理ソフト利用して落として来てもいいわけですが)

6.Provisioning

Provisioningとは"vagrant up"を行った後にシェルスクリプトなどを自動で実行してくれる。 同じサーバー設定を行いたい場合、この機能を利用してやることでより簡単に環境の構築を行える。

設定の方法はVagrantfileに "config.vm.provision :shell, :path => "provision.sh" とすることでpathで指定したシェルスクリプトの実行を行ってくれる。

vagranto upでProvisioningを実行してくれるのは初回立ち上げ時のようで2回目以降は実行してくれない様子

一度立ち上げた後にProvisioningを実行したい場合

vagrant provision

とすることで再度Provisioningの実行をしてくれる。

7.自分のBoxを作成する

必要なソフトをインストールした仮想マシンをパッケージングすることで、同じ状態のサーバーを再構築又はチーム内に共有を行うことができる。 作成した仮想マシンをパッケージングする場合

vagrant package

とすることでboxを作成することができる。 処理が終わったら現在のディレクトリにpackage.boxというファイルが出来る。 あとは工程1の時に行ったのと同じようにbox add [Box名][ファイル名**]とすることで自分で作成したBoxを新たに追加することができる。

Boxを追加した後の使い方は今までと同じ。(initで仮想マシンを作成、upで立ち上げ)

node.jsを始めました。

node.js

最近作りたいものがなくていろいろとやってたけど、"node.js"でやりたいことができたので暫くこれで記事更新ができるといいな。。。 とりあえず環境設定から

nvmインストール

"node.js"を始めようとして調べてたら"python"とか"ruby"とかでもあったように"nvm"というバージョン管理ツールを見つけたのでこいつを使ってバージョン切り替えが出来るようにしよう!!

homebrewで"nvm"は入れることが出来るようなので早速実行

brew install nvm

インストールに成功したようなので早速実行

nvm

(;゚ Д゚) …!?

(つд⊂)ゴシゴシ

(;゚ Д゚) …!?

command not found: nvm

homebrewで入れたのにコマンドがない言われる。なぜじゃ。。。 先に"node.js"をインストールしているとダメみたいな記事を見つけたりしたので uninstallを試したけど入ってないよ的なエラーで怒られた。。。 調べてもエラーの原因は見つからずにgitから直でDLして起動みたいな記事をよく見つけたのでそちらに切り替え

brew uninstall nvm # ひとまずbrewで入れたnvmを削除
git clone git://github.com/creationix/nvm.git ~/.nvm # gitリポジトリからnvmをDL
source ~/.nvm/nvm.sh

で起動する形にしたら無事成功!!(ちょっと疑問が残るがひとまずは無視して先に)

node.jsインストール

これで"nvm"コマンドが利用可能になったので今度こそ"node.js"をインストールしていく。 せっかくバージョン管理ツールを入れたので、適当にいれないでちょっとバージョンを確認指定して入れてこう

nvm ls-remote

このコマンドで現在インストール出来る"node.js"のバージョン確認ができる。 ※ちなみに、Node.jsはバージョン番号が偶数が安定バージョン、奇数は開発バージョンである なので今回は v0.10.32 を入れていこう。

nvm install 0.10.32 # node.jsをインストール
nvm use 0.10.32  # 使用するバージョンの指定

これで"node.js"のインストールが完了して使用準備ができた。

node -v

でバージョンの確認ができる。

環境構築完了!!

注意点

今回やった方法だとhomebrewを利用していないのでこのままだとターミナルで新規ジョブなどを立ち上げると、nvmの起動ができないので少し面倒。 ".zshrc"などに source ~/.nvm/nvm.sh を追加するなどして新規ジョブ立ち上げる時に自動でnvmが立ち上がるようにしてやったほうが良さそう


※2014年11月9日追記

nvmにaliasを設定する

.zshrcなどシェル設定ファイルにnvmを自動起動する設定を書いたほうが良いと書いたが、これだけだと少し足りなかった。 nvmが自動で立ち上がってもnodeのデフォルトバージョンが指定されて居ないようで新規でシェルを立ち上げてもnodeコマンドが見つからなかった。 そのためnvmのコマンドでnodeのデフォルトバージョンを指定を行う。

nvm alias default [version]

とすることでデフォルトバージョンの指定ができる。 こうしておくことで新規ジョブ立ち上げ時にnvmとnode両方の利用が可能になる。

pythonで画像編集

python

pythonで画像合成を行う場合pillowとうモジュールが楽だった。 ※Pillowは、Pythonの画像処理ライブラリで、Python Imaging Library (PIL)のforkプロジェクトです。 まあPILからして知らないわけですが。。。。

pip install pillow

でモジュールの追加!!

画像合成

layer1 = Image.open( 'image1.png' )
layer2 = Image.open( 'image2.png' )

layer1.paste( layer2, ( 0, 0 ), layer2 )

Image.openで画像を読み込む→Image.pasteで指定した画像を上に貼り付けることができる。 第2引数は座標を指定してやる、第3引数のmaskはいまいちわからないのでひとまず無視。

これで画像の合成事態は出来るのだがアルファ情報を持っている画像をpasteで合成する場合完全に上書きされているのがアルファが変な結果になって期待通りの合算を行ってくれなかった。

アルファ付きの画像合成

layer1 = Image.open( 'image1.png' )
layer2 = Image.open( 'image2.png' )

result = Image.alpha_composite( layer1, layer2 )

とやることで期待通りの結果になってくれた。

画像の保存

上記の方法で画像を作成しても結局保存出来なければ何も意味がないわけで画像を保存する場合

layer1 = Image.open( 'image1.png' )
layer2 = Image.open( 'image2.png' )

result = Image.alpha_composite( layer1, layer2 )
result.save( 'output.png' )

Image.save( 保存ファイル名 )とすれば保存を行える。

その他

機能的には他にもピクセル操作、リサイズ、回転などいろいろなことができるので結構便利そう コレ使えば設定ファイルと連携しての画像合成ツールとして優秀なのが作れそうで少し楽しみ

関数テーブル

C++

if文はそこまで嫌いではないのだが、switchはとても嫌いだ。 というのもswitchを使うときは大抵その関数が大きくなるからだ!!(自分の書き方的な所もあるのだろうが) だからといってswitchをif文に変えれば嫌いじゃなくなる!! というわけでもない。 結局のところ関数の大きさによってはif文だろうがなんだろうが嫌いになるわけで。。。

こういった条件分岐により関数が大きくなる場合は各条件の内容を全て関数にして関数テーブルを利用することで1関数のサイズを小さく保ってやる。

[func03.cpp]はメンバ関数ポインタを利用しての実装

[func11.cpp]はC++11で追加されたstd::function・std::bindを利用しての実装

両方とも各関数を配列の中に格納し、インデックスで各関数を呼び出すことができる。 見てわかるように[func03.cpp]は呼び出し時に特定のインスタンスに対して関数の呼び出しを行っているのがコードを見るとわかるが、[func11.cpp]のテーブル作成時にインスタンスに対して束縛しているためただ関数を呼んでいるようにみえる。(この様に見せない記述方法もあるけど) [func11.cpp]の場合特定のクラスに対して紐付いているわけではないので、戻り値と引数さえ一致していればどんな関数でも入れることができる。

pythonでのデータ型

python

タプル

タプルは複数の要素から構成される。 初期化後に内包する値に対して変更することができないimmutableなコレクションとなる

python_tuple = ( "year", "month", "day", 1, 3 )
print( python_tuple )

タプルで要素に対してアクセスする場合は配列と同じようにindexを指定してアクセスする

print( python_tuple[0] )
print( python_tuple[1] )
print( python_tuple[2] )

タプルの内包要素数はlen関数で調べることが可能

print( len( python_tuple ) )

リスト

リストはタプルと同じように複数の要素から構成される。 リストはタプルと違い内包する値に対して変更を行うことが可能なmutableなコレクションとなる

python_list = [ "year", "month", "day", 1, 3 ]
print( python_list )

各要素のアクセスや要素数はタプルと同じように行える

print( python_list[0] )
print( python_list[1] )
print( python_list[2] )
print( len( python_list ) )

リストの末尾に要素を追加する場合list.append関数を使用する

python_list.append( "time" )
print( python_list )

リストの末尾に複数の要素を追加する場合list.extend関数を使用する

python_list.extend( [1, 2, 3, 5] )
print( python_list )

リストから要素を取り出す場合list.pop関数を使用する

popValue = python_list.pop( 2 )  #指定したindexの要素の値を取り出す
print( python_list )
print( "popValue =" + str( popValue ) )

popValue = python_list.pop()  #引数を指定しない場合末尾から取り出す
print( python_list )
print( "popValue =" + str( popValue ) )

リストから要素を削除する場合list.remove関数を使用する

python_list.remove( "year" )
print( python_list )

ディクショナリ

リスト・タプルと同じ様な構造ではあるが、キーと値がセットで内包されている

ディクショナリの宣言方法

python_dict = { "year" : 2013, "month" : 3, "day" : 31 }
print( python_dict )

ディクショナリ型ではタプル・リストのようにindexでのアクセスをする場合は keyを配列の演算子に指定してやる

python_dict = { "year" : 2013, "month" : 3, "day" : 31 }
print( python_dict["year"] )
print( python_dict["month"] )

要素に対してアクセスする場合はdict.get関数を使用することでも取得できる

python_dict = { "year" : 2013, "month" : 3, "day" : 31 }
print( python_dict.get( "day" ) )
print( python_dict.get( "ddd", "NON" ) ) #キーが見つからなかった場合第2引数を返す

素数はタプル・リストと同じように行える

python_dict = { "year" : 2013, "month" : 3, "day" : 31 }
print( len( python_dict ) )

ディクショナリに要素を追加する場合dict[key] = valueと キーに対して代入をするようにすれば追加される

python_dict = {}
python_dict["year"] = 2013
python_dict["month"] = 3
python_dict["day"] = 31
print( python_dict )

C#でUnixTimeを扱う

C#

C#では時間計算をする際にDateTimeクラスを利用する。 DateTimeクラスではUnix時間を習得をすることができない。 そのためC#でUnixTimeを利用する場合utcから算出する必要がある.

UnixTimeは開始はUTCで1970年1月1日0時0分0秒から計算開始なので 現在のUTCからUnixTimeを引くことで現在時刻のUnixTimeを得ることができる。 ただUnixTimeから日本での時間を算出する際は指定時間のUnixTimeに対してUnixTimeの開始時間を換算するだけだとUTCでの時間で表現されるので日本時間にはならない。 そのためUTCから9時間(日本はUTC+9のため)進めてやる必要があるがDateTimeクラスに内部で計算をしてくれるメソッドがあるのでそれを利用して日本時間にしてやればいい。

C#でのUnixTime

C#での型変換

C#のキャストで詰まった所があったので忘れないように書いておこう。


C#の型変換は暗黙的変換と明示的変換の2つがある。

暗黙的型変換

変数に対して別の型の変数を代入すると自動的に型を変換してくれる機能。

int a = 10;
long b = a;
float c = 10.0f;
double d = a;

このように普通に代入式を書いてやるだけで int → long float → double へと変換を行ってくれる。

ただ、暗黙的変換は変換後に情報が失われない場合にのみ可能という条件がつく。 例えば

long a = 10;
int b = a;
double c = 10.0;
float d = c;

64bit整数→32bit整数への変換を行った場合コンパイルエラーになる。

明示的型変換

暗黙的変換で変換できない場合はこちらの明示的型変換を使用してキャストをしてやる必要がある。 暗黙的型変換でエラーになるコードも

long a = 10;
int b = (int)a;
double c = 10.0;
float d = (float)c;

この様に「(変換後の型)変数名」という式にすることで変換を行うことができる。

※だからといってなんでも変換出来るわけではなく文字列型から値型などの無理な変換は行うことはできない。


ここまでは大まか知っていたが今回詰まったのは※で書いたなんでも変換出来るわけではない部分でどういった変換が可なのか不可なのかを知らなかったので発生した。

minijsonを利用してパースされたデータ取り出そうとした際にfloat型に変換しようとした際に[System.InvalidCastException]となってしまった。 minijsonでは値を全てobject型で保存してありobject型から型変換を行う際は明示的型変換でも変換が行えず例外になっていた。

object a = 1.0;
float b = (float)a;  // InvalidCastException

object型のデータを変換する場合元の型(minijsonの少数データならdouble型)に一度変換を行った後に変換を行ってやる必要がある。

プリミティブ型であればobject型から変換する場合であればConvertクラスを利用することで変換を行うことができる。

double型→object型→float型に変換したい場合は下記のようになる。

object a = 1.0;
float b = System.Convert.ToSingle( a );