まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

2018年08月

久しぶりに The Weather Company API を使ってみました。なお以下で紹介するサンプルのソースコードはこちらで公開しています:
https://github.com/dotnsf/twc_api

2018081400


使い方は Node.js が導入されているシステムに git clone(またはダウンロード&展開)して、npm install して、node app.js します。成功すると "server starting on XXXX ..." というメッセージが表示されます(この XXXX が動的に決まるポート番号です。以下の例では 6039 番):
$ npm install
$ node app.js
server starting on 6039 ...

ウェブブラウザで上記のポート番号を指定してサンプルアプリケーションに接続します。成功すると東京周辺の(OpenStreetMap の)地図が表示されます:
2018081401


2018/08/14 時点では、このサンプルアプリケーションで3つの The Weather Company API を試すことができ、それぞれ画面上部にある3つのボタンで実行可能です:
2018081402


一番左の "alertsByCoundryCode" ボタンは GET /v1/country/{countrycode}/alerts.json を countrycode = "US" で実行します。つまり "US"(アメリカ合衆国)で現在発生している天候に関する警報の一覧を取得します:
https://twcservice.mybluemix.net/rest-api/#!/Weather_Alerts/v1ccalertheadln


このサンプルアプリケーションでは上位30個の警報を取り出して、その発生位置にマーカーを置き、各警報の内容を参照できるようにしています:
2018081403
(↑この API は以前には存在してなかったような・・・)


真ん中の "currentConditions" ボタンをクリックすると、そのタイミングで地図の中心にある地点を座標を使って GET /v1/geocode/{latitute}/{longitude}/observations.json を実行します。地図の中心にある地点の現在の天候の様子を取得して表示するので、最初に地図をある程度スクロール(マウスドラッグでスクロールします)してから実行し、このサンプルアプリケーションではその情報の一部を表示します:
2018081404


一番右の "historicalData" ボタンをクリックすると、そのタイミングで地図の中心にある地点を座標を使って GET /v1/geocode/{latitute}/{longitude}/observations/timeseries.json を実行します。地図の中心にある地点の過去 24 時間の天候の移り変わりの様子を取得します。このサンプルアプリケーションでは過去 24 時間の気温の移り変わりを表示するようにしています:
2018081405


実装方法など、詳しくは Github 上のソースコードと、The Weather Company API の API Reference を参照ください。

BMXUG(IBM Cloud ユーザー会)の勉強会がきっかけで知り合いになる機会のあった MonAmie さんが今月出版した SF 小説、「H -アッシュ- 仮想通貨BLOODとAIになった歌姫」を読了しました:



近未来である西暦 2025 年、ブロックチェーンと AI の技術が普及した東京を舞台としています。この作品最大の特徴の1つ(と思っている)血液と交換可能な仮想通貨 "BLOOD" を巡るストーリーです。ここでは世の中のいたるところに AI が活用されていて、またそのセキュリティシステムにも話が及び、ひとりの IT エンジニアとして読んでいても興味深い内容でした。

感想として、まず何よりもこれを伝えたいのですが、血液という(現代の日本では法律でお金との交換が禁じられているものの)非常に高価なアイテムを電子的に取引する、というブロックチェーンのユースケースが非常にユニークであり、かつ技術的には実現が不可能と思えるほどでもなく、いろいろな意味で興味深い仕組みが描かれていました。「そうか、血液が扱えるなら○○だって・・・」とブロックチェーンの応用アイデアを刺激される内容でした。

次にこの小説の中では「ブロックチェーン」、「人工知能」、「セキュリティ」という IT の中でも比較的ホットな3つの分野がテーマとして描かれています。この3つの分野全てに精通したエンジニアの存在だけでも珍しいのではないかと思っていますが、(フィクションとはいえ)それらの近未来ユースケースと考えると IT の読み物としても先進的で面白いと感じる人が多くいるのではないかと思いました。

また西暦 2025 年の東京という舞台から見た、現在である西暦 2018 年がブロックチェーンや仮想通貨の黎明期として描かれていて(どこかで聞いたような流出事件が過去事例になっていたりして)、タイムリーな話題が物語の中で自然に取り込まれて紹介されていました。この点も面白く読み進められた理由だったと感じています。気の早い話かもしれませんが、次回作を読んでみたいと思いました。


ブロックチェーンに携わる機会のあるエンジニアや、ブロックチェーンで新しいビジネスを興そうと考えている人にとっては興味深い近未来のユースケースとしても是非読んでいただきたいと感じた一冊でした。


アナログな「手書きのボード」(イメージとしてはキングジムのブギーボード)をデジタル&ネットで提供できるようなアプリ: FreeBoard を作ってみました:
https://github.com/dotnsf/freeboard/


使い方を以下に紹介しますが、以下は IBM Cloud 上で動かすことを前提とした使い方です。アプリケーションサーバーを個人PCなどで動かすことは可能ですが、ちょっと手順が異なります(まあ自分でサーバーを動かそうと思うような人なら大丈夫だと思います)。ただしデータストアで IBM Cloudant (IBM Cloud の DBaaS)を使うので、IBM Cloud のアカウントは必須となります。


IBM Cloud を使って実際に動かすには Node.js ランタイムと IBM Cloudant サービスインスタンスを作成して、これらをバインドした状態で(或いは IBM Cloudant のユーザー名とパスワードを settings.js に記載した状態で)リポジトリから取得したソースコードをプッシュするだけです:
2018080601


作成したアプリケーションサーバーに PC またはスマートフォンのブラウザでアクセスします。以下のような画面になればとりあえず実行環境が作成できています(なお、以下のスクリーンショットは 2018/08/10 時点でのものです):
2018080701


画面中央の四角がキャンバス部分です。ブラウザのサイズを変更しても一定割合を計算しながらキャンバス部分のサイズも自動的に変更されます:
2018080702


キャンバス上部にある2つのセレクトボックスからペンの色と太さを選択します。このペンの色と太さはいつでも変更可能です:
2018080703


ペンが決まったらキャンバス部分に向かってマウスドラッグまたはタッチで自由に絵を描くことができます:
2018080704


途中でペンを変えることで多色で描くことができます。描き終わった画像を保存するには "save" ボタンをクリックします:
2018080705


画面最上部に日付時刻が表示されました。これは先程の画像がここに保存されたことを意味しています:
2018080708



"reset" ボタンをクリックするか、画面をリロードしてキャンバスをクリアします。その後でこの保存した画像の日付時刻部分をクリックして呼び出します:
2018080707


保存された画像が呼び出されてキャンバス内に表示されます:
2018080708


呼び出された画像に更に変更を加えることも可能です。変更後に改めて "save" をクリックします:
2018080709


保存画像が1つ追加されました。これで2つの画像が保存され、呼び出しが可能になっています:
2018080710


保存した画像を削除するには選択後に "delete" ボタンをクリックします:
2018080711


確認メッセージが表示されたあとに削除が実行されます。削除後、保存画像が(2つから)1つに減っていることがわかります:
2018080712


同じ画面をスマートフォンのブラウザから見ても同じように見えます(画面サイズは異なりますが・・)。スマートフォンの場合はタッチ操作で絵を描画できます:
2018080713


注意事項として、保存時の排他制御は行っていない点に注意ください。どちらかというと保存はおまけ機能のつもりで、でっかい画面で共有ホワイトボードとして使うようなイメージで作成しました。

なお、マウスドラッグやタッチ操作でキャンバスに描画する部分はすべて HTML5 と JavaScript だけで(サーバーサイド処理を使わずに)実現しています。この部分だけを切り出して別リポジトリで公開しているので、この部分に興味あるかたはこちらを参照ください:
https://github.com/dotnsf/html5pen


特に見た目に関してはまだまだ改善の余地があると思っていて、issue リストの先頭にも加えています。この辺りは自分の余裕時間と相談しながらぼちぼちと。


 

「エクセルファイルを扱えるライブラリ」といえば、Java であれば Apache POI などがありますが、Node.js ではどうだろう?? と思って調べてみました。その名もズバリの xlsx という npm ライブラリを見つけたので使ってみました:

npm - xlsx
https://www.npmjs.com/package/xlsx

2018080100


ライブラリ名は xlsx ですが、対応フォーマットは xls や XML に加えて ODS まで含まれていて、かなり柔軟に使えそうです。


【扱うサンプル】
こんな感じのエクセルファイルを用意して使うことにします:
2018080101


データとしては "A1:C14" の範囲にまとまっていて、その右に2軸の折れ線グラフが1つあります。この表の B14 セルは B2:B13 の合計(SUM)、C14 セルは C2:C13 の平均値(AVERAGE)がマクロで定義されています。まあ「よくあるシート」だと思っていますが、このエクセルファイルを xlsx で扱ってみます。ちなみに同じファイルがこちらからダウンロードできます:


【読み込み例】
まず npm で xlsx ライブラリをインストールします:
$ npm install xlsx

そして xlsx ライブラリを使ってエクセルファイルを読み込む Node.js コードを作成します。この例ではファイル名を指定して読み込み、"Sheet1" シートを取得して console.log() で出力しています:
var XLSX = require( 'xlsx' );

// ファイル読み込み
var book = XLSX.readFile( './SalesSample.xls' );

// シート
var sheet1 = book.Sheets["Sheet1"];
console.log( sheet1 );


実行結果はこんな感じになります。ダンプされたような感じです:
{ '!margins':
   { left: 0.7,
     right: 0.7,
     top: 0.75,
     bottom: 0.75,
     header: 0.3,
     footer: 0.3 },
  B1: { v: '売上', t: 's', w: '売上' },
  C1: { v: '前年比', t: 's', w: '前年比' },
  A2: { v: 1, t: 'n', w: '1' },
  B2: { v: 7370, t: 'n', w: '7370' },
  C2: { v: 0.87, t: 'n', w: '0.87' },
  A3: { v: 2, t: 'n', w: '2' },
   :
   :
  A12: { v: 11, t: 'n', w: '11' },
  B12: { v: 24380, t: 'n', w: '24380' },
  C12: { v: 0.812, t: 'n', w: '0.812' },
  A13: { v: 12, t: 'n', w: '12' },
  B13: { v: 28283, t: 'n', w: '28283' },
  C13: { v: 0.814, t: 'n', w: '0.814' },
  B14: { v: 156518, t: 'n', f: 'SUM(B2:B13)', w: '156518' },
  C14:
   { v: 0.8603333333333333,
     t: 'n',
     f: 'AVERAGE(C2:C13)',
     w: '0.860333333' },
  '!protect': false,
  '!ref': 'A1:C14',
  '!objects': [ , , , , { cmo: [Object], ft: [Object] } ] }

この結果の見方を少し説明します。例えば sheet1["!ref"] の値は 'A1:C14' となっていて、このシートの中で有効なセルとして認識されている範囲は A1:C14 とされています。つまりグラフ部分は完全に無視されていて、このライブラリでは現在は扱えない情報ということになります。xlsx はあくまで表部分の読み書きを対象としています。

次に sheet1["C2"] の値は { v: 0.87, t: 'n', w: '0.87' } となっています。この意味は以下のようになります:
 v: 0.87(数値としての値は 0.87)
 t: 'n'(数値のセルとして認識されている)
 w: '0.87'(表示されているテキストは '0.87')

なお、t の値は以下のいずれかになります:
 b: Boolean
 n: 数値
 d: 日付時刻
 s: 文字列
 z: スタブ
 e: エラー

したがって sheet1["C2"] の { v: 0.87, t: 'n', w: '0.87' } の意味は「値が 0.87 の数値セルで、画面上では '0.87' と表示されている」ということになります。

また sheet1["B14"] の値は { v: 156518, t: 'n', f: 'SUM(B2:B13)', w: '156518' } となっています。この中の f: 'SUM(B2:B13)' は値が数式で定義されていて、その式が SUM(B2:B13) であることを意味しています(sheet1["C14"] も同様です)。表としてはこのレベルで各セルの値を取得できている、ということがわかります。

この読み込み例のサンプル(app1.js)はこちらからダウンロードできます。こちらのファイルは(後述の書き込み機能の結果を確認できるように)上記のコードに少し機能を追加していて、コマンドラインパラメータで読み込むエクセルファイルを指定可能にしています(無指定の場合は SalesSample.xls を読み込みます):
$ node app1.js (xxx.xls)


【書き込み例】
xlsx ライブラリを使ってファイルの書き込みを行うサンプルです。この例では SalesSample.xls を読み込んだあとに "C13" セルの値を上書きして、SalesSample2.xlsx というファイル名で保存しています:
var XLSX = require( 'xlsx' );


// ファイル読み込み
var book = XLSX.readFile( './SalesSample.xls' );

// シート
var sheet1 = book.Sheets["Sheet1"];
console.log( sheet1 );

// セル更新
sheet1["C13"] = { v: 1.01, t: 'n', w: '1.01' };

// シート更新
book.Sheets["Sheet1"] = sheet1;

// ファイル書き込み
XLSX.writeFile( book, './SalesSample2.xlsx', { type: 'xlsx' } );


(注1 最後の XLSX.writeFile() 実行時の最後のオプション { type: 'xlsx' } を指定しないとマクロ関数が無効な状態で保存されてしまいます)

この書き込みのサンプル(app2.js)はこちらからダウンロードできます。実行はそのまま node コマンドで実行します:
$ node app2.js

実行すると SalesSample2.xlsx というファイルが出来ているはずです。試しにこのファイルをエクセルで開いてみるとこのようになります:
2018080201



"C13" セルの値は { v: 1.01, t: 'n', w: '1.01' } に上書きしましたが、たしかに 0.814 から 1.01 に更新されています。同時に "C14" セルの値も(AVERAGE関数が再計算されて)変わっています。一方でグラフが完全に消えてしまいました。まあ読み込みを実行した時点でグラフの情報は消えていたので、その内容で保存するとこのようになってしまうのだと思います。xlsx ライブラリの制限事項になると思いますが、実際に使う際にはご注意ください。

(注2 厳密には SalesSample2.xlsx ファイルが生成された時点では C14 セルの値は変わっていませんが、このファイルをエクセルで開くと AVERAGE 関数が再計算されて開くので、そこで値が正しく変わったように見えます)


以上、詳細は本家のドキュメントを参照いただきたいのですが、少なくともグラフを操作せずにシートの中身を取り出す用途であれば充分につかえて、対応フォーマットも多そうだな、、という印象を持っています。自然言語処理機械学習の学習データとしてエクセル資産を活用する、なんて話になった時に活躍できそうなライブラリですね。



このページのトップヘ