問題を整理しながら期限を守る上で大切だと思ったことをまとめてみた

## はじめに
こんにちは！先日製造業界の設計職からIT業界へ転身した者です。
ITはペーペーです。

先日、社内の個人カリキュラムでWebアプリケーションを一人で作るという課題がありました。（フロントエンド・バックエンド・インフラ（デプロイ）を経験）

そのカリキュラムではアプリの実装に必要な知識を理解することはもちろんですが、
期限意識を持って期限までに終わらせる、または延長する場合は早めに上長へ報告することが必要でした。

日中は通常業務がある中で、期限を守りつつ、きちんとプログラミングを理解しながらアプリを作り切るということは結構難題です。

そこで今回はカリキュラムを終えてみて感じた**期限を守る上で大切だ**と思ったことを、私が普段使用している問題を整理する時の考え方を交えながら紹介します。

期限に悩む方にとって少しでも参考になれば嬉しいです。

:::note warn
読み終えるのに10分くらいかかるかと思います。
ご興味がある方は、お暇な時にご覧いただければと。
記事の内容はあくまで個人的見解になります。
:::

## 記事の流れ

* 問題を取り巻く7つの要素
    * 目標
    * 出力
    * 問題
    * 入力
    * プロセス
    * 制約条件
    * 外乱
</br>

* 期限を守るために大切だと思うこと
    * 定数ではなく変数に注力する
    * 使えるリソースは全て使う
    * 極力精度の高いスケジュールを作る

順番にいきます。

## 問題を取り巻く7つの要素
いきなり何？
期限の話なのに問題の要素？

と思われた方はこの記事を読んでみてほしいです。

期限があるのに守れなかったとか、思ったように勉強時間が確保できないとか、一度はこれらの問題に直面した方が多いと思います。これらに限らずですが、いかなる問題でもまずはその問題がどんな要素で構成されているのかを整理・理解することが必要だと思います。

そうすることで、問題の全体像を把握できて、漏れなく効果的な対策を打てる可能性が高くなるためですね。

今回、登場人物としてタロウ君という新人エンジニアを例として、期限に間に合わなかったタロウ君の問題を簡単にですが把握・整理してみたいと思います。タロウ君の状況は以下の通りです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670922/5768797e-72d0-a3a3-0ef2-c7de269109db.png" width=50%>

* todoアプリの開発を会社から依頼されている
* その要件はA、B、Cの3つ
* その要件全てを100％完遂することで完了とする
* 期限：4月30日
* 現在：4月30日でアプリ全体の60%しか完成していない
* 開発者：タロウ君（プレイヤー）のみ
* IT経験：プログラミングスクール6ヶ月通った経験のみ
* 開発場所：会社内（電車通勤）、PC（macbook)は会社にあり
* 開発に費やせる時間：平日3時間、土曜日5時間

そして、問題を構成している要素を模式的に描いたのが下図になります。

![問題を取り巻く構成要素.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670922/f7fe6b5f-f249-9527-819d-85972d242b26.png)



こちらの模式図は以下の書籍を参考にしています。今回の例だけでなく、問題解決する上で参考になる部分がとても多いので、気になる方は読んでみてください。

参考文献：<a href="https://www.amazon.co.jp/%E6%96%B0%E7%89%88-%E5%9B%B3%E8%A7%A3%E3%83%BB%E5%95%8F%E9%A1%8C%E8%A7%A3%E6%B1%BA%E5%85%A5%E9%96%80%E2%80%95%E5%95%8F%E9%A1%8C%E3%81%AE%E8%A6%8B%E3%81%A4%E3%81%91%E6%96%B9%E3%81%A8%E6%89%8B%E3%81%AE%E6%89%93%E3%81%A1%E6%96%B9-%E4%BD%90%E8%97%A4-%E5%85%81%E4%B8%80/dp/4478750068">「図解」問題解決入門: 問題の見つけ方と手の打ち方</a>

</br>

今回の例では期限に間に合っていないという問題が発生しています。
その問題はどのような要素が影響しているのか、タロウ君の状況を加味しながら、一つづつ問題を取り巻く要素を見ていきます！

### 目標（①）
これは言葉の通り、**ある事柄についてのゴール**です。

今回は期限までにtodoアプリを100%完成させる、が目標になります。

### 出力（②）
これは**目標を達成するために行動した結果**です。


今回の例では、タロウ君が何も考えず闇雲にアプリ開発をした結果、4月30日時点でアプリ全体の60%までしか完成しなかったとします。

### 問題（③）
これは**目標と出力のギャップ**です。

4月30日時点で100％アプリを作りきるという**目標**と、60％しかできていないと言う**出力**間のギャップが問題になります。

ここまでで、目標と出力のギャップが問題であることが分かりました。


問題（ギャップ）を生み出す「出力」がどのような要素に影響を受けているか。それが次の「入力」、「プロセス」、「制約条件」、「外乱」になります。

### 入力（④）
これは**投入するリソース**です。今回の例ではアプリを開発する上で必要になるものですね。

例えば以下が挙げられます。

* タロウ君という作業者
* パソコン:macbook
* 開発エディタ：vscode（拡張機能なし）
* 開発場所：会社の自席

こんな感じで、一つのアプリを作るのに少なくともこれらのリソースが必要になると思います。一般的に大きなくくりでのリソースは「人、もの、お金、情報」と言われてます。

今回、タロウくんはこの「入力」について、事前検討なく上記にあげたものだけをリソースとして投入していたとします。

### プロセス（⑤）
**入力から出力に至るまでの行動の事実**です。

ここは要件：A,B,Cをどのような流れで実装したかを時系列で事実を把握します。

今回タロウ君は特に理由なく要件A,B,Cをアルファベット順に実装し、全体的なスケジュールも特に作成していなかったとします。また、進捗管理も一切せずに上長にも進捗の相談をしていませんでした。

### 制約条件（⑥）
**入力時点に存在する当事者（今回ならタロウ君）が勝手に変えられない事実**です。

今回の例では少なくとも「要件A,B,Cの内容が固定されている」というのが制約条件になると思います。

タロウ君は今回、要件Aを実装しているときに「要求されているデザインは個人的にあんまりかっこよくないと思うから、自分が思うかっこいいデザインを一生懸命考えていた」とします。

### 外乱（⑦）
**プロセスに影響を与える不可抗力的な事柄**です。

例えば、電車に雷が落ちて遅延したことで、会社への到着が5時間遅れ、コードを書く時間が削減された。などですね。

このように未然に予測ができない事柄がプロセスに影響を与えるものが外乱にあたります。

今回タロウ君は外乱の影響を全く考えなかったとします。

### これまでのまとめ

ここまでの話でタロウ君が期限に間に合わなかったという問題の構造を図にすると以下のようには整理できます。

![現状把握.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670922/159d980c-c682-c275-57fb-facde2c84439.png)

このようにして問題を整理するとどこに原因があるのか把握しやすくなり、対策を立てやすくなると思います。

また、これは本来以下のようになるのが理想的だったわけです。

![目標.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670922/5d5b0472-e2f5-4ad1-f6b2-32053364a82c.png)


目標と出力が同じ、要は目標と出力の間にギャップ（問題）がない状態ですね。


この状態を目指すために、今回タロウ君は期限を守るという点において、どこに気をつければよかったか、個人的に大切だと思うポイントを3つにまとめてみました。


## 定数ではなく変数に注力する
今回タロウ君は制約条件であるお客様の要件の中のデザインを変えようと時間を使っていましたね。

仕事をする上で期限に間に合わせるためには、いかに生産性を高められるかが大切です。そのため、制約条件のような**基本的に自分では変えられないもの（定数）に時間を使うのではなく、変えられるもの（変数）に対してどのように効率を上げるかに時間を使った方がいい**と思います。

プログラミングの文脈で変数というと例えば、コードの書き方とかエラー対処などのプロセス中の作業時間とかですね。いかに効率的かつシンプルにコードを書けるかとか、どうやったらエラーを早期に潰せるかとか、そっちに時間を費やした方が生産性はもちろん、自分の成長のためにも良いと思います。

そのため、制約条件という基本的に自分で変えられないものと自分で変えられるものをしっかり区別することが生産性向上の第一歩になると思います。これまでの経験上、意外と定数と変数をごちゃ混ぜに考えてしまっている人が多い印象なので、僕も含めて気をつけたいですね。

#### 注意点
この例に関して1点注意が必要なのが、お客様のためを思っての制約条件の変更なら、それを上司に提案をすることは全然いいと思います。

どないやねん！と言いたいたくなりますよね。ちょっとここがややこしい部分にはなるのですが、実はこの制約条件は当事者の立場によって変わります。

お客様の要件はプレイヤーであるタロウ君には変えられません。ただし、顧客折衝するようなPMクラスの方だと、変えられる可能性はあります。それはお客様と交渉する権限を持っているためですね。なので、お客様の要件はタロウ君にとっては制約条件だけど、PMクラスの上司にとっては制約条件ではないということがあり得ます。

このように、制約条件は当事者の立場によって変化することがあるので、与えられた立場の中での制約条件を把握して、その範囲内で自分の役割を果たす必要があります。

一方で、お客様のためを思っての制約条件の変更なら、それを上司に提案をすることは全然いいと思います。本当にそれが良い提案であれば、むしろ上司やお客様も、嬉しいと思うので。制約条件の言いなりになってください、と言いたいわけではないので、そこは誤解のないように頂けると幸いです。

## 使えるリソースは全部使う
今回、タロウくんは「入力」について、特に調べずになんとなく開発に必要そうなものだけをリソースとして設定していましたね。

期限に間に合わせるために必要なのは一見プロセス中の作業（例えば、コードを早く書くとか、Googleで素早く目的の検索結果に辿り着くとか）が注目されがちですが、「入力（リソース）」の部分も大切だと思います。

このリソースが問題（ギャップ）の発生に大きな影響を与えます。

### 例えば

原始人を現在の東京駅にタイムスリップさせたとします。スマホと2万円、新幹線の線路沿いをまっすぐ進めば大阪駅に辿り着くという情報だけ渡して「今から5時間以内に大阪駅に行ってください」と伝えたとします。

そうすると、おそらくその原始人さんは新幹線の線路沿いを一生懸命走ることでしょう。
この原始人さんの身体能力が平凡であれば、まず目標は達成できないです。

しかし、世の中には新幹線という「もの」があるし、新幹線に乗るための「お金」も用意できるし、どうやって新幹線のチケットを買うか、どこで乗るかという「情報」をgoogleで調べられるし、スマホを使って情報にアクセスできる「人」がいます。
これらのリソースをうまく使うことで、5時間と言わず3時間くらいで大阪駅に着くことができます。

### 要するに
投入するリソースを知っているか知らないか、またそれらを適切に使えるか使えないかで、プロセスの効率性に大きな影響を与え、最終的には目標と出力のギャップを生み出すか、生み出さないかに影響を与えると思います。

僕の話で言うと、個人カリキュラムに入る前に、まず効率化するためのリソースは何かないかを自分なりに調べて、Xdebug（デバッグツール）やPHP Intelephense(メソッドジャンプができるvscodeの拡張機能）を開発環境に取り入れました。それにより、デバッグの効率性をあげたり、目的のコードに早く辿り着くようにしました。

このように**なるべく開発の初期で「今より良いリソースはないか？今のままで十分か？」について検討しておくと、プロセス実行中にリソースの効果を最大限発揮できる**と思います。

## 極力精度の高いスケジュールを立てる・管理する
今回タロウ君はプロセスにおいての全体的なスケジュールも特に作成していませんでしたね。また、スケジュールを立てていないことで、進捗管理もできず、上長にも進捗の相談をできていませんでした。（上長の管理責任についてはここでは触れません。）

このスケジュール管理の重要性については今まで上司から口酸っぱく言われてきている方が多いと思います。仕事には大抵目標期限があり、**きちん計画を立てて進めないとお客様に迷惑がかかったり、会社の信用を失うなどのリスクが上がってしまう**からですね。

そうならないためには、プロセス中のタスクが、どれくらい時間がかかって、いつ完了する見込みなのか、現状の人数で不足はないか計画したり、外乱などの突発的な要因を考慮したりする必要があります。また、定期的な進捗管理により順調なのか遅延しているのかを早い段階で察知し、遅延しているなら対策を早期に立案する必要があります。

これらを実施するために、なるべく精度の高いスケジュールを開発前に立てることとそれを管理することが大切だと思います。

僕が実践したスケジュールを作る方法について、ご興味がある方は以下の記事をご参考頂ければ幸いです。

https://qiita.com/MasanoriHarada/private/c0aa3d7d84399c829a79

## 最後に
今回は社内の個人カリキュラムを通して、期限に間に合わせるために必要だと思ったことを紹介させていただきました。僕自身、今回の内容を記事にすることで、今までぼんやり頭の中で考えていたことを整理できましたし、まだまだできてない部分があるなと反省しました。
どんな仕事でも勉強でも期限に関する悩みはあるのかと思います。この記事がそんな方々にとって一助になれば良いなと思います。

最後までご覧いただき、ありがとうございました。