詩と創作・思索のひろば

ドキドキギュンギュンダイアリーです!!!

Fork me on GitHub

Spreadsheet に送信したスピードキュービングの記録を Slack や Pixela に連携する

ご機嫌いかがでしょうか。以前作ったタイマーアプリ fuTimer はスピードキュービングの測定記録をスプレッドシートに送信できるんですが、

記録をスプレッドシートに保存できるスピードキューブ用タイマーアプリを作った - 詩と創作・思索のひろば

スプレッドシートは貧者のサーバレスこと(言い飽きた)Google Apps Script を呼びだせるので、記録データをその他の外部サービスと連携できます。自分が求めているのは Slack と Pixela の2つだったので、これらに投稿する仕組みを作りました。あとは Twitter もあってもいいかもな。

Slack

こんな感じで、セッションをシートに保存するたびに、Slack に通知できます。

f:id:motemen:20181106101801p:plain

インストールと設定

  1. fuTimer の記録に使っているスプレッドシートを開き、メニューから [ツール] → [スクリプト エディタ] を選択して開く。リポジトリにある slack.js を "slack.gs" など適当な名前のスクリプトファイルとして追加します。
  2. [ファイル] → [プロジェクトのプロパティ] から、[スクリプトのプロパティ] を選択し、 SLACK_WEBHOOK_URL という名前で、任意の Slack ウェブフック URL を追加します。
    • f:id:motemen:20181106102022p:plain:w450
  3. [編集] → [現在のプロジェクトのトリガー] で、「スプレッドシートから」「変更時」に postStatsToSlack を呼ぶよう設定します。さっき見たらここの UI が変わっててびっくりした。
    • f:id:motemen:20181106101812p:plain:w450
  4. あとは fuTimer から記録を送信するたびに Slack に通知されるはずてすが、外部アクセスの認可は一度だけ手動で与えてやる必要があるので、[実行] → [関数の実行] から手で postStatsToSlack を実行し、権限を与えてください。たぶん「このアプリは確認されていません」と出るけど、「詳細」からポチポチしてると進められた。

仕組み

シートに仕込んだスクリプトでは、シートの編集時に onEdit という名前の関数が(あれば)呼ばれ、引数のイベントオブジェクトから変更された範囲も取得できるんだけど、fuTimer がやってるような API からの変更の場合はどうもこれが呼ばれないらしい。

ってのと、onEdit トリガからだと外部サービスを呼べないっぽい気がする(未検証)。

仕方がないので上に書いたように onChange トリガを受けるようにして、変更された範囲も取れないのでスクリプトプロパティに、最後に取り扱った行数を記録して、差分を Slack に送信しています。

Pixela

同様に Pixela。Pixela については、commit以外の数値でも草を生やせる、PixelaというAPIサービスを作った! - えいのうにっき を読んでもらうとして、毎日の計測回数でもって、以下のように芝を生やすことができます。自分の場合は fuTimer 以前の記録もシートに転記しているので、練習はじめたころからの記録もある。

意外と計測してない日があって、身が引き締まりますね。

インストールと設定

  1. https://pixe.la のドキュメントにのっとって、Pixela のユーザとグラフを作成します。
  2. Slack の場合と同様に、 pixela.js を配置します。
  3. [ファイル] → [プロジェクトのプロパティ] から、[スクリプトのプロパティ] を選択し、 PIXELA_API_URL という名前で、任意の Pixela API エンドポイント URL を、PIXELA_TOKEN という名前で Pixela ユーザトークンを設定します。
  4. [編集] → [現在のプロジェクトのトリガー] で、「時間主導型」「日付ベースのタイマー」「午前3〜4時(自分が寝てそうな時間帯)」で syncPixelDelta を呼び出すよう設定する。
  5. 上記のトリガは差分更新(前日1日分)なので、手動で syncPixelaAll を実行して、これまでの記録を Pixela に送信します。

仕組み

こちらは一日一度のバッチとして動かして、前日の日付の記録を洗い出し、その数を前日のカウントとして Pixela に投稿している。簡単ですね。なので更新は一日遅れになります。

Webpack で Google Apps Script のスクリプトを生成する

gas-webpack-plugin を利用した。global のプロパティへの代入があれば、トップレベルの関数として宣言するようになっているらしいんだけど、README 通り mode: "production" とすると Uglify されるからかうまくいかなくて、mode: "development" としたうえで devtool: false としpluginsModuleConcatenationPlugin を与えた らうまくコンパイルできた。

Tensorflow.js で notMNIST 学習済みモデルの文字認識

Udacity の Deep Learning 講義 を途中までやって、ははーんこれが CNN ね〜、という気持ちになった。

課題 4 では Tensorflow で CNN に notMNIST を学習させるのだけど、なかなか思ったとおりに精度が上がらない一方、層を増やすたびに重みやバイアスの変数を定義する必要があって試行錯誤するのが面倒だったので、Keras を使ってみたところ、コードを書くのはかなり楽になった。

ごちゃごちゃやっていると正答率 97.6% という数字が出たものの、本当にこれがあってるのかどうか自信がない……というか、数字ばかり見ていて、自分が何やってるのかわからなくなってきたので、インタラクティブに判定を試せる装置を作って遊んでみた。推定のところは、Tensorflow.js を使うと簡単にできる(この記事も参考にした)。ソースは GitHub にある。今見たら Chrome じゃないと縮小がうまくいってなさそうだった……。

https://motemen.github.io/ml-keras-cnn-notmnist/

f:id:motemen:20180913133138g:plain

ほんとは正答率の推移なんかを追ってかなきゃいけないんだろうけど、そのへんの知識はあいまいなまま。

今回は「貧者の GPU」こと Google の Colaboratory にたいへんお世話になった。とりあえずこんなものを作ってるだけじゃ虚無だなということがわかったので、もっと面白いことやりたいな……。

記録をスプレッドシートに保存できるスピードキューブ用タイマーアプリを作った

これです。

https://motemen.github.io/futimer/

そしてリポジトリはこちら。

GitHub - motemen/futimer: Web-based speedcubing timer

数ヶ月前からスピードキューブをはじめている。バラバラの状態に(スクランブル)されたルービックキューブをいかに早く揃えられるか、という競技で、自分はようやく40秒切れるようになったくらい。はじめた頃の自分から見ると驚異的な数字だけど、いま自己評価すると、脱初心者できたかな〜っという段階。

社内でもやや流行っている。スピードキューブの何が面白いのかというと、少なくとも自分がやり続けているのは、「圧倒的成長を感じられること」。やってみる前はルービックキューブを揃えることなんて想像もつかなかったし、習得するだけでも相当な苦労なのだろうと思っていたけれど、実は広く使われる手順というものがあって、これに従うとじつに意外なことに、ひと晩ふた晩も集中すれば何も見ずにキューブを揃えられるようになる。頭じゃなくて、手で覚えるのがミソ。

ソフトウェアエンジニアとして10年近くやっていると、自分の学習プロセスについてある程度のパターンができてしまっていて、新しいことに接しても想像がついてしまうところがあると思うのだけれど、スピードキューブをやることはその範囲外のことで、あらためて学びのプロセスというものを客観視するいい機会になる。それに、見た目以上に学習曲線が急なこともあって、楽しい。

そういうわけで揃えるのに3分くらいかかっていた最初期から、plusTimer という Android アプリを使ってソルブ時間を記録していたのだけど、データのエクスポートが簡単にはできず、成長記録と分析という観点ではもっと扱いやすい Google スプレッドシートに置きたい! と思うのが人情なわけで、PWA で自作することにした。スマホのホーム画面に置いていて、自分のレベルでは普通に使えてます。

シートに書くと、こんなグラフを楽しめる。

アプリの使い方の説明は特にしません。不親切!

特徴

  • Google スプレッドシートに記録を保存できる
    • 唯一にして最大の特徴
    • 保存ボタンでセッションをローカルに記録して、同期ボタンでセッションをシートに保存するイメージ
    • 複数デバイス間の同期には対応していない。スプレッドシートは追記のみ
  • 試しに録画機能もつけてみている。PC など広い画面でアクセスすると、右下のパネルから選べます。手前からの撮影にはならないけど……
  • 公式スクランブラの TNoodle のコード(を JS 化したもの)を使っている。そのぶん少し重い。Web Worker 化できたらいいんだけど
    • これを利用してる関係でライセンスは GPLv3
  • インスペクションのカウントダウンや、DNF の記録とかはとりあえず作ってない

ご意見ご感想お待ちしております。

はてなで一緒に働きませんか?