一歩ずつ進める

あなたが解きたい問題には、簡単なものもあれば難しいものもあります。
単純なものもあるし複雑なものもあります。とても簡単でとても単純な問題だったら、一発で解決できるかもしれません。しかしもう少し難しかったりもう少し複雑だったりすると、一発では解決できなくなってきます。こうした問題は少しずつ、一手ずつ解いていくことになります。

大きくて複雑な問題を一息で解決できれば、カッコいいかもしれません。
しかしそのやり方にはリスクがあります。一息でやっつけようとして、それが上手くいかないと、振り出しに戻ってしまい一歩も先へ進めません。ことによっては、最初よりも状況が悪化してしまうかもしれません。カッコよさよりも、問題解決という目的を大切にして、確実で効果のある進め方が必要です。小さな問題でも大きな問題でも、自分に合った歩幅で一歩ずつ進めましょう。ひとくちサイズずつ食べるという言い方もします。

一歩ずつ進めるアプローチにはメリットがたくさんあります。一歩で考えるのは小さな問題、元の問題から切り出した一部分になります。そうすると同時に考えないといけないことが減って、比較的簡単に解決できるようになります。問題はわかりやすく、解決方法もシンプルで、善し悪しも客観的に評価しやすくなります。解決方法が正しいかどうか、判断も容易です。考慮漏れや見落としが入り込む可能性も小さくなります。さらにより良い解決方法を求めて、方法自体を洗練させたり、他の案を検討したりもできます。

例題:
  • 皿洗い問題 汚れたお皿が10枚あります。洗って拭いて食器棚にしまわないといけません。
    • どういうやりかたをしますか?
    • 100枚だったらどうですか? 10000枚だったら?

自分の歩幅

一歩ずつ進めるといっても、どんなふうに一歩を決めればいいでしょうか。Webアプリの開発を例にすると、たとえば次のように6つに区切るという手があります(あくまで一例です)。

  1. 画面を実装して入力できるようにする
  2. 入力したデータをどう保持するか設計する
  3. 入力と既存のデータを組み合わせて保存する実装をする
  4. ユーザーが使いやすいよう画面を修正する
  5. 全体が矛盾なく整合しているかテストする
  6. 実行時間が遅くなったりしないか確認する

1ステップごとに、プログラムが少しずつ増え、完成に近づいていきます。2番は設計を検討するだけですし、5番や6番はテストやレビューが中心で、コードは書かないようなステップもあります。

こうした「一歩の大きさ」は様々です。ベテランならば1番から6番までまとめて一歩で片付けてしまうかもしれません。新人だったら、もっと細かく分けないとうまく進めないかもしれません。あるいはベテランでも、1画面に300項目あるような複雑な機能なら、念入りに小さな一歩で進めるでしょう。Rubyならまとめてできる人でも、C++では設計だけ先に考えるということもあります。問題の性質、人の経験やスキル、解決に使う道具やテクノロジーによって、妥当な一歩の大きさが変わってきます。自分が自信を持てる、これなら踏み外したり、うっかり間違えたりしないと思えるような一歩を、そのときどきで選んでください。

プログラミングの世界ではよく、設計・実装・テストという作業をしますが、こうした「作業の分解」も一歩ずつ進める一つの方法です。

  • 設計: 対象の問題全体を解決する方法を決める
  • 実装: 設計で決めた方法を具体化する
  • テスト: 問題が解決したか確かめる
例題:
  • 普通の一歩問題 普通に歩いているときの、一歩の大きさを測ってください。そのうえで、「自分が自信を持てる」一歩の大きさは、どのくらいだと思いますか?
    • 平坦な道路では?急な山道だったら?ツルツルに凍った氷の上なら?
    • 裸足のとき、履き慣れた靴のとき、ビーチサンダル、下駄、竹馬ではどうでしょう?
    • 空中100メートルで綱渡りをするとしたら、一歩の大きさはどのくらいですか?一歩でも進めますか?
  • 間違えない問題 プログラムを書くとき、何文字、あるいは何行までなら絶対に一箇所も間違えないで書けますか?
    • 確かめてください。
    • 自分で自信があると感じる度合いと、実際に間違えてしまう割合は、合っていますか?

前に進まない一歩

一歩ずつ着実に確実に前に進むという考え方ではあるのですが、前に進まない一歩というものもあります。進めていくうちに、わからないところが見つかることがあります。最初の想定と違う箇所が出てくることもあるし、今までやったことが間違っていたとわかることもあります。単に、自信が持てなくなることだってあります。そうしたときは、前進するのをいったんやめて、考え直さないといけません。状況を再確認したり、方針を見直したり、情報を収集したりするのも、前に進まない感じがありますがこれもまた一歩です。

大きな問題を少しずつ解決するのは、長い道のりを一歩ずつ進むようなものです。一歩ずつ進んでいると、先行きがわからなくなったり、見失ったりしやすくなります。全体として問題解決に近づいているかどうか、ときどき周りを見渡し、行く手を確認したほうがよいでしょう。本当に前進しているか、解決に近づいているか、事実の確認と仮説の検証をしながら進んでください。道を間違えていると困るので、ときどき行く手を探索して情報収集しましょう。むしろ、一歩ずつ進んでいるからこそ、問題点や不明点に気づくことができます。

コラム 前に進まない楽しい仕事

プログラミングというのは楽しいものです。 楽しいことをしていると、つい時間を忘れて没頭しがちです。 やっていることが面白くなって、もともとの目的を忘れてしまうことも、またありがちです。 コードの美しさにこだわったり、アルゴリズムのチューニングに熱中したり、モデリング中毒になったり、アニメーションの気持ちよさを追求したりと、ハマりどころはたくさんあります。

そういう点ももちろん大事なので、かけるべき時間はかけましょう。しかし今やらないといけないのか、どれくらい時間をかけるべきなのか、意識して確認しましょう。先にやるべきことは先にやる、後に回せることは後にするのが大事です。

いま、なんのために、どんな一歩を踏んでいるところなのかを忘れずに。

解としての一歩ずつ

そもそもプログラミングとは、問題を解くために、コードを1行ずつ書くことです。プログラムはまさしく、一歩ずつの積み重ねでできているわけです。アルゴリズムを勉強していると、解説はたいてい、1ステップずつの処理に分けて書いてあります。分割統治との組み合わせで、様々なアルゴリズムにおいて、扱いやすい一部分だけを取り出して処理するというアプローチが利用されています。問題解決の方法と進め方はどちらも、一歩ずつ進めるのと相性がいいのです。

一歩ずつのアプローチは、後から他の人が見たときも理解しやすくなります。理解するほうも、やはり一歩ずつ理解を進められるためです。一歩ずつの考え方を反映したプログラムやシステムの構造も、同様です。

例題
  • 問題分解問題 スマホアプリに入力したデータをサーバで集計して、運用者がGoogle Spreadsheetで見られるようにしたいとします。
    • まずこの問題を3つの問題に分解してください。
    • 3つに分けたそれぞれを、さらに小さな問題に分解してみてください。ここでも一歩ずつ進めましょう。一気にうんと小さくしようとせず、2つか3つくらいずつ、段階を追って分解してください。

https://github.com/yattom/text_for_programmer/wiki/%E4%B8%80%E6%AD%A9%E3%81%9A%E3%81%A4%E9%80%B2%E3%82%81%E3%82%8B