تمرين - مراجعة واختبار تطبيق وحدة تحكم C# باستخدام نموذج البيانات

مكتمل

في هذا التمرين، يمكنك مراجعة التعليمات البرمجية واختبارها في مشروع Starter، وعزل مشكلة منطقية وإصلاحها، ثم التحقق من أن التطبيق المحدث يعمل كما هو متوقع.

إكمال المهام التالية أثناء هذا التمرين:

  1. مراجعة التعليمات البرمجية: راجع محتويات ملف Program.cs.

    يتضمن Program.cs أقسام التعليمات البرمجية التالية:

    • عبارات المستوى الأعلى: تحاكي عبارات المستوى الأعلى سلسلة من المعاملات باستخدام صفيف أو testData عدد أكبر من المعاملات التي تم إنشاؤها عشوائيا.
    • LoadTillEachMorning: LoadTillEachMorning يستخدم الأسلوب لتكوين السجل النقدي حتى مع عدد محدد مسبقا من الفواتير في كل فئة.
    • MakeChange: MakeChange يتم استخدام الأسلوب لإدارة النقد حتى أثناء معاملات الشراء.
    • LogTillStatus: LogTillStatus يتم استخدام الأسلوب لعرض عدد فواتير كل فئة حاليا في حتى.
    • TillAmountSummary: TillAmountSummary يتم استخدام الأسلوب لعرض رسالة تظهر المبلغ النقدي في حتى.
  2. الاختبار الأولي: تحقق من MakeChange موازنة الأموال بنجاح حتى عند استخدام testData الصفيف لمحاكاة المعاملات.

  3. تصحيح أخطاء التعليمات البرمجية: عزل وتصحيح مشكلة منطقية يتم كشفها عند استخدام بيانات تم إنشاؤها عشوائيا.

  4. اختبار التحقق: قم بإجراء اختبار تحقق على التعليمات البرمجية التي تطورها في هذا التمرين.

مراجعة محتويات ملف Program.cs

في هذه المهمة، يمكنك إكمال معاينة التعليمة البرمجية لمشروع Starter. يحتوي ملف Program.cs على تطبيق يحاكي شروط المعاملات اليومية. يستدعي MakeChange التطبيق الأسلوب لإدارة المال حتى أثناء كل معاملة. يتم استخدام أساليب أخرى لتهيئة حتى وإنشاء رسائل إعداد التقارير.

  1. تأكد من فتح مجلد GuidedProject في Visual Studio Code.

  2. في طريقة عرض EXPLORER، قم بتوسيع المجلدين GuidedProject وStarter.

    يحتوي مجلد Starter على نموذج التطبيق لوحدة المشروع الإرشادية هذه.

  3. افتح ملف Program.cs في محرر التعليمات البرمجية Visual Studio.

  4. في القائمة عرض، حدد لوحة الأوامر.

  5. في موجه الأوامر، أدخل .net: g ثم حدد .NET: Generate Assets for Build and Debug.

  6. في المطالبة Select the project to launch ، حدد مشروع Starter .

    سيتضمن ملف launch.json الذي تم إنشاؤه تكوينا لمشروع Starter.

  7. يستغرق بضع دقائق لمراجعة عبارات المستوى الأعلى لهذا التطبيق:

    /*
    This application manages transactions at a store check-out line. The
    check-out line has a cash register, and the register has a cash till
    that is prepared with a number of bills each morning. The till includes
    bills of four denominations: $1, $5, $10, and $20. The till is used
    to provide the customer with change during the transaction. The item 
    cost is a randomly generated number between 2 and 49. The customer 
    offers payment based on an algorithm that determines a number of bills
    in each denomination. 
    
    Each day, the cash till is loaded at the start of the day. As transactions
    occur, the cash till is managed in a method named MakeChange (customer 
    payments go in and the change returned to the customer comes out). A 
    separate "safety check" calculation that's used to verify the amount of
    money in the till is performed in the "main program". This safety check
    is used to ensure that logic in the MakeChange method is working as 
    expected.
    */
    
    string? readResult = null;
    bool useTestData = true;
    
    Console.Clear();
    
    int[] cashTill = new int[] { 0, 0, 0, 0 };
    int registerCheckTillTotal = 0;
    
    // registerDailyStartingCash: $1 x 50, $5 x 20, $10 x 10, $20 x 5 => ($350 total)
    int[,] registerDailyStartingCash = new int[,] { { 1, 50 }, { 5, 20 }, { 10, 10 }, { 20, 5 } };
    
    int[] testData = new int[] { 6, 10, 17, 20, 31, 36, 40, 41 };
    int testCounter = 0;
    
    LoadTillEachMorning(registerDailyStartingCash, cashTill);
    
    registerCheckTillTotal = registerDailyStartingCash[0, 0] * registerDailyStartingCash[0, 1] + registerDailyStartingCash[1, 0] * registerDailyStartingCash[1, 1] + registerDailyStartingCash[2, 0] * registerDailyStartingCash[2, 1] + registerDailyStartingCash[3, 0] * registerDailyStartingCash[3, 1];
    
    // display the number of bills of each denomination currently in the till
    LogTillStatus(cashTill);
    
    // display a message showing the amount of cash in the till
    Console.WriteLine(TillAmountSummary(cashTill));
    
    // display the expected registerDailyStartingCash total
    Console.WriteLine($"Expected till value: {registerCheckTillTotal}\n\r");
    
    var valueGenerator = new Random((int)DateTime.Now.Ticks);
    
    int transactions = 10;
    
    if (useTestData)
    {
        transactions = testData.Length;
    }
    
    while (transactions > 0)
    {
        transactions -= 1;
        int itemCost = valueGenerator.Next(2, 20);
    
        if (useTestData)
        {
            itemCost = testData[testCounter];
            testCounter += 1;
        }
    
        int paymentOnes = itemCost % 2;                 // value is 1 when itemCost is odd, value is 0 when itemCost is even
        int paymentFives = (itemCost % 10 > 7) ? 1 : 0; // value is 1 when itemCost ends with 8 or 9, otherwise value is 0
        int paymentTens = (itemCost % 20 > 13) ? 1 : 0; // value is 1 when 13 < itemCost < 20 OR 33 < itemCost < 40, otherwise value is 0
        int paymentTwenties = (itemCost < 20) ? 1 : 2;  // value is 1 when itemCost < 20, otherwise value is 2
    
        // display messages describing the current transaction
        Console.WriteLine($"Customer is making a ${itemCost} purchase");
        Console.WriteLine($"\t Using {paymentTwenties} twenty dollar bills");
        Console.WriteLine($"\t Using {paymentTens} ten dollar bills");
        Console.WriteLine($"\t Using {paymentFives} five dollar bills");
        Console.WriteLine($"\t Using {paymentOnes} one dollar bills");
    
        // MakeChange manages the transaction and updates the till 
        string transactionMessage = MakeChange(itemCost, cashTill, paymentTwenties, paymentTens, paymentFives, paymentOnes);
    
        // Backup Calculation - each transaction adds current "itemCost" to the till
        if (transactionMessage == "transaction succeeded")
        {
            Console.WriteLine($"Transaction successfully completed.");
            registerCheckTillTotal += itemCost;
        }
        else
        {
            Console.WriteLine($"Transaction unsuccessful: {transactionMessage}");
        }
    
        Console.WriteLine(TillAmountSummary(cashTill));
        Console.WriteLine($"Expected till value: {registerCheckTillTotal}\n\r");
        Console.WriteLine();
    }
    
    Console.WriteLine("Press the Enter key to exit");
    do
    {
        readResult = Console.ReadLine();
    
    } while (readResult == null);
    

    التعليمات البرمجية لعبارات المستوى الأعلى تكمل المهام التالية:

    • تكوين بيانات التطبيق ومتغيرات البيئة المستخدمة لاختبار MakeChange الأسلوب.
    • LoadTillEachMorning()استدعاء أساليب و LogTillStatus()و TillAmountSummary() لإعداد المال حتى وطباعة رسائل الحالة إلى وحدة التحكم.
    • while يستخدم حلقة لمحاكاة سلسلة من المعاملات.
    • MakeChange استدعاء الأسلوب من داخل كتلة التعليمات البرمجية للحلقةwhile.
    • يبلغ عن حالة المال حتى بعد كل معاملة.

    إشعار

    تتضمن عبارات المستوى الأعلى عبارة Console.ReadLine() . launch.json يجب تحديث الملف قبل تصحيح الأخطاء.

  8. خذ لحظة لمراجعة LoadTillEachMorning() الأسلوب.

    static void LoadTillEachMorning(int[,] registerDailyStartingCash, int[] cashTill)
    {
        cashTill[0] = registerDailyStartingCash[0, 1];
        cashTill[1] = registerDailyStartingCash[1, 1];
        cashTill[2] = registerDailyStartingCash[2, 1];
        cashTill[3] = registerDailyStartingCash[3, 1];
    }
    
  9. يستغرق بضع دقائق لمراجعة MakeChange() الأسلوب.

    static string MakeChange(int cost, int[] cashTill, int twenties, int tens = 0, int fives = 0, int ones = 0)
    {
        string transactionMessage = "";
    
        cashTill[3] += twenties;
        cashTill[2] += tens;
        cashTill[1] += fives;
        cashTill[0] += ones;
    
        int amountPaid = twenties * 20 + tens * 10 + fives * 5 + ones;
        int changeNeeded = amountPaid - cost;
    
        if (changeNeeded < 0)
            transactionMessage = "Not enough money provided.";
    
        Console.WriteLine("Cashier Returns:");
    
        while ((changeNeeded > 19) && (cashTill[3] > 0))
        {
            cashTill[3]--;
            changeNeeded -= 20;
            Console.WriteLine("\t A twenty");
        }
    
        while ((changeNeeded > 9) && (cashTill[2] > 0))
        {
            cashTill[2]--;
            changeNeeded -= 10;
            Console.WriteLine("\t A ten");
        }
    
        while ((changeNeeded > 4) && (cashTill[1] > 0))
        {
            cashTill[2]--;
            changeNeeded -= 5;
            Console.WriteLine("\t A five");
        }
    
        while ((changeNeeded > 0) && (cashTill[0] > 0))
        {
            cashTill[0]--;
            changeNeeded--;
            Console.WriteLine("\t A one");
        }
    
        if (changeNeeded > 0)
            transactionMessage = "Can't make change. Do you have anything smaller?";
    
        if (transactionMessage == "")
            transactionMessage = "transaction succeeded";
    
        return transactionMessage;
    }
    

    الطريقة MakeChange تدير المال حتى أثناء كل عملية شراء. تعتمد عملية المعاملة على الموارد والشروط التالية:

    • المعاملة النقدية: MakeChange تقبل الطريقة دفعة نقدية من العميل ثم تحدد عدد فواتير كل فئة يجب إرجاعها إلى العميل في التغيير. MakeChange يجب أولا التأكد من أن العميل قد قدم ما يكفي من المال لتغطية المعاملة. إذا كان الدفع كافيا، تبدأ عملية "إجراء التغيير" بأكبر فئة فاتورة وتعمل وصولا إلى أصغر فئة. في كل مرحلة، MakeChange يضمن أن الطائفة الحالية أقل من التغيير المستحق. MakeChange كما يضمن أن فاتورة الفئة المطلوبة متاحة في حتى قبل إضافتها إلى التغيير الذي تم إرجاعه إلى العميل.

    • معلمات الإدخال: MakeChange يستخدم الأسلوب معلمات الإدخال التالية:

      • عدد صحيح يمثل تكلفة العنصر الذي يتم شراؤه: itemCost
      • صفيف عدد صحيح يحتوي على عدد الفواتير في حتى لكل طائفة: cashTill
      • الدفعة التي يقدمها العميل، حيث يتم تحديد عدد الفواتير لكل فئة بشكل منفصل: paymentTwenties، paymentTens، ، paymentFivespaymentOnes
    • النقود المتوفرة في حتى: يجب تضمين الفواتير المقدمة كدفعة من قبل العميل في فواتير كل فئة متوفرة لإجراء التغيير.

    • التغيير المستحق للعميل: يتم حساب التغيير المستحق للعميل باستخدام المبلغ الذي دفعه العميل مطروحا منه تكلفة الصنف.

    • الدفعة الناقصة: إذا لم يقدم العميل دفعة كافية، MakeChange فسترجع رسالة وصفية، ويتم إلغاء المعاملة.

    • غير كاف حتى: إذا تعذر على حتى إجراء تغيير دقيق، MakeChange فترجع رسالة وصفية، ويتم إلغاء المعاملة.

  10. خذ لحظة لمراجعة LogTillStatus() الأسلوب.

    static void LogTillStatus(int[] cashTill)
    {
        Console.WriteLine("The till currently has:");
        Console.WriteLine($"{cashTill[3] * 20} in twenties");
        Console.WriteLine($"{cashTill[2] * 10} in tens");
        Console.WriteLine($"{cashTill[1] * 5} in fives");
        Console.WriteLine($"{cashTill[0]} in ones");
        Console.WriteLine();
    }
    

    LogTillStatus يستخدم cashTill الأسلوب الصفيف للإبلاغ عن المحتويات الحالية لل حتى.

  11. خذ لحظة لمراجعة TillAmountSummary() الأسلوب.

    static string TillAmountSummary(int[] cashTill)
    {
        return $"The till has {cashTill[3] * 20 + cashTill[2] * 10 + cashTill[1] * 5 + cashTill[0]} dollars";
    
    }
    

    TillAmountSummary يستخدم cashTill الأسلوب الصفيف لحساب الرصيد النقدي الحالي المتوفر في حتى.

هذا يكمل مراجعة مشروع التعليمات البرمجية الموجود.

تحقق من إدارة MakeChange الأموال بنجاح عند استخدام testData الصفيف

في هذه المهمة، يمكنك محاكاة المعاملات باستخدام testData الصفيف والتحقق من MakeChange موازنة الأموال حتى بنجاح.

  1. في قائمة Visual Studio Code Run ، حدد Start Debugging.

  2. لاحظ حدوث IOException خطأ.

    لا تدعم Console.Clear() وحدة تحكم تتبع الأخطاء أو Console.ReadLine() الأساليب. تحتاج إلى تحديث ملف launch.json قبل تصحيح الأخطاء.

  3. في شريط أدوات تتبع الأخطاء، حدد إيقاف.

  4. استخدم طريقة عرض EXPLORER لفتح ملف launch.json.

  5. في ملف launch.json، قم بتحديث السمة console كما يلي:

    // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
    "console":"integratedTerminal",
    

    القيمة الافتراضية للسمة console هي internalConsole، والتي تتوافق مع لوحة وحدة تحكم DEBUG. لسوء الحظ، لا تدعم لوحة وحدة تحكم DEBUG بعض أساليب وحدة التحكم. يتوافق integratedTerminal الإعداد مع لوحة TERMINAL، التي تدعم إدخال وحدة التحكم والإخراج.

  6. احفظ التغييرات التي أجريتها على ملف launch.json.

  7. في قائمة Visual Studio Code Run ، حدد Start Debugging.

  8. راجع الإخراج الذي تم إنشاؤه بواسطة التطبيق في لوحة TERMINAL.

    قم بالتبديل من لوحة وحدة تحكم DEBUG إلى لوحة TERMINAL لمراجعة الإخراج.

  9. لاحظ أن MakeChange يوازن بنجاح حتى عند استخدام testData الصفيف لمحاكاة المعاملات.

    يجب أن تشاهد الأسطر التالية مدرجة في أسفل الإخراج المبلغ عنه:

    The till has 551 dollars
    Expected till value: 551
    
    
    Press the Enter key to exit
    

    لاحظ أن القيم المبلغ عنها والمتوقعة حتى تبلغ 551.

  10. للخروج من التطبيق، اضغط على مفتاح الإدخال Enter.

تحديد مشكلات المنطق وإصلاحها

في هذه المهمة، يمكنك استخدام عمليات المحاكاة لعرض مشكلة منطق التعليمات البرمجية، ثم استخدام أدوات مصحح أخطاء Visual Studio Code لعزل المشكلة وإصلاحها.

  1. لتشغيل التعليمات البرمجية باستخدام المعاملات التي تم إنشاؤها عشوائيا، قم بتغيير القيمة المعينة إلى useTestData false.

    يمكنك العثور على useTestData المتغير بالقرب من أعلى عبارات المستوى الأعلى.

  2. احفظ ملف Program.cs، ثم قم بتشغيل التطبيق في مصحح الأخطاء.

  3. راجع الإخراج في لوحة TERMINAL.

  4. لاحظ التناقض في رصيد حتى.

    يتم الإبلاغ عن رصيد حتى النهاية المحسوبة بواسطة MakeChange والرصيد المحتفظ به في عبارات المستوى الأعلى في أسفل الإخراج. على سبيل المثال:

    Transaction successfully completed.
    The till has 379 dollars
    Expected till value: 434
    
    
    Press the Enter key to exit
    

    إشعار

    ينشئ التطبيق عشوائيا تكلفة شراء العناصر. لذلك، فإن القيم حتى المبلغ عنها في الإخراج الخاص بك مختلفة.

  5. للخروج من التطبيق، اضغط على مفتاح الإدخال Enter.

  6. أغلق لوحة TERMINAL.

تصحيح التعليمات البرمجية

في هذه المهمة، يمكنك استخدام أدوات مصحح أخطاء Visual Studio Code لعزل ثم إصلاح مشكلة المنطق.

  1. بالقرب من نهاية عبارات المستوى الأعلى، حدد موقع سطر التعليمات البرمجية التالي:

    Console.WriteLine();
    
  2. تعيين نقطة توقف على سطر التعليمات البرمجية المحدد.

  3. في قائمة Visual Studio Code Run ، حدد Start Debugging.

  4. لاحظ أن تنفيذ التعليمات البرمجية يتوقف مؤقتا على نقطة التوقف.

  5. في شريط أدوات عناصر التحكم في تتبع الأخطاء، حدد خطوة إلى.

  6. راجع الإخراج في لوحة TERMINAL.

  7. إذا كانت القيم التي تم الإبلاغ عنها والأحرف المتوقعة متساوية، فحدد متابعة على شريط أدوات عناصر التحكم في تتبع الأخطاء.

  8. كرر الخطوة السابقة حتى ترى تعارضا بين القيم التي تم الإبلاغ عنها والأحرف المتوقعة.

  9. بمجرد أن ترى تعارضا، خذ دقيقة لفحص تفاصيل المعاملة.

  10. لاحظ أن النقود المبلغ عنها التي تم تلقيها والتغيير الذي تم إرجاعه صحيحة، ولكن حتى قصيرة بمقدار خمسة دولارات.

    يشير هذا النقص إلى أن cashTill الصفيف يتم تحديثه بشكل غير صحيح، على الرغم من أن التقارير صحيحة.

  11. أوقف جلسة تصحيح الأخطاء وأغلق لوحة TERMINAL.

  12. قم بالتمرير إلى أسفل MakeChange الأسلوب.

    while توجد العبارات المستخدمة في "إجراء تغيير" في نهاية MakeChange الأسلوب.

  13. راجع كتل التعليمات البرمجية while للبيانات المستخدمة لإجراء تغيير.

    بما أن حتى هو إيقاف بمقدار خمسة دولارات، من المحتمل أن تكون المشكلة في while كتلة التعليمات البرمجية التي تستخدم لإرجاع فواتير خمسة دولارات.

  14. لاحظ التعليمات البرمجية التالية:

    while ((changeNeeded > 4) && (cashTill[1] > 0))
    {
        cashTill[2]--;
        changeNeeded -= 5;
        Console.WriteLine("\t A five");
    }    
    

    cashTill[] يتم استخدام الصفيف لتخزين عدد فواتير كل فئة متوفرة حاليا. يتم استخدام عنصر 1 الصفيف لإدارة عدد فواتير الدولار الخمسة في حتى. يشير التعبير في العبارة while إلى cashTill[1] بشكل صحيح. ومع ذلك، فإن العبارة داخل كتلة التعليمات البرمجية cashTill[2] تتناقص بدلا من cashTill[1]. تحديد قيمة فهرسة 2 يعني أنه تتم إزالة فاتورة بقيمة عشرة دولارات من حتى بدلا من فاتورة خمسة دولارات.

  15. تحديث كتلة التعليمات البرمجية while كما يلي:

    while ((changeNeeded > 4) && (cashTill[1] > 0))
    {
        cashTill[1]--;
        changeNeeded -= 5;
        Console.WriteLine("\t A five");
    }    
    
  16. احفظ ملف Program.cs.

راجع عملك

في هذه المهمة، يمكنك تشغيل التطبيق الخاص بك والتحقق من أن التعليمات البرمجية المحدثة تعمل على النحو المنشود.

  1. في قائمة Visual Studio Code Run ، حدد Remove All Breakpoints.

  2. في قائمة Run ، حدد Start Debugging.

  3. راجع الإخراج في لوحة TERMINAL.

  4. تحقق من أن قيمة اللغاية التي تم الإبلاغ عنها مساوية لقيمة الدرج المتوقعة:

    يتم الإبلاغ عن رصيد حتى النهاية المحسوبة بواسطة MakeChange والرصيد المحتفظ به في عبارات المستوى الأعلى في أسفل الإخراج. على سبيل المثال:

    Transaction successfully completed.
    The till has 452 dollars
    Expected till value: 452
    
    
    Press the Enter key to exit
    

    ينشئ التطبيق عشوائيا تكلفة شراء العناصر. لذلك، فإن القيم حتى المبلغ عنها في الإخراج الخاص بك مختلفة. طالما أن القيمتين متساويتين، فقد نجحت في إصلاح مشكلة المنطق.