iOS 12ショートカットからim@sparqlにアクセスしてクイズをつくってみた

このあいだiOS 12のショートカットを試して楽しかったので、今度は遊べるようにクイズを作ってみた。 完成系はこんな感じ↓。アイマスのアイドル(、他)がランダムに10名表示されるので、身長が149cm以下のアイドルをすべて選択すると、合っているかどうかを表示してくれる。

https://esa-storage-tokyo.s3-ap-northeast-1.amazonaws.com/uploads/production/attachments/9621/2018/09/27/1855/6b48385d-8576-4ace-b7a2-cf84881efeaa.mp4

このショートカットの中身は、下記のアクションで構成されている。このブログエントリでは、ショートカットの配布リンク提供と、ショートカットの中身のウォークスルー解説をする。

f:id:banjun:20180926200311j:plain

うまくオリジナルサイズの画像が貼れなくて読めないと思うので、オリジナルサイズはこっち。

https://img.esa.io/uploads/production/attachments/9621/2018/09/26/1855/aa46e4ad-7205-49a2-8607-c6f58a46ab3f.jpg

ショートカットの入手と実行

ショートカット本体は、iCloudでシェアできる。実際にこのiCloudリンクから入手して、実行したり、なかみを見たりできる。ぜひiPhoneに入れて動かしてみてほしい(App Storeでショートカットアプリを入れておく必要がある)。

im@sparql 身長U149クイズショートカット: https://www.icloud.com/shortcuts/93a3d2a6052048638943300edb80e8a9

なお依存先のショートカットがひとつあるので、下記のショートカットと合わせて2本、インストールする必要がある。

im@sparqlクエリ実行ショートカット: https://www.icloud.com/shortcuts/922ef6fc7366437e8b01659372fe48af

im@sparql 身長U149クイズショートカット のフロー解説

以下、ざっと流れの解説。長いスクショを見ながら追うといいかも?(いいのか?)

f:id:banjun:20180927001540j:plain

テキスト「SELECT...」→ ショートカットを実行「im@sparqlクエリ実行」で、アイドル名と身長のリストをとってくる。400以上の結果が返ってくる。データが充実しているのはim@sparql自体がすごい。「im@sparqlクエリ実行」ショートカットは、別のショートカットの入力に渡して結果を受け取る。さしあたり、SPARQLのSELECTクエリを渡すとim@sparqlから結果を辞書でとりだしてくれるすごいやつ、と認識しておけばよい。

SPARQL自体をどう書くか、については下記のページで解説されているので、そちらを参照。

im@sparqlを組み込んでみる

f:id:banjun:20180927001743j:plain

「リストから項目を取得」→「それぞれで繰り返す」で、ランダム順のあたま10名ぶんを取り出し、なまえと身長の辞書、のリスト、を得る。「辞書の値を取得」は、JSONのキーを辿るやつ。.name.valueになまえ、.height.valueに身長がはいっているので、そう辿る。「それぞれで繰り返す」は、リストのmapであるから、「繰り返しの終了」の直前をみると、map先の値がわかる。アクションの入出力のフローは一直線なので、「繰り返し項目」を二回入力として使うために、途中で「変数を取得」して入力を読みなおしている。

出力はこまめに変数にいれておくと、わかりやすい(変数にいれなくても、各アクションの出力は、マジック変数で参照できる)。

f:id:banjun:20180927001927p:plain

「リストから選択」ではクイズの出題と回答のUIを提供する。この入力は、ユーザーにみせる文字列のリストでないといけない。この制約がけっこう厳しい。辞書を渡せればいいのだが、表示名だけを渡さないといけない。。「複数を選択」にすることで、選択した項目のリストを得られるので、今回のクイズが実現できる。

f:id:banjun:20180927002007p:plain


f:id:banjun:20180927002020p:plain

そのあとほぼ終わりまで続く長い「それぞれで繰り返す」が、答え合わせのループとなる。「リストから選択」の制約で、選択された項目については、アイドルの表示名のリストについてのデータしか持ち合わせていない。したがって、再度、なまえ身長リストをループして、答え合わせをしていく必要がある。

f:id:banjun:20180927002105p:plain

または不正解

f:id:banjun:20180927002651p:plain

「次の場合」はif-else-endifの形式のブロック構造をしている。アイドルごとの判定は「そのアイドルは149cm以下かどうか」×「ユーザーはそのアイドルを選択したかどうか」なので、「次の場合」を2重にネストして、それぞれの4パターンの答え合わせ結果を生成する。「次の場合」も結果を上位のブロックに出力するので、4パターンとも、結果を「テキスト」にして、正解と不正解をもたせる。すると、2重ネストの外側の出力として、「結果が以下の場合」の変数に、正解か不正解かが流れてくる。

f:id:banjun:20180927002121p:plain

f:id:banjun:20180927003229p:plain

f:id:banjun:20180927003729p:plain

[結果が以下の場合] に答え合わせ結果のテキストを絵文字で入れているので、こんな感じの出力になる。×が出たら覚えていこう。

f:id:banjun:20180927002148p:plain

これがアイドル10名ぶんmapで繰り返されてくるので、joinする。joinは「テキストを結合」で、改行区切りを選択する。 最後に「クイックルック」で結果をユーザーに表示してやる。「クイックルック」は、ショートカットを組み立てるときに、途中に挟んで、実行を止めて出力の内容を見られるので、プリントデバッグ的な感じでべんりに使える。

im@sparqlクエリ実行ショートカット のフロー解説

こちらのほうが短いけれど、オリジナルサイズの全容はこちら。

https://img.esa.io/uploads/production/attachments/9621/2018/09/27/1855/932481f7-a32c-4d65-8993-f466f8962652.jpg

SPARQL初心者なので、SPARQLのSELECT書いたらim@sparqlで実行してくれるだけのモジュールとしてのショートカットを作って、試行錯誤しようとして、↑↑のクイズのショートカットから分離したもの。

SPARQLのクエリはPREFIXとSELECTからなるようで、PREFIXはお決まりのものを入れておけば良いかなと思って、SELECTだけ書いたら動くようになっている。

「ショートカットの入力」で他のショートカットから入力をもらう。「次の場合」では、空実行されたときに後段まで実行されて無駄クエリを投げることがないように、キャンセルできるようにしている。ただのキャンセルというのが分からなかったので、[キャンセル][OK]でキャンセルできる、というだけ。

URLエンコードして、im@sparqlのエンドポイントのqueryにくっつける。im@sparqlの結果はJSONで返ってくるようで、辞書にして、お決まりの階層がいくつかあるようなので、results→bindingsと辿って、結果の辞書部分だけをこのショートカットの出力とする。

これで、SELECTを書くだけのショートカットを作りやすくなる。例えば、下記のページで提供されているようなクエリ実行は、こうなる。

https://sparql.crssnky.xyz/imas/ImasIllustTheme.html

f:id:banjun:20180927001333j:plain

このサンプルのショートカットへのリンク: https://www.icloud.com/shortcuts/41d10a57b1e84a03b38914fc95be0d86

おわりに

こうやって、ショートカットでなにかをするときにはこのアクションを使えばいいのかな?、ってアクションの語彙が増えていくと、iPhoneだけでどんどんロジックを組めるようになってくる。iPhoneなので電車のなかでも組める。実際に今回のショートカットのほとんどは、毎日の電車のなかで作成した。 たぶんショートカットはもっといろんな連携のパターンがあると思うから、ショートカットで出来ることの語彙を増やしていきたい。

こんなアクションつかったらきれいにできる、とか、ここは分離して別のショートカットにしたらいい、とか、そういうネタがあったら教えてほしい。

謝辞

github.com

このデータ量よ

nrstudy.connpass.com

このブログ書きました

esa.io

べんり