どくぴーの備忘録

真面目なことを書こうとするクソメガネのブログ。いつ投げ捨てられるのかは不明

ノリと勢いで買ってよかったものベスト10 2017

まずこの記事について

この記事は #kosen10s Advent Calendar の24日目の記事です。

<- 前日の記事(@sonet_sou) 翌日の記事(最後なんだけど何故か埋まっていない)->

今年もいっぱい散財した

メリークリスマス、メリー散財。今年もいろんなものを皆さん買いましたね?僕もいろんなものを買いました。 みんなに「物買い過ぎでは…?」って言われるんだけど多分飲み会とかのお金がこっちに回ってきてるだけな気がしています。でも来年はもうちょっと節約したい気もしますね!

そんなわけで今年何買ったかを覚えていないと来年また散財マンになってしまいそうなのでここはガジェオタっぽく買ってよかったものランキングでもしてみようとかいうモチベーションです

ちなみに誕生日等でいろんなものをkosen10sの人であったりから頂きました。だいたい以下の感じ

送ってくれた方々本当にありがとうございました :bow: :bow:

そんな感じで始めていきましょう!

10. 君の名は。BDスペシャルエディション(Amazon限定版)

言わずと知れた去年公開の名作映画ですね。僕も劇場で何回も見ました。 予約開始で速攻で予約して、届いて即一回見ました。やっぱり良いですよね。最高。先週の日曜早起きに失敗して新海誠展行けなかったのが本当に悔やまれる。 ちなみにUHDBD版だと縮刷版の台本がついてくるのですが、お値段とUHDBDを見れる環境がいつまでたっても整わなさそうなので見送りました。悔しい。

9. ジャンクPC + GeForce GT 1030 + WD Green 240GB

同期が秋葉原に8月当時出回っていたThinkCentre M73 Tinyを見に行っていた横でしれっと購入。MouseProがi5-4430と8GB RAMが乗っかった状態で13000円で売られていたので割安では…?って思って買って、その場でSSDとSteamで持っていた古めのゲームを動かしたくてグラボを買いました。

ちなみに今でも一応動いています。結構Windowsがあると便利なんですよね…

まぁ安いなーとは思っていたんですがちゃんと裏があって、通電時間が長くなったときに再起動をするとBIOS POSTが走らず再起動を繰り返す多分電源周りの病気持ちでした。うーん、まぁ起動はするし…って気持ちです

8. 新宿御苑の年間パスポート

新宿御苑、いいです。

いや何がいいって自然に囲まれてひたすら芝の上でゴロゴロしてもいいし、カメラを担いで写真を撮りに行ってもいいし、PCとモバイル回線を持っていって作業をしてもいいしと、とにかく僕にとっては非常にリラックスできるスペースだと思います。夏とか秋口とかは @puhitaku とかとカメラを持っていって写真を撮っていたり、一人でPCを持っていってコーディングや何かしらの書き物をしたりしてました。何故か僕は結構捗ってめっちゃ良かったです。

f:id:e10dokup:20170708144415j:plain

ちなみに通常入場200円、年パス2000円です。僕はもう10回は軽く通っている記憶があるので元を取ってしまった感がすごい。流石に冬は寒いので行けてないですけど…。

7. LINE WAVE(先行体験版)

clova.line.me

日本で最初に買えるスマートスピーカーだと言うことで飛びつきました。当時15000円(LINIE MUSIC 6ヶ月分バンドル)結構今でも便利に使っていて、明日の天気を聞いたりアラームを掛けたりラジオ的に音楽を垂れ流してもらったりしてます。案外喋って動かすインターフェースって使わないんじゃないのかなーって思ってたのですがあると結構使ってますし案外便利なんですよね。使ってみないとわからない感じというか…。

個人的にはその後に出た正式版がキャンペーン価格とは言え12000円でLINE MUSIC 12ヶ月分バンドルなのが悲しいですね…。

LINE WAVE + Clovaだとオレオレカスタマイズが出来ないなぁって言うのがあって、最近半額になっていたGoogle Home Miniを買ってきました。GoogleアシスタントSDKの日本語対応もあったので何かおうちハック的なことをやろうかなーなんて考えています。

6. 単焦点レンズ(PENTAX DA50mmF1.8)

僕はPENTAX K-S2を使っているのですが、PENTAXで手頃な単焦点というとこの50mm/F1.8か35mm/F2.4な感じがあります(どちらも15000円前後)。個人的には風景とかを明るいレンズで撮ってみたかったので50mm/F1.8にしてみました。上の御苑の写真とかはこのレンズを使って撮ってみたものだったりします。ただふと寄りたいなーって思うと50mmじゃちょっと不自由なのでうーん、35mmが良かったかなーって思わなくもない感じだったりします。こんなことをやってるから沼にハマる。

5. PlayStation 4 + HORI Racing Wheel Apex + グランツーリスモSPORT

PS4自体はじゃんぱらで16000円できれいなものが売られてたので衝動買いでした。そのきっかけで「やっぱグランツーリスモSPORTしたいじゃん」となり、せっかくだからハンドルコントローラーも一緒に買おうってなったので一緒に購入しました。これまでレースゲームは普通のパッドでやっていたのですが、やっぱりハンコンを使うと別の楽しさがありますね。GT SPORTも「GTらしくない」と酷評され気味ですが最近ついにオフラインモードに昔のGTっぽいモードが実装されたのでまた熱が再燃しています。というかGT SPORTは写真を撮るのがくっそ楽しいですね、こんな写真が撮れたりします。4Kサイズでレンダリングも可能で、しかも撮ったデータはUSBメモリにエクスポートできるのできれいに撮れるとPCの壁紙にしたりとかして楽しい。

f:id:e10dokup:20171026020645j:plain

f:id:e10dokup:20171224002203j:plain

ちなみにハンコンは上のジャンクPCに繋いでEuro Track Simulator 2をマルチプレイでやったりしています、こっちもかなり楽しいのでおすすめです。

4. Sony Xperia XZs(au SOV35)

www.sonymobile.co.jp

以前使っていたau isai Vividがよく壊れて3台目になっていたのとXperia XZsの発売日と更新月が重なっていたり、キャッシュバックキャンペーンがいい感じに重なって適用できたりと何かとタイミングが良くて買い替えました。なにげに初めてのXperia

そもそもisai Vividがよく壊れたりでかなり怪しかったのもあって、とても快適です。Snapdragon 808からSnapdragon 821になったものRAMが4GBになったのも十分大きい気がします。なんとなくバッテリーの持ち具合が良くない気がするけど普段の使い方だとよく充電器につながりっぱなしなので別に気にはならないレベル。

ちなみに今年は他にiPhone 6s(同期に譲ってもらった)、Moto G5 Plus(検証機)、NuANS Neo(Windows 10 Mobileの方、公式に終了したのでいよいよ使いみちが…)を買ったりしています。

3. Sony PHA-1A + Sony XBA-N1

カメラの沼にハマりかけてると思ったら今度はオーディオ沼です。

PHA-1Aが何故かじゃんぱらできれいなものが13000円くらいで売ってたので衝動買いでした。中古屋ウォッチング、時々こういうのが出てくるので本当に良くない。

実はXBA-N1は昨日届いたので実質セルフクリスマスプレゼントです。溜まりに溜まっていた楽天ポイントをぶっこみました。

XBA-N1の前はJVC HA-FXT100を使っていましたが乗り換えてみて個人的にすごい好みの音が出るようになった気がします。HA-FXT100より中音域が厚くなった感じがあってすごい好きな感じです。完全に主観なのでレビューというよりプラシーボという説もあるのですが多分こういうのって本人が満足できればそれが一番なんだろうなって思わなくもないです。

同期には「どうせ二ヶ月後くらいにXBA-N3を買うやつ」って言われたんですが流石にそんなつもりはないしこれ以上オーディオ沼に足を取られたくないのでこれで僕は満足です。そういうことにさせてくださいマジで。

2. iMac 5K Retina

www.apple.com

今年最大のお買い物です。仕事用じゃないです。

実はApple Storeからの購入ではなくビックカメラのアップグレードプログラムでの購入です。ビックロの店舗で購入したのですが店員さんに「明日の配送でよろしいですか?」と聞かれたときに何故か満面の笑みで「いや、ここから自分で持って帰ります!」と言ってしまいクソデカい台形の箱を抱えて新宿のビックロから家に1時間かけて帰る謎の体験をしました。

「なんでiMac買ったの?」っていう話になるのですが使っていたMacBook Pro 13インチ(Early 2015)が二年を迎えるのですが案外元気に動いているのでリプレースするにはもったいない感じで、コスパ的にiMacを手に入れればいい感じになるのではないかというところです。買ったのCore i5-7500搭載モデルで、それに自前で8GBメモリを増設して16GBで運用しているのですがやはりUシリーズではないデスクトップ版Kaby Lakeのパワーはすごくて、ものすごい速さでAndroidプロジェクトのビルドをしてくれます。最高。

流石にお仕事でiMac…となると会議とかでPCを持ち運びたいのでそこはMacBook ProとかのノートPCのほうが良さそうですよね。難しいところです。ただ本当にiMac 5K Retinaはすごいので購入直後には下のツイートみたいな気持ちになります。

1. Nintendo Switch

www.nintendo.co.jp

なんか本当にありきたりなんですが、Nintendo Switchは今年本当に買ってよかったなって思います。僕は予約購入勢です。

長い時間遊んでいるタイトルがこれまたマリオカート8DX・スプラトゥーン2スーパーマリオオデッセイとありきたりなタイトルですが、久々に楽しんでゲームしたなっていう薄っぺらい感想が出るくらいには現在進行形で楽しんでいます。スプラトゥーン2スマホ連携でボイスチャットしながらサーモン・ランとかできるのでくっそ楽しいですよね。

おすそ分けプレイをやりたくて何処かで友達とボンバーマンをやったり、飲み会の席でぷよぷよテトリスをやったりしたのですが、携帯ゲーム機じゃありえなかった「外でみんなでプレイする」ことを成し遂げているのが本当に新体験で良かったです。一人プレイでもいつでもどこでもプレイできる仕組みあるおかげでゼルダの伝説とかでみんなが時間を大量に溶かしていたりするので、PS4Xbox Oneなんかにはないオンリーワンの体験を提供しているのはさすが任天堂って感じです。はい。

ちなみにスプラトゥーンはクソ雑魚です。時々上手い人のプレイ動画を見たりすると何が起きているのかわからない感じになります。

大散財を並べた後に思うこと

普通にベスト10がスッと埋まるあたりどんだけ物欲があったんだ…ってなりました。上京1年目だったので色々物が揃ってなかったのもあるなーって感じで一年かけてやっといろんなものを揃えていい感じに家の中が充実してきたなーって思ってます。流石に来年はこんな大散財を控えるつもりです。

案外ポジティブなのが「買ったものはだいたい使い続けていられてる」って言うところなのかなと。安物買いの銭失いで買ってすぐ壊れちゃった、みたいなものはあったのですが、なんだかんだ買ったものを一度も使わなかったとか、すぐ使わなくなっちゃったみたいなケースが実はないので衝動買いと言いながら意外と個人的ニーズがあるものを買っていたという説がある。

来年はもっと計画的に衝動買いをしていきます。みんなも軽率にお買い物をしていきましょう。

MAに抱く感情 #MA_2017

まずはじめに

この記事は MashupAwards Advent Calendar 2017 22日目の記事です。

Mashup Awards 2017が終わっちゃいました

今年も無事というかなんというか、年一度の長ーい楽しみと言っても過言ではないMashup Awardsが終わってしまいました。

僕が何を作って散っていったかは下の記事を見てもらえるとわかりやすいです。

e10dokup.hateblo.jp

えっ、このネタこっちでやるんじゃなかったんかいって言われるとそれもあったんですが、MashupAwards Advent Calendarならやっぱり自分とMAの話したいなーっていうそんな思いがありましてですね…。

MAに4回くらい参加して思うこと

初めて参加したのはMashup Awards 9の頃だった記憶があります。今となってはよくボッチでMAに何かしらを投げているのですが、MA9-10の頃はちゃんとチームを組んでいたなぁとしみじみながら思っております。今はボッチで何かしらすることが多いですね。よくわからないままサーバサイドをやってみたりしています。多分MAでちょっとだけ勉強したGAE/Goの話は別の記事に書くと思います。

9から今回の2017まで含めると4回連続で何かしらの作品を投げてきたり、負けて悲しいのでスタッフの真似事をしていたりするのですが、2nd stageに訪れてみると毎年「次は・次も参加者としてこの場所に来たい!」って思わせてくれる不思議な魅力があるんですよね。何なんだろう。

個人的にはMAについて今年思ったことはなんだろう…って思ったらこんなツイートをしていました。

ちょっとお酒の入った頭で考えると、本当に参加者がみんな自分の自慢したい作品を作って持ってきて、自分の作品に自信を持っていながらも他の人の作品を「やべぇ!」「すげぇ!」「おもしれぇ!」と素直に褒めることができる環境が出来上がっているんですよね。MA自体に寄せられてくる作品の技術ベクトルの向き先が増えすぎているっているのもあるんですが、ワンアイデアからいろんな手段・技術で誰かが何かしらの実装をしてきていて「その発想はなかった」「技術の無駄遣い」みたいな感じでみんながお互いを作品からいい意味で認識し合うって言うのは本当にMAオンリーの空気感だなって思います。

あと、僕が思うMAのいいところは「目的の手段化」すら許される、ってところなのかなって思っています。目的の手段化から生まれた作品が勝ち上がれるってわけじゃないんですが、「いやー、あのAPI使ってみたくて…」とか「あの機材めっちゃ良さそう、使ってみたい!」みたいなモチベーションがアイデアによって形になる、みたいな作品がたくさんあるのが普通のコンテストとかではまあありえない光景だよなーって毎年思わされています。自分も今年はやったことないことやってみたいって思いでものを作りましたし、知らないものに触れる、勉強できる、実際に形にするっていうプロセスを歩めるのは個人にとってもすごい成長環境だよなと思います。

ただ個人的に毎年直したいなーって思うところはあって、ギリギリにならないと稼働できないっていうすごい問題があるんですよね、毎年「忙しい…」とか言いながらギリギリまで手を付けられない、みたいな状況になっているのですがもっといいもの、ちゃんとしたものを作ろうと思うと計画建てるというか、もっと早く目覚める必要があるなーって思います。毎年思ってるのに実行できないのが非常に悲しい。この時期だとMAが終わって開発に対する意欲がハイになっている上に大晦日ハッカソンなるものもあるので何かを作り出そうとするのですが道半ばで何処かに消えてしまう作品をなんとかして作り上げるのが今の僕の課題です。

あ、今年も大晦日ハッカソンがあるので皆さん大晦日の前に大掃除して全力で開発しましょう。僕はこの土日で大掃除をします。

atnd.org

とりあえず来年も

Mashup Awardsは色々変化を迎える(一般社団法人化とか…)ような気がしますが作り手の熱い思いがあればMashup Awardsはどんどん面白く、ハイレベルになっていくんだろうななんて思っています。来年も全力でやっていきましょう!

ガルパン劇場版のお陰でコンテンツ消費環境に興味が出てしまった話

まずはじめに

この記事は ガールズ&パンツァー Advent Calendar 2017 19日目の記事です。

最終章第一話が始まりましたね

いやー、ガールズ&パンツァー 最終話 第一話がついに公開されましたね!一週間以上前の話ですけれども! 皆さんはもう見られましたか!?僕はいろいろ忙しかった事もあってこの間の日曜日にシネマシティに行って観てきました! じゃあレビューでもするのかとでもなるのですが、そんなネタバレなどという無粋なことは言いません。ただ一言

ガルパンはいいぞ

と言い残すのみです。

じゃあ何の話をするのか

コンテンツ消費の環境についてのお話をしようかと思います。

ガルパンにハマるまで

ガルパンガルパン劇場版に出会うまでは、正直なところ「コンテンツは消費さえできればそれでいい」なんて思っていました。音質や画質よりもコンテンツそのものが良ければどうでもいいと。なので映画をわざわざ映画館で見る、なんてせずに後からストリーミングサービスでタブレットやパソコンに安いイヤホンを繋いでみればいいじゃない、みたいな消費をしていたわけです。

そんな感じでコンテンツを消費していた大学時代、同期が東京に行ってくるついでにあのシネマシティでガルパン劇場版を観て帰ってきました。どうにもドハマリしたようで「いいぞ」という言葉を残してきました。当時ガルパンを知らなかったので、そこまで言うなら劇場版を見に行こうと話を聞いていたら「絶対にシネマシティで極上爆音上映を観ろ」と言ってきます。極上爆音という言葉はひたすらヤバそうなのですが一体何が違うのかわからないなぁって思いながらその一週間後に東京に行く予定があったので、そこまでに予習としてAmazonプライムビデオでTV版とOVAアンツィオ戦を観て本編サントラを買うなどしていました。本編サントラを買うあたり若干もうコンテンツ自体にハマりかけていますね。

そんなこんなで迎えた劇場版を見に行く日。もうすでに観た人は「ガルパンはいいぞ」としか言い残さない文化が出来上がっているので「ネタバレをしないように最大限考えた上で出てくる言葉なんだろうなぁ」くらいにしか思っていませんでした。なのでこんなツイートもしてしまう。

そして観てきた後の僕がこれです。

風潮に乗っかったつもりは毛頭なかったのですが、色々と体験が素晴らしすぎたのか、ツイートどころかシネマシティの建物を出てため息のように出た言葉すら「よかった…」でした。素晴らしい環境での素晴らしい体験は脳を揺さぶり溶かすということを身をもって知った瞬間でした。

ハマってから

その後も一回では飽き足らず、他の映画館でもガルパンを観たい!などと言い出し何度もガルパンを鑑賞する一年になりました。すべてを数えてみると

  • シネマシティ:6回(内レオバルド3回)
  • 梅田ブルク7:2回
  • 塚口サンサン劇場:3回
  • BD:数えるのをやめた

という感じに。あまりにも観すぎて次に来るセリフがわかるあたりはガルパンおじさんなら皆経験があるのではないでしょうか。

この中でもやはり素晴らしかったなと思うのはレオパルド化したシネマシティと塚口サンサン劇場でした。当時関西圏の学生だった僕には塚口であの脳が揺さぶられる体験ができるって言う事実に打ち震えたものです。

コンテンツ消費に思うこと

まず映像作品、特に映画を見る際の意識が変わりました、やはり新鮮さという意味でも体験の品質という意味でも映画館のスクリーンで見るという体験は家のディスプレイで見るものとは違うものがあります。家のディスプレイで友達とワイワイ見るのも素晴らしいんですが、好きなコンテンツで映画館に行ける環境があるならばぜひとも映画館でみたい!って思えるようになりました。なので気になった映画は映画館に行く余裕があれば観に行っています。『君の名は。』とか『響け!ユーフォニアム』とか。事前情報がまったくなかったのですが『ダンケルク』も面白かったです。

そんなことをしていると映像作品ではないコンテンツ消費にも気を使いたくなってきました。真っ先に思いつくのは音楽ですね。これまで「イヤホン良くわからないんだよなー、いいやつとか何が違うの?」という考えで、2000円程度のイヤホンを使っていたのですが社会人になって自由に使えるお金が発生したこともあり、プラシーボでもなんでもいいからいい環境でコンテンツを消費したくなってイヤホンを突然10000円くらいするJVCのものに買い替えたりしだしたり、安物ですがポータブルアンプを買ったりしました。そして今ではポータブルアンプがSony PHA-1Aに変わっていたりしています。「何が変わった?」と聞かれると説明しにくいのですが僕としては幸せな気分なので大丈夫でしょう(一応ちゃんと感想を述べると中低音の粒がくっきり聞こえるようになったのでベースとかドラムの音が聞き分けやすくなったりしたと思っている)。まだオーディオ沼の入り口に片足も突っ込んでいないのですがいつ足を取られるかわかったもんじゃないので己を強く持ちたいところです。

ここまで行くと次はゲームやBDの映像をきれいに観たい!ってなるのでしょうけど今の家だと流石に狭くなっちゃうのでしばらくはおあずけなのかなーって気がしています。今だと4KでHDR対応なディスプレイとそれが扱えるプレイヤーが当たるのでしょうね。一体いくらお金がかかるのやら…

最後に

とりとめのない感じになってしまいましたが、僕はガルパン劇場版を観たことで「コンテンツの消費のための環境に対して金をかけることは全然損にならないし気持ちいい」と思うようになってしまいました。周りの友人たちがコンテンツ消費のためにお金を注ぎ込んだりしているのを見てたりしていたのもあってかなり背中を押されまくっている感じがあります。これからも懐具合と相談しながらガルパンにかぎらず、様々なコンテンツを満足できる環境で消費したいなと思います。

頑張って作ったアプリがクソの域を出なかった話 #MA_2017

まずはじめに

この記事は クソアプリ Advent Calendar 2017 11日目の記事です。

一日遅刻しています。土下座モン。

作ったものの話をしよう

今年もMashup Awards真っ只中の冬でございます。MAというとハッカソンって言う人もめちゃくちゃいますがその本質は50以上の作品がひたすらプレゼンを繰り返す2nd stage(日曜にありました)に詰まっている気がします。この楽しみを「参加者として」楽しむために目指している人もいるんだろうなーと思っています。

僕はスタッフをしていました。カメラマンです。

そんなMAに僕が今年何を放ったか、そしてどうしてクソのまま終わったのか、どうやってクソから抜け出していこうかという話をしようと思います。

今年作ったもの

hacklog.jp

そう、今年僕は「課題解決」をしようと思いました。

LTイベントやMAのようなプレゼン大会で欠かせないのは「運営としてのTwitter実況」。その中でも僕が目をつけたのは「発表一回目のツイート」でした。

このツイート、僕は本当に大事だと思っていてハッシュタグウォッチしながら参加している人には今誰がどんな内容で登壇しているのかを伝える役割があり。更にはイベント後にtogetterにまとめるようなときにも区切りとしての役割を果たします。

ではその最初のツイート、どうやって投稿しているか考えてみましょう。

  1. 事前の発表リストを用意する
  2. ツイート内容を構成する
  3. 発表者の手番が来たらそれをTwitterの投稿フォームにコピペして投稿

1はしょうがないとして、2、3はかなり面倒です。ツイート内容の構成では決まったテンプレに収まるように与えられたデータを配置する必要があり、3に至ってはコピペなんかしていては発表が始まってスライドが2枚流れてしまう、なんて言ったことだってあります。

僕はそれを解決したくてこのとうだんくんを作る決意をしました。MAの締め切り3日前に。

どんな感じのものなの

f:id:e10dokup:20171211235853p:plain

Hacklogからサルベージした画像がくっそでかい。

こんな感じで登録したイベントの登壇タイトルを選んで開始時にワンボタンでSNS通知できるっていうそれだけのアプリです。なんで一回選ぶの?っていう疑問も持ったのですが、こういうイベントあるあるとして「直前に何らかの事情で発表順が前後する」という話があるのであえて一旦自分の・今から始まる発表を選択するというアクションを要求するようにしました。 イベントや登壇内容の登録はCSVでバルクアップロードできるように後々改良しましたが、基本的にはイベントに紐つけたIFTTTのWebhookに対してリクエストを飛ばしてそこから自作のレシピに応じてアクションを起こすのでIFTTTが許す範囲とWebhookで扱える変数3つの中であればなんでもできるようになっています。

f:id:e10dokup:20171211235753p:plain

実際の構成はこんな感じで、スマホからはデータ登録が(個人的に)めんどくさいので一切その手のことは扱わず、スマホからサーバへの通信はすべてGETリクエストです。ということは登録はWebアプリ化しないといけなかったのですがCSS力とJS力とHTML力が生まれたての赤子未満なレベルのためMaterial Design Lightを使ってもまともに作れていないやっつけ具合で用意しました。サーバはちょっとだけ見に覚えのあったGolangをgin/gormの構成で雑にGAEにデプロイしています。この辺の話は後々の Mashup Award Advent Calendar で書こうと思います。

こんな小規模なのですが、Androidアプリは当時は拡張する気まんまんで作っていたので多少設計しました。と言っても大げさなものを用意してもアレなのでRxJava2/DataBindingでMVVMな構成をとってKotlinで実装しました。KotlinかわいいよKotlin

何がクソだったのか

ここから反省会フェイズです。端的に三点反省していきましょう。

iOS版がない

ないです。持ってないですしおすし…。 こういうものを作って人に見せると日本って残念ながらiPhoneが圧倒的マジョリティなのでiOS版つくらないんです?」とか言われてしまいます。ぐやじい

ニーズに応えきれない

IFTTT-Webhookで変数3つ使えるじゃん!とか考えてしまったのが運の尽きでした。実際運用してみると思っていたよりも初回ツイートテンプレって柔軟性が高くて、発表順が必要なケースがあったり、文字数オーバーに応じてちょちょいと内容を修正できるようにしてあげられるような仕様にして上げる必要があったりと、IFTTTに投げてドゥン!みたいな銀の弾丸的思考は通用しませんでした。

そもそも自分以外セッティング不能

これが最悪。デザインセンスも思ったものを形にするWebフロント知識もないので、出来上がったWebフロントは使いにくく、作った自分くらいしかデータのセットアップが出来ない代物になってしまいました。時間をかければできたんじゃね?と言われれば勉強込みで出来た気もしますが、結果論では他人が気兼ねなく使えるような状態ではないので残念すぎました。

クソから抜け出すために

でもせっかくクソとはいえある程度形にして自分だけでも楽に使えるようにしたいってのが本音なので、これからも作っていこうと思います。というか作っていって自分で使いたいんです。とりあえず次のことを今は考えています。

Web APIの抜本的作り直し

上がったニーズに応えようとすると、IFTTTのWebhookを使うのはともかくとして、サービス側にテンプレを持っている必要があるという結論にしかなりませんでした。そうじゃないと文字数チェックも出来ないし、3つ以上のパラメータに対応できないし…。

ただIFTTT自体はクソ便利なので、最終的にIFTTTに投げるという格好はしばらく変わらないと思います。

ちゃんとWebフロントの勉強をする

少なくとも僕以外の人がまともに使えるものを作れるように勉強します。というか時間をかけます。従いましては誰かおすすめの本を教えてください。

iOS版を作る

モバイル端末に関してはどうもApple端末が気に食わなかったのですが、ついにこの間買いました。知り合いに譲ってもらったiPhone 6sです。 とりあえず早速使いだしていますが今は先月買ったポータブルアンプのPHA-1Aが接続できることに歓喜しておりほぼ開発に使っていないという有様です。さっさとこっちも勉強しろ。

多分Androidと似たような構成でMVVMにやっていく気がしています。AutoLayoutむずかちい。AutoLayoutを1時間くらいいじった後にAndroidのConstraintsLayoutのエディタを触るとなんかめっちゃ快適に思えてすごく楽しくなってくるのでおすすめです。

まとめ

とりあえず本当に思うことは「急ごしらえするんじゃなくて一旦自分でも身近な人にでも一度使ってもらって何かしらのフィードバックを得るべき」ということでした。ワイワイ作って勢いで作り上げるハッカソン的開発メソッドはテンションがハイのまま一段落つくまで持っていけるのですが、出来たものがどうなるのかというのはやってるうちはやっぱわからないので頭を冷やして出来たものを見る時間が必要だと思いました。ですがクソでも作り上げていかないと何も始まらないので一気にやってよかったなって思います。

多分来年のMAにはもっとまともな姿に生まれ変わっていると思います。みんなもクソアプリ、やっていこうな。

kotlinx.coroutinesでAndroid用画像ローダを実現する

まずこの記事について

この記事は #kosen10s Advent Calendar の6日目の記事です。

<- 前日の記事(@do_su_0805) 翌日の記事(@kogepan159)->

Kotlinについて何かを書きたい

ちょくちょくAndroidについて書いたりしている(最近イベントレポートしかしてない。まずい)んですが、最近業務でKotlinを書いてた(今はJavaに戻ったりしている)り、趣味コードや勉強会に出るときのサンプルを全部Kotlinにしたりしています。KotlinかわいいよKotlin。

というわけで今年も終わるということでちょっと趣味で書いているAndroid向けの画像ローダについて話してみます。ちゃんと欲しい機能ができればOSS化するつもりですが時間がなかなか取れなくてこいつにコミットする時間がなくてア

作りたい物

Androidで画像ローダといったら square/picassobumptech/glide が有名ですが、これらと似たような使用感の小さいライブラリを用意したいという感じです。usageとしてはこんな感じ

Katsushika.with(context)
        .load(url)
        .into(imageView)

トップクラスの命名は適当です。これを思いついたときはSplatoon2にドハマリしてたので思考回路がわかる人にはわかるはず。

何が必要か

ネットワークを介して画像をロードするので、Androidでは当然非同期処理を扱います(メインスレッドで通信はできない)。非同期で扱いたい処理を挙げると

  • 画像のネットワークからのダウンロード
  • 画像の縮小
  • etc.(キャッシュとか。今回は考えない)

そしてこれらの処理を終えた後にImageViewに対して画像を反映させるわけです。

まずは画像取得以外を作ってみる

とりあえずネットワーク周りはめんどくさいので今のところは square/okhttp を頼ります。

とりあえず最初のスニペットで動かせるように考えて実際にBitmapの取得以外をKotlinで実装するとこんなコードになるはず。 @JvmStatic をcompanion object内のwith関数につけるとJavaコードからも読めるようになるけど今回は省略。

class Katsushika private constructor(private val context: Context) {

    private var url: String? = null

    companion object {
        fun with(context: Context): Katsushika {
            return Katsushika(context)
        }
    }

    fun load(url: String): Katsushika {
        this.url = url
        return this
    }

    fun into(target: ImageView) {
        url ?: return

        // ここで画像ロード
    }

}

実際にpicassoやglideみたいに機能をバシバシつけたいときはこの部分を拡充していくことになるのだけど、キリがないので今回はここまでにします。

画像ロードをする

というわけでinto関数の中身を実装していきましょう。まずは愚直にCall.enqueueのCallbackを使って実装してみます。

fun into(target: ImageView) {

    OkHttpClient().newCall(request).enqueue(object: Callback {
        override fun onResponse(call: Call?, response: Response?) {
            val body = response?.body()
            body ?: return

            // 取得した画像バイト配列から縮小画像生成
            val byteArray = body.bytes()
            val options = byteArray.getBitmapOptions()
            val bitmap = byteArray.decodeByteArray(options, byteArray.size)

            // 対象のImageViewに画像を表示
            (context as Activity).runOnUiThread {
                target.setImageBitmap(bitmap)
            }
        }
    })

}

ちなみにここでのバイト配列からの縮小画像生成はByteArrayにKotlinの拡張関数を生やしたりして手抜きをしています

// Bitmapのサイズ情報を取得する
fun ByteArray.getBitmapOptions(): BitmapFactory.Options {
    val imageOptions = BitmapFactory.Options()
    imageOptions.inJustDecodeBounds = true
    BitmapFactory.decodeByteArray(this, 0, this.size, imageOptions)
    return imageOptions
}

// 取得したBitmapFactory.Optionsを元に2のべき乗のサンプルサイズで縮小する
fun ByteArray.getScaledBitmap(target: ImageView, options: BitmapFactory.Options): Bitmap {
    val widthScale = options.outWidth/target.width
    val bitmap : Bitmap
    if (widthScale > 2) {
        val imageOptions = BitmapFactory.Options()

        var i = 2
        while (i <= widthScale) {
            imageOptions.inSampleSize = i
            i *= 2
        }

        bitmap = BitmapFactory.decodeByteArray(this, 0, this.size, imageOptions)
    } else {
        bitmap = BitmapFactory.decodeByteArray(this, 0, this.size)
    }
    return bitmap
}

ここでinto関数を見ると、 Callbackの中で runOnUiThread ブロックを実行したりしている都合でネストが深めになってしまっています。しかもこんな感じでバシバシCallbackを使う処理を使っているとコールバック地獄になったりしてかなり怖い感じです。どうせならPromiseとか使って上から流れるように書いておきたい…

kotlinx.coroutinesを投入する

Coroutines - Kotlin Programming Language

kotlinx.coroutines はkotlin 1.1にてExperimentalとして実装された言語機能で、コルーチンを扱う低レベルAPIkotlin.coroutines.experimental を扱う高レベルAPIとなっています(開発者がコルーチンを扱うために触るAPIはこっち)。公式リファレンスのコルーチンに関するページを雑に読んでみると

  • コルーチンは軽量のスレッドのようなもの
  • 非同期処理の呼び出しでコルーチンを中断・再開することができる

みたいなことが書いています。kotlinx.coroutinesは外部ライブラリとして提供されているので、使用する際にはbuild.gradleのdependenciesに宣言してあげます。

dependencies {
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.20"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.20"
}

詳しく日本語で読みたい場合は以下の記事とかがいいかも…

qiita.com

コルーチンの中断・再開というのがとても重要で、コルーチン内から呼ぶことができるsuspend関数と言うものを使うようになります

suspend fun foo(): Bar { // 何かしらの処理... }

kolinx.coroutinesではES7やC# 5.0以降で提供されるようなasync/awaitが一機能として提供されており、非同期処理を同期処理っぽく書くことが出来ます。

fun requestItems() {
    itemApi.getItems(object: Callback {
        override fun onSuccess(item: Item) {
            textView.text = item.name
        }
    })
}

という風に書いていたものがkotlinx.coroutinesのasync/awaitを使うことで

fun requestItems() {
    val job = launch(UI) {
        // 一旦ここで関数の実行がitemApi.getItems()が完了するまで止まる
        val item = async { itemApi.getItems() }.await()
        textView.text = item.name
    }
}

こんな風にかけるようになります。 launch(UI) のブロックはコルーチンビルダーといい、引数のCoroutineContextにUIを与えることでUIスレッドで動くコルーチンを作成することになります。async のブロックでは新しく別のスレッドで動くコルーチンを作成し、await()を呼ぶことでブロック内の処理が完了するまで停止することができ、ブロック内の返り値を処理の完了後に返すことが出来ます。asyncの引数としてこちらもCoroutineContextを渡したりでき、これによって実行するスレッドを制御したりすることが可能です。

すると最初に書いたinto関数もいい感じに書けそうだ、という感じがしてきます。とはいうもののまずはCall.enqueueをsuspend関数として呼べるようにCallに拡張関数を用意してあげる必要がありそう。

Call.enqueueをsuspendCancellableCoroutineで包んであげて、その結果に応じてcontinuationの発火をさせるメソッドを変更するようにしてあげます(理解不足で説明が謎なことになっている…)

suspend fun Call.do(): ResponseBody {
    return suspendCancellableCoroutine { continuation ->
        enqueue(object : Callback {
            override fun onResponse(call: Call, response: Response) {
                val responseBody = response.body()
                if (responseBody == null) {
                    // responseBodyが空なら失敗として扱う
                    continuation.resumeWithException(Exception("ResponseBody is null")) 
                } else {
                    // このresumeがawait()した結果の返り値となる
                    continuation.resume(responseBody) 
                }
            }

            override fun onFailure(call: Call, e: IOException) {
                if (continuation.isCancelled) return
                continuation.resumeWithException(e)
            }
        })
    }
}

最後に、これを扱うようにinto関数を書き換えて完了です。

fun into(target: ImageView) {
    url ?: return

    val job = launch(UI) {
        val byteArray = async(CommonPool) { // Responseを待ってからバイト配列を取得
            OkHttpClient().newCall(request).do().bytes()
        }.await()
        
        val options = async(CommonPool) { // 結果からBitmapFactory.Optionsを取得
            byteArray.getBitmapOptions()
        }.await()

        val bitmap = async(CommonPool) { // 上2つが終わったらBitmapを縮小
            byteArray.decodeByteArray(options, byteArray.size)
        }.await()

        target.setImageBitmap(bitmap.await()) // bitmapが出力されたらtargetに表示
    }
}

まとめ

こんな感じでkotlinx.coroutinesを利用することで動作スレッド・処理の完了待機を明示的に宣言でき、非同期処理を同期処理っぽい羅列で書くことが出来ます。やはりこういう機能やPromiseなりで非同期処理を完結にかけると嬉しいですね。

実際はpicasso/glideが強すぎるのでこういう完全な車輪の再発明はうーんうーんって感じになりがちですが、新しい機能なりで試すと結構勉強になったりでいいなぁと思いました。

追記

今回はコルーチン内のasyncを途中でキャンセルさせることをあまり考えていませんでしたが、実際にコルーチンをキャンセルするとその中のasyncもキャンセル出来ないケースがあるそうで、そういうケースにはasyncのCoroutineContextにContext(こっちはAndroidの方)を与えることで親のジョブの子のような扱いになり、ジョブをキャンセルしたときに子もキャンセルされるようになるらしいです。そして async(context + CommomPool) のように和で指定することでUIスレッドでない状態でかつジョブのキャンセルもされるようになるらしいです。

↓参考↓

medium.com

Bonfire Android #2に参加してきた

お詫び

色々あって投稿が本当に遅くなりました。申し訳ありません…

はじめに

yj-meetup.connpass.com

11/6にYahoo! JapanのLODGEで開催されたBonfire Android #2に参加してきました。テーマとしては「Kotlin × サービス」ということで、Yahoo! Japan内外問わず様々なプロダクトでのKotlin採用に関するトークがありました。Toggeterはこちらになります。

togetter.com

まとめ

スライドのまとめ等はconnpassのページから見ることができるので、トークを聞いていて個人的に思ったトピックを幾つか…

導入・JavaからKotlinへのコンバート

やはりサービスでKotlinを導入するとなると新規開発はともかく、既存で動いているアプリケーションのJavaコードをKotlinコードへと置き換えるというケースが多く、その点に関してのお話をたくさん伺うことが出来ました。

  • とりあえずAndroid Studioのconvert機能で1ファイルずつKotlin化する
    • コンバートした後にCompanion Object内のvalconst valにしたりNonNull/Nullableの考慮をしたり
  • 既存クラス置き換えは良い勉強になる。とりあえず「習うより慣れろ」でKotlinの学習を進めるのもあり
    • もちろんKotlin Koansもとっても有効
    • よく言われているように自由度が高いのでチームとしてのベストプラクティスを持つのが大事だと思いました
  • 成長のためのKotlin導入
    • 「使う技術・言語は自分で決める。いい道具で仕事をしよう」という言葉が印象的でした
    • 成長したら/勉強したらやるから… -> いつ成長するの?いつ勉強するの?というジレンマ

エンジニア外から見たKotlin採用

特に興味深かったのが、スクラムマスター、ビジネスサイドと言ったメインでコードを書くようなエンジニアではない視点からの言及がいくつかあったことでした

  • Kotlin導入にビジネスインパクトはあるのか
    • 一応品質向上や広報効果といったインパクトはある
      • Javaと比較してNull安全であること等による品質向上
      • 最新技術に挑戦しているという技術広報的なメリット
  • そもそもリプレースをやるべきであるか?という問に明確に答えが出せないなら踏みとどまるという策もある
    • 置換え中のサービスのグロースは?
    • 新機能開発は?
    • ビジはどう説得するの?
  • 業務の一部を使ってインパクトのないところで検証して新規モジュールからじわじわKotlinにというケース
    • 既存モジュールへの影響を廃していつでもやめられる状態を作り出す
  • 置き換えを頑張るくらいならユーザさんに新しい価値を届けることに時間を使いましょう
  • スクラムマスター的には…?
    • タイミングがあればチームのモチベーション・成長観念的にKotlin導入は全然アリ
    • Kotlinの時点でコストがかかる、けどポジティブな結果を呼べるので取り組みたい…!
      • 導入に対するネガティブチェック・ロードマップの作成で取り組みへの説得力をもたせたい
    • ここまで動けるスクラムマスター、素晴らしいし大変だしで尊敬する…

まとめ

KotlinがAndroid開発の1st languageになったことでみんな導入したいという思いがある中でこういうモデルケースをたくさん伺うことが出来たのはとても良かったなと思いました。ただ、その中でもAndroid FrameworkはJavaで書かれているという事実もあって、Kotlinを導入してもJavaからは逃げることが出来ないということや、プロタクトのインパクト的な観点から導入に際してどう付き合っていくのか、チームとしてどうKotlinを導入して実装を進めていくのかなど、課題と言うか考えるべき案件もまだまだあるなと…。でもそれを乗り越えて得られるものもたくさんあると思いました。

主催のYahoo! Japanさん、発表者の皆様、ありがとうございました :bow:

第50回 情報科学若手の会に参加してきた #wakate2017

通算3回目の参加だそうです。社会人になってからは初めての参加っぽいです。

というわけで、今年も伊東市は山喜旅館にて開催された情報科学若手の会に参加してきました。なんと50回目。アニバーサリーって感じです。おまけに伊東市はその日は秋祭りで市政70周年だったそうで、こちらもアニバーサリーって感じでした。

前回の参加ブログはこちらです。

e10dokup.hateblo.jp

雑なまとめ

  • 相も変わらず話題が豊富
  • 50周年記念なので記念セッションがあった
    • 国立国会図書館に眠る記録が掘り出されていた
    • 案外昔想像されていたことが今実現されてたりして心温まる感じ
    • 手書きの報告書の書き手が村井純先生だったり
  • 交流イベント
    • 今年は何をやらされるかと思ったらQRコード陣取りゲーム
      • QRコードが読めなくなるまでお互いに付箋を貼って読めなくなった時点で一番多い枚数を貼った人が勝ちとか
    • 第1問の回答が各位絞り出したエモさで強かった
      • 「相互投票」になると思っていなかったので幹事の方のサンプルと100%一致する答えをしてしまって選外になりました :bow:
    • 強いQRコードリーダーは強い
      • スマホのリーダーは全滅してもなお読めたりする
  • ナイトセッション
    • 相変わらずエモい話で盛り上がる
    • ピングー
    • 今年のLT用プロジェクタの配置が神がかっていて一杯の人が聴ける感じでとても良かった
    • 結局毎日3-4時就寝
    • 突発的スプラトゥーンバイト若手の会
      • オフラインよりオンラインプラベのほうが落ちないっぽい
      • 評価が155%まで上がりました :bow:
  • お祭り
    • 二日目にお祭りがあったのでみんな外に出てみた
    • ついに旅館から出ることの許されなかった若手の会の参加者が外へと足を踏み出す奇跡の瞬間
      • こう書くとシャバの空気を吸うみたいな話になる
  • ネットワーク
    • 今年は明らかにオーバーキルだった
    • 幹事/野生の幹事の方々ありがとうございます
    • 快適にも程がある

ところで来年は…

幹事を勤めさせていただくことになりました

噂によると「初参加の人が突然肩を叩かれて気付いたら幹事になっている」とのことでしたが3年目にして突然肩を叩かれました。 今年幹事を引退される方々に負けないように幹事業をやっていきたいと思います。とにかくやっていくぞという気持ちです。

ちなみに幹事の杯として50年物のワインをみんなで頂きました。ワイン苦手なのですがなんかドチャクソ美味しくてすごかったです。

来年の情報科学若手の会もよろしくお願いいたします :bow:

ところで何かあなた発表したの?

ちゃんとした学術・技術的な発表はしませんでした。ただ幹事の方からご希望を頂いたので新宿御苑をひたすら勧めるLTをしていました。新宿御苑はリビングであると同時にコワーキングスペースなのでみんな行きましょう。寝ましょう。コーディングもしましょう。

ちなみに新宿御苑というと映画「言の葉の庭」で雪野先生が東屋で金麦片手にチョコレートを食べているのが印象にある方も多いと思いますが新宿御苑は禁酒ですのでお気をつけください。一体何を気をつけるのか…