忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2026/03/31 09:34 |
今週の実績 2011/07/17
2011/07/15の実績

Test Drive Unlimited 2

ひとつずつ 30
各タイプの車を所有(A7-A6-A5-A4-A3-A3-A1、C4-C3、B4-B3)

イベントコンプリート 40
イベントをすべて達成

2011/07/14の実績

Test Drive Unlimited 2

チーズ! 10
ゲームモード、スピードトラップでレーダーに100回計測される

2011/07/13の実績

Test Drive Unlimited 2

レーシングスクールマスター 20
すべてのライセンスを取得

なにこのスクラップ? 5
トレジャーハントでボーナスカー1台を入手

2011/07/10の実績

Test Drive Unlimited 2

カンガルー 20
任意のゲームモードで100m(109ヤード)ジャンプ
PR


2011/07/17 17:43 | Comments(0) | TrackBack() | 実績
PHP5.3 Services_JSONで数値をデコード
<?php
	require_once('Services/JSON.php');
	
	$data = '{"hoge" : 12345678901234567890}';
	$json = new Services_JSON();
    $decode = $json->decode($data);
    
	var_dump($decode->hoge);
float(1.2345678901235E+19)

値が数値となっているJSONデータをServices_JSONでデコードすると結果が浮動小数となり、元のJSONデータが無くなってしまいます。

仕方ないので無理矢理文字列型でデコードできないのかと思えばできません。
数値をパースしているのはServices/JSON.phpの600行目あたり、if (is_numeric($str))の分岐内です。

処理はどうなっているかというと
if (is_numeric($str)) {
    return ((float)$str == (integer)$str) ? (integer)$str : (float)$str;
}
と見事に割り込む余地が無く、integerに入りきればint型、長い数値は自動的にfloat型になってしまいます。
数値だとしても正確な値がほしいんだよ、という場合は無理矢理継承するかソースを直接編集するしかありません。

Services/JSON.php
	//メソッドひとつ追加
    function setDecodeMode($decodeMode = false){
		if(isset($this->decodeMode) && $this->decodeMode){
			$this->decodeMode = $decodeMode;
		}
	}

	//Services_JSON::decode()の中を一部修正
		if (is_numeric($str)) {
			//デコードモードが指定してあれば
				if($this->decodeMode){
					if($this->decodeMode === SERVICES_JSON_IN_STR){
						return $str;
					}
				}
			// Return float or int, as appropriate
				return ((float)$str == (integer)$str)
				? (integer)$str
				: (float)$str;
		}
setDecodeMode(SERVICES_JSON_IN_STR)を呼べば数値型の場合でも文字列で返ってきます。 
<?php
	require_once('Services/JSON.php');
	
	$data = '{"hoge" : 12345678901234567890}';
	$json = new Services_JSON();
	$json->setDecodeMode(SERVICES_JSON_IN_STR);
    $decode = $json->decode($data);
	
	var_dump($decode->hoge);
実はSERVICES_JSON_IN_STRとかは元々Services_JSON内で別の意味で使用されている定数なので、あまりこういう使い方はするべきではないのですが、まあいいや。
ていうか、いいかげんPearもクラス定数使うべき。

実行すると、
string(20) "12345678901234567890"
となり無事に元の値を復元できました。
この場合元の"hoge"が数値型だったという情報は失われてしまうのですが、型が失われるのと値が失われるのとどちらがいいと言われたら前者ではないかと。


// Lookie-loo, it's a number
// This would work on its own, but I'm trying to be
// good about returning integers where appropriate:

とか書いてあるので中の人も微妙って思ってるのかね?


2011/07/16 01:22 | Comments(0) | TrackBack() | PHP
PHP5.3 PHPからMongoDBを使う
前回MongoDBをインストールしましたので、次はPHPから利用してみます。
まず必要なのはphpinfo()。

見るのはPHPのバージョンとCompiler欄。

何に使うかってインストールに必要です。
http://jp2.php.net/manual/ja/mongo.installation.php#mongo.installation.windows
何故かやたら細かくバージョンが分かれてるんですよね。

https://github.com/mongodb/mongo-php-driver/downloads
Gitから執筆時点での最新版、mongo-1.1.4.zipをダウンロードしました。
解凍するとバージョンがいっぱい出てきますが、手元のCompilerは「MSVC6 (Visual C++ 6.0)」となっていたので、「mongo-1.1.4-php5.3vc6ts」を選択しました。
中にあるphp_mongo.dllをエクステンションディレクトリにコピー。

次にphp.iniを編集。
extension=php_mongo.dll
って追加するだけです。

最後にApacheを再起動。

これだけでMongoDBが使用できるようになります。

早速実験。
<?php
	//接続
		//Mongo
		$mongo = new Mongo();
		//データベース
		$db = $mongo->selectDB("test");
		//コレクション
		$collection = $db->selectCollection("collect_test");
	
	//インサート
		$collection->insert(array('a'=>'hoge', 'b'=>'fuga'));
		$collection->insert(array('a'=>1, 'c'=>array('foo','bar','baz')));
	
	//セレクト
		$cursol = $collection->find();
		foreach($cursol as $key=>$val){
			var_dump( $val );
		}
コレクションはRDBMSでいうところのテーブルみたいです。
インサートのところでありえない渡し方をしていますが、結果どうなるかというと。
array(3) {
  ["_id"]=>
  object(MongoId)#7 (1) {
    ["$id"]=>
    string(24) "4e0401a5488316e413000004"
  }
  ["a"]=>
  string(4) "hoge"
  ["b"]=>
  string(4) "fuga"
}

array(3) {
  ["_id"]=>
  object(MongoId)#8 (1) {
    ["$id"]=>
    string(24) "4e0401a5488316e413000005"
  }
  ["a"]=>
  int(1)
  ["c"]=>
  array(3) {
    [0]=>
    string(3) "foo"
    [1]=>
    string(3) "bar"
    [2]=>
    string(3) "baz"
  }
}
普通に取得できました。

・ユーザやパスワードを指定していないのにいきなり接続できた
・CREATE DATABASE testしてないのにいきなりtestデータベースを取得できた
・CREATE TABLE collect_testしてないのにいきなりcollect_testテーブルにインサートできた
・型が違うデータを同じ列に挿入できた
・それどころかレコード毎に列が合っていないでーたも同じテーブルに挿入できる

なんなんだこれは。
今までのRDBMSの常識が全く通用しません。


使用上の注意点といえば、やはりCREATE TABLE文などがない点でしょうか。
これによって任意のデータを登録しやすくなったかわりに、後先考えずに使っていると半端なくカオスなデータベースになってしまいそうです。
実際上で作ったcollect_testテーブルは、早くも使い物にならなそうな構造になっています。
NoSQLを使うにあたってはRDBMS以上の自制が必要になりそうな気がしないでもない。


で、これアクセス制御とかどうすればいいんですかね?


2011/07/11 20:43 | Comments(0) | TrackBack() | PHP
買ったものリスト 2011/07/10
結局地球防衛休暇取ってしまった。
EDF!EDF!

………肝心のEDFIAの出来ががっかりだった。


iKILL 渡辺 浩弐
☆☆☆☆

イキル……生きる!
なんてポジティブなんだ!

などと思えばいつもの渡辺節が炸裂するI kill小説でした。

しかしどう考えてもあんなセキュリティではすぐ捕まるとしか思えないんだがな。

ところで渡辺浩弐が訊くVol2はまだですか。


プラスティック 井上 夢人
☆☆☆☆

最初の数十ページ読んでこういうことなんだろうなあと思ったら、予想の数歩前を行く展開でした。
推理の方向性自体は正しかったのですが、それを考えた時点で停止してしまって、そこから先がどのようなことになっているのかまで考えが至りませんでした。
最後のページが実に見事な作品です。


カミオロシ―縁結びの儀 御堂 彰彦
☆☆

ミステリだと思ってたら超常現象じゃねえか。
超常的な展開に最終的には論理的解決が行われるのかと思いきやそのまんまでした。
あと最初の伏線が投げっぱなのはなんなんだ。

まあミステリ読みとしての評価だからこんなものですが、ホラー好きであればもしかしたら面白いのかもしれません。


ITサービスマネージャ「専門知識+午後問題」の重点対策〈2011〉 粕淵 卓

DBも終わったことだし秋は何を受けようかな、と見てみたらなにげにITサービスマネージャとITストラテジストしか残っていなかった。
どちらもあまり馴染みのないジャンルなんだが、そういえば昔4年くらい前にITILファウンデーションを取ったなあということを思い出したのでITサービスマネージャを狙うことにした。
果たしてどうなる?


EARTH DEFENSE FORCE: INSECT ARMAGEDDON

………やっぱり外人には地球防衛軍はわからんか。

とりあえず画面が暗く、よくある洋FPSな見た目になってしまっています。
敵が近くにばらばらと湧いて出るため、「大地は巨大生物で、埋め尽くされています」がありません。
まだ1-3までしかプレイしてないんですが、その時点でもはや相当やる気が出ません。


2011/07/10 18:24 | Comments(0) | TrackBack() | 買ったもの
今週の実績 2011/07/10
2011/07/09の実績

Test Drive Unlimited 2

重労働 10
F.R.I.M.の最大レベル(10)で預ける

2011/07/08の実績

メモリーズオフ ゆびきりの記憶

ハッピーバースデー織姫 3
織姫の誕生日にゲームをした。

Test Drive Unlimited 2

イビサカメラマン 10
イビサで5箇所の撮影ポイントで撮影

浪費家 50
$1,000,000使う

ドライブでリッチに 25
$1,000,000所有

キング オブ イビサ 25
イビサカップ、エリア1に勝利

2011/07/07の実績

EDF: Insect Armageddon

アマチュア・アリキラー 5
100?そんなの朝飯前!

2011/07/05の実績

Test Drive Unlimited 2

ロードイーター 10
1000km(621マイル)走破


2011/07/10 18:21 | Comments(0) | TrackBack() | 実績
PHP5.3 WindowsにMongoDBをインストール
MongoDBってなんだ?

http://ja.wikipedia.org/wiki/MongoDB
> MongoDBは従来の関係データベース管理システムでは簡単に解決できない多量のトランザクション処理が要求されない問題に対し設計されている。

意味逆じゃないか?

いつものことながらWikipediaの表現は全く要領を得ませんが、MongoDBはNoSQLです。
NoSQLとは、RDBMSが持っているACID特性を一部犠牲にして、性能やスケーラビリティを確保したデータベースらしいです。
サーバを追加してちょっと設定をいじるだけでふたつのサーバにデータが分散して登録されるとか、DBやテーブルを作らないでいきなりインサートできるとか、そんなようなこれまでのRDBMSではありえない使い方ができるみたい。
CREATE DATABASEするまえに容量までも指定しとかないといけないOracleなどとは対極の存在と言えましょう。

ということでローカルPCのXAMPPにNoSQLを導入してもスケーラビリティの恩恵とかこれっぽっちもないような気がするんですが、まあとりあえず試してみます。

公式サイトからダウンロード、解凍、C:\xampp\mongodbに移動。

DBを設置するフォルダ「C:\xampp\mongodb\data\db」を作成。

コマンドプロンプトから以下を実行
>mongod --install --logpath D:\xampp\mongodb\log.txt --dbpath D:\xampp\mongodb\data\db

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

お?
ググったらC++ランタイムエラーだとか。
でもインストールし直しても変わらず。
よく見てみたらパスが存在しないDドライブだったとかいう。
エラーメッセージだけでは全然わからないので気をつけよう。

>mongod --install --logpath C:\xampp\mongodb\log.txt --dbpath C:\xampp\mongodb\data\db

all output going to: C:\xampp\mongodb\log.txt
Creating service MongoDB.
Service creation successful.
Service can be started from the command line via 'net start "MongoDB"'.


インストールできました。

サービスを起動
>net start "MongoDB"

起動したら、せっかくなのでコマンドをバッチファイルにしておきましょう。
といっても単にコマンドをmongostart.batとかの名前で保存するだけです。
あとはスタートメニューにでも入れておけば好きなときに起動できます。


サービスが起動したら接続してみます。

>mongo

MongoDB shell version: 1.8.2
connecting to: test
>


何もしてないのにあっさり繋がりおった。
ユーザ作成とか権限とかはどうなってんの?


2011/07/08 21:44 | Comments(0) | TrackBack() | PHP
Dojo1.6.1 dojo Dojo道場09 dojox.charting.Chart2Dのその他のメソッド
前回の続き。

記事では紹介だけに留められている悲しいメソッドたちを簡単に使ってみます。
http://codezine.jp/article/detail/5572?p=3
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	
	<style type="text/css"> 
		@import "dojo/resources/dojo.css";
		@import "dijit/themes/claro/claro.css";
	</style>
	
	<script type="text/javascript" src="dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
	<script type="text/javascript">
		dojo.require("dojox.charting.Chart2D");
		dojo.require("dijit.form.Form");
		dojo.require("dijit.form.RadioButton");
		dojo.require("dojox.charting.themes.Charged"); 
		
		//グローバルにする
		var myChart;
		
		//ランダムな値の配列を作成
		function getRandArray(count){
		    if (count == undefined) { var count = 12; }
			var retArr = new Array();
			var i=0;
			while(i<count){
				retArr.push(Math.floor(Math.random() * 1000));
				i++;
			}
			return retArr;
		}
		
		var drawChart = function(){
		
			//折れ線グラフ
				myChart = new dojox.charting.Chart2D("myChart");
				myChart.addPlot("plot1", {type: "Lines"});
				myChart.addPlot("plot2", {type: "ClusteredColumns", vAxis: "right"});
				myChart.addAxis("x", {majorTickStep: 1, natural: true});
				myChart.addAxis("y", {vertical: true});
				myChart.addAxis("right", {vertical: true, leftBottom: false, fixUpper: "major", includeZero: true}); 
				myChart.addPlot("grid", {type: "Grid"});
				myChart.addSeries("series1", getRandArray(), {plot: "plot1"});
				myChart.addSeries("series2", getRandArray(), {plot: "plot1"});
				myChart.addSeries("series3", getRandArray(), {plot: "plot2"});
				myChart.setTheme(dojox.charting.themes.Charged);
				myChart.render();
				
		}
		
		//拡大縮小
			var resizeChart2DToggle = 0;
			var resizeChart2D = function(){
				resizeChart2DToggle = 1 - resizeChart2DToggle;
				
				if(resizeChart2DToggle == 1){
					myChart.resize(500, 300);
				}else{
					myChart.resize(400, 200);
				}
			}
		
		//値の更新
			var updateSeries = function(series, span){
				myChart.updateSeries("series1", getRandArray(span));
				myChart.updateSeries("series2", getRandArray(span));
				myChart.updateSeries("series3", getRandArray(span));
				myChart.render();
			}
		
		//Plotの順番入れ替え
			var movePlotToFrontToggle = 0;
			var movePlotToFront = function(){
				movePlotToFrontToggle = 1 - movePlotToFrontToggle;
				myChart.movePlotToFront("plot"+(movePlotToFrontToggle+1));
				myChart.render();
			}
		
		//Seriesの順番入れ替え
			var moveSeriesToFrontToggle = 0;
			var moveSeriesToFront = function(){
				moveSeriesToFrontToggle = 1 - moveSeriesToFrontToggle;
				myChart.moveSeriesToFront("series"+(moveSeriesToFrontToggle+1));
				myChart.render();
			}
		
		//削除
			var removeSeriesToggle = 0;
			var removeSeries = function(){
				removeSeriesToggle = 1 - removeSeriesToggle;
				
				if(removeSeriesToggle == 1){
					myChart.removeSeries("series1");
					myChart.removeSeries("series2");
					myChart.removeSeries("series3");
				}else{
					myChart.addSeries("series1", getRandArray(), {plot: "plot1"});
					myChart.addSeries("series2", getRandArray(), {plot: "plot1"});
					myChart.addSeries("series3", getRandArray(), {plot: "plot2"});
					myChart.render();
				}
			}
		
		//起動時実行
		dojo.addOnLoad(drawChart);
		
	</script>
</head>
<body class="claro">
	<form dojoType="dijit.form.Form">
	  <input type="radio" dojoType="dijit.form.RadioButton" onClick="resizeChart2D()" name="span" id="formButtonResizeChart2D" /> 
	  <label for="formButtonResizeChart2D">拡大/縮小</label>
	  <input type="radio" dojoType="dijit.form.RadioButton" onClick="updateSeries('series1', 12)" name="span" id="formButtonUpdateSeries"/> 
	  <label for="formButtonUpdateSeries">値の更新</label>
	  <input type="radio" dojoType="dijit.form.RadioButton" onClick="moveSeriesToFront()" name="span" id="formButtonMoveSeriesToFront"/> 
	  <label for="formButtonMoveSeriesToFront">Seriesの順番入れ替え</label>
	  <input type="radio" dojoType="dijit.form.RadioButton" onClick="movePlotToFront()" name="span" id="formButtonMovePlotToFront" /> 
	  <label for="formButtonMovePlotToFront">Plotの順番入れ替え</label>
	  <input type="radio" dojoType="dijit.form.RadioButton" onClick="removeSeries()" name="span" id="formButtonRemoveSeries" /> 
	  <label for="formButtonRemoveSeries">Series削除/戻す</label>
	</form>

	<div id="myChart" style="width: 400px; height: 200px;"></div>
	
</body>
</html>


2011/07/04 22:24 | Comments(0) | TrackBack() | JavaScript
買ったものリスト 2011/07/03
今週は地球防衛休暇を取るべきか悩み中。


歯と爪 ビル・S・バリンジャー
☆☆☆

この袋とじを読み進めれば、まさかのどんでん返しが…大どんでん返しが…
……あれ?

いやいや、予想通りというかあらすじそのまんまじゃないですか。

袋とじにしなければならないほどのトリックかと言われると全然そうではありません。
ストーリーそのものは実に面白いので、売り方を間違った作品と言えましょう。


絶対☆霊域2 吉辺 あくろ
☆☆☆☆☆

一巻のラスであんだけ引っ張っておいてそんなオチとは…見事に引っかかった。
ぶっちゃけヒナちゃんがかわいいだけの漫画なのでストーリーはあってないようなものですが、ヒナちゃんがかわいいのでそんなことはどうでもよし。
本気で兄を捜すなら大家に行くなり色々手立てはあると思うのですが全然行っている様子はありません。
ていうか、後藤ってどうやって生計立ててるんだったっけ。


シューティングゲームサイド Vol.2
☆☆☆☆☆

Vol1を買ったとき、どう考えてもネタ不足で一発で終わりだろう、と思ってたらまさかのVol2発売。
しかもやたら分厚くなってます。

巻頭特集はグラディウスとSNK。
新作特集という名の360STG特集
開発者インタビューもたっぷり。
最後に少しだけ同人STG特集。

読み応えたっぷりなのでシューターおよびオールドゲーマーは抑えておきましょう。
まあオトメXを大々的プッシュしているのは非常に違和感があるのですが。


ファミ通XBOX360 2011年8月号
☆☆☆☆

E3特集に数多くの新作発表と、今後のスケジュールが楽しみになります。
ただ発売日未定とか何ヶ月も先の発売予定とかばかり紹介されても「今」遊べないので、発売済ソフトを紹介するコーナーがあってもいいと思うんだ。

さていよいよEDF:IAの発売ですが、やはり開発が海外と言うことで地球防衛軍シリーズ特有のチープさと無駄な熱さが失われるのではないかというのが心配されるところ。
しかし開発者インタビューを読む限りではそのような心配は不要そうです。
まあもちろん、実際どうなってるかはプレイしないとわかりませんけどね。


テストドライブ アンリミテッド2

イビザ島、およびオアフ島をどこまでも、文字通りどこまでも走り回れるというとんでもない規模のドライブゲーム。
とりあえず現在500キロくらい走ったとは思うんだけど、マップがまだ全然埋まっていないとかそんなレベルの大きさです。
単にドライブしているだけでも、どこまでも知らない景色が現れて楽しい作品です。

ひとつ問題点として、本作ではライセンス制が導入され、テストに受からないとそのランクのレースに出場できなくなりました。
前作のフリーダムさが薄れてしまっているのが残念。


2011/07/03 18:33 | Comments(0) | TrackBack() | 買ったもの
今週の実績 2011/07/03
2011/07/02の実績

Test Drive Unlimited 2

アロハ! 20
ハワイに行く

ヘルパー 15
イベントを10回成功

ミニコレクション 5
違うタイプの車を3台所有

クルージング 5
200km(124マイル)走破

無謀なドライバー 10
CPU車と破壊できるオブジェクトに100回衝突する

2011/07/01の実績

Test Drive Unlimited 2

ビギナー 5
チャンピオンシップに勝利

ラーニング 5
C4ライセンスを取得

すてきなマイ・トレーラーハウス 5
家を1件所有(トレーラーハウス)

2011/06/30の実績

HALF-MINUTE HERO SMNC

はじめてのおいのり 30
シングルプレイヤーモードで初めて女神に祈りを捧げた

STEINS;GATE 比翼恋理のだーりん

黎明曙光のレシオ 50
萌郁のエンディングを見た


2011/07/03 18:21 | Comments(0) | TrackBack() | 実績
Dojo1.6.1 dojo Dojo道場08 dojox.charting.Chart2Dでズーム
前回の続き。

これまでdojoで作ってきたグラフは単に表示するだけでした。
いよいよグラフに対し動的な変化を与えてやりましょう。

dojox.charting.Chart2D.setAxisWindowメソッドでスケールの変更を行うことができます。
あとはその値を設定するインターフェイスを追加するだけです。
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<script type="text/javascript" src="../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
	<script type="text/javascript">
		dojo.require("dojox.charting.DataSeries");
		dojo.require("dojo.data.ItemFileWriteStore");
		dojo.require("dojox.charting.Chart2D");
		dojo.require("dijit.form.Form");
		dojo.require("dijit.form.RadioButton");
		
		//グローバルにする
		var myChart;
		
		var drawChart = function(){
			//ダミーのストア
				var store = new dojo.data.ItemFileWriteStore({data:{items:[{value: 0}]}});
			
			//折れ線グラフ
				myChart = new dojox.charting.Chart2D("myChart");
				myChart.addPlot("default", {type: "Lines"});
				myChart.addAxis("x", {majorTickStep: 1, natural: true});
				myChart.addAxis("y", {vertical: true});
				myChart.addPlot("grid", {type: "Grid"});
				myChart.addSeries("stockprice", new dojox.charting.DataSeries(store));
				myChart.render();

			//適当に値を設定
				var i=1;
				while(i<12){
					var val = Math.floor(Math.random() * 1000);
					store.newItem({value: val});
					i++;
				}
			
		}
		
		//クリックで拡大率変更
			var changeView = function(span){
				//オンであれば
				if(dijit.byId(span + "months").get("checked") == true){
					// 拡大率の計算
					var sx = (12 - 1) / (span - 1);
					// グラフの表示期間変更
					myChart.setAxisWindow("x", sx, 12 - span);
					myChart.render();
				}
			}
		
		//起動時実行
		dojo.addOnLoad(drawChart);
		
	</script>
</head>
<body class="claro">
	<form dojoType="dijit.form.Form"> 
	  <input type="radio" dojoType="dijit.form.RadioButton" onChange="changeView(3)" name="span" id="3months"/> 
	  <label for="3months">3ヶ月</label> 
	  <input type="radio" dojoType="dijit.form.RadioButton" onChange="changeView(6)" name="span" id="6months"/> 
	  <label for="6months">6ヶ月</label> 
	  <input type="radio" dojoType="dijit.form.RadioButton" onChange="changeView(12)" name="span" id="12months" checked/> 
	  <label for="12months">1年</label> 
	</form> 

	<div id="myChart" style="width: 400px; height: 200px;"></div>
</body>
</html>


2011/07/01 21:57 | Comments(0) | TrackBack() | JavaScript

<<前のページ | HOME | 次のページ>>
忍者ブログ[PR]