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で画像合成を行う場合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( 保存ファイル名 )とすれば保存を行える。
その他
機能的には他にもピクセル操作、リサイズ、回転などいろいろなことができるので結構便利そう コレ使えば設定ファイルと連携しての画像合成ツールとして優秀なのが作れそうで少し楽しみ
関数テーブル
if文はそこまで嫌いではないのだが、switchはとても嫌いだ。 というのもswitchを使うときは大抵その関数が大きくなるからだ!!(自分の書き方的な所もあるのだろうが) だからといってswitchをif文に変えれば嫌いじゃなくなる!! というわけでもない。 結局のところ関数の大きさによってはif文だろうがなんだろうが嫌いになるわけで。。。
こういった条件分岐により関数が大きくなる場合は各条件の内容を全て関数にして関数テーブルを利用することで1関数のサイズを小さく保ってやる。
[func03.cpp]はメンバ関数ポインタを利用しての実装
[func11.cpp]はC++11で追加されたstd::function・std::bindを利用しての実装
両方とも各関数を配列の中に格納し、インデックスで各関数を呼び出すことができる。 見てわかるように[func03.cpp]は呼び出し時に特定のインスタンスに対して関数の呼び出しを行っているのがコードを見るとわかるが、[func11.cpp]のテーブル作成時にインスタンスに対して束縛しているためただ関数を呼んでいるようにみえる。(この様に見せない記述方法もあるけど) [func11.cpp]の場合特定のクラスに対して紐付いているわけではないので、戻り値と引数さえ一致していればどんな関数でも入れることができる。
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#では時間計算をする際に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#での型変換
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 );