GDD2011のDevQuizにトライ。GAS編。
Googleが新しいサービスやツール、APIを発表するGoogle Developer Day 2011 Japanに参加するためのDevQuizに挑戦してみました。
8月後半〜9月初旬は仕事が決算時期で多忙な少し諦めていたのですが、なんとか仕事が落ち着いてきたので空いた時間を使ってのトライ。
と言ってもプログラムは素人同然な僕なので解ける問題は限られていたのですが、なんとかGoogleChrome拡張を利用した神経衰弱ゲームとGoogle SpreadSheetsを利用したGoogle Apps Script問題を解くことができました。
Go言語とAndroidアプリにもトライしたかったのですが時間が足りず断念。来年は問題発表時からトライしたいと思います。
問題
ある都市(複数)における日別の供給電力と最大消費電力に関する記録が以下のような JSON の形式で与えられます。 この記録を Google SpreadSheets 上に展開してください。
[
{
"city_name": "Oykot",
"data": [
{
"capacity": 1000,
"usage": 750,
},
{
"capacity": 1200,
"usage": 1000,
},
...
]
},
{
"city_name": "Akaso",
"data": [
{
"capacity": 1000,
"usage": 800,
},
...
]
},
...
]
上の例では、最初のオブジェクトには Oykot という都市における記録が含まれています。1 日目には 1000W の供給能力があり、ピーク時に 750W が消費されました。
実際のデータはこちらから取得できます。
以下の条件に従って、ひとつの Google Spreadsheets を作ってください。JSON 内の各都市ごとにシートを分けて生成していただくことになります。 条件は以下の通りです。
- シートの名前は都市名にしてください。上の例では、最左のシートの名称は「Oykot」とします。
- データは 1 行目の A 列目から順番に埋めます。ヘッダ(タイトル行)は付けないでください。
- n 行目の A 列に n 日目の供給電力(capacity)を入れます。
- n 行目の B 列に n 日目の消費電力(usage)を入れます。
- n 行目の C 列に n 日目の電力の消費割合を入れます。上の例の 1 日目では 1000W の供給力のうち 750W が消費されたので、セル C1 の値は 75.00% とします。 同様にセル C2 の値は 83.33%(1000 / 1200 = 0.8333...)になります。 小数点以下の桁数は問いませんが、値の誤差が 0.01 以内となるようにしてください。 たとえば、75.00% を 75% としたり、83.33% を 83.33333% としても差し支えありませんが、 83.33% を丸めて 83% とはしないでください。
作成したスプレッドシートは、gdd2011jp@gmail.com のアカウントと共有してください。
まずはJSON?なにそれ?Google Apps Script?なにそれ?という状態をクリアにすることが必要でした。
GASはExcelVBAをJavaScriptで書けるみたいなので、JavaScriptの構文とこの辺→Google Apps Script Documentationみながら書いたらなんとかなりました。
恥ずかしいけどソースUP。なにこのウンコ!氏ね!的なダメだし大募集です。
// JSONのURLを指定。
var url = UrlFetchApp.fetch("http://gdd-2011-quiz-japan.appspot.com/apps_script/data?param=5456926337828408576");
// JSONファイルを取得。
var json = Utilities.jsonParse(url.getContentText());
// スプレットシート準備
var Ss = SpreadsheetApp.getActiveSpreadsheet();
// スプレッドシートの既存シート数を把握
var Sn= Ss.getSheets().length;
//不要なシートをすべて削除。0シートにはできない。
for(var i=Sn -1;i>0;i--){
Ss.setActiveSheet(Ss.getSheets()[i]);
Ss.deleteActiveSheet();
};
for(var x=0; x<json.length;x++){
if (x == 0){
Ss.getSheets()[x].setName(json[x].city_name); //シート名をリネーム
Ss.setActiveSheet(Ss.getSheets()[x]);
Ss.getActiveSheet().clear(); //全データ削除
for(var c=0; c<json[x].data.length; c++) {
var range= Ss.getActiveSheet().getRange(1, 1);
range.offset(c, 0).setValue(json[x].data[c].capacity);
range.offset(c, 1).setValue(json[x].data[c].usage);
range.offset(c, 2).setValue((json[x].data[c].usage / json[x].data[c].capacity)*100);
range.offset(c, 2).setNumberFormat("0.00%")
};
}else{
Ss.insertSheet(json[x].city_name, x); //新シートを挿入
for(c=0; c<json[x].data.length; c++) {
range= Ss.getActiveSheet().getRange(1, 1);
range.offset(c, 0).setValue(json[x].data[c].capacity);
range.offset(c, 1).setValue(json[x].data[c].usage);
range.offset(c, 2).setValue(json[x].data[c].usage / json[x].data[c].capacity);
range.offset(c, 2).setNumberFormat("0.00%")
};
};
};
JSONの各階層のデータを取得するのに手こずりましたが、トライ&エラーでなんとか取得できました。
CSVやらXMLより扱いが簡単かもしれません。
この辺参考にしましたよっと。→ GAS(Google Apps Script)からATND APIにアクセスする。 - プログラマとSEのあいだ
次は神経衰弱ゲームのソースをUPする予定。こっちは作りかけなので恥ずかしいんですけどねw