おいしい健康 開発者ブログ

株式会社おいしい健康で働くエンジニア・デザイナーが社内の様子をお伝えします。

Androidで動画をサクッと撮るコマンドラインツール作った

ここ2~3年Android開発から離れていましたが、最近Androidエンジニアとして復帰を果たした @tomorrowkey です。

開発を楽にするために日頃からいくつかの工夫をしており、以前Cookpadに在籍していたときに Android開発を爆速にする10のコマンドラインスクリプト という記事を書きました。

今回Androidエンジニアとして復帰するにあたって、Androidアプリの開発をするためにそういったツールを準備をしているうちに、いつのまにか新しいスクリプトを書き始めていました。まるでラーメンを作るために畑から作っている人たちみたいですね。

コードレビュー時によくあるシーン

おいしい健康ではGitHubリポジトリとして使っており、PRを作ってマージするためには、他のエンジニアにレビューしてもらう必要があります。 モバイルアプリだとよくあると思うのですが、このときに動きが分かるものが説明に貼られていると、レビュアーにも親切です。

PRに貼られたGIFアニメーション

これはiOS版おいしい健康に対するPRに貼られたGIFファイルです*1GitHubに添付できるファイルの種類の中で、アニメーションできるのは、GIFだけです*2。なので、iOSの場合、シミュレータであれば、画面をそのままキャプチャしたり、フィジカルデバイスの場合は QuickTimeミラーリングしたものをキャプチャしたりしていました。

Androidの場合

Androidの場合にはどういった方法でキャプチャすることが可能でしょうか。

少し前でしたら AndroidTool というものがあり、なかなか手軽でおすすめしていましたが、最近息をしている様子がありません。

ApowerMirrorVysor などを使えばキャプチャできそうですが、一部有償なわりに私がそこまで使いこなすイメージも沸かなかった。デバイス側にアプリのインストールが必要などの理由で、断念しました*3

そもそもAndroidには録画機能がある

そもそもなんですが、Androidには画面を録画するためのコマンドラインが用意されています。

Android Debug Bridge  |  Android Developers

このコマンドラインを使えば録画することができます。 ですが、本来の目的である「コードレビュー時にGIFファイルを貼りたい」を達成するためには、2つの不満点があります。

  • 動画ファイルはデバイス側に保存される
  • 動画のままではGitHubに貼り付けられない

前置きはだいぶ長くなりましたが、この不満点をスクリプトを書くことで解決しました。

android-screen-record

本来の目的である、「コードレビュー時にGIFファイルを貼りたい」という欲望を満たすために、android-screen-record というコマンドラインツールを書きました。

github.com

やっていることといえば、adb shell screenrecord を実行して、動画ファイルを抜き出して、ffmpeg でGIFファイルに変換していることくらいです。 いくつか工夫したことはありますが、詳しくはコードを読んでみてください。稚拙なコードなので、きれいに書く方法をご存知であればPRお待ちしております!🤗

使い方

ただ単にコマンドを実行すれば録画が始まります。今のところオプションはありません。

$ android-screen-record

ctrl + c でインタラプトすると録画を終了します。自動的にGIFファイルに変換してデスクトップにコピーされますので、あとはGitHubにペタペタ貼るだけです。動画ファイルもそのまま残しているので、単に録画だけしたいケースでも使うことができます。

インストール方法

homebrew をお使いであれば2つのコマンドだけでインストール可能です。

$ brew tap tomorrowkey/self
$ brew install tomorrowkey/self/android-screen-record

残る問題点

ffmpeg のオプションをあまり知らないからか、GIFアニメーションがなかなか大きいファイルサイズになってしまいます。本来の目的から考えると多少フレームが落ちたり、画質が悪いのは受け入れられるので、質を落としてファイルサイズを減らせるような工夫ができるといいなあと思っています。

おわりに

今回はAndroidエンジニアとして復帰するにあたり作ったツールをご紹介しました。 おいしい健康では、Androidだけではなくサーバサイドやサービス開発など、バリエーションに富んだ開発に興味があるエンジニアを募集しております*4。 もし興味があればWantedlyよりご応募ください!

*1:GIFアニメーションを表示しているシーンをGIFアニメーションとして表示するのはなかなかシュールですね

*2:File attachments on issues and pull requests - GitHub Help https://help.github.com/en/articles/file-attachments-on-issues-and-pull-requests

*3:さんざんお世話になったadakodaさんの ASM ももう息をしてなかった…

*4:もちろんAndroidに特化した人も募集中です

Google Colaboratory上でPythonのフォーマットをチェックしよう

こんにちは、おいしい健康アルバイトの成澤です。

おいしい健康には2019年2月に入社して、主に食べリズム*1という調査研究アプリのデータ分析周りを担当しています。いま大学院で数学を勉強していて、研究内容がデータ分析や統計には関係していないのですが、アルバイトのでの実務を通してスキルを磨いています。社員の花井さん(BIgQueryで協調フィルタリングを書いた人)と一緒にデータ分析をやっています。

最近は Google Colaboratory 上で Python を書いていることが多いです。 Google Colaboratoryは分析結果の共有にも便利なので可読性の高いコードを書きたいですよね。

そこで今回はGoogle Colaboratory 上のコードが Python のスタイルガイド PEP8 *2 に準拠しているか、Flake8*3を利用して、フォーマットチェックする方法を書きます。 PEP8に準拠したコードで可読性を高め、分析結果の共有をスムーズにしましょう。

Jupyter Notebook には拡張機能で autopep8 などをすぐに追加し利用することができますが、Google Colaboratory で同じようなことをするのに苦労したのでまとめておきます。

f:id:oishi-kenko:20190705191755p:plain

Flake8を適用する

まず、セル上で以下を実行して、pycodestyle, flake8, pycodestyle_magicをインストールします。

!pip install pycodestyle flake8 pycodestyle_magic

次にpycodestyle_magicでmagic functionを使うために、セル上で次を実行します。

%load_ext pycodestyle_magic

これで準備は終わりです。セルに%%flake8を入れて実行するとフォーマットチェックがかかります。

試しにやってみる

下記のようなコードを実行するとフォーマットエラーが表示されます。

f:id:oishi-kenko:20190705181221p:plain

また、flake8でなくpycodestyleを使うこともできます。

f:id:oishi-kenko:20190705181234p:plain

表示されたフォーマットエラーを修正すればいいわけですが、ここで気をつけたいポイントがあります。

インデントに関するエラーを詳しく見てみることにします。

インデントのスペースと行番号の設定

さて、上のフォーマットチェックで、

3:3: E111 indentation is not a multiple of four

3行目のインデントがスペース4つではない と怒られました。PEP8ではインデントにスペース4つに使用することになっているので、それに違反しているようです。

実は、Google Colabratoryではインデントが初期設定ではスペース2つ になっています。これを変更します。また行番号が表示された方がエラーが読みやすいのでそれも追加しておきます。

ツールバーツール設定からエディタを開きます。そこでインデント幅(スペース)4 に変更します。また行番号を表示するにもチェックを入れます。

f:id:oishi-kenko:20190705161206p:plain

これで自動的でスペース4つで下げられるようになりました。他の部分も言われた通りに直せばフォーマットチェックが通ります。

f:id:oishi-kenko:20190705161900p:plain

参考

Google Colaboratory のフォーマットチェックに関する情報は少ないのですが、以下が参考になりました。

github.com

stackoverflow.com

東京大学の Deep Learning 基礎講座に参加して

おいしい健康 関口です。

おいしい健康のエンジニアには、様々な学習機会に積極的に触れていくことを推奨しています。

少し時期は遅くなってしまいましたが、私ともう2名のエンジニアで、東京大学で開かれている Deep Learning 基礎講座(2018) に 2018年10月~2019年3月まで参加してきましたので、そのレポートをお伝えしようと思います。

Deep Learning 基礎講座 2018

deeplearning.jp

2018と書いていましたが、公開講座自体は 2015年から開かれているようです。 私が参加できることになった 2018年では、事前に python の基本的なコードを書けるかのテストがあり、そのテストに回答できた人から抽選で参加者が決まるという、少し参加にハードルが設けられたものになっていました。

私自身は、 python でこれまでコードを書いたことはありませんでしたが、機械学習周りで特に必要になるような行列の操作を中心に事前に勉強しておき、テストに臨みました。

そして、ありがたいことに参加できることになりました。。!

(こぼれ話ですが、2017年にも応募していたのですが、python 周りの経験に関するアンケートだけで、ハードルは限りなく低かったものの、落選してしまい、2018年が2度目の応募でしたw)

本講座の流れ

講座はかなり幅広く機械学習周りのトピックについて触れられるようになっています。

講義では数式をベースとした理論の話、講義の直後の演習ではそれをコードに落とすとどうなるかというところを中心に話が展開されます。

この講座を修了すると、その気になれば TensorFlow のようなライブラリーが作れるくらいの理論を身につけられる。というところを目指して講義が進んでいくため、内容としては理論のところが深く掘り下げられていきます。

また中盤までは TensorFlow などの高レベルのAPIを提供しているライブラリーは使わず、むしろそれらが提供している関数(活性関数や、 誤差関数、畳込み処理の仕方 etc...) を自前で実装していくことになります。

python を主流で扱っていない私としては、言語的にも苦しみながら、なんとか宿題を終わらせていました。

中盤から後半にかけては、 TensorFlow や Keras を用いながら、少し複雑な処理が必要になってくる NLP、 生成モデル、強化学習について触れられて行きます。

2018年12月まではそういった基礎を積み上げていき、講義後半では NLP、生成モデル、強化学習のいずれかのトピックについてさらに深ぼって学習が進んでいきます。

最終的には、運営側より指示されたチームごとにプロジェクトを組み、一つのアウトプットを出すことになります。 私自身は、キックオフこそ参加していたものの、途中でどうしても優先しなければならない仕事が立て込んでしまい、残念ながらチームへのコントリビューションは叶いませんでした。。

感想

実際に参加してみて、理論と実践が入り交じるこの講座が無料で受けられるというのはかなりありがたいことだなと思います。 落選してしまった 2017年に Cousera の Andrew Ng 先生の Machine Learning を受けていたり、 ゼロから作る Deep Learning を読んでいたりしていたこともあって、講義の途中振り落とされそうなところもなんとか振り落とされずについていくことができました。

ja.coursera.org

生徒一人に対して GPU 付きのリソースを割り当ててくれたり、高品質な授業と、課題、プロジェクトで現在の Deep Learning で盛り上がっているところを手を動かしながら学べるというのは非常によい経験となりました。

2017年には弊社から別のメンバーが参加していましたが、非常に進化が早い技術領域でもあるので、2017年から内容もアップデートされており、どんどん講座の内容も進化していっています。

授業自体、平日に開催され、内容にもかなりスピード感があり、宿題もいい感じに時間が必要になるくらいの難易度なので、講座に出席している間はだいぶこちらにコミットすることになります。 会社の理解がなければ修了することはなかなか難しいかもしれませんが、もしお時間が許せば是非参加してみてください!

また、おいしい健康では業務時間を用いて、こういった学習をしていくことも推奨しておりますので、いいな!と思う方は下のリンクより、ご応募をお待ちしています!

おいしい健康オフィス紹介

こんにちは。おいしい健康エンジニアアルバイトの伊藤です。

おいしい健康ではiOSアプリを開発しています。

今回は社内の様子をお伝えしますと書いてあるのに様子を伝えてるのがペアプログラミングを導入して分かったことしか書かれていないということに気づいたのでオフィス紹介をしたいと思います。

弊社のオフィスはザ・パークレックス小網町第2ビル 4階 にあります。

東京メトロ東西線 茅場町駅7番出口より徒歩5分

東京メトロ半蔵門線 水天宮前駅8番出口より徒歩5分

という便利な場所にあり近くには飲食店がたくさん並んでいます。

ここがおいしい健康の入り口です。

f:id:oishi-kenko:20190508151705j:plain 中に入るとオフィスエリアが広がっていています。

ディスプレイは誰でも自由に使うことができ、仕切りがないので広々と使えます。

f:id:oishi-kenko:20190501152634j:plain

左手には打ち合わせスペースがあります。ここではミーティングや面接などを行っています。

f:id:oishi-kenko:20190501150406j:plain

本棚にはプログラミングの技術書や病態やダイエットなどのヘルスケア系の本が並んでいています。

本棚の本は借りることができるので電車の中や自宅などで読むことができます。

弊社は書籍購入補助制度があり好きな本を購入することができます。

オフィスにはキッチンが面していて、誰でも自由に使うことができます。

自分でお昼ご飯を作ったり、管理栄養士が試作レシピを作っているので、試食することもできます。

f:id:oishi-kenko:20190501150454j:plain

最後に集中エリアです。

f:id:oishi-kenko:20190508185853j:plain いかがだったでしょうか?

以上、オフィス紹介でした!

AndroidStudioのテンプレートを活用する

こんにちは、おいしい健康の真崎です。

おいしい健康ではAndroidアプリの開発を行っています。

日々、Android開発を行っていて、開発効率を上げるために、テンプレートを作成した話を紹介します。

弊社では以下のような構成で開発を行っています。

  • MVVM
  • DataBinding
  • DIとしてKoin

そのため、既存の テンプレートであるFragment ( with ViewModel )を利用していました。しかし、既存のテンプレートでは以下の作業が発生してしまいます。

  • Databinding対応のための書き換え
  • DIとしてKoinを使う書き換え

この手間が毎回発生していたので、もっと楽にできる方法はないかと調べいたところ、Android Studioのテンプレートをカスタムする方法にたどり着きました。

Android Studio のテンプレートとは

developer.android.com

Android Studio では、Android の設計と開発におけるベストプラクティスに基づいたコード テンプレートが用意されているため、適切な道筋に沿って美しく機能的なアプリを作成することができます。

Android Studio のテンプレートカスタマイズについて

Mac の場合は以下のパスにテンプレートがおいてあります。

cd /Applications/Android\ Studio.app/Contents/plugins/android/lib/templates/other/

今回はFragment ( with ViewModel )のテンプレートをカスタマイズするので、適当なディレクトリ名でコピーします。

cp -r ViewModelFragment MyViewModelFragment

中身を見てみると以下のような構成になっています。

% tree
.
├── globals.xml.ftl
├── recipe.xml.ftl
├── root
│   ├── res
│   │   └── layout
│   │       └── blank_fragment.xml.ftl
│   └── src
│       └── app_package
│           ├── BlankFragment.java.ftl
│           ├── BlankFragment.kt.ftl
│           ├── BlankViewModel.java.ftl
│           └── BlankViewModel.kt.ftl
├── template.xml
└── template_blank_fragment.png

テンプレートを記述方法としてFreeMarkerが使われているようです。

freemarker.apache.org

書き換えたファイルとしては以下のようなことを作業しました。

  • template.xml の name を書き換えて自分のテンプレートの名前を決定します。
  • BlankViewModel.kt.ftl, BlankFragment.kt.ftl, blank_fragment.xml.ftl を Databinding + Koin に対応した形に書き換えました(弊社ではkotlinを使っているので、java側のテンプレートは書き換えず削除してしまってます。

結果

テンプレートを作成したことにより、あらたな画面を作っていくときにすぐその画面の実装作業に映ることができるようになったので、開発効率は上がったと感じています。

以上です

1行の変更でWebサービスの速度を5倍にした話

こんにちは。おいしい健康エンジニアの近藤です。

おいしい健康では、iOS、Web(API / フロントエンド)、インフラ、SEOなど幅広く担当しています。 今回は掲題の通り、たった一行の変更でおいしい健康のWebサイトのパフォーマンスを大きく改善することが出来ましたので、ご紹介させていただきます。

PageSpeed Insightsとは

皆さんは、PageSpeed Insightsはご存知でしょうか?

PageSpeed Insightsとは、Googleが提供しているWebサイトのパフォーマンス(速度)を測定するためのツールです。 無料で利用することができ、改善事項なども細かく提示してくれますので、利用したことが無い方は、ぜひ一度お試しください。

developers.google.com

おいしい健康の速度スコア

お恥ずかしながら、おいしい健康のPageSpeed Insightsの速度スコアはとても低くなっていました。

私の方で https://oishi-kenko.com/ に対して、実行した結果は以下の通りです。

f:id:oishi-kenko:20190411154056p:plain

100点満点で、0〜49が遅いという評価のため、おいしい健康の11というスコアはとても遅いという位置づけでしょうか。

ただし、この速度スコアには少しカラクリがあり、モバイルのパフォーマンスについては、3G回線利用時の通信速度をベースとしたスコアとなっています。

そのため、4G回線を利用している場合は、おいしい健康の表示にそこまで遅いとは感じないはずです。 日本では、現在は4G回線が主流で、2020年には、NTTドコモKDDIソフトバンク楽天モバイルで、5Gの商用通信サービスが開始される見込みとの報道もありました。

しかし、日本以外ではまだ3G回線以下の速度の地域も多いことや、ページ読み込み速度はSEOの指標の一つになっていることもあり、可能であれば速度改善をしたいところです。

速度スコアの改善項目

PageSpeed Insightsで主に以下の項目が指摘されていました。

No 改善できる項目 短縮できる時間(推定)
1 レンダリングを妨げるリソースの除外 7.93s
2 テキスト圧縮の有効化 7.05s
3 キー リクエストのプリロード 6.12s
4 オフスクリーン画像の遅延読み込み 3.75s
5 次世代フォーマットでの画像の配信 1.95s
6 使用していない CSS の遅延読み込み 1.8s
7 効率的な画像フォーマット 0.9s

多くの改善項目がありますが、前述の通り、モバイルの速度スコアは3G回線利用時の通信速度がベースとなっており、通信容量の影響を非常に多く受けます。 そこで、通信容量の削減を行うことで、全体的に表示速度を改善できるのではないかという仮説を立て、先ずは、テキスト圧縮の有効化を実施することにしました。

テキスト圧縮の有効化

おいしい健康では、 AWS の S3 に CSS や JS などのアセットを配置し、CloudFront経由で配信しています。 今回はこれがgzipで圧縮されていなかったため、PageSpeed Insightsで改善項目として挙がっていました。

CloudFrontで配信しているファイルの圧縮は非常に簡単です。

docs.aws.amazon.com

おいしい健康では、Cfdefというgemを使い、CloudFrontの設定内容をDSLとして管理しているため、今回の対応内容としてはDSLの変更のみです。

実際の変更内容は以下の通りです。

-    compress false
+    compress true

タイトルの通り、diffは1行だけですね。

改善後の速度スコア

気になる改善後の速度スコアはこちらです。

タイトル通り、1行の変更で速度スコアが11から58と、ほぼ5倍になりました。

さいごに

この記事では、テキスト圧縮の有効化の対応内容をご紹介させていただきましたが、これ以外にもいくつか比較的簡単に改善できる項目もあるため、 皆さんも一度確認してみてはいかがでしょうか。

今回は以上です。

git commitする前にktlintでフォーマットチェックをかける

こんにちは。おいしい健康エンジニアの小林です。

昨年12月に入社しまして、Androidアプリの開発をしています。おいしい健康ではAndroidアプリをKotlinで開発しておりフォーマッターにはktlintを使用しています。

ktlintとは

Android公式のスタイルガイドに基づいてコードチェックをしてくれるKotlin用のlinterです。自動でフォーマットしてくれる機能も用意されています。

ktlint.github.io

ktlintはGradleプラグインが提供されているためAndroidプロジェクトへの導入が簡単です。

おいしい健康ではPullRequestのコードに対してCircle CI上でktlintを走らせるようにしています。

レビュワーの労力を、コードフォーマットのレビュー(本質的ではないこと)に使いたくないで非常に便利です。

Push前にもlintしたい

コードフォーマットの修正漏れがあっても気づけるようにCircle CI上でktlintを実行しているのですが、

  • ほぼ毎回Push後にフォーマットの修正漏れに気づく。
  • ./gradlew ktlintFormatかけてまたPush!
  • あ、ビルド渋滞が……
  • 修正漏れ分のビルド中止をするの面倒。
  • push前にフォーマットかけていれば、ビルドを無駄に走らせなくてもよかったのに。

と言った点から、ローカルでも自動チェックしたいなと考えました。 ./gradlew ktlint って叩けばチェック可能なんですが、コード書く度に手動で叩きたくないので(叩くの忘れるので)、何かをトリガーに自動化したいです。

Commit前にlintする

Command Line版のktlintに用意されてました。

$ ktlint --install-git-pre-commit-hook

と実行すると自動でpre-commitファイルが作成されます。

すでにpre-commitを使用している場合は、

git diff --name-only --cached --relative | grep '\.kt[s"]\?$' | xargs ktlint --relative .
if [ $? -ne 0 ]; then exit 1; fi

を追記すれば良さそうです。(ktlint --install-git-pre-commit-hookで生成された中身です。)

Commitすると以下のようにktlintが自動でチェックしてくれます。

$ git commit
app/src/main/java/com/example/MainActivity.kt:8:27: Missing spacing before "{"
app/src/main/java/com/example/MainActivity.kt:10:1: Unexpected indentation (1) (it should be 8) (cannot be auto-corrected)

これでローカルでフォーマットの修正漏れに気づくことができますね。

Android Studioで使う

Gitをコマンドで実行している場合は特別意識せずにgit commitすればktlintが走ってくれます。

Android StudioGUI上でGit Commitしている場合は、 Commit Changes の Run Git hooks オプションをオンにしてあげればOKです。

Android StudioのRun Git hooks
Run Git hooksをオンにする

Ktlintのコードチェックに失敗すると、以下のような目に悪いアラートが表示されるので、フォーマット忘れに一目で気づくことができますね。

ktlintの実行結果
ktlintの実行結果

これで修正忘れにプッシュ後気づくこともなくなり、Commit分のコード自体も綺麗になります。

今回は以上です。