プログラミングの問題を解決する10ステップ





バリンダ・チェンの記事の翻訳。



これは、空白の画面を見ていて、どこから始めればよいかわからない初心者の開発者向けのヒント集です。 プログラミングのいくつかのタスクの解決に取り組んでいる若い開発者から、何をつかむかわからないことがよくあります。 タスク自体、ロジック、構文の基本などを理解しています。 誰かのコードを見たり、誰かがあなたを助けてくれたりしたら、あなたは自分ですべてをすることができます。 しかし、構文やロジックを知っているという事実にもかかわらず、能力に自信がない、または最初はコードで自分の考えを実現するのが難しいことが起こります。 カットの下で-あなたの毎日の仕事に役立つこの問題を解決するためのいくつかのヒント



1.問題の状態を少なくとも3回(または、必要な回数だけ)読んでください。



理解しないと問題を解決できません 。 タスクと、あなたが解決しようとしていると思うタスクには違いがあります。 最初の数行を読むことができ、残りは以前と同じように見えるため、仮定を立てることができます。 ハングマンのような人気のあるゲームを作成した場合でも、以前にプレイしたことがある場合でも、すべてのルールを必ずお読みください。



友人に問題を説明して、あなたの説明を理解しているかどうかを確認することもできます。 途中まで行って、要件を誤解しているとは思わないでしょう。 そのため、最初はより多くの時間を費やして物事を片付ける方が良いでしょう。 問題をよく理解すればするほど、簡単に解決できます。



単純なselectEvenNumbers



関数を作成して、数字の配列を受け取り、偶数のみの偶数番号の配列を返すとします。 ソース配列に偶数がない場合、 evenNumbers



配列evenNumbers



evenNumbers



返されます。



 function selectEvenNumbers() { //    }
      
      





自問できる質問:





2.少なくとも3つのデータセットを使用して手動でタスクを実行する



用紙を取り、タスクを手動で実行します。 少なくとも3つのデータセットを選択して確認します。 最大許容および極端なケースを選択します。



最大許容ケース :通常の機能パラメーター以外で発生する問題または状況。 たとえば、各パラメーターが特定の範囲内にある場合でも、複数の変数または環境条件が同時に極端な値を持つ場合です。



極端な場合 :機能パラメーターの極端な(最小または最大)値でのみ発生する問題または状況。


たとえば、使用するデータセットは次のとおりです。



[1]

[1、2]

[1、2、3、4、5、6]

[-200.25]

[-800.1、2000、3.1、-1000.25、42、600]



始めるとき、あなたはしばしばいくつかのステップを無視します 。 脳はすでに偶数に精通しているため、脳が特定の数字を選択する方法を考えずに、数字のセットを見て、すぐに2、4、6などを渡すことができます。 自分でこれに気づいた場合は、数字を見るだけで脳が問題を解決するのを防ぐために、大きなデータセットを取得するのが最善です。 これは実際のアルゴリズムに固執するのに役立ちます。



配列を見てみましょう[1]







  1. 配列[1]



    単一の要素を見ます。
  2. 偶数かどうかを判断します。 ありません。
  3. 配列には他の要素がないことがわかります。
  4. 偶数はないと判断します。
  5. 空の配列を返します。


では、配列[1, 2]



を見てみましょう[1, 2]







  1. 配列[1, 2]



    の最初の要素を見ます
  2. これは1



    です。
  3. 偶数かどうかを判断します。 ありません。
  4. 次の要素を見てください。
  5. これは2



    です。
  6. 偶数かどうかを判断します。 です
  7. evenNumbers



    配列を作成し、 evenNumbers



    2



    を追加します。
  8. 配列には他の要素がないことがわかります。
  9. 配列evenNumbers- [2]



    を返します。


タスクをさらに数回実行できます。 [1]



アルゴリズムのステップ数は[1]



アルゴリズムとは異なることに注意してください。 したがって、いくつかのデータセットを確認することをお勧めします。 たとえば、単一の要素がある場合。 整数と非整数の混合。 複数桁の番号。 負の数で設定します。



3.アルゴリズムを簡素化し、最適化します。



適切なパターンを探して、多分何かを一般化することができます。 ステップ数を減らすことができるかどうかを検討してください。



  1. 関数selectEvenNumbers



    作成します。
  2. 偶数を保存する新しい空のevenNumbers



    配列を作成します。
  3. 配列[1, 2]



    各要素を調べます。
  4. 最初の要素を見つけます。
  5. 2で割り、偶数かどうかを判断します。 はいの場合、 evenNumbers



    追加しevenNumbers



  6. 次の要素が見つかります。
  7. ステップ4を繰り返します。
  8. 配列内の要素がなくなるまで、手順5と4を繰り返します。
  9. 何かがあるかどうかに関係なく、evenNumbers配列を返します。


このアプローチは数学的帰納法に似ています:



  1. n = 1



    n = 2



    、...の真理を証明します
  2. n = k



    場合に真になると仮定します。
  3. n = k + 1



    の真理を証明します。






4.擬似コードを書く



基本的な手順を完了したら、実際のコードに変換できる擬似コードを作成します。 これは、コードの構造を決定し、実際に記述を容易にするのに役立ちます。 擬似コードを1行ずつ記述します 。 これは、紙で行うことも、エディターでコメントとして行うこともできます。 始めたばかりで、空白の画面が気味が悪いまたは気が散ると思われる場合は、紙に書くのが最善です。



一般に、擬似コードを記述するためのルールはありませんが、より便利な場合は、言語の構文を含めることができます。 ただし、構文ではなく、アルゴリズムのロジックとステップに注目してください



このケースに関連して、多くの異なるオプションがあります。 たとえば、 filter



を使用できますが、例の単純化のために、単純なfor



ループを使用for



ます(ただし、その後のリファクタリングではfilter



が発生しfilter



)。



主に単語で構成される擬似コードの例を次に示します。



 function selectEvenNumbers   evenNumbers             ,       (   2   )     evenNumbers return evenNumbers
      
      





そして、ここに単語がはるかに少ない擬似コードがあります:



 function selectEvenNumbers evenNumbers = [] for i = 0 to i = length of evenNumbers if (element % 2 === 0)     evenNumbers return evenNumbers
      
      





主なことは、コードを1行ずつ記述し、各行のロジックを理解することです。



タスクに戻って、正しい方向に進んでいることを確認してください。



5.擬似コードを通常のコードに変換してデバッグする



擬似コードの準備ができたら、各行を言語の実際のコードに変換します。 ここではJavaScriptを使用します。



紙に書いた場合は、すべてをコメントとしてエディターに転送してから、各行を置き換えます。



次に、関数を呼び出して、以前に使用したデータセットの一部を指定します。 そのため、コードが目的の結果を返すかどうかを確認できます。 また、テストを記述して、出力が期待される結果と一致することを確認できます。



 selectEvenNumbers([1]) selectEvenNumbers([1, 2]) selectEvenNumbers([1, 2, 3, 4, 5, 6]) selectEvenNumbers([-200.25]) selectEvenNumbers([-800.1, 2000, 3.1, -1000.25, 42, 600])
      
      





各変数または行の後に、 console.log()



使用できます。 これにより、次に進む前に、値とコードが期待どおりに動作するかどうか確認できます 。 このようにして、問題をキャッチすることができます。 作業の開始時にチェックできる値の例を次に示します。



 function selectEvenNumbers(arrayofNumbers) { let evenNumbers = [] console.log(evenNumbers) //      console.log(arrayofNumbers) //      }
      
      





以下は、擬似コードの各行を処理した後に取得されるコードです。 //



文字は、擬似コードの行を示します。 太字は、実際のJavaScriptコードを示します。



 // function selectEvenNumbers <b>function selectEvenNumbers(arrayofNumbers) {</b> // evenNumbers = [] <b> let evenNumbers = []</b> // for i = 0 to i = length of evenNumbers <b> for (var i = 0; i < arrayofNumbers.length; i++) {</b> // if (element % 2 === 0) <b> if (arrayofNumbers[i] % 2 === 0) {</b> //     evenNumbers <b> evenNumbers.push(arrayofNumbers[i]) } }</b> // return evenNumbers <b> return evenNumbers }</b>
      
      





混乱しないように、疑似コードを削除します。



 function selectEvenNumbers(arrayofNumbers) { let evenNumbers = [] for (var i = 0; i < arrayofNumbers.length; i++) { if (arrayofNumbers[i] % 2 === 0) { evenNumbers.push(arrayofNumbers[i]) } } return evenNumbers }
      
      





新しい開発者は構文に非常に夢中になって、先に進むのが難しい場合があります。 時間が経つにつれて、構文を観察しやすくなり、構文を正しく観察するためのコードを記述するときに参照資料を参照することを恥じることはないことに注意してください







6.コードを簡素化して最適化します。



単純化と最適化が繰り返し行われるテーマであることに気づいたかもしれません。



「シンプルさは信頼性の前提条件です。」
オランダの科学者であり、コンピューターサイエンスのさまざまな分野の先駆者の1人であるEdsger Dijkstra



この例では、最適化の方法の1つは、 filter



を使用して新しい配列を返すことにより、配列内の要素をフィルタリングすることです。 この場合、 filter



はフィルターに一致する要素のコピーを含む新しい配列を返すため、 evenNumbers



変数を定義する必要はありません。 この場合、元の配列は変更されません。 また、 for



ループを使用する必要はありません。 filter



は各要素を通過し、trueを返す場合、要素は配列に分類され、 false



場合、スキップされます。



 function selectEvenNumbers(arrayofNumbers) { let evenNumbers = arrayofNumbers.filter(n => n % 2 === 0) return evenNumbers }
      
      





新しい方法が見つかると、コードを単純化および最適化するために数回の反復が必要になる場合があります。



次の質問を自問してください。





「プログラムは、人々が読むように、そして二次的にのみ、マシンが実行するように書かれるべきです。」
「コンピュータープログラムの構造と解釈」の著者であるジェラルドサスマンとハロルドアベルソン



7.デバッグ



このステップはプロセス全体で完了する必要があります。 エンドツーエンドのデバッグは、構文エラーやロジックの欠陥を早期に発見するのに役立ちます。 IDE(統合開発環境)とデバッガーを活用してください。 バグが検出された場合、予期しないものを見つけようとして、コードを1行ずつスキャンすることをお勧めします。 いくつかのヒント:





「最も効果的なデバッグツールは、思慮深い思考と、合理的に配置されたオンスクリーンディスプレイコマンドです。」
プリンストン大学のコンピューターサイエンス教授、ブライアンカーニガン



8.有用なコメントを書く



1か月後、コードの各行が何を意味するのか覚えていないかもしれません。 そして、あなたのコードを扱う人はこれをまったく知りません。 したがって、問題を回避し、後でこのコードに戻る必要がある場合に時間を節約するために、有用なコメントを書くことが重要です。



このようなコメントは避けてください:



// . .





// .







わかりにくい場合は、ここで何が起こっているかを理解できるように、短い高レベルのコメントを書くようにしてください。 これは、複雑な問題を解決する場合に役立ちます。特定の機能が何をするのか、そしてその理由をすばやく理解できます。 明確なコメントと変数名および関数名を使用することにより、あなた(および他の人々)は以下を理解できます。





9.コードの改訂を通じてフィードバックを取得します。



同僚、幹部、その他の開発者からフィードバックを受け取ります。 スタックオーバーフローを読み取ります。 他の人が同様の問題をどのように解決するかを見て、そこから学んでください。 多くの場合、問題を解決する方法はいくつかあります。 それらが何であるかを調べてください。そうすれば、あなたが自分でそれらに来るのがより速く簡単になります。



「きれいなコードを書くのがどれほど遅くても、汚いコードを書くときはいつもより多くの時間を費やします。」
ソフトウェアエンジニアであり、アジャイルマニフェストの共著者であるボブマーティンおじさん



10.練習、練習、練習



経験豊富な開発者でさえ、常に練習と学習を行っています。 有用な応答を受け取ったら、それを実装してください。 繰り返しますが、問題または同様のタスクを解決します。 自力で。 各タスクを完了すると、開発者としてより良くなります 。 成功するたびに喜び、あなたがすでにどれだけ合格したかを忘れないでください。 プログラミングは、他のアクティビティと同様に、時間の経過とともにますます簡単になります。



「どれだけ合格したかを誇りに思う。 あなたはさらに行くと信じています。 しかし、旅を楽しむことを忘れないでください。」
マイケル・ジョセフソン、ジョセフとエドナ・ジョセフソン倫理研究所の創設者



All Articles