プログラミング初学者、初のチーム開発を省みる。

## 1. はじめに
初めまして！未経験からエンジニアを目指しているTaKu(名前迷い中)です！
2023年8月から独学でPythonを学び始め、現在は株式会社ユーブルさんが提供する[アプレンティスシップ制度](https://apprentice.jp/)の2期生としてカリキュラムに沿ってエンジニアになる勉強をしています。 そのカリキュラムの一環として初のチーム開発を行いました。
自分たちのチームは全員同じ実務未経験、プログラミング歴数ヶ月レベルのアプレンティスシップ生3人(Hさん,Kさん)。
開発期間は1週間。最終日に代表者一人がアプリのデモを動かしながらプレゼン発表するというものでした。
開発期間までの2か月の間にGit, GitHub, Ruby, SQL(DB), HTML, CSS, JavaScript の基本を学びながらチームMTGを週2回行っていました。
当記事はその初のチーム開発での経験を整理、反省するために作成しています。

## 2. 開発アプリ案決定まで
### 課題定義
まずはじめに与えられた開発テーマから以下の通りに課題定義を行いました。
- 与えられた開発テーマ『自分たちの役に立つもの』
- 『自分たち』をプログラミング初学者
- 『役に立つもの】をコーディングを効率化させるもの

### プログラミング初学者の現状と問題
- エディタショートカットで一気に出来る操作を一つ一つ同じように操作しがち。それにより変更漏れ、誤字等のバグが増えやすい。
- 便利にできるショートカットの存在自体をそもそも知らない。
- 実際にショートカット一覧を見て勉強しても使えそうな場面に出くわしたときにショートカットがすぐに出てこない。

これらの初学者の現状をふまえ、ショートカットを効率よく知る、覚えることが出来れば初学者のコーディング効率が上がると考えクイズアプリを作ることにしました。

## 3. 製作アプリ
アプリ名:**VScode Shortcut Quiz**

名前の通りVScodeのショートカットのクイズアプリです。
ローカルサーバー上でブラウザで動作します。

## 4. 機能
問題レベルボタンを押すとVScodeのショートカットを有効的に使える場面が問題として出題され、回答して正誤判定される。この処理を規定回数繰り返された後、正解数が表示されるという簡単なものになります。
以下バックエンド側の処理も含めて書きます。

1. タイトルページ(index.html)で問題レベルボタンを押すとDBを参照してその問題レベルに応じた問題オブジェクトデータが規定個数ランダムで生成され、バックエンド側で配列として保持されます。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586521/282b70a4-cd32-b680-0dd2-531e3a8065f3.png)
2. クイズページ(quiz.html)に遷移し、問題データ(現在の問題数、問題レベル、問題ジャンル、問題画像のパス、問題文)を受け取り、画面に描画させます。
3. ユーザーに回答となるショートカットをCtrl, Alt等のボタンとフォームを使って送信してもらい、その入力情報をバックエンドで受け取り正誤判定を行う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586521/b8752283-54e6-a09b-a7c8-46ed625b18ee.png)
4. 解答ページ(answer.html)に遷移し、解答データ(正誤情報、解答GIF画像パス、解説文、解答ショートカット)を受け取り、画面に描画させる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586521/cdf26e66-1d74-233b-0018-b8ad4aae08ce.png)
問題GIF例
![ctrl_f.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586521/01954b63-7aa9-06d6-c3fc-a391c106fbab.gif)
5. 次の問題を押すともう一度同じクイズページ(quiz.html)に戻るがクイズの問題数が更新されるので次の問題が表示される。
6. 規定問題数を終えると結果画面(result.html)に遷移し、正誤履歴情報を参考に正解数が描画される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586521/429273c9-860f-7ba0-df87-3004da410806.png)

## 5. 使用技術
- フロントエンド:HTML/CSS/JavaScript
    - 主要ライブラリ:http-server, axios
- バックエンド:Ruby
	- 主要ライブラリ:webrick,mysql2
- DB:MySQL
- ソース管理:Git/GitHub
- GIF画像作成:ScreenToGif
### 技術制限
- 現状使える技術(HTML/CSS/JavaScript/MySQL/Ruby)を一通り使って出来るもの
- 大きく技術範囲を超えるものを使用しない(フレームワークは禁止)
## 6. 環境構築
- OS:Windows10(自分のローカル)
- Webサーバー:http-server(JavaScript)
- APサーバー:Webrick(Ruby)
- DB:MySQL

npmとbundlerのパッケージ管理ツールでライブラリ環境を統一した程度です。
Dockerは使いませんでした。開発期間が一週間というのもあり、チームの学習進行度的にDockerを学ぶコストを増やす余裕がない、理解度が低いまま導入してDocker周りでエラーが起きたらがかなり時間がとられそうな気がしたので今回は見送りました。
WSL等でのOS環境統一も見送り。理由もDockerと同様です。

## 7. チーム内役割分担
- 自分:フロントエンド、プロジェクトリーダー、ワイヤーフレーム、ER図作成
- Hさん:バックエンド、テックリーダー、技術アーキテクチャ作成
- Kさん:DB、SQL、テーブル作成
問題データ作成は全員で行いました。

## 8. 技術アーキテクチャ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586521/771fd2e5-4e7d-962b-84b6-538913edd567.png)
Hさん作成。このアーキテクチャが早期作成出来たことで必要技術のイメージ把握できてよかったです。

## 9. ワイヤーフレーム
ワイヤーフレーム例(解答画面)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586521/a48101b2-139d-f962-bb8d-0a4114c550f7.png)
自分製作。figmaの学習コストを考え、googleプレゼンで製作しました。
## 10. ER図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586521/9bf105a4-a695-d811-73d6-a4d70bc420b7.png)
自分作成。クイズに対して正解のショートカットを複数表示させるつもりだったので多対多の関係で中間テーブルを作成しました。

## 11. 画面遷移図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586521/fcff5412-6429-d180-4f05-499532e78ade.png)
自分作成。問題別でページを作らず、解答画面からの遷移をフラグとして受け取って問題データの配列の次に

## 12. ガントチャート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586521/abb6f9d4-a5f0-d2f6-3233-9923d64fc020.png)
Hさんが雛形を作成。正直上手く使いこなせませんでした。
今回はスプレッドシートでしたが次回はNotion等を使用してみようと思います。

## 13. 追加したかった機能
- ショートカット一覧ページ
- 問題お気に入り機能
- 問題の正解となる複数のショートカットを最短手数順で順位付けて表示


## 14. やって良かったところ(Keep)
### 止まるならとりあえず走り出す、コーディングしてみる
初のチーム開発だったのでチーム開発において何をどうやって決めていくのかも全く分からず手探り状態でした。
タスク分割もこれでいいのかなど決めた後結構うだうだして時間が過ぎてしまっていたので、とりあえず各々タスクこなしてみて問題が起こったら起こったでその都度対処していこうという方針になりました。
結果的にこの判断はチーム開発の経験値的には良い判断でした。別の問題を生むことにはなりましたが、先に済ませるべきことを怠るとこういう問題が生じるんだという認識を身をもって体感することができてよかったです。
初めてのことは最初から完璧を目指さない。

### Git, GitHubの使い方、理解の確認
初チーム開発において、Git, GitHub回りの理解の差でとりかえしのつかない事が起こりそうな気がしたので大まかな使い方とプルリクの流れを一通り全員で確認しました。
こうしたことでGit, GitHub周りで致命的なミスが起きることなくチームコーディングが上手くいきました。
プルリクやコミットの頻度、コーディングルールはもう少し定めるべきだったかもしれません。

### アイスブレイク意識の雑談
最初の顔合わせ段階の数週間で趣味や提出課題の話で親交を深め、会話の中で自然とアプリ案となる種を引き出しました。
ここでの雑談でお互いのなんとなくの人となりや気質が分かり、開発期間に突入した時に得意そうなところを任せ合ったり、疑問点などを気軽に聞き合ったりできたので最初のアイスブレイクで良い関係性が築けたおかげかなと感じました。

### プレゼンでデモをバグ無しで動作させることが出来た
時間的に本当にギリギリで前日は20時間作業、当日もプレゼン発表数十分前までバグ取り、問題データ作成をしていました。
途中で何度も諦めそうになって動画で済まそうと考えましたが、なんとか最低限の形になるまでやり遂げることが出来ました。夜遅くまで通話しながら付き合ってくれたメンバーに感謝です。

## 15. 開発期間中の解決できた問題(Solved Problems)
### 必要技術、ライブラリの知識不足
今までの勉強の範囲外のことを行う必要があり、サーバー通信で何が必要かほぼ分からない状態でした。

**→技術アーキテクチャの読み合わせ**
バックエンド担当のHさんが少しサーバー周りについて学んだ経験があるとのことで必要な技術を調べてくれました。その後技術アーキテクチャを作成、そのアーキテクチャの読み合わせをお願いしました。
これによりブラックボックスと化していたサーバー周りのチーム理解が進み、フロント側でどういう情報を送ればいいか、受ければいいかのコーディングの方針が立ちました。
特に APIを叩く という感覚をこれのおかげで大分つかむことが出来たのは大きかったです。

### 環境構築でのエラー
mysql2のライブラリのインストールエラー。
様々なQiita記事を確認したが上手くいかず。

[**→10時間程試行錯誤しながら英語のGitHubの問題解決ページで書かれているridkのコマンドを入れることで解決。**](https://qiita.com/TK1422/items/98cff394b640c3ad2c09)
なんとか解消出来たがこのエラーでタスクの進捗に大きく影響を及ぼしました。
Mac環境なら大丈夫だったがWin環境の同じ操作でこのエラーが起こったのでOS環境を揃える大切さを痛感しました。

### メンバー間のモチベーション格差
このアプレンティスシップ制度に対してどれくらい懸けてるのかの部分がこのチーム開発だと浮き彫りになりました。タスクの量はおおよそ均等に分けましたが進行度に差が生じました。

**→人によってリソースを割ける量も違うためそれに合わせたタスク量に調節**

### 個人間の情報の受け渡しが多すぎる
タスク割り当てについて、最初は経験値的な側面からページ別に振り分け、そのページ中で使われる技術 フロント、バック、DBの一通りを全員が触れるようにするつもりでした。しかしこのタスク割り当てだと個人間の情報の受け渡しが大量になり、かなり時間がかかって間に合わないと感じました。

**→締切意識でタスクの割り当てを変更**

途中でページ別でなく[担当の技術範囲のタスクを全て行う方針](#7.チーム内役割分担)になりました。
締切をしっかり意識して途中で掲げた理想を早めに捨てれたこの判断は良かったです。


## 16. 今回解決に至れなかった問題(Not Solved Problems)
### 集団での役割(リーダーとか、プロジェクトマネージャーなど)が曖昧
本来は上司部下、先輩後輩関係があってそれに応じて自ずと役割(リーダーやプロジェクトマネージャーなど)が決まることが多いですが、今回のチーム開発はお互いが対等な関係だったので役割をしっかりと事前に決める話し合いが必要でした。
決定アプリ案は自分の発案で全体のイメージがついているということで自分がリーダー的な指示をすることになりましたが、**進行度を管理する人も決め切れていなかったためガントチャートもしっかりと作成出来ず、結果タスクの責任も曖昧になり、場当たり的なタスク進行**になってしまいました。
[前述](#止まるならとりあえず走り出す、コーディングしてみる)でとりあえず走り出したのは良かったですが、ここの部分をもう少ししっかりとしていればアプリの出来も変わった気がして反省です。
生じた問題の大部分はこの**役割分担の曖昧さ**に集約されていました。

### タスクの依存関係が曖昧でボトルネックになるタスクが生じた。
タスクBを行うためのタスクAが終わっていないのでタスク進行がスムーズにいかないという問題が起こりました。
具体的には問題データの作成が全体のタスク進行度に対して進んでおらず、問題画像のパスの指定の処理を記述したいのに出来ない、全体の画面のデザインを調整したいのに画像自体がないから調整出来ない等が起こりました。

### 他の人の進捗状況分からない
MTGがある日はお互いの現状報告でやっている内容が把握出来ていましたが、何もない日の進捗状況が分からないことが多かった。
この人がここまで進んだから次のこれが必要で自分がここまでやる必要がある、という他の人の進捗で自分のタスクの優先順位を変えたりする融通利かす場面が少なかったです。
結局なあなあで最後までいったのでチーム内日報を行うべき働きかけるべきでした。

### タスクの受け渡し、情報の受け渡しが曖昧
どこの何の情報を相手に渡して、どこの何を受け取るかが曖昧になってしまい非効率なことが多くありました。

### バックエンドコードのスパゲッティ化
時間的に厳しかったり、バック担当が一人、技術的に理解がコーディングを正せるほどの理解が自分ともう一人含め進んでいなかったのもあり、バックエンドのコードが担当本人にしか分からない状態になってしまいました。
これにより担当本人が詰まったり、エラーの際に助け船を出せる回数が少なく、本人に踏ん張ってもらう他なくなってしまった。
時間的にも余裕がなかったためリファクタリングに時間を割くことも出来なかったです。
自分としてもバックエンドの知識をアウトプットする良い機会を逃してしまったので、次はもっとフォロー出来るレベルまで知識を入れたいです。

### チームMTGに締まりがなかった
開発期間前の数週間で週2程度集まる機会がありましたが、事前に話す議題、会議時間を始まる前にしっかりと決めるべきでした。気が付くとダラダラと話し合ってしまいました。議題を事前にチーム内チャットに書いていた時もありましたが毎回出来ているわけではありませんでした。会議中の役割（司会、タイムキーパー、書記）もしっかりチームで役割を振り分けるべきでした。
自分が書記をしながら話を回していたことが多かったため、せっかく話をした内容に漏れがあったり決まったことを書く作業で話し合いが止まってしまって時間が勿体なかったです。



## 17. 個人の反省
### プレゼンの方向性
代表者としてプレゼン発表を行いましたが、他のチームのプレゼンと比べると自分のプレゼンの方向性がかなり間違っていました。
時間的にもギリギリで洗練出来なかったのもありますが、他の方は本当にアプリを一般の人に紹介するような感じで『魅せる』プレゼンを行っていましたが、自分は教育的な側面を意識して技術的、開発背景的なことを発表する場だと勘違いしてかなり固く、味気ない感じになってしまいました。
もっと色んな人のプレゼンを勉強する意識で見ることで『プレゼンの技術』を盗んでいきたいです。

### データ作成の指示が曖昧だった
データ作成のお願いをする際に指示が曖昧でなおかつ口頭で済ませてしまったのもあり何度もリテイクさせてしまいました。
お願いする成果物のイメージをもっと自分の中で明確なものにしてから文章化した指示を送ればこのタスクの時間を少なく出来たと思います。

## 18. メンター評
### 驚き、目を見張る要素を盛り込む意識
メンターさんからは色々と言われていましたが一番印象に残ったお言葉が目を引く要素、「WAO!」となる要素が少ないとのことでした。
時間的に余裕があったとしても追加予定の機能も少しありがちな機能だったのでこのアプリの目玉となるような機能についてもっと意識すべきだったなと思いました。

### そもそもショートカットを覚える必要がない
メンターさんもあまりショートカット覚えてない、そんなに使ってなくてもやっていけるとのことでそもそもの案が微妙でした。
プログラミング初学者にとってコーディング効率化させるものはもっとあったんじゃないかと言われました。
確かに課題設定に対してもう少し深掘り出来たかなと思いました。あくまで[今回の課題設定](#課題定義)をしたのは発案者の自分で、アプリ案を出し合う中で**チームの中でまず今回の課題設定をしてアプリ案を出し合ったわけではありません**でした。各々の中で課題設定をしてアプリ案を出し合っていました。
課題設定→アプリ案の流れだと考えるスコープも狭まり、より深掘り出来たアプリ案があったのではないかと思いました。

## 19. 次のチーム開発でチームに対して行うべきことまとめ
- アイスブレイクを行いながら前のチーム開発で反省を共有し、それらを踏まえた上で今回やりたい事をしっかりと話し合う。
- チームでの役割を先にはっきりさせる。(プロジェクトマネージャー等)
- MTGでの役割、毎回話す議題をはっきりさせ、議事録もしっかり取る。(司会、書記、タイムキーパー)
- タスクの責任所在、依存関係を明確化させるガントチャートを作って運用する。
- 互いのコードの接続部をはっきりさせる。何をどこで受け取るのか、渡すのか。
- 開発チーム内で日報のようなものを出し合う(今日の成果、次やること、詰まってること)
- 技術アーキテクチャ、ER図の等の大事な情報はチャットに流すだけじゃなくてしっかりチーム全員で読み合わせをして共有する。 

## 20.チーム開発終えての感想
締切が迫ってまだやるべきタスクが多くある中、深夜にCSSが言うこと聞いてくれない時は本当にメンタルがどこかに逝きそうでした。
時間的にも直前までバグ取りと問題データの作成をしていたため、予定していた機能を追加する時間、デザインを洗練させる時間、プレゼンを洗練させる時間が十分無かったのが悔しい。(こうやって何回も書いてしまうほど)
フロント部分を担当しましたがデザインセンスの自信がなかったので無骨な感じになってしまいました。
今までは一人で自由に動けるタスクをこなすことが多かったため、今回のように集団で色々と決めて業務を進める経験、特に率いる立場では初めてだったのでとても苦労しましたが良い経験にもなりました。
次回のチーム開発では他の方の進め方を参考にしてもっとより効率化させて進めていきたいです。