17年開発運用しているECナビの改善事例をご紹介します!実コードも見れます! #phpcon2016

3行まとめ

  • リードエンジニアが登壇!17年運用開発しているECナビの改善事例をご紹介!
  • 企業ブースではECナビの改善事例として実際のPull Requestをお見せします!
  • 懇親会ではポイント交換体験を行いますので気軽にお声がけください!

こんにちは!
ECナビエンジニアのゆきみねです。

11/3 は何の日かご存知でしょうか?
そうです!PHPカンファレンス2016 ですね!

PHPカンファレンスは今回で21回目となる、国内最大級のPHPイベントです。

VOYAGE GROUPはPHPカンファレンスにプラチナスポンサーとして協賛させていただいており、当日はECナビのリードエンジニアによる 登壇発表 や企業ブースでの 実コード公開 を行います。
当日は僕もVOYAGE GROUPのスタッフとして参加させていただきます。

本記事では、どんな発表をするの?企業ブースで実コード公開ってどこまで公開するの?ということをご紹介させていただきます! 懇親会で行う ポイント交換体験の告知 もありますのでお見逃しなく!

ちなみに昨年も参加させていただいています! PHPカンファレンス2015で発表してきましたよ #phpcon2015

続きを読む

電子工作と画像処理でVR用の3Dスキャナーを自作する!

f:id:jujunjun110:20161012230115g:plain

はじめまして。VOYAGE GROUP VR室長の @jujunjun110 です!

いきなりですが、VOYAGE GROUPでは10月からVR室を立ち上げ、VRという新領域に取り組みはじめました。

また、それに伴いVR室ブログも立ち上げました。

こちらは毎週水曜日更新ですので、ぜひチェックしてみて下さい!

vr-lab.voyagegroup.com


...さて、以上で私の言いたいことは120%言い終わったのですが、これだけで更新するのも申し訳ないので、今回はVRアプリケーションで使うための3Dスキャナーを自作したときの話を寄稿させていただきます!

非エンジニアにもかかわらずこの場に書かせていただけて大変光栄です!

目次

今回作る3Dスキャナーの仕組み

突然ですが、一つのモノを様々な角度から撮影した大量の2次元写真が欲しいなと思ったこと、みなさんも一度はありますよね?

今回作っていくのは、みなさんのそんな課題をズバッと解決してくれるマシンです!

Multiple View Geometryについて

今回作る3DスキャナーはMultiple View Geometryというコンピュータービジョンの技術を利用したものです。

f:id:jujunjun110:20161013104615p:plain

(wikipedia より)

Multiple View Geometry とは、その名の通り、一つのモノを様々な角度から撮影した大量の2次元写真を組み合わせて、1つの3Dモデルを構成する技術です。

具体的にはこんな感じ。

  1. 写真に写っているオブジェクトの中で、複数の写真で「同じ部分」と認識できる箇所(特徴点)を見つける
  2. 1で発見した特徴点を元に、写真が撮られたときのカメラ位置を特定 (Structure from Motion: SfM)
  3. 3で特定したカメラ位置から、オブジェクト自体の形状を復元

この手順自体は、RealityCaptureという市販ソフト*1が非常によくできているので、それほど難しくはありません。

しかし、一つのモノを様々な角度から撮影した大量の2次元写真を撮影するのがとにかく面倒だし難しい。

やってみるとわかりますが、取り漏れる面があったり、変に背景が写り込んだり、理想的な写真を撮影するのはなかなか困難です。なにより綺麗なモデルを作るには数十枚の写真が必要なのですが、これを撮るのはかなりの重労働です。

そこで、今回はMultiple View Geometry用の大量の画像を自動で撮影するマシーンを作成していきたいと思います。

Let's 電子工作!

今回作るマシンの仕組みは至ってシンプルです。

  1. 回転テーブルに撮影したいものを乗っける
  2. 回転テーブルを少し回す
  3. カメラのシャッターを切る
  4. 2に戻る

今回はArduinoをベースにこれを作っていきます。

全体像はこんな感じになります。

f:id:jujunjun110:20161012003614p:plain

(↑回路図の読み書きが全くできない哀しき男の書いた図)

非常にシンプルですね。早速見ていきましょう。

なお、電子工作初心者なので説明が不正確・不十分なところがあると思います。はてぶコメントなどで指摘いただければ幸いです。

連続回転サーボ制御による回転テーブル作成

まず、360°ぐるっと写真を撮影する必要があるので、連続回転サーボを使って回転テーブルを使います。

一般的なサーボモーターは0〜180°までしか回らないのに対して、何回でも自由回転できるようになっているのがこの連続回転サーボです。

参考にさせていただいたこの記事( Arduino 連続回転サーボ | アンドロイドな日々 )によると、

制御信号は、周期的なパルスで、周期 20ms、パルス幅 1.0ms – 2.0ms です。
パルス幅 1.5ms で停止、1.0 – 1.5ms で時計周り、1.5 – 2.0ms で反時計周りです。
停止の 1.5ms から離れるに従い回転数が増えます。

とのこと。

こんな感じでPWM信号のパルスを設定してやると、キュっと一瞬だけ動いて止まる動作が実現できます。回転角度はこのパルスを調整することである程度調整可能です。

digitalWrite(TablePin, HIGH);
delayMicroseconds(2000); // PMW信号のパルスを設定
digitalWrite(TablePin, LOW); 

普通のサーボと違って回転角度を厳密に指定してやるのは難しいですが、今回は一定の角度ずつ回し続けられればよいのでこれで十分です。

ちなみにテーブル面は、フィギュア用の回転テーブルのものを使いました。*2

フォトカプラによるシャッターの制御

これで回転テーブルの部分はできたので、次にカメラのシャッターを自動制御する部分を作成していきます。

今回撮影に利用した一眼レフ(Canon EOS Kiss X7)は、2.5mm ステレオミニプラグがシャッタースイッチになっているものなので、適当に使えそうな延長ケーブルを利用します。

これをおもむろにニッパーで半分に切ると、2本のケーブル(赤、白)とその外側の銅線(GND)が出てきます。

f:id:jujunjun110:20161012214339j:plain

2.5mmジャックの側をカメラに挿した状態で、

  • 赤とGNDを触れさせると、ピントを合わせる
  • 白とGNDを触れさせると、シャッターを切る

という動作をすることが確認できます。意外とシンプルな機構なんですね。

つまりシャッターを切りたいタイミングで白のケーブルとGNDを通電させれば、タイミングをコントロールできるので、フォトカプラを使って実現します。

【ノーブランド品】DIP-4817CフォトカプラIC 10個

【ノーブランド品】DIP-4817CフォトカプラIC 10個

フォトカプラからは4本の足が出ており、下の画像のように、ある2本に電流を流すと光の信号を通じてもう2本の間が通電します。

f:id:jujunjun110:20161012154840p:plain

Arduinoに接続されている側のPINがHIGHになると、フォトカプラの逆側も通電し、シャッターがおりて写真が撮影されるというわけです。

void shot() { 
  digitalWrite(ShutterPin, HIGH);
  delay(1000); // 1秒くらい待たないと、ピントが合いきらずシャッターがおりないことがある
  digitalWrite(ShutterPin, LOW);
}

Arduinoのソースコード

今までの部分をソースコードにまとめるとこんな感じになります。

メインのループである loop( ) 関数で、テーブルを回転 → 1秒待機 → シャッターを切る(1秒かかる) → 3秒待機 となっているのが分かると思います。

int TablePin = 12;
int ShutterPin = 13;
int width = 2000;

// 初期設定
void setup() {
  pinMode(TablePin, OUTPUT);
  pinMode(ShutterPin, OUTPUT);
}

// メインループ
void loop() {
  rotateTable();// テーブルを回す
  delay(1000); // 1秒待機
  shot(); // シャッターを切る
  delay(3000); // 3秒待機
}

void rotateTable() { 
  digitalWrite(TablePin, HIGH);
  delayMicroseconds(width); // PMW信号のパルスを設定
  digitalWrite(TablePin, LOW); 
}

void shot() { 
  digitalWrite(ShutterPin, HIGH);
  delay(1000); // 1秒くらい待たないと、ピントが合いきらずシャッターがおりないことがある
  digitalWrite(ShutterPin, LOW);
}

ユニバーサルプレートによる組み立てと配線

これで基礎となる仕組みはできたので、使いやすいように組み立てていきます。

枠組みにはタミヤのユニバーサルプレートを使います。

タミヤ 楽しい工作シリーズ No.157 ユニバーサルプレート 2枚セット (70157)

タミヤ 楽しい工作シリーズ No.157 ユニバーサルプレート 2枚セット (70157)

タミヤ 楽しい工作シリーズ No.172 ユニバーサルプレートL 210×160mm (70172)

タミヤ 楽しい工作シリーズ No.172 ユニバーサルプレートL 210×160mm (70172)

ユニバーサルプレートはネジだけで電子工作の骨組みができるすごいヤツです。

こんな感じでニッパーで穴をあけてサーボモーターを固定し、

f:id:jujunjun110:20161012115032j:plain

下面にはArduinoを固定します。

f:id:jujunjun110:20161012115117j:plain

配線については、設計時はブレッドボードで行いますが、実際稼働させるとなると配線が抜けやすかったり邪魔だったりするので、はんだ付けで固定します。

フォトカプラ周辺などは、むき出しのままだと不意に配線同士が触れて予期せぬ動きをするので、こんな感じにグルーガンで固めて絶縁すると良いです。

f:id:jujunjun110:20161012184501p:plain

これで完成です!

f:id:jujunjun110:20161012115759j:plain

うーん、無骨で漢らしくも、繊細でデリケートな一面も垣間見える、惚れ惚れするデザインですね...!

写真撮影

それでは、早速撮影に移っていきましょう。

セッティング

クロマキーで背景抜きをする必要があるので、ブルーバックのフォトブースを買いました。

ロアス 撮影ブース 大 DCA-069

ロアス 撮影ブース 大 DCA-069

今回は、個人的に髪型に親近感を感じる懐かしキャラ、アフロ犬を撮影していきます。

f:id:jujunjun110:20161014104522j:plain

こんな感じでフォトブースを途中まで組み立て、

f:id:jujunjun110:20161012132443j:plain

回転台を外した状態で青い布の下に本体をセットし、

f:id:jujunjun110:20161012132503j:plain

上に回転テーブルを固定すればセッティング完了です!

f:id:jujunjun110:20161012132506j:plain

ちょっと暗かったので斜め前からLED照明を当てています。

撮影開始

この状態でおもむろに電源を入れると、動き出します!※倍速にしてあります

https://media.giphy.com/media/3o7TKBCXGN1ilg24HS/giphy.gif

ちょっと分かりにくいですが、ターンテーブルが少し回ってはシャッターが切られているのが分かると思います。

そんな感じで撮影された写真がこちら。

壮観ですな。

f:id:jujunjun110:20161012135048p:plain

今回は特徴となりそうな点が多いので、全体が写っている写真がなくても問題ないと判断し、上からと下からの2アングルから、1周ずつ撮影しています。

クロマキーによる背景処理

Multi View Geometryは、本来固定されたオブジェクトに対しカメラを回転させて撮影することが前提なので、 今回のようにオブジェクト自体を回してしまうと、背景部分が回転していないため矛盾が生じてうまく合成することができません

そこで、ブルーバックの部分を削除するため、OpenCVを利用して簡易的なクロマキー合成を行います。

クロマキー処理の仕組み

#OpenCV HSV H:0-180, S:0-255, V:0-255
lower_color = np.array([100, 110, 30]) # 色空間の下限
upper_color = np.array([120, 255, 255]) # 色空間の上限

このような感じで、HSV形式で抜き出す色空間の下限と上限を設定します。

図にするとこんな感じ。

f:id:jujunjun110:20161012181441p:plain

色味的には青っぽいところでも、あまりに白や黒に近い部分はマスク対象にしないような設定であることが分かると思います。

なお、ふつう角度は0〜360°で表しますが、OpenCVにおいては角度は0〜180°で表します。したがって、本来「青」はHSV空間で200〜240°付近にあるのですが、コード上では1/2をかけて100〜120°と表現していることに注意しましょう。

撮影するオブジェクトやライティングによって青色の範囲は変わるはずなので、環境によってこの値は調整してみてもいいかもしれません。

Pythonで一気にクロマキー処理を行う

この処理を、撮影した全ての画像に対して行っていきます。

以下は、指定したディレクトリにある拡張子.JPGの画像全てにクロマキー処理をかけて、./chromakey/ 以下に配置するスクリプトです。

#!/usr/bin/python
import os, glob
import cv2
import numpy as np

def main():
    dir_name = "path/to/directory/"

    if not os.path.exists(dir_name + "chromakey"):
        os.mkdir(dir_name + "chromakey")

    img_paths = glob.glob(dir_name + "*.JPG")

    for img_path in img_paths:
        file_name = img_path.split("/")[-1]
        export_chromakey(dir_name, file_name)

def export_chromakey(dir_name, file_name):
    print file_name

    #OpenCV HSV H:0-180, S:0-255, V:0-255
    lower_color = np.array([100, 110, 30]) # 色空間の下限
    upper_color = np.array([120, 255, 255]) # 色空間の上限

    img = cv2.imread(dir_name + file_name);
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 画像をBGR形式からHSV形式に変換

    mask = cv2.inRange(hsv, lower_color, upper_color) # マスクを設定
    inv_mask = cv2.bitwise_not(mask) # マスクを反転
    result = cv2.bitwise_and(img, img, mask= inv_mask) # 画像からマスク部分を削除

    cv2.imwrite(dir_name + "chromakey/" + file_name, result)

if __name__ == '__main__':
    main()

f:id:jujunjun110:20161012182551p:plain

綺麗にヌケたね★

RealityCaptureで立体起こしを行う

さて、こんな感じで前処理が終わったのでReality Captureにぶっこんでいきましょう。

特徴点とカメラ位置の特定

f:id:jujunjun110:20161012191209p:plain

RealityCaptureにドラッグ&ドロップで画像を読み込ませ「Align Images」ボタンで特徴点の発見とカメラ位置の特定(SfM)を行います。



ドン!

f:id:jujunjun110:20161012191337g:plain

おおおー!!!かなり綺麗にいきました!

今回は80枚の画像を読ませたのですが、全てが一つのコンポーネント(特徴量で紐付けられる画像群)にまとまりました!ちなみに所要時間はハイスペックPCで2分程度。

f:id:jujunjun110:20161012191731p:plain

画像の周りに見えている、白い点々がそれぞれのカメラ位置です。

今回は上からのアングルと下からのアングルで1周ずつしたのがわかると思います。

f:id:jujunjun110:20161012191816p:plain

特徴点がこんな感じで緑の線で紐付けられています。

ちなみにぬいぐるみのような布状のものは特徴点を見つけるのがやりやすく、うまくいきやすいです。一方でテカテカした素材や、同じ色でのっぺりした丸っこい素材のオブジェクトは特徴量を見つけるのが難しいようで、うまくいきにくいので注意です。

ちなみに一回のAlign Images で一つのコンポーネントにまとまらない場合は、それぞれのコンポーネントの、同じような角度から撮られている画像同士に、手動で特徴点(control point)を指定してあげる必要があります。これがかなり根気のいる作業なので、一発で合成できたのはかなりラッキーですね。

モデルの生成

さて、この状態だと特徴点の集まりにすぎないので、次に「Normal Detaiil」もしくは「High Detail」ボタンで点同士の間をより丁寧に埋めていきます。(だいたい20分くらいかかる)

すると、このようにモデルができるので、

f:id:jujunjun110:20161012205728p:plain

ついで「Colorize」「Texture」と選択し、色とテクスチャを設定します。(これは1分くらいで終わる)

f:id:jujunjun110:20161012205557g:plain

さきほどより色がカバーされている部分が増え、ぬいぐるみっぽい質感に近づきましたね!

ちょっと後頭部の薄さは気になるところですが...。

メッシュの書き出し

最後に、オブジェクトを書き出していきます。対応拡張子はply, obj, xyz, partList の4つ。

今回は扱いやすいobjを選択し、Mayaで読み込んでみます!

できました!

f:id:jujunjun110:20161012221224g:plain

先程は穴になってしまっていた部分も周辺色で補完され、きっちり閉じた立体になっています。

アフロのふわふわ感もかなり綺麗に再現されています!

あとは土台の部分を取り除いたりすれば、そのままVRアプリケーションなどに使えますね!

... と言いたいところなのですが、一つ問題が。

今回作ったこのファイル、実は332MBもあります。

かなり細かく凹凸が再現されている分、ポリゴン数が300万を超えてしまっており、HTC Viveが動くようなハイスペックPCでも、Mayaで扱うとかなり重くなってしまっています。

VRにおいては、

  • 常に両目分レンダリングする
  • 酔いを防ぐため90fpsは欲しい(PS4のゲームでも30fpsのものが多い)

という事情もあるため、このモデルサイズは実はかなり厳しいです。

当然RealityCaputureの機能でローポリに落とすこともできるのですが、見た目のクオリティはかなり下がってしまうので、これをリアルタイムレンダリングに用いるのはもう少し処理速度の進歩を待つ必要があるかなと言った感じです。


以上、3Dスキャナ(の撮影部分)を自作してみた話でした!

...まだ難点もあるとはいえ、このクオリティの3Dスキャンが自作のツールで簡単にできるのは、かなり夢があるというのがお分かりいただけたかと思います。

今回は有料ソフトのRealityCaptureを利用しましたが、openMVGというオープンソースのライブラリもあるようなので、このあたりを使ってみて、完全自作でやってみるのも面白そうですね。


やっぱり自分で手を動かしてみて、最新の技術に触れるというのはいいもの。

VR室では、これからも「実写 × VR」で面白いものを作るために、研究開発を進めていきたいと思います!

まとめ

VOYAGE GROUP VR室ブログ、毎週水曜更新なので見てね!!!

vr-lab.voyagegroup.com

今回はオブジェクトを3Dスキャンしましたが、部屋そのものをスキャンした時の記事なんかもありますよ!

vr-lab.voyagegroup.com

f:id:jujunjun110:20161014105141j:plain

おわり。

はーたのしかった。

*1:モデルのエクスポートができない体験版は無料、基本機能が3ヶ月使えるPromoライセンスは99ドル

*2:当初はこれに直接制御された電流を流そうと思っていたが、慣性でピタッと止まらない欠点があるのでサーボモーターを使う方法に切り替えた。

Treasure2016を経て

f:id:suzu_v:20161111133552j:plain

こんにちはsuzukenです。VOYAGE GROUPでは学生向けエンジニアインターンシップTreasureを毎年開催しています。今年の内容について主に講義の面から振り返ってみたいと思います。

https://voyagegroup.com/internship/treasure/

Treasureは私が入社するもっと前から開催されていて、かれこれ10年弱続いているそうです。去年までは @brtriver がメインの講師を担当していました。今年は私がメイン担当ということで、言語をPHPからGoに変えてみたり、新たな講義を追加してみたりしました。

今年のカリキュラムは http://techlog.voyagegroup.com/entry/treasure2016info にも少し書きました。最終的に今年の講義スケジュールは以下のようになりました。

そしてあとはチームでのアプリケーション開発に取り組んでもらう、という日程です。全体で3週間あるなかで前半が講義という構成になっています。

事前課題

Treasureでは毎年事前課題を出しています。ここで参加者がどれくらい実装できるかというのをみておき、授業資料を調整しています。

Goの事前課題だと以下のものを出しました。

Pull Requestで事前課題リポジトリに解答を提出してもらいました。ちなみに以下のコメントをよくつけました。

  • gofmt おねがいします
  • main 以外で os.Exit や panic するのは大抵好ましくないです
  • error はよっぽど自明じゃないかぎり無視しないように
  • 変数や手続き名は snake_case ではなくて camelCase で書きましょう
  • 変数名は分かる範囲なら短くしていいです
  • 余分なelseを書かないこと。正常なフローのインデントを最小にしましょう。

ほとんど https://golang.org/s/style にあることが多かったです。課題自体はそんなに難しい内容ではないのでさくさく解けている様子でしたが、Goのコードのスタイルについてはやはりレビューでのフィードバックがあったほうがよいと考えています。なので事前課題ではコードのスタイルについても丁寧にコメントをつけてフィードバックしていました。提出は一回して終わりではなく、コメントでやりとりしながら書き換えてもらい、最終的にはマージをする、という進め方をしました。

ちなみに事前課題リポジトリにはwerckerでの go buildgo test を走らせていました。なので動作しないPull Requestは提出時点でわかるようになっています。

最初は https://tour.golang.org を丁寧にやっていれば事前課題は必要ないだろうと考えていたのですが、コードのスタイル周りはやはり自分でコードを書いてもらわないと身につかないのでやってもらってよかったです。

Go講義の設計

Treasureは例年Webアプリケーション開発のインターンとなっています。今回のGoの講義をする上で、何が最低限Webアプリケーション開発のためのベースの知識として必要だろうかと考えました。全体のスケジュールの兼ね合いでGoの講義には時間を使えても2日間だろうということで最終的には以下の内容に絞りました。

  • なぜGoなのか?
  • testing
  • net/http
  • encoding/json
  • テンプレート
  • Goとデータベース

スライドは http://go-talks.appspot.com/github.com/voyagegroup/talks/2016/treasure-go/intro.slide です。

ちなみに原案ではもっと言語の基礎の話をする予定でした。しかしそれをやっていてはもう1日ほしくなる・・ということで結果的には「Tour of Goをしっかりやってきてね」と伝えて、言語の基礎部分については個別に補足していくということにしました。Goの言語仕様は小さいので課題をやっているうちになれるだろうと考えました。

講義は基本的に演習を中心に組み立てています。人間は30分説明を聞いていると眠くなるいきものなのかもしれません・・。ということで講義資料にも一定のペースで演習がはいっています。講義中の演習では以下のものを実装してもらいました。

  • スタック(これはペアプログラミングで)
  • 並行に動作するスクレイパ
  • サンプルアプリケーションにコメント欄を追加しメモリに保存する
  • MySQLのCRUDをする小さなコマンドラインアプリケーションをつくる
  • サンプルアプリケーションにコメント欄を追加しDBに保存する
  • サンプルアプリケーションに機能を追加する

また講義のためにサンプルのアプリケーションを2つ用意しました。両方共 https://github.com/gin-gonic/gin をつかっています。

net/http をそのままつかって書こうとしていたのですが、結局ginを使いました。理由はHTMLテンプレートに値を埋め込むのとJSONを返すのでインタフェースが統一されているため、もともと html/template をつかっている実装をしていてもJSONを返すAPIに移行しやすいからです。

最初はgin-boilerplateだけしか用意していませんでした。事前課題の提出状況なりコメントをみていてあまりWebアプリケーション慣れしていなさそうな参加者も多かったので、ベーシックなHTMLを書くアプリケーションのサンプルがあったほうがいいなと考え、 suzuken/wiki の実装も追加しました。

サーバサイド実装はMVCっぽくなっていますが、単純にpackageを分割する以外のことはしていません。gin自体はルーター拡張 + 便利メソッド集なのであまり凝らずにかかれています。去年のPHPでの実装例では Pimple を利用したDIをいれていたりもしたのですが、今年はGoなので単純に structpackage をつかうのみにしました。アプリケーションの大きさによってはべたっと1ファイルに実装してもいいのですが、テスト容易性やチーム開発時の利便性を考えるとある程度package分割をしていったほうがやりやすいという話をしました。このあたりは一人での開発に慣れている参加者からは幾分面倒に感じられたようです。

より細かい内容や演習の中身についてはスライドをご覧いただければ幸いです。

中間課題とレビュー

中間課題をTreasureでは例年やっています。一通り小さなWebアプリケーションを自分でつくる、という課題です。課題は以下のとおり2コースあります。

  • TODOアプリをつくる
  • なんでもOK

約半分の参加者はTODOアプリですが、わりと好きなものをみんな作っていました。SlackのbotもあればECサイトっぽいものがあったり、Trello的なUIを実装してきたりと様々でした。中間課題の前にアイデアソン、Goの講義、HTTPの講義を終えているので、一通りのWebアプリケーションは作れるという設計です。とはいえこのときのアウトプットには講師一同驚くことになります。

中間課題はデモをしてもらいます。例年ではそれで終わりなのですが、今年はせっかく全力で書いてもらったコードなので個別にコードのレビューもして返すことにしました。とはいえ20人超のWebアプリケーションのコードをレビューするのはなかなか大変ではあったのですが・・個別のフィードバックほどクオリティを上げる方法もないかなと思いやっています。だいたい以下のようなフィードバックをしました。

  • DBの正規化をうまくつかおう
  • HTTP APIの名前付けをちゃんと考えよう
  • 使ってないコードは消しましょう
  • package分割をうまくつかってみましょう
  • 変数のスコープはなるべく小さくしましょう
  • structをうまくつかおう
  • エラーハンドリングは適当なヘルパやハンドラを書くといい
  • HTTPハンドラの中でカジュアルにpanicしないこと

特に変数のスコープについては半分以上の人にコメントしたような気がします。コードを読んでいる人は、変数が有効なスコープを意識して読みます。そうすると変数のスコープが広いと「あれ、今この変数はどういう状態なんだろう?」というのがわかりづらくなります。

特に対面フィードバックの際に「なぜこう書いたの?」と聞くと「動くから」という返答が多かったのも印象的でした。他の人にとって読みやすいコードを書きましょうという話をしたものの、やはりこれは複数人でコードを書き、コードをある程度の期間メンテナンスするということをしないとなかなか実感が得られないのかもしれないなと思うのでした。

またstructをうまくつかおうというのは関数の引数が長くなってしまっているケースが多い場合に話しました。こういうケースは引数のパラメータ化をしたいパターンとstructに状態を持たせたほうがよいパターンがあります。今回は後者のようにしたほうがよいケースがいくつかありました。なので関数ではなくメソッドをつかうことで問題をシンプルに解決できることもあるという話をしました。特に関数の名前がどうしても説明すると長くなってしまうようなものの場合、うまくstructを使えていないケースというのが多かったように思います。

エラーハンドリングについては特に他の言語に慣れている人にとっては面倒に感じられているケースが多いようにみえました。単純に以下のような簡単なヘルパを書くと楽になる例もあります。

func iferr(err error)

ひとによっては「 var ErrInvalid = errors.New() のような定義が増えて辛い」という話もありました。こういう場合はstructに対して Error() string を実装すると ハンドリングしやすくなる場合があります。パッケージレベルでのエラーを書く場合には var でグローバルに宣言してもよいですが、コンテキストによってエラーの内容を変えたいような場合には error がインタフェースであることをうまく利用するとハンドリングしやすくなります。以下のブログも参考にするといいでしょう。

Error handling and Go - The Go Blog

グレースフルにエラーをハンドリングしたい場合には、https://github.com/pkg/errors をつかうのもよいでしょう。

HTTPハンドラの中でカジュアルにpanicさせないというのも上のエラーハンドリングに繋がる話です。HTTPハンドラの中でpanicしてもginだとrecoverされてしまいますが、だからといって積極的にpanicさせるのは好ましくありません。panicは本当に例外的な状況でのみ使われるべきです。なので、ログ出力とエラーレスポンスを返すことを正しくやりましょうという話をしました。今回は認証周りだけmiddlewareを使う例を示したのですが、このあたりは net/http での実装を説明したほうがわかりやすかったかもしれません。上のブログでも紹介されていますが、以下のようなエラーハンドリング用のラッパーをハンドラとしてつかえるようにしておくことで、単純にerrorを返せばエラーレスポンスが返るようにしておくこともできます。

// https://blog.golang.org/error-handling-and-go より
func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if err := fn(w, r); err != nil {
        http.Error(w, err.Error(), 500)
    }
}

こうすると例えばすべて500で返すのではなく、エラーの型に応じてエラーレスポンスを変えることもやりやすくなります。

講義全体の設計

今年は例年いれていないインフラとチーム開発の講義を追加しました。これは私達が普段働いている時もエンジニアとして知ってもらいたいと思っていることを感じてもらう何らかのきっかけになってもらえたら、と思い今年からとりいれることにしました。Treasureの後半戦は数人でチームを組んでアプリケーション開発をしてもらっています。例年「何をつくるか」で議論になってなかなか決まらないということがおきます。各チームの方針が決まるまで、なかなか進みだすことができません。それによって実装することがどんどん遅れていく、という問題がよく起きていました。

チーム開発というものを講義に入れようというのは今年の全体設計をする上で最初から考えていました。とはいえどういう講義にすべきかをなかなかイメージできませんでした。そこで @katzchang にお願いしてみようと考えました。インターンでのチーム開発と僕らが実際に仕事でやっているチーム開発というのは似ていて非なるものでもあります。とはいえ、そこから何かしらのエッセンスを伝えられたらよいだろうと考えました。この講義はある意味Treasureのエッセンスがつまっているとも言えるものでした。

インフラ及びCIの講義についても今年からはじめてのものです。これは @_nishigori@s_tajima_tech 後半のチーム開発でのサーバ環境を用意してもらうというのとセットで講義をお願いしました。この講義の狙いは以下のとおりです。

  • 私達が普段仕事でつかっているようなCIの環境をつかってもらうこと
  • 各チームごとに独立したdisposableな環境を用意し、自分たちでインフラ構成をいじってもらうこと
  • そしてインフラやCIもプログラマが問題解決に関われる領域であるということを知ってもらうこと

この講義は、私達が仕事で扱っているようなデプロイの整備された環境を提供して便利さを感じてもらうともに、インフラやCIといった部分にもソフトウェアエンジニアリングは活かすことができるというのを学生に疑似体験してもらう目的もありました。TreasureはWebアプリケーション開発のインターンであるというイメージが強いですから、参加者も「プログラムを書くことはWebアプリケーションをつくることである」と暗黙的に思っている人が多かったりします。ソフトウェアというのはいたるところにあって、実装するアプリケーションの選択肢もたくさんあります。Webアプリケーションを普段書いている人以外でも、プログラマの活動できる領域はもっとあるのだよ、ということを感じてもらえたらと思い、この講義をいれてもらいました。インフラ・CIの講義では実際にCIのスクリプトを自分で書いてもらう、ということもやってもらいました。

このあたりは参加者にあとから聞いてみると9割以上が難しいと感じていたので、継続してやってみると面白いかもと思っています。

まとめ

前半講義及び私の担当したGoの講義にしぼってTreasure2016のあとがき的なものを書いてみました。私自身、ソフトウェアエンジニアリングとの関わり方も毎年変わっていっています。事業環境もそうですし、よりよくアプリケーションを開発する方法というのも毎年多くのエンジニアが考え、実践し、改善されていきます。そのような背景を踏まえ、Treasure自体も毎年少しずつ形や内容を変えながら取り組んでいます。参加者のみなさんが少しでも多く現場のエンジニアから学び取り、今後のエンジニアリングに活かせてもらえたなら嬉しく思います。

社内向けニュース提供APIをS3+API Gatewayでサーバーレスにサクっと構築してみた

こんにちは!VOYAGE MARKETINGシステム本部の@gomachan46です。 普段はRuby on Railsを用いてPeXというポイント交換サイトの開発を主に行っています。

さて、PeXにはポイントを貯められるコンテンツがたくさんあります。その中のひとつ「YOUの気持ち聞かせてよ!みんなのNEWSウォッチ」は、ニュース記事を読んでリアクションするだけで、簡単にポイントが貯まるコンテンツです。

pex.jp

今回は、「みんなのNEWSウォッチ」のコンテンツストレージとしてはもちろん、APIとしても縁の下から支えてくれているS3の活用事例について書いていきたいと思います。

3行まとめ

  • S3をAPIとして実際に利用してみた
  • 負荷や管理周りなど考える事が減って良い
  • ファーストリリースの価値検証等のフェーズでは特に一考の価値あり

「みんなのNEWSウォッチ」の仕組み

はじめに「みんなのNEWSウォッチ」の仕組みを簡単に説明しようと思います。

登場人物

  • ニュース提供元
    • 「みんなのNEWSウォッチ」の大元となるニュース記事を提供してくれている社内外のメディア
  • ニュースAPI
    • ニュースを配信するための社内用のAPI
  • PeX
    • ニュースAPIを利用して「みんなのNEWSウォッチ」を提供する自社サイト

「みんなのNEWSウォッチ」でニュースを表示するまでの流れ

ニュース提供元が用意したニュース情報をPeXが利用するまでには、簡単に言うと以下のステップが必要となっています。

  1. ニュース提供元に取り込んで欲しいニュース情報をxml形式で記載してもらう
  2. クローラが定期的に取得する
  3. ニュース情報を蓄積する
  4. 蓄積されたニュース情報をニュースAPIで取得可能にする
  5. PeXからニュースAPIを利用して「みんなのNEWSウォッチ」を表示する

はじめに検討していたシステム

一番はじめにパッと思いついたのは以下の構成図のようなシステムでした。

f:id:shiro_goma:20160908110534p:plain

Ruby on Rails等を用いたオーソドックスなwebアプリケーション+RDBの構成ですね。

バッチ処理でニュース提供元から情報を取得し、RDBに取り込む。そしてフロントとしてAPIサーバを立てて要求に応じてRDBにアクセスしニュース情報を返す。

そんな感じのごくごく普通のアプリケーション構成を考えていました。

出来れば楽をしたい

当然ではありますが、出来れば楽をしたいものです。

上記のような一般的なアプリケーションを一から作ってもまぁ良いのですが、出来れば

  • 開発は少なくライトに済ませたい
    • 新規コンテンツリリースというところもありコストをかけずにまず価値を検証したい
  • 安定して稼働するために色々頑張りたくない
    • 冗長構成など
  • 負荷とか気にしたくない
    • 負荷状況に応じてスケールアップ/スケールアウトするなど
  • レスポンスタイムとか気にしたくない
    • API周りのパフォーマンスチューニング等
  • データ量とか気にしたくない
  • 安く済ませたい

というように色々と欲はあるので、どうにかもう少し良くできないか、というところを考えた結果アプローチとして取ったのがS3でした!

S3を活用してサーバーレスAPIを実現

実際に構築したシステム構成図は以下の通りです。

f:id:shiro_goma:20160908111031p:plain

今回は、上記ステップの

ニュース情報を蓄積する

蓄積されたニュース情報をニュースAPIで取得可能にする

という部分をS3に任せるようにしてなるべく楽が出来るようにしてみました。

ニュースAPIとしての部分は、

などを用いて比較的簡単に実現することが出来ます。

S3を上手く活用することでニュースAPI周りのサーバーが不要になり、サーバーレスなアーキテクチャに近づける事が出来ました!

S3を活用にすることでどう楽が出来たか

ニュースAPI周りをサーバーレスに出来たことで、色んな恩恵が受けられるようになりました。

開発は少なくライトに済ませたい

webアプリケーションを一からカチッと作るのではなく、ニュース記事を取り込むスクリプトを1つ用意して定期的に実行する程度で済むようになりました。

APIとして安定して稼働するために色々頑張りたくない

S3任せにできるので、基本的に気にしなくて良くなりました。

負荷とか気にしたくない

ここもS3任せにできるので、基本的に気にしなくて良くなりました。

データ量とか気にしたくない

ここもS3任せにできるので、基本的に気にしなくて良くなりました。

レスポンスタイムとか気にしたくない

ここもS3任せにできるので、基本的に気にしなくて良くなりました。

出来れば安く済ませたい

上記のように強いAPIを作るための頑張りどころがS3任せに出来るようになったので、サーバ代を大きくコストダウン出来ました。S3も相当安いのでほぼ気にならない程度です。

また、監視体制などもだいぶ手軽なもので良くなったので、管理コストなども下げる事が出来ました。

まとめ

いかがでしたでしょうか。

もちろん普通にwebアプリケーションを作るよりも機能面での幅の効き方は劣ってしまうのでケース・バイ・ケースな部分はありますが、余りあるメリットも持っているアプローチだと思います。

要件と照らしあわせてみて、採用出来た時のメリットなどが少しでも伝われば、と思って書かせて頂きました。

リクエストに応じた動的な挙動(例えば検索など)はやはり静的コンテンツを扱うS3では厳しいですが、要件によっては必要十分な機能を取り揃えた、非常に簡単で、かつ安定したAPIを提供することが出来ます。

また、仰々しい構成を取らなくても良くなるので、機能は限定的でも良い新規コンテンツなどのファーストリリース等、価値検証のフェーズでの投入は有効なアプローチなのではないかなと思っています。

引き出しの一つとして持っておいて損はないのではないでしょうか。

「VOYAGE GROUP内ではこんな風にS3をAPIとして実際に活用しているよ!」という一例としてのご紹介でしたが、「うちではこんな感じに使ってるよ!」などなどあれば是非教えていただけると嬉しいです。

ライトニングトークで社内コミュニケーションを活性化させる3つの仕掛け

みなさんこんにちは.新卒2年目 fluct DR 開発本部の @ism1000ch と申します. ふだん広告配信サーバを賢くするお仕事をしています. アドテク業界の規模感,スピード感に唸らされる毎日です.

またメイン業務外の活動として,社内のライトニングトークの運営チームに所属しています. VOYAGE GROUP では社員同士のコミュニケーションを促進するために様々な「仕掛け」を行っており,その一環として開催しているイベントです. 初回は2008年11月にはじまり,以降3ヶ月ごとに開催し,前回2016年8月で第34回になりました. 今では多いときで100名近くも参加するイベントになっており,全社での交流イベントとして継続的に運用できています.

そこで今回は,VOYAGE GROUP で取り組んでいる社内ライトニングトークの様子を紹介し,その運営で気をつけているコミュニケーションを活性化させるための3つの仕掛けについてお話しします.

f:id:ism1000ch:20160830105814j:plain

ライトニングトーク?

ライトニングトーク(LT)とは,自分の興味あることなどを5分間で発表する,ショートプレゼンテーションのことです. プレゼンテーションというと堅苦しくきこえてしまいますが,要は登壇者が好きなことを話せる表現の場,というイメージです. 最近では各種技術勉強会などにおいて開催されることも多いですね.

以下,実際に VOYAGE GROUP におけるのLTの様子をご紹介します.

技術系

業務で利用している技術や,最近の注目技術についてのトークです. 他事業部の方の話やノウハウの共有として,非常に参考になるものが多いです.

こちらは @at_grandpa さんによる crystal言語を触ってみたレポートの様子です. 「達人プログラマー」を読んで以降,「毎年1つ新しい言語を学ぶ」を実践されるなかで触れたのだそう.

f:id:ism1000ch:20160830103731p:plain

f:id:ism1000ch:20160830105356p:plain

f:id:ism1000ch:20160830103739p:plain

自己紹介系

最近のハマっているもの,などスピーカーの趣味全開のトークです. 新たにジョインしたメンバーの人となりを知るためのトーク,という意味合いが強いです. 顔を広めると言う意味で,毎年春は新卒紹介特集が組まれたりもしています. 様々なトークがありますが,あらためて社内には色々な人がいるな,と感じます.

こちらは @maki さんによる 買ってよかったものリスト紹介の様子です. 過去買ったものを紹介すると,その人のパーソナルが見えてきますよね.

f:id:ism1000ch:20160829211917p:plain

f:id:ism1000ch:20160830190825p:plain

f:id:ism1000ch:20160830190834p:plain

つくってみた系

業務で使っている技術には関係なく「ものづくりする身として,とにかく作ってみたぞ!」というアツい思いを感じるトークです. 自分のアイディアを形にしてみたぞ!どや!という作り手のアツい気持ちを感じるものが多いです.

こちらは 私 @ism1000ch による ライブ鑑賞支援システム作ってみた発表の様子です. ライブに出かけたときのサイリウムの光で会場が一体になる感覚に感動し, 自宅でブルーレイ見るときも再現したい!という思いであれこれしたお話です.

f:id:ism1000ch:20160830105042p:plain

f:id:ism1000ch:20160830105059p:plain

f:id:ism1000ch:20160830105134p:plain

このように,VOYAGE GROUP のLTでは 技術トピックに限らず様々なテーマについてトークをしています. LT中に反響の多かったトークの中には,下記のように本ブログの記事になっているものもあったりします.

コミュニケーションを活性化させる3つの仕掛け

VOYAGE GROUPのLTは,技術共有ではなく社員同士のコミュニケーションを第一の目的として運営しています. これは技術ノウハウの共有などはコミュニケーションが活性化されれば自然と行われるようになる,と考えているためです. そのおかげか,上記見てきたように毎回様々なトークが集まり盛り上がりを見せています.

ここでは,運用を続ける中で得られたコミュニケーションを活性化するための知見をいくつかご紹介していきます.

仕掛け1. テーマを絞らない

コミュニケーション促進をうたう以上,最も重要なのは広く様々なクルー(社員)の参加を促すことです. しかし発表を技術トピックに絞ってしまうと,「自分の技術力には自信ないな」「間違ったことをしゃべったら嫌だな」など,初めて発表する参加ハードルが上がってしまうことが想定されます. その結果,登壇者が固定クルーになってしまいがちです. こうなってしまうと,固定クルーでの身内イベントとなってしまい,社内全体の活性化にはつながりません.

そこでVOYAGE GROUPのLTでは,少しでも発表のハードルを下げるため,トークのテーマを絞らないようにしています. これにより新規の発表者でも参加しやすい環境を作っています. 「技術の共有」よりも「発表者を知る」ことに重きを置いている,ともいえますね.

仕掛け2. 発表者は依頼制

テーマを自由にすることで登壇者のハードルを下げることができますが,それでも「自分が話すのはちょっと...」ということは多々ありますよね. また登壇者が自分の知らない人ばかりだと今ひとつ楽しめない,ということもあります.

そんなクルーの参加を促すため,聴衆としても楽しめるよう,登壇者は運営から依頼する制度を取っています. ここで工夫している点が2点あります. ひとつは各チームから,ひろくアサインすること. これにより,なるべく登壇者の中に1,2人は知り合いが入るような形を目指しています. そしてもう一つは,新しくジョインしたクルーをアサインすること. 自己紹介を兼ねたLTをお願いして,早く会社に顔を知ってもらえるようにしています.

そして依頼枠(8~10人)とは別に飛び入り枠を設けており,自由に話したい人が話せる時間を用意しています. 最近では依頼枠よりも飛び入り枠の方が多くなることもあったりします. 中には前半のLTをみて「そういえばこんな話もあるぞ」という飛び込みLTをするクルーもいたり. このような状況を見ると,LTの文化が根付いているなと感じます.

仕掛け3. 会場全体で作り上げる

このようにしてクルーの参加を促しても,発表が一方的なものになってしまってはコミュニケーションになりません. 登壇者と聴衆が共に楽しめる仕掛けが求められます.

そこで我々は,登壇者の発表スライドとは別に,横に実況用のslackを流すスタイルでLTを行っています. 発表のなかで気になったワードがあったりすると目に見えてタイムラインが進み,盛り上がっている様子がわかります. 発表者としてもたまに実況チャンネルをのぞき,ちょっとした質問に答えるようなコミュニケーションが生まれています. 逆にコアな技術トピックのトークでは,皆トークに集中しているため流速が下がることもあり面白いです. またこのような中で,一方的に喋り散らすスタイルのLTもあり,それが一定の根強い人気をはくしていることも付記しておきます. 聴衆の反応の見える化により,トークスタイルのバリエーションが豊かになってきたな,と感じます.

f:id:ism1000ch:20160830211822p:plain

まとめ

VOYAGE GROUPにおけるライトニングトークの様子と,その取り組みの工夫についてご紹介させていただきました. いかがでしたでしょうか.

VOYAGE GROUPは「人を軸にした事業開発会社」をうたう会社です. だからこそ,クルー同士のコミュニケーションを活性化させるために様々な取り組みを行っています. その一環であるイベントの運営に関われるのはなかなか面白いことです. そしてなにより,このようなイベントを開いたときに「やろうぜ!」となれる仲間がいること自体がすごく恵まれたことだなぁと思います.

今回は運営上の工夫という形でご紹介させていただきましたが,このような取り組みから生まれたコミュニケーションが別の取り組みにつながるといいなと願いつつ,筆を置かせていただきます.

実際に効果を出せてきた! ECナビのレコメンデーションシステムのご紹介

こんにちは、システム本部データプラットフォームグループ(DPG)エンジニアのEthan Huです。

今回はECナビ(http://ecnavi.jp/)で使用しているレコメンデーションシステムについてご紹介します。

ECナビでのレコメンデーションシステムの利用方法は、ユーザ1人1人に合わせた情報配信を行う事を目的としています。この様なシステムの導入時、社内でも話題に上がるのが「そもそもレコメンデーションシステムって効果あるの?」の声です。

また、レコメンデーションシステムは様々な手法(アルゴリズム)があり、正直どれが良いか検証しないとわからない所が大きいです。

今回は各アルゴリズムの評価、効果検証も考慮したレコメンデーションシステムの構成について紹介します。 

レコメンデーションアルゴリズムについて

その前に、レコメンデーションの手法を簡単に説明します。

レコメンデーションアルゴリズムとして「協調フィルタリング」があります。

協調フィルタリングには大きく分けて、メモリーベース(ユーザ行動履歴)とモデルベース(機械学習等の手法)に分けられ、メモリーベースはアイテムベース(アイテム間の類似度を元に推薦)とユーザベース(ユーザ間の類似度を元に推薦)に分類できます。

ECナビのレコメンドシステムは協調フィルタリングになります。 

f:id:EnzhaoHu:20160801153633j:plain

レコメンデーションシステム構成

ECナビのレコメンデーションシステムでは、メモリーベース・モデルベースの両方のアルゴリズムを使用しています。その為、検証したいアルゴリズムパターンが30個近くなります。

また、今回の構成では、複数のアルゴリズムを同時に検証でき、且つアルゴリズムの追加・更新をしやすい構成を取っています。

検証方法は複数のアルゴリズムを同時に検証できるようユーザのサンプリングを行い、サプリングユーザvs各アルゴリズムパターンでの多変量テストを実施してます。 

f:id:tokosa:20160816171122p:plain

上図がざっくりとしたシステム構成です(かなりざっくりですが)。レコメンドシステムはオンプレとクラウド(AWS)を使用したハイブリッドな構成です。

簡単に各処理の説明を書きます。

  • データクレンジング(前処理)
    ETLサーバでは、学習データの元になるデータの前処理を行ってます。データの前処理後、DWHにLoadします。

  • ユーザサンプリング
    各アルゴリズム検証用にユーザサンプリングを行います。サンプリングでは検証用のユーザが偏らないようにする為と、検証に必要なサンプルサイズを担保する為で、検証する際はとても重要なポイントです。

  • 学習データの作成
    学習データは様々な特徴データを作成する必要がある為、DWHで集計→作成しています。データはログデータがベースになるため、大規模な集計になります。

  • 推薦データの作成
    各アルゴリズムによって学習データから実際に推薦データを作成する方法は様々です。メモリーベースの推薦の場合、DWHで推薦データ処理を行なっていますが、モデルベースの場合AWS EMR(Apache Spark)で処理しています。

レコメンデーションのチューニング

レコメンデーションシステムの実装・リリースは完了しましたが、各モデルの精度をさらに向上させるためチューニング作業を行います。

チューニング作業の一般的な流れは以下のようになります。

  1. モデル実装
  2. 検証(2週間 ~ 1ケ月頃)
  3. 結果FB
  4. モデル最適化調整
  5. 上記 1 ~ 4 を繰り返す

まとめ

この記事では、ECナビで実装したレコメンドシステムについて、おおまかに構築した仕組みについてまとめしました。

実際に検証、利用しているモデルや、その特徴量、パラメータの値については、システムのキモとなるのでブログに載せることはできませんでしたが、ざっと10~30近くのモデルを随時検証・走らせています。

実際レコメンドでの効果は、CTRが1.8倍、CVRで4倍位出てます。

また、高速化を求めてSparkのチューニングも頑張っています。

この辺に興味のある方は、ツイッター(@tech_voyage)に気軽に連絡をください。#ajitingしましょう! そして、ECナビでは仲間を募集しています。 http://voyagegroup.com/crew/recruit/career/

Reference

http://www.kamishima.net/archive/recsysdoc.pdf
https://www.moresteam.com/toolbox/design-of-experiments.cfm

中高生のための夏休みプログラミング教室をお手伝いしてきました

みなさんこんにちは、fluct DR 開発本部の @kanufy です。

今年VOYAGE GROUPに新卒として入社し、fluct DR(Direct Reach)にて、広告配信機能のサーバサイドと日々戦ってます。

さて今回は事業・技術ネタではなく、VOYAGE GROUPとしての取り組みの一貫の話をしようと思います。 8/12, 14と東京工業大学CBECプログラムの一貫で行われた、中高生のための夏休みプログラミング教室に協賛として参加してきました。 その様子をお伝えしたいと思います。

伝えたいこと

  • 中高生ののびしろは無限大なので我々も頑張ろう
  • VOYAGE GROUPは良さそうなイベントには協賛としてスポンサーします!
    • ピザまたは?、会場提供も致します!

イベント概要

協賛のきっかけ

東工大の特任講師も務める『リーダブルコード』の訳者で有名な 角さん( @kdmsnr )がツイッターで呟いた一言


に弊社エンジニア @katzchang がやりましょう!と言ったのがはじまり。 弊社ではこのようにわりとカジュアルに協賛が決まったりします(社内で審査・議論は行われます)

1日目@東京工業大学

中高生35名が参加してくれたこのイベント。まずは仲良くなろうということで、角さんがアイスブレイクを行ってくださいました。

  • 学年別に一列になってみよう
  • なまえであいうえお順で一列になってみよう
  • 誕生日順で一列になってみよう etc.

f:id:kanufy:20160815143052j:plain:w300

初対面の子がほとんどなのでみんな最初は緊張してコミュニケーションが取りづらい様子でしたが、回を重ねるにつれ自然と会話が生まれていました。 そして今回驚いたのは女の子の参加者が多いこと!参加者の半数くらいは女の子だったのできっと日本の未来は女子エンジニアが増えている、ハズ?笑

さて、いよいよプログラミング! 今回の教室では、

  • Processing 3 でつくる横スクロールゲーム
  • JavaScript(+ HTML/CSS)でつくるメモアプリ

のどちらかを選んでもらい、東工大のtraPのメンバーがチューターとして付いて学ぶという内容でした。 講義資料は東工大traPのメンバーが作成したもので、初心者のために詳しく説明してあってとてもわかりやすい内容になっていました。

教室の様子

f:id:kanufy:20160815144525j:plain:w270 f:id:kanufy:20160815144538j:plain:w270

みんな集中してプログラミングに打ち込んでいました! お昼はお待ちかねのピザ!

f:id:kanufy:20160815144938j:plain:w300

参加者、保護者の方、東工大生、VOYAGE GROUPと総勢約80名でピザを食べて盛り上がりました。

午後もがっつりプログラミング!女の子の参加者が多いこともあり弊社の女子エンジニアの @kanufy@momoe_yoshinaga もサポートしました〜。 みんな自分の作りたいものが作れたかな?

イベントの最後にはスポンサーとしてスポンサートークの場を設けていただきました。 中高生のためにVOYAGE GROUPの簡単な紹介と、弊社の就活支援事業サポーターズの紹介を行いました。

f:id:kanufy:20160815145819j:plain:w270 f:id:kanufy:20160815145827j:plain:w270

最後に記念写真!みんな笑顔で楽しかったと言ってくれて大盛況でした。

f:id:kanufy:20160815150356j:plain:w500


2日目@VOYAGE GROUP

2日目は1日目やり残したことがある子や、もっとオリジナルにしたい!といった子のために VOYAGE GROUPオフィスにて補習を行いました。カンバン術をつかってTODO管理にもトライ。

f:id:kanufy:20160815151856j:plain:w300

弊社人事からはおやつとしてアイスの差し入れもありました。

f:id:kanufy:20160815172428j:plain:w270 f:id:kanufy:20160815151915j:plain:w270

そしてなんと、この補習の最後にある発表会に参加してくれた子には、角さんの声かけで各所からスポンサーしていただいた技術書が貰えるという豪華な特典付き!

f:id:kanufy:20160815151727j:plain:w400

弊社からもVG賞としてソロシアターを用意しました!実はこれ、弊社の事業のひとつ、LUCY ALTER DESIGN で制作されたものなのです!

www.makuake.com

発表会のようす

さていよいよ発表会!みんな堂々とした発表で会場を沸かせていました。

f:id:kanufy:20160815152332j:plain:w300 f:id:kanufy:20160815152338j:plain:w300

みんな技術書を熱心に選んでいました。今回は一人2冊も選ぶことができました!(残りは東工大traPのみなさんへ)

f:id:kanufy:20160815172352j:plain:w300

栄えあるVG賞を勝ち取ったのは、敵を攻撃できるProcessingのゲームを制作した女の子。オリジナリティを求めつつ、やりたいことをミニマムケースから実現した姿勢がよかったですね!おめでとうございます。ソロシアターお家で使ってくださいね〜(^^)

f:id:kanufy:20160815152427j:plain:w300

最後に

今回のように、VOYAGE GROUPではピザや?のスポンサーを行っていたり、無料で会議室を貸し出したりしています。 社内審査がありますが、積極的にスポンサーを行っていますので気になった方はぜひ @tech_voyage や弊社エンジニアまでお声掛けください。

http://livedoor.blogimg.jp/ecnavi_tech/imgs/5/9/596d1dab.png voyagegroup.com