開発合宿で優勝するまでとしてからの話

Opt Technologiesの[開発合宿2018 in 三浦海岸](https://tech-magazine.opt.ne.jp/entry/2018/12/10/170000)に参加したら優勝しました。
ネタにできそうだったので、優勝チームのメンバーとして何をやってどう思ったかなど書こうと思います。
技術っぽい話はあまり無いです。

作ったものはバナー広告を入稿する際、テキストが多くて審査落ちしそうな画像を検出して教えてあげるという運用ツールです。
ツールの詳細は上記リンク先に書かれています。

# 自己紹介

2018年4月にオプトに新卒入社し、広告配信に関わるプロダクトのチームで色々やっています。
理論物理系の研究室出身なので、特段得意だったり体系的に学んだりした技術スタックが無く、OJTで学んでいる途中というところです。

# 優勝するまで

## 合宿参加を決めるまで

去年の様子を聞いていて面白そうだったし、普段の開発チーム以外の人と一緒に開発できる機会は貴重なので参加しないという考えはありませんでした。
~~チーム業務ヤバそうだったけど他のチームメンバーも参加したし。~~

## 機械学習やるぞ！　Pythonやるぞ！

今回のバナーチェックツールチームに決めた理由は以下の通り。

- PythonやMLやってみたかった
    - 理論物理界でDeep Learningを使うのがちょっとしたブームになっていて[^ml-phys]、大学院生時代から大変おすすめされていた[^phys]
- 他にインフラ・フロントを触れる人が居なさそう
    - Webサーバー立ち上げ・保守の経験が活かせそう
- 他のチームメンバーが普段絡みの無い人ばかりだった

## 既に開発されていた？

合宿前に、[@___uhuさんが既に開発着手しているツール](https://qiita.com/___uhu/items/a7b489561af9cac6a1e1)があるとの情報が入ってきました。流石に全く同じものを作る意味は無いので、@___uhuさんが作っているものではカバーできない部分を実装することで突破[^toppa]しようという方針に。

~~こういうのは発表したもの勝ちですしね。~~

## 事前準備[^jizen]は（自分は）ほぼできず

直前まで帰省していたのもあり、前日にやっとPythonとFlaskをチームメンバーに教えてもらいながらローカルとデモ用サーバーに環境構築するというギリギリっぷり。
時間が限られている中での作業で慌ててしまい、ローカルとサーバーで環境が違う部分が出て、それが当日まで足を引っ張りました。

## 当日の体制で苦しんだこと

### 役割分担

私のチームは非エンジニア（リーダー）が1人、エンジニアが4人で構成されていましたが、実際にコードを書いたりサーバーを触っていたのは3人で、もう1人の方にはリーダーをサポートして発表スライド作りをしてもらいました。

「スライド作りにエンジニアが絡んでいなければ、成果発表がイマイチになって優勝できなかったのでは？」という気持ちもあり、また当人から「開発したい」という要望を聞いた訳ではないのでこの体制が悪かったとは思っていませんが、**事前にちゃんと話し合っておきたかった点として心残り**です。

### 分業しているが触るファイルが同じ点

**全員がgitマスターしていたら無問題かもしれないんですけどね。**
そもそもブランチの運用方法やレビュー・マージのやり方等も決めておらず、当日「このブランチは使っていない」だの「時間が無いのでセルフマージして良いか？」だのといった話でバタバタしてしまったのは良くなかったです。

また、同じファイルを触る以上はgitで解決できない問題も発生します。
今回はあらゆる開発作業を並行してやっていたため、手動でコンフリクトを直したり、バグが出てきても何が原因かすぐにはわからなかったりと大変でした。

## やったこと

当初の目的だった機械学習やPython、フロントは殆どできなかったので残念です。
しかし合宿中に立ち上げたデモ用サーバーはその後も役立っており、サーバー移転までは保守を続ける予定です。

### サーバー立ち上げ

GCEの**Ubuntu上で、Apache＋wsgi＋FlaskのWebアプリを動かす**設定をしました。

（Apacheはともかく他は）事前知識ゼロだったのでその場でググってなんとかしました。
**人間やればできる！**

```
sudo apt install zip
sudo apt install apache2
sudo apt install apache2-dev
sudo apt install libapache2-mod-wsgi-py3
sudo apt install -y libsm6 libxext6
sudo apt install -y libxrender-dev
sudo wget https://github.com/GrahamDumpleton/mod_wsgi/archive/4.6.5.zip
sudo unzip 4.6.5.zip
sudo ./configure --with-apxs=/usr/bin/apxs --with-python=/usr/bin/python3
sudo make
sudo make install
chmod 644 /usr/lib/apache2/modules/mod_wsgi.so
sudo a2enmod wsgi
sudo service apache2 start
```

Flaskの仮想環境の設定をした後、以下を追記します。
`/path/to/virtual-env/` は仮想環境フォルダまでのパスに、pythonバージョンはお使いのものに書き換えてください。

```/etc/apache2/mods-available/wsgi.conf
WSGIPythonPath /path/to/virtual-env/lib/python3.6/site-packages
```

Apacheのサイトの設定の方は以下を追記。

```/etc/apache2/sites-available/000-default.conf
<IfModule mod_wsgi.c>
    WSGIScriptAlias / /path/to/repository/flacker/adapter.wsgi
</IfModule>
```

```adapter.wsgi
# coding: utf-8
import os,sys
sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))

from main import app as application
```

あとは `~/.profile` に `export FLASK_APP=/path/to/repository/flacker/main.py` などしておくと便利です。

Apacheがファイルをアップロードしたりするディレクトリの権限設定も必要でしたが、このあたりはアプリの仕様を知っていないとできないので、コードをちゃんと読む時間や担当者にヒアリングする余裕があったらもっとスムースにできたと思います。

貧弱インスタンスでもこのくらいのツールなら動くだろう、と思ったらちゃんとチューニングしないとすぐ重くなってしまうみたいなので、それは今後の課題です。

# 優勝してから

実用化に向け、お金や人やサーバーをどうするのか考えたり、工数見積りなどをしています。
通常業務ではそれぞれ違うチームに所属している同士で、その合間を縫って色々しないといけない大変さはありますが、良い経験になっています。

# まとめ

- 今回優勝できたのは成果物の有用性や発表の質が大きく寄与していると思う
    - 前回の勝負事（社内ISUCON）では惨敗だったのですが、前回・今回ともに **「何がどう評価されるか」を考えて行動する** のが最適解だと感じた
    - 今回は技術的に難しいことをしているかどうかで言えば、他のチームの方がすごかったように思う
- こういった勝負事は「新しいことをやろう」というきっかけにはなるけれども、実際にできるかどうかは事前準備やチームメンバーとのすり合わせができるかどうかにかかっている
    - というか**勝負事の時は使い慣れているものを使うに限る**
    - 人間焦っている時にまともなコミュニケーションが取れると思ってはいけない
- サーバー移転するまでは頑張って面倒見るぞい[^zoi]

[^jizen]: 事前準備は推奨されていませんが、通常業務に影響がなければやっても良い事になっています。
[^ml-phys]: [私の出身研究室では昨年くらいから研究会を開いています。](http://kabuto.phys.sci.osaka-u.ac.jp/~koji/workshop/DLAP2018/)今年は行けませんでしたが昨年はここで深層学習の集中講義を受けました。技術者が参加して解るようなワークショップではありませんが、こういうのに技術が応用されていますよという宣伝。
[^toppa]: 社是みたいなやつ。
[^phys]:  …が、物理に対する考え方の違いや自分の研究で手一杯だった等の理由でずっとできていませんでした。それが本当に正しいかどうか理論的に解っていなくても、出てきた結果がそれっぽくて人の役に立つのであれば、ツールとして使う分には良いと思います。
[^zoi]: これの元ネタ知らないんですよね…。