2013年7月18日木曜日

php curl でちょっとはまった

phpのcurlを使って、バイナリデータを送る際ちょっとはまったのでメモ。

RestfulなAPIへxmlデータをサーバに送信する際、key無しで送信するためには、以下のように「file_get_contents」関数を使ってファイルデータを取得して、POST 送信する必要がある。


2013年7月17日水曜日

Virtual Box の vdi のUUIDを変更する。

複数のPC(特に同一ネットワーク上)でVirtual Boxのイメージを使いまわそうとする場合に出ることがあった。

UUIDの重複エラー。以下でUUIDを変更

"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" -nologo internalcommands sethduuid C:\VirtualBox_vdi\os.vdi
UUID changed to: ~

2013年7月6日土曜日

MongoDBの基礎

MongoDB

ドキュメント指向データベース NoSQL

パフォーマンス良い、スケーラブル良い→大量のデータを扱う

ドキュメント指向

カラムが固定されない=スキーマレス
 ユーザ、状況、データによって柔軟に変更可能

以下のような用語を使用する。()はRDBMSの用語

コレクション (Table)

ドキュメント (Record)

データ格納はJSON


ex)
[x, y, z] ←ただ値を格納したいとき
{"key":value, "key":value} ←keyとvalueの組で格納するとき 
{"key":value, "key":[x,y,z]} ←多重配列的に格納するとき

on Windows

Windowsでは、公式サイトからmongodbのバイナリzipを取得、解凍して、任意のディレクトリに
置いた後、以下のコマンドでdataを保存するディレクトリを指定してから使う。


> mongod --dbpath C:\mongodata\db\data

接続

> mongod

シェルでは JavaScript が使える。


データベース

show dbs:一覧表示

use [データベース名]:新しいデータベースの作成(これだけだとempty状態)

db.createCollection("コレクション名"):新しいコレクションを作成する

db.stats():一覧表示

db.dropDatabase();:データベースの削除


コレクション


db.createCollection("dictionary"); :dictionaryコレクション作成

db.createCollection("points"); :pointsコレクション作成

show collections :コレクションの一覧を見る

コレクションを操作したいときは、dbのあとの要素に操作したコレクションを「.」で結合する

db.points.drop(); :pointsコレクションを削除する

db.dictionary.renameCollection("textdic"); :deictionary コレクションの名前を textdic に変更


ドキュメント

mongodb textdic :textdicデータベースに接続

show collections :コレクションの一覧を見る

db.points.insert({["date":"vector", "word":"test1"}); :pointsコレクションにdate:vector、word:test1の要素をもつドキュメントを追加

スキーマレスなので、同じコレクションに大して、構造のドキュメントを追加する必要がない。

db.points.insert({"date":"vector","wordarray":["test2", "test3"]}); :pointsコレクションに上記とは違う構造のドキュメントを追加

db.points.find() :pointsコレクション内のドキュメント一覧

db.points.remove():pointsコレクション内のドキュメントを削除


大量のドキュメントの生成

JavaScriptが使える利点を使って、データを生成する。

ex)pointsコレクションにランダムな点データドキュメントをmod3でグループに分けて10点生成する。

> for (var i=0; i<10; i++) {
... db.points.insert(
... {"pointnum":i,
... "group":i % 3,
... "x":Math.floor(Math.random()*100),
... "y":Math.floor(Math.random()*100)
... }
... );
... }
結果を見る。

db.points.find()
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa12"), "pointnum" : 0, "group" : 0, "x : 5, "y" : 8 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa13"), "pointnum" : 1, "group" : 1, "x : 54, "y" : 45 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa14"), "pointnum" : 2, "group" : 2, "x : 47, "y" : 9 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa15"), "pointnum" : 3, "group" : 0, "x : 16, "y" : 31 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa16"), "pointnum" : 4, "group" : 1, "x : 84, "y" : 28 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa17"), "pointnum" : 5, "group" : 2, "x : 35, "y" : 71 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa18"), "pointnum" : 6, "group" : 0, "x : 8, "y" : 90 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa19"), "pointnum" : 7, "group" : 1, "x : 13, "y" : 53 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa1a"), "pointnum" : 8, "group" : 2, "x : 21, "y" : 11 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa1b"), "pointnum" : 9, "group" : 0, "x : 10, "y" : 63 }

ドキュメントの抽出

db.points.find():全件抽出
db.points.find({"group":0});:groupが0のもののみ抽出
db.points.find({"group":0}, {"pointnum":true});:gourpが0のものの、pointnumのみ抽出
db.points.find({"group":{$ne:0}}); :groupが0で無いもののみ抽出 $ne→not equals
db.points.find({"x":{$gt:5}});:xが5より大きい
db.points.find({"x":{$gte:5}});:xが5以上
db.points.find({"x":{$lt:5}});:xが5より小さい
db.points.find({"x":{$lte:5}});:xが5以下
db.points.find({"x":{$gt:5, $lt:30}});:xが5より大きく30より小さい

正規表現

db.points.find({"":{$regrex:/<正規表現パターン>/i}});:正規表現パターンに合致したものを抽出

ソート

db.points.find().sort({"score":1}); :scoreで昇順に取得、-1だと降順


件数制限

db.points.findOne(); :先頭から1件抽出
db.points.find().limit(3); :先頭から3件抽出
db.points.find().skip(2).limit(3); :添字2 (0開始) のドキュメントから3件抽出
db.points.find().count(); :抽出した件数


ユニークな値を取得

db.points.distinct("group"); :ユニークな値を抽出

包含関係

db.points.find({"group":{$in:[0 ,1]}}); :グループが0または1に含まれるものを抽出
db.points.find({"group":{$nin:[0 ,1]}}); :グループ0か1以外を抽出


存在

db.points.find({"group":{$exists:true}}); :groupが存在しているドキュメントのみ。

Index インデックス

> db.points.getIndexes(); 現在のインデックスを参照
[
        {
                "v" : 1,:
                "key" : {
                        "_id" : 1
                },
                "ns" : "textdic.points",
                "name" : "_id_"
        }
]
db.points.ensureIndex({"pointnum":1});:pointnumに昇順Indexはる、-1だと降順
db.points.ensureIndex({"pointnum":1}, {"unique":true}); :pointnumにuniqueな昇順Indexはる、
db.points.dropIndex({"pointnum":1}); :インデックスの削除

ドキュメントの更新

updateの引数:1つ目が抽出条件、2つ目が置き換えたい値

db.points.update({"pointnum": 2}, {$set:{"x": 2000}}); :pointnum2のドキュメントのxを2000に書き換える
db.points.update({"pointnum": 3}, {$inc:{"x": -10}}); :pointnum3のど球面とのxを-10する
db.points.update({"pointnum": 5}, {$unset:{"x":1}}); :pointnum5の要素xを削除する
db.points.update({"pointnum": 6}, {$rename:{"y":"z"}}); :pointnum6の要素のyの名前をzに変更

updateの引数:3つ目が「upsert」、あれば変更、なければinsert(3つ目をtrueにする)

db.points.update({"pointnum":"100"},{$inc:{"x":1000}}, true);

                                                     
updateの引数4つ目が「date更新件数」:4つ目がtrueだと全件に適用

db.points.update({}, {$inc:{"y": 3000}}); :最初の1件のみ
db.points.update({}, {$inc:{"y": 3000}}, false, true);

外部ファイルからコマンドを実行

方法1

コマンド を記述したファイルを用意。(JavaScriptなので拡張子はjsとする)

mongo [データベース名] [実行したいjsファイル]


方法2

mongoインタラクティブコマンドから実行

mongo [データベース名]で接続したら

load("[実行したいjsファイル名(windowsでは\を\\とすることに注意)]");

バックアップと復元

ダンプ

mongodump:バックアップを取得

コマンドの出力にバックアップバイナリファイルの出力先が出る。

mongodump --db textdic:

C:\Users\真宏>mongodump --db textdic
connected to: 127.0.0.1
Sat Jul 06 12:38:25.349 DATABASE: textdic        to     dump\textdic
Sat Jul 06 12:38:25.351         textdic.system.indexes to dump\textdic\system.in
dexes.bson
Sat Jul 06 12:38:25.353                  2 objects
Sat Jul 06 12:38:25.355         textdic.dictionary to dump\textdic\dictionary.bs
on
Sat Jul 06 12:38:25.357                  0 objects
Sat Jul 06 12:38:25.357         Metadata for textdic.dictionary to dump\textdic\
dictionary.metadata.json
Sat Jul 06 12:38:25.361         textdic.points to dump\textdic\points.bson
Sat Jul 06 12:38:25.361                  10 objects
Sat Jul 06 12:38:25.363         Metadata for textdic.points to dump\textdic\poin
ts.metadata.json

リストア

mongorestore --drop [dumpファイルの格納ディレクトリ]:元のデータをdropして、dumpから復元する



便利だが、はやく Json に慣れたい。

2013年7月3日水曜日

sage 基礎編

数理処理システム sage 


Mathmatica や Matlab の代わりを目指すオープンソース。

変数宣言

変数宣言しておくことで、以降の数式に利用出来る。
var('変数名')

複数宣言の場合、スペース区切り

var('変数名 変数名 …')

関数の宣言

[関数名] = [式]

ex)

f = (x - 3) * (4x - 5)

関数の計算

変数に値を代入して、関数を計算する。

[関数名]([変数] = [値])

ex)

f(x = 5)
戻り値は計算結果。


lambda式を使って関数を定義する

lambda 変数のリスト: 式

ex)

f = lambda x: x^3
f(2)
sageは 8 を出力する。


規則を代入する

定義した関数の一部を新たな関数で置き換えるなど

f6 = x^2 + 1;
f6

ここで、x^2 を y とすると、は以下の様に表現。

var('y')
f6.subs_expr(x^2 == y)


次は 図形 について、そして API についても早めにとりかかる。






数理処理システム sage の local sign in ができなくて困った

admin sage だった。 この情報がわかりづら!!

EXEファイルの仕組み

EXEファイルの構造

MZヘッダー、PEヘッダー、セクションヘッダー からなる。

  1. MZヘッダー:DOSヘッダー
  2. MZヘッダー:MS-DOS用スタブ
  3. PEヘッダー:シグネチャ
  4. PEヘッダー:ファイルヘッダー
  5. PEヘッダー:オプションヘッダー
  6. セクションデータ:セクションヘッダー1
  7. セクションデータ:セクションヘッダー2
  8. セクションデータ:…
  9. セクションデータ:セクション1
  10. セクションデータ:セクション2
  11. セクションデータ:…

DOSヘッダー

先頭はMZ。


MS-DOS用スタブ

This program cannot be run in DOS mode. を表示するプログラム


PEヘッダー

PEという2文字と2byte分の0からなるシグネチャが先頭。


セクションデータ

Windowsプログラム本体。いくつかのコード(命令)やデータのまとまり(セクション)に分けられている。
各セクションヘッダーの並びの後に、セクション本体が並ぶ。



EXEファイルの内容をダンプする


ダンプツール:dumpbin.exe → MZヘッダーを読み飛ばす。

以下のダンプ出力コードで、exeを作成すれば、すべて閲覧できる。



%02Xは16進数を表す%xに02: 最低2文字出力し、足りなければ 0 で埋める。と X: 大文字で表記を追加した書き方。
%08Xであれば、最低8文字で足りなければ0で、大文字表記。


上記をコンパイル&リンクすれば、良い。

cl dump.c
上記で作成した dump.exe でMZ(4D 5A)ヘッダも確認できる。 50 45 00 00 はPEヘッダー。


このダンププログラムは exe だけに使えるわけではなく、txt ファイルなどにももちろん使える。

たとえばある文字列が exe のヘッダに含まれていることを確認したければ、txt ファイルに文字列を
記述して dump した文字列が、exe のdump結果に含まれているか見ればよい。


PEヘッダーとセクションデータの内容

dumpbin /[オプション] EXEファイル名

FILE HEADER VALUES の number of sections の個数分、section ヘッダー があることを確認できる。

プログラム中に分散したコードやデータは、コードのセクションとデータのセクションにまとめれていることも確認できる。


セクションの内容を見る

dumpbin /rawdata EXEファイル名
RAW DATAのナンバーが、セクションナンバーの数だけある。


逆アセンブル

コマンド: dissm

dumpbin /disasm EXEファイル名

push や mov、call などから、callが関数、pushがそれに渡す引数のように使われていることがわかる。


簡単なプログラムを書いて、コンパイラがどのようにコードを整理するのか確認してみると
おもしろい

次は メモリーロード。






2013年7月2日火曜日