演習 - 新しいペット データを入力するためのループを構築してテストする

完了

この演習では、新しい ourAnimals 配列データの入力を制御するコードを開発します。 ループ制御変数の初期値を計算し、動物のユーザー指定データを収集するループを構築します。 この演習で完了する詳細なタスクは次のとおりです。

  1. petCount を計算する: データが割り当てられている ourAnimals 配列内のペットの数をカウントするコードを記述します。
  2. 条件付きメッセージ: petCountmaxPets未満の場合にメッセージ出力を表示するコードを記述します。
  3. 外側のループ: 新しい ourAnimals 配列データを入力するために使用されるループ構造を構築します。
  4. 終了条件: "新しい ourAnimals 配列データの入力" ループの終了条件を評価するコードを記述します。
  5. 検証テスト: この演習で開発したコードの検証テストを実行します。

重要

この演習を開始する前に、このモジュールの前の演習を完了する必要があります。

ourAnimals 配列内のペットの数をカウントする

このタスクでは、データ入力ループの終了条件を設定し、データが割り当てられているforのペットの数をカウントするために使用できるourAnimals ループを作成します。

  1. Visual Studio Code が開き、Program.cs ファイルがエディターに表示されていることを確認します。

  2. switch(menuSelection)ステートメントを見つけて、case "2":コード行を見つけます。

  3. "近日公開予定" メッセージを表示する Console.WriteLine() ステートメントを見つけて、空白のコード行に置き換えます。

  4. 作成した空白のコード行で、 anotherPet 変数と petCount 変数を宣言するには、次のコードを入力します。

    string anotherPet = "y";
    int petCount = 0;
    

    これら 2 つの変数は、新しいペット データの入力に使用される while ループの反復を制御します。 両方の変数を宣言の一部として初期化します。

    • anotherPetは、y ループの開始前に while の値で初期化されます。 y ループ内でユーザー割り当て値 (nまたはwhile) を受け取ります。

    • petCount は、ペットの特性が割り当てられた動物の数を表します。 while ループの外部に計算値が割り当てられ、新しい動物が1配列に追加されるたびに、while ループ内のourAnimalsずつインクリメントされます。

    重要

    変数のスコープは、常にできるだけ狭くする必要があります。 Contoso Pets アプリケーションでは、petCount コード ブロックにスコープを設定するのではなく、アプリケーション レベルでcase "2":スコープを設定できます。 スコープが大きいほど、アプリケーション内のどこからでも petCount にアクセスできます。 petCountアプリケーション レベルでスコープが設定されている場合は、サンプル データを作成するときに値を割り当て、アプリケーションの残りの部分でその値をプログラムで管理できます。 たとえば、ペットの家を見つけてourAnimals配列からペットを削除すると、petCount1を減らすことができます。 問題は、アプリケーションの他の部分で変数が使用されるかどうかわからないときに、どのレベルで変数のスコープを設定する必要があるかです。 この場合、他の場所で使用していない場合でも、アプリケーション レベルで petCount のスコープを設定するのは魅力的です。 結局のところ、アプリケーション レベルで petCount スコープを設定すると、他の場所で使用する場合に使用できるようになります。 アプリケーション レベルで他の変数のスコープを設定することもできます。 そうすることで、変数は常にスコープ内にあり、アクセス可能になります。 では、後でアプリケーションで使用される可能性があると思われるときに、アプリケーション レベルで変数のスコープを設定してみませんか? 必要以上に高いレベルで変数をスコープすると、問題が発生する可能性があります。 昇格されたスコープにより、アプリケーションのリソース要件が増大し、アプリケーションが不要なセキュリティ リスクにさらされる可能性があります。 アプリケーションの規模が大きくなり、複雑になるにつれて、より多くのリソースが必要になります。 電話とコンピューターは、スコープ内にあるときにこれらのリソースのメモリを割り当てます。 アプリケーションの "現実世界" が増えるにつれて、アプリケーションのアクセシビリティが高くなります。 多くの場合、アプリケーションはクラウドや他のアプリケーションからアクセスできます。 これらの問題を複合化すると、多くの場合、アプリケーションは使用されていないときに実行したままになります。 アプリケーションのリソース要件を制御し、セキュリティフットプリントを可能な限り小さくすることが重要です。 現在のオペレーティング システムは、リソースを管理し、アプリケーションをセキュリティで保護する優れた仕事をしていますが、変数を実際に必要なレベルに範囲指定しておくことをお勧めします。 Contoso Pets アプリでアプリケーション内でより広くpetCountを使用することを決定した場合、より高いレベルでスコープをpetCountするようにコードを更新できます。 変数のスコープはできるだけ狭くし、必要になったときにのみスコープを広げることを忘れないでください。

  5. 変数宣言の下のコード行で、 ourAnimals 配列内の動物を反復処理するループを作成するには、次のコードを入力します。

    for (int i = 0; i < maxPets; i++)
    {
    }
    

    このコードは使い慣れているはずです。 この for ループは、 ourAnimals 配列を反復処理するたびに使用します。

  6. for ループのコード ブロック内で、ペットの特性データが動物に割り当てられているかどうかを確認するには、次のコードを入力します。

    if (ourAnimals[i, 0] != "ID #: ")
    {
    }
    

    ここでも、このコードは使い慣れているはずです。 この if ステートメントは、ペットの特性が割り当てられているかどうかを確認するたびに使用します。

  7. 作成した if のコード ブロック内で、 petCount を 1 ずつインクリメントするには、次のコードを入力します。

    petCount += 1;
    
  8. 完了した for ループを調べるには 1 分かかります。

    完了した for ループは、次のコードのようになります。

    for (int i = 0; i < maxPets; i++)
    {
        if (ourAnimals[i, 0] != "ID #: ")
        {
            petCount += 1;
        }
    }
    

    このコードは、割り当てられたデータをチェックする ourAnimals 配列をループ処理します。 データが割り当てられている動物が見つかると、 petCounter増加します。

  9. Visual Studio Code の [ファイル] メニューで、[保存] を選択します。

  10. Visual Studio Code で [統合ターミナル] パネルを開き、コマンドを入力してプログラムをビルドします。

    エクスプローラー ビューから統合ターミナルを開くには、[ スタート] を右クリックし、[ 統合ターミナルで開く] を選択します。 [ 表示 ] メニューまたは [ターミナル ] メニューを使用して、[統合ターミナル] パネルを開くこともできます。

    プログラムをビルドするには、ターミナル コマンド プロンプトから dotnet build コマンドを入力します。

  11. 続行する前に報告されたビルド エラーを修正します。

    現時点では、割り当てられているが使用されていない anotherPet に関する警告メッセージは無視できます。 この演習の後半で、 anotherPet を使用するコードを追加します。

    ビルド エラーがある場合は、ビルド エラーと警告メッセージに、問題の内容と見つかる場所が示されていることに注意してください。 コードを更新する場合は、リビルドする前に必ず変更を保存してください。

  12. [ターミナル] パネルを閉じます。

petCount が maxPets 未満の場合にメッセージ出力を表示する

このタスクでは、 petCountmaxPets 未満かどうかを確認し、その場合はユーザーのメッセージを表示します。

  1. 作成した for ループの下の空白のコード行で、 petCountmaxPets未満かどうかを確認するには、次のコードを入力します。

    if (petCount < maxPets)
    {
    }
    
  2. if ステートメントのコード ブロック内で、ユーザーにメッセージを表示するには、次のコードを入力します。

    Console.WriteLine($"We currently have {petCount} pets that need homes. We can manage {(maxPets - petCount)} more.");
    

    アプリケーション ユーザーは、ペットの特性を入力します。 このメッセージは、重要なコンテキストを提供します。

  3. 少し時間を取って、case "2": ステートメントの switch コード ブランチを確認してください。

    この時点で、 case "2": コード ブランチは次のコードのようになります。

    case "2":
        // Add a new animal friend to the ourAnimals array
        string anotherPet = "y";
        int petCount = 0;
        for (int i = 0; i < maxPets; i++)
        {
            if (ourAnimals[i, 0] != "ID #: ")
            {
                    petCount += 1;
            }
    
        }
    
        if (petCount < maxPets)
        {
            Console.WriteLine($"We currently have {petCount} pets that need homes. We can manage {(maxPets - petCount)} more.");
        }
    
        Console.WriteLine("Press the Enter key to continue.");
        readResult = Console.ReadLine();
        break;
    
  4. Visual Studio Code の [ファイル] メニューで、[保存] を選択します。

  5. Visual Studio Code で [統合ターミナル] パネルを開き、コマンドを入力してプログラムをビルドします。

  6. 続行する前に報告されたビルド エラーを修正します。

    ここでも、割り当てられているが使用されていない anotherPet に関する警告メッセージは無視できます。 次のタスクでは、1 つ以上のペットのデータを入力するために使用する while ループの構築を開始します。 while ループ用に作成した式では、anotherPetが使用され、この警告メッセージは表示されなくなります。

    警告メッセージは懸念すべき事柄ですが、プログラムの実行を妨げることはありません。

  7. ターミナルのコマンド プロンプトで、プログラムを実行するコマンドを入力します。

    ターミナル コマンド プロンプトで dotnet run コマンドを入力して、プログラム コードを実行します。

    コードでランタイム エラーが生成されない限り、アプリのメイン メニューがターミナル パネルに表示されます。

  8. ターミナルのコマンド プロンプトで、「2」と入力します。

    この値は、 case "2": コード ブランチに対応します。

  9. ターミナルに次のメッセージが表示されていることを確認します。

    We currently have 4 pets that need homes. We can manage 4 more.
    Press the Enter key to continue.
    

    予想されるメッセージが表示されない場合は、コードを確認して問題を特定して修正します。 変更を保存し、再構築して、アプリをもう一度実行します。 続行する前に、コードを期待どおりに動作するようにしてください。

  10. ターミナル コマンド プロンプトで Enter キーを押して、アプリケーションの実行を続行します。

  11. アプリケーションを終了し、ターミナル パネルを閉じます。

新しい ourAnimals 配列データの入力に使用されるループ構造を構築する

このタスクでは、whileanotherPetに等しく、ypetCount未満である限り、反復処理を継続するmaxPets ループを作成します。

  1. コード エディターで、 if (petCount < maxPets) コード ブロックの下に空白のコード行を作成します。

  2. 新しい while ループを作成するプロセスを開始するには、次のコードを入力します。

    while (anotherPet == "y" && petCount < maxPets)
    {
    }
    
  3. Visual Studio Code の [ファイル] メニューで、[保存] を選択します。

  4. Visual Studio Code で [統合ターミナル] パネルを開き、コマンドを入力してプログラムをビルドします。

  5. 使用されていない anotherPet に関する警告メッセージが表示されなくなったことに注意してください。

    ビルド エラーまたは警告が報告された場合は、続行する前に問題を修正してください。

新しいペット ループの終了条件を調べる

このタスクでは、 while (anotherPet == "y" && petCount < maxPets) コード ブロックを更新します。 新しいコードは petCount インクリメントされ、 petCountmaxPets未満かどうかを確認します。 petCountmaxPets未満の場合は、別のペットの情報を入力するかどうかをユーザーに確認し、応答がyまたはnであることを確認します。 while (anotherPet == "y" && petCount < maxPets)コード ブロックの後に、petCountの値を確認します。 petCountmaxPetsと等しい場合は、ペットを追加できないことをユーザーに通知します。

ペットデータの入力に使用されるコードは、次の演習で開発されます。 現時点では、データが入力され、petCount配列に保存されているかのように、ourAnimalsがインクリメントされます。 これにより、 while ループに関連付けられているコード ロジックの開発を完了できます。

  1. 前のタスクで作成した while (anotherPet == "y" && petCount < maxPets) ループのコード ブロック内に空白のコード行を作成します。

  2. petCountをインクリメントするには、次のコードを入力します。

    // increment petCount (the array is zero-based, so we increment the counter after adding to the array)
    petCount = petCount + 1;
    
  3. petCountmaxPets未満かどうかを確認するには、次のコードを入力します。

    // check maxPet limit
    if (petCount < maxPets)
    {
    }
    
  4. 作成した if ステートメントのコード ブロック内で、別のペットを追加するかどうかをユーザーに確認するには、次のコードを入力します。

    // another pet?
    Console.WriteLine("Do you want to enter info for another pet (y/n)");
    
  5. 入力した WriteLine() メッセージの下で、ユーザーの応答を読み取り、ユーザーが "y" または "n" と入力したことを確認するには、次のコードを入力します。

    do
    {
        readResult = Console.ReadLine();
        if (readResult != null)
        {
            anotherPet = readResult.ToLower();
        }
    
    } while (anotherPet != "y" && anotherPet != "n");
    
  6. break ステートメントでcase "2";case "3";を分離するswitch ステートメントを見つけます。

  7. Console.WriteLine() コードの末尾にあるConsole.ReadLine()ステートメントとcase "2"; ステートメントに注目してください。

    このコードは、ユーザーにメッセージを表示し、アプリケーションを一時停止します。

  8. Console.WriteLine()ステートメントとConsole.ReadLine() ステートメントを if ステートメント内で囲むには、次のようにコードを更新します。

    
    if (petCount >= maxPets)
    {
        Console.WriteLine("Press the Enter key to continue.");
        readResult = Console.ReadLine();
    }
    
    break;
    
    case "3":
    

    petCountの値は、while ループ内でインクリメントされます。 petCountmaxPetsと等しい場合、ourAnimals配列にペットを追加することはできません。 この状況が発生した場合は、ユーザーに通知する必要があります。

  9. Contoso Pets が容量に達したことをユーザーに通知するには、次のようにコードを更新します。

    
        if (petCount >= maxPets)
        {
            Console.WriteLine("We have reached our limit on the number of pets that we can manage.");
            Console.WriteLine("Press the Enter key to continue.");
            readResult = Console.ReadLine();
        }
    
        break;
    
    case "3":
    
  10. while ループ内のコードと、作成したユーザー メッセージを確認します。

    ユーザー メッセージを表示する while (anotherPet == "y" && petCount < maxPets) ループとコードは、次のコードのようになります。

    while (anotherPet == "y" && petCount < maxPets)
    {
        // increment petCount (the array is zero-based, so we increment the counter after adding to the array)
        petCount = petCount + 1;
    
        // check maxPet limit
        if (petCount < maxPets)
        {
            // another pet?
            Console.WriteLine("Do you want to enter info for another pet (y/n)");
            do
            {
                readResult = Console.ReadLine();
                if (readResult != null)
                {
                    anotherPet = readResult.ToLower();
                }
    
            } while (anotherPet != "y" && anotherPet != "n");
        }
    }
    
    if (petCount >= maxPets)
    {
        Console.WriteLine("We have reached our limit on the number of pets that we can manage.");
        Console.WriteLine("Press the Enter key to continue.");
        readResult = Console.ReadLine();
    }
    
  11. Visual Studio Code の [ファイル] メニューで、[保存] を選択します。

  12. Visual Studio Code で [統合ターミナル] パネルを開き、コマンドを入力してプログラムをビルドします。

  13. 続行する前に報告されたビルド エラーまたは警告を修正します。

作業を確認する

このタスクでは、統合ターミナルからアプリケーションを実行し、作成したループロジックと分岐ロジックが期待どおりに動作することを確認します。

  1. 必要に応じて、Visual Studio Code の統合ターミナル パネルを開きます。

  2. ターミナルのコマンド プロンプトで、「dotnet run」と入力します。

  3. ターミナルのコマンド プロンプトで、「2」と入力します。

  4. 次のメッセージが表示されることを確認します。

    We currently have 4 pets that need homes. We can manage 4 more.
    Do you want to enter info for another pet (y/n)
    
  5. ターミナルのコマンド プロンプトで、「n」と入力します

  6. "n" と入力したときに、コードが新しいペットを入力するためのループを終了することを確認します。

    コード ロジックが想定どおりに動作している場合は、ターミナルにメイン メニューが表示されます。

    想定どおりにコードがループを終了しない場合は、ターミナルで Ctrl キーを押しながら C キーを押して、強制的に実行を停止します。 コードを手動でステップ実行し、終了条件変数の値をトレースする必要があります。 必要に応じてコードを更新し、ユーザーが "n" を入力したときに while ループを終了するようにします。 変更を保存し、プログラムをリビルドし、検証テストを実行して、この時点に戻ります。

  7. ターミナルのコマンド プロンプトで、「2」と入力します。

    もう一度、次のメッセージが表示されます。

    We currently have 4 pets that need homes. We can manage 4 more.
    Do you want to enter info for another pet (y/n)
    
  8. ターミナルのコマンド プロンプトで、「y」と入力します

  9. コードでの petCount の使用方法を少し考えてみましょう。

    コードを検証する前に、コード ロジックを理解する必要があります。

    この場合、コード ロジックは petCountmaxPetsの関係に依存します。 maxPetsには8の値が割り当てられていることを知っていますが、petCountはどうでしょうか。 次の項目は、実装したロジックを評価するのに役立ちます。

    • petCountループの最初のイテレーションに入るときに、4whileであると認識しています。

    • petCount ループが反復処理されるたびに、whileがインクリメントされることがわかります。

    • petCountに割り当てられた値とpetCountのインクリメント方法が、ourAnimals配列へのデータの格納方法に影響を与えることがわかります。 次の項目では、 petCountourAnimalsに格納されているデータの関係について説明します。

      • アプリケーションは、サンプル データを作成するときに、 ourAnimals 配列に 4 つのペットを追加します。
      • ourAnimalsの値がpetCountされると、アプリケーションは新しいデータを4配列に格納します。 これはバグではありません。 このコードは、配列要素が 0 から始まることを思い出すときに理にかなっています。 たとえば、 ourAnimals[0,0] には動物 1 のペット ID が含まれており、 ourAnimals[3,0] には動物 4のペット ID が含まれます。 したがって、 petCount4 場合は、5 番目のペットのデータを格納します。
      • アプリケーションは、 petCountインクリメントする前に、ペット データを配列に格納します。
      • アプリケーションは、別のペットの追加をユーザーに求めるメッセージを表示する前に、 petCount インクリメントします。
      • アプリケーションで初めて別の ペットの情報を入力しますか (y/n) プロンプトが表示されたら、 petCount は既に 5に設定されています。
    • ユーザーが最初に y と入力した場合、 別のペットの情報を入力しますか (y/n) というプロンプトは、次のようになります。

      • while (anotherPet == "y" && petCount < maxPets) ループが反復処理されます。 anotherPet == "y"petCount < maxPetsのため、ループが反復処理されることがわかります。
      • petCountに割り当てられた値はインクリメントされます (while ループが反復処理されるときに)。
      • petCountに割り当てられた値は6されます (ユーザーが最初に y を入力した後)。

    このコード ロジックの分析は、アプリケーションのテストを続ける際に念頭に置いておきます。

  10. ターミナルパネルは「別のペット?」という同じメッセージで更新されますが、コードには更新されたpetCountが表示されません。

    ターミナル パネルに次の出力が表示されます。

    We currently have 4 pets that need homes. We can manage 4 more.
    Do you want to enter info for another pet (y/n)
    y
    Do you want to enter info for another pet (y/n)
    
  11. ターミナルのコマンド プロンプトで、「y」と入力します

    2 回目 y 入力すると、 petCount7にインクリメントされます。 そのため、petCount はまだ maxPets よりも小さいです。

  12. ターミナルのコマンド プロンプトで、「y」と入力します

    3 回目 y 入力すると、 petCount8にインクリメントされます。 そのため、 petCount は次のようになります。 maxPets

  13. 3 回目に while と入力したときに、コードが ループを終了することを確認します。

    ターミナル パネルに次の出力が表示されます。

    We currently have 4 pets that need homes. We can manage 4 more.
    Do you want to enter info for another pet (y/n)
    y
    Do you want to enter info for another pet (y/n)
    y
    Do you want to enter info for another pet (y/n)
    y
    We have reached our limit on the number of pets that we can manage.
    Press the Enter key to continue.
    

    想定どおりにコードがループを終了しない場合は、コードを手動でステップ実行し、終了条件変数の値をトレースします。 petCountmaxPets と等しい値に達したときにループを終了するようにコードを更新します。 petCountが既定値の maxPets を持つ 8 と等しいことがわかっているまで、"y" と答え続けます。

  14. ターミナル コマンド プロンプトで Enter キーを押して、アプリケーションの実行を続行します。

  15. アプリケーションを終了し、ターミナル パネルを閉じます。