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

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

プログラミング無しで「つながり」ネットワーク解析(2部グラフの隣接行列の計算)

こんにちは。データ分析チーム(仮)の花井です。最近は、社内に蓄積されたデータを分析し可視化する方法を模索しています。 過去の記事では協調フィルタリングによるレシピ類似の可視化があります。 oishi-kenko.hatenablog.com

「つながり」を解き明かすネットワーク科学は、これまで薬品設計・代謝工学などの分野で研究者の間で応用されてきましたが、最近では人事に関わる「ピープル アナリティクス」*1といった分野が急速に発展しています。弊社では、ホットなネットワーク科学を食と医療に応用して様々な「つながり」を分析・活用していこうとしています。

今回は、 弊社のSlackデータを例にして、スプレッドシートを使ったネットワークの解析を説明します。BigQueryやPythonを題材にしようと思ったのですが、エンジニアに限らず誰でもネットワークの解析ができるよう、ノンプログラミングできる表計算ソフト(MicrosoftエクセルやGoogleスプレッドシート)を使った解析方法について扱います。また、どのような見方でネットワーク構造を捉えているか解説します。

一言でいうと、メンバー集合およびチャンネル集合で構成される2部グラフの隣接行列の二乗をスプレッドシートで計算し、メンバーネットワークおよびチャンネルネットワークを隣接行列から考察します。

問題設定

「ほぼ全員が参加しているチャンネルは除いて、発言が活発なSlackチャンネルにどのメンバーが所属しているか」という情報をリスト形式のデータを持っていると仮定します。 このとき、どのメンバー同士が会話可能か、チャンネル同士の共通メンバー数を一覧で見る方法を考えます。

持っているデータは下記のような2つのリスト形式です。

リスト1(チャンネルとメンバーの所属関係)

チャンネル メンバー
A 1
A 2
A 5
A 10
... ....
E 45

リスト2(メンバー一覧)

メンバー
1
2
3
4
...
46

記事執筆時点では46名の社員がSlackに参加しています。ほぼ全員が参加しているチャンネルは除いて、発言が活発なSlackチャンネル上位5つにジョインしているメンバーを(Slack APIを使って無理やり)抽出しました。

アプローチと用語説明

今回ようなリスト1を見たとき「これは2部グラフの枝だな」と思いました。

なぜそのように思ったのか説明していきます。

まず、メンバーとチャンネルをそれぞれノードとして配置してみましょう。

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

Aチャンネルにメンバー5が所属している」という所属関係を下記のように線を結んで枝を作成します。

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

リスト1に基づいて、枝を追加していくと下記のようなグラフができます。

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

リスト1は、所属関係を示しているのでチャンネルとメンバーの要素間に枝が生成され、チャンネル同士やメンバー同士の枝はありません。

このように、要素間に枝がないノード集合が2つできるグラフを2部グラフと言います。

チャンネル集合を  {C} , メンバー集合を  {M} とすると、頂点が  {U \cup M} に属し、枝が  {(v, u), v  \in C, u \in M } となる無向グラフになっています。

隣接行列の表示

ここで、隣接行列を作ります。表計算ソフト(MicrosoftエクセルやGoogleスプレッドシート)ではピボットテーブルの作成により行います。

隣接行列とは、頂点uからvに枝があるとき(u, v)成分を1とし、枝がなければ0とする行列です。

隣接行列を作るために下記操作をしてリスト3を作ります。

  • リスト1をそのままノード1、ノード2に追加。リンクは1にする。
  • リスト1の左右を入れ替えてノード1、ノード2に追加。リンクは1にする。
  • 各メンバーをノード1、ノード2に追加。リンクは0にする。
  • 各チャンネルをノード1、ノード2に追加。リンクは0にする。

リスト3(隣接行列の準備)

ノード1 ノード2 リンク
A 1 1
A 2 1
A 5 1
A 10 1
... .... ...
E 45 1
1 A 1
2 A 1
... ... ...
45 E 1
1 1 0
2 2 0
3 3 0
... ... ...
46 46 0
A A 0
... ... ...
E E 0

このリスト3を選択してピボットテーブルを作成すると次のようになります。

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

このピボットテーブルを別シートにコピーして、空白を0に置換し、1を緑色で塗る書式設定をすると次のような見やすい表になります。

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

この大きな表から行がメンバー・列がチャンネルの部分だけ取り出して並び替えてみましょう。

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

色々なことが分かります。

  • 5つのチャンネルすべてに所属しているハブとなるメンバーがいる
  • 5つチャンネルは3つのグループに分かれている
    • (1) A,D (2) C, E (3) B
    • チャンネルA, Dは共通メンバーが多い
    • チャンネルC, Eは共通メンバーが多い

隣接行列の2乗を計算

さて、今回は次のことを明らかにしようとしています。

  • どのメンバー同士が5つのチャンネル内だけで会話可能か知りたい
  • チャンネル同士の共通メンバー数を一覧で見たい

言い換えると*2

  • ある2人のメンバー  {m_1, m_2 \in M} と任意のチャンネル  {c \in C} に対して  {m_1 c m_2 } となるパスが存在するか知りたい
  • ある2つチャンネル  {c_1, c_2 \in C}と任意のメンバー { m \in M}に対して パス  {c_1 m c_2} の数を知りたい

これを解くためにグラフ理論の定理を利用します!

あるネットワークに対する隣接行列{A}{n}{ {A}^n }{(i,j)} 成分は点{i}から点{j}への長さ{n}のパスの数となる

今回のケースに置き換えると次のようになります!

リスト3のピボットテーブルで生成した隣接行列{A}の2乗 { {A}^2 }{(i,j)} 成分はメンバー{i}からメンバー{j}もしくはチャンネル{i}からチャンネル{j}への長さ2のパスの数となる

隣接行列の二乗を計算には MMULT 関数を使います。*3

=MMULT(行列の範囲,行列の範囲)

隣接行列の隣に MMULT 関数を使った隣接行列の2乗を表示します。カラースケールで書式設定して見やすくしています。

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

それぞれの数字をどのように見ればいいのか説明します。

  • 行と列が同一メンバーのとき、所属しているチャンネル数を示しています。
    • メンバー '2' は2つのチャンネルに所属している
    • メンバー '3' は2つのチャンネルに所属している
    • メンバー '5' はすべてのチャンネルに所属している
    • メンバー '6' はどのチャンネルに所属していない
  • 行と列が異なるメンバーのとき、共通の所属チャンネル数を示しています。
    • メンバー '2', '3' で共通しているチャンネルはない
    • メンバー '2', '5' で2つ共通して所属しているチャンネルがある
  • 行と列が同一チャンネルのとき、所属メンバー数を示しています。
    • チャンネルAは19人が所属している
  • 行と列が異なるチャンネルのとき、共通の所属メンバー数を示しています。
    • チャンネルA, B で5人のメンバー共通して所属している。

目的のデータが得られましたね!

ネットワークの可視化

表計算ソフトではネットワークの可視化ができませんが、Cytoscape等のソフトウェアを使うとこのように可視化できます。

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

例えばメンバー '10' は オレンジ色で塗られたA, C チャンネルを通じて、ピンク色で塗られたメンバーとやり取りできます。

このピンク色のユーザー数が隣接行列の2乗から分かる事が本記事のポイントでした。

データ分析チームを募集しています

冒頭で「データ分析チーム(仮)の花井です」と自己紹介しましたが、現在はデータ分析チームはありません。これからデータ分析チームを作っていこうとしています!

今回はノンプログラミングのデータ分析事例を紹介しましたが、ネットワーク科学などの理論を駆使した面白いデータ分析をプログラミングによりスケールできるよう計画中です。

自社サービスの拡充と医療従事者との共同研究にチャレンジするデータ分析・可視化業務に興味ある方は下記からご応募ください。

※上記はアルバイトの募集ですが、フルタイム勤務も募集しております!

*1:https://rework.withgoogle.com/jp/subjects/people-analytics/

*2:グラフ理論に詳しい方が見たら突っ込まれそうな書き方ですが... 厳密に書くのは諦めました

*3:https://support.google.com/docs/answer/3094292?hl=ja

XcodeGenを使ったiOSプロジェクトに、XCUITestとXCTestを導入した話

はじめまして。昨年10月からiOSエンジニアとして入社しました、佐々木と申します。 子育て中のため時短で働いております。

今回はおいしい健康アプリのプロジェクトに、Apple公式のテストフレームワークであるXCUITest(UIテスト)とXCTest(Unitテスト)を導入した時の事を書きます。 XcodeGenというツールにも対応したので、そこも含めての内容となります。

XCUITestを導入

まずは、XCUITestの導入手順になります。

  • File> New> Target...> iOS UI Testing Bundle> Next
  • ProductNameにoikenUITestsと入力> Finish
  • プロジェクト配下に、ProductNameと同じディレクトリとファイルができます。
  • ファイルを開き、testExampleメソッド内にカーソルを置くと、赤丸のRecord UI Testボタンが有効になります。
    f:id:oishi-kenko:20190719144601p:plain
    Record UI Test Button
  • そのボタンを選択すると、アプリが起動します。
  • アプリ内のボタン等をタッブすると、挙動が自動でファイルに記述されていきます。スゴイ!
  • テストを実行するには、cmd+Uキーです。

XCUITestの方はこれでOKです。

XCTestを導入

次に、XCTestの導入手順になります。

  • File> New> Target...> iOS Unit Testing Bundle> Next
  • ProductNameにoikenTestsと入力> Finish
  • こちらもプロジェクト配下に、ProductNameと同じディレクトリとファイルができます。
  • ファイルを開き、試しにテスト処理を入れます。 その際アプリの処理を呼ぶには、importの並びに以下のような記述が必要となります。
@testable import oiken

しかしこのままだと、No such module ...でエラーになってしまいます。

プロジェクトの設定ファイル等を修正

エラーを解消するには、いくつか設定ファイルを変更する必要があります。 修正箇所はstack overflowの投稿をいくつか参照してを見つけました。

  • Podfileにテストのターゲットを追加します。

修正前

pod 'XXX'
pod 'XXX'

target 'oiken' do
end

use_frameworks!

修正後

def standard_pods
  pod 'XXX'
  pod 'XXX'
end

target 'oiken' do
  standard_pods
end

target 'oikenTests' do
  inherit! :search_paths
  standard_pods
end

target 'oikenUITests' do
  inherit! :search_paths
  standard_pods
end

修正後は以下のコマンドで、CocoaPodsを更新します。

bundle exec pod install

  • oiken> Product Module Name> アプリ名を変更します。 開発スキーマの末尾に追加していたDevの文字列をとり、どのスキーマoikenにしました。

  • oikenTestsとoikenUITests> Build Setting> Defines Module> Yesに変更します。

  • oikenTestsとoikenUITests> iOS Deployment Target> iOS10.3に変更します。 テストターゲットのDeployment Targetがデフォルトの最新になっていたので、変更しました。

これでビルドが通るようになります。 cmd+Uキーで、テストを実行できました!

プロジェクトの環境にもよりますが、このような手順でテスト環境が整います。 しかし今回は、XcodeGenの対応も必要となります。

XcodeGen

おいしい健康アプリのプロジェクトは、複数のエンジニアが開発しているため、以前からXcodgeGenを導入しています。 https://github.com/yonaskolb/XcodeGen

XcodeGenは、project.pbxprojのコンフリクトを防ぐためのもので、ymlに設定情報を書き、そのymlからproject.pbxprojを生成してくれるツールです。 おかげ様で最近はコンフリクトする事が少なくなり、とても生産性が上がった気がします!

しかしテストを導入する場合には、project.ymlにその変更を反映しなくてはなりません。

project.ymlに変更を反映

XcodeGenはOSSなので、GitHubにあるドキュメントやソースコードを見ながら修正箇所を見つけました。 セキュリティ上全部は載せられないのですが、部分的に紹介します。

  • プロジェクトファイルを戻します。 まずは以下のコマンドで、project.pbxprojを元に戻します。 (厳密には、project.ymlから生成するため、変更が元に戻ってしまうのです)
xcodegen & bundle exec pod install

この状態だと、cmd+Uキーを押しても何も起こりません。

  • Product Module Name追加します。
settingGroups:
  oiken:
    base:
      PRODUCT_MODULE_NAME: "$(TARGET_NAME)"
  • UIテストを追加します。
oikenUITests:
  type: bundle.ui-testing
  platform: iOS
  sources:
    - oikenUITests
  settings:
    groups:
      - oiken
    base:
      GCC_PREPROCESSOR_DEFINITIONS: "$(inherited) COCOAPODS=1"
      INFOPLIST_FILE: "$(SRCROOT)/oikenUITests/Info.plist"
      IPHONEOS_DEPLOYMENT_TARGET: "10.3"
      CODE_SIGN_STYLE: Automatic
      DEFINES_MODULE: true
      PRODUCT_BUNDLE_IDENTIFIER: "oikenUITestsのバンドルID"
    configs:
      Develop:
        TEST_HOST: "$(BUILT_PRODUCTS_DIR)/oikenDev.app/oikenDev"
      Release:
        TEST_HOST: "$(BUILT_PRODUCTS_DIR)/oiken.app/oiken"
  dependencies:
    - target: oiken
  • Unitテストを追加します。
oikenTests:
  type: bundle.unit-test
  platform: iOS
  sources:
    - oikenTests
  settings:
    groups:
      - oiken
    base:
      GCC_PREPROCESSOR_DEFINITIONS: "$(inherited) COCOAPODS=1"
      INFOPLIST_FILE: "$(SRCROOT)/oikenTests/Info.plist"
      IPHONEOS_DEPLOYMENT_TARGET: "10.3"
      CODE_SIGN_STYLE: Automatic
      DEFINES_MODULE: true
      PRODUCT_BUNDLE_IDENTIFIER: "oikenTestsのバンドルID"
      TEST_HOST: "$(BUILT_PRODUCTS_DIR)/oiken.app/oiken"
  dependencies:
    - target: oiken
  • スキーマのTestにテストターゲットを追加します。
schemes:
  Develop:
    test:
      config: Develop
      gatherCoverageData: true
        targets:
          - name: oikenUITests
          - name: oikenTests
  Release:
    test:
      config: Release
      gatherCoverageData: true
        targets:
          - name: oikenUITests
          - name: oikenTests
  • ymlからproject.pbxprojを生成します。 修正後は以下のコマンドで、再生成します。
xcodegen & bundle exec pod install

ymlに記述した設定は、階層がずれるだけでプロジェクトファイルに反映されず、、結構苦労しました。。。

  • cmd+Uキーで、テストが実行できます!

これでテスト環境が構築できました。

おわりに

今回テストを導入したきっかけは、try! Swift Tokyo 2019 でテストの重要性を再認識したからでした。 まだまだスタートラインに立っただけの状態ですが、少しずつ自動テストの環境を育てていこうと思います!

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側のテンプレートは書き換えず削除してしまってます。

結果

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

以上です