Exercício - Revisar e testar um aplicativo de console em C# usando dados de exemplo

Concluído

Neste exercício, você revisa e testa o código no projeto Starter, isola e corrige um problema de lógica e, em seguida, verifica se seu aplicativo atualizado está funcionando conforme o esperado.

Conclua as seguintes tarefas durante este exercício:

  1. Revisão de código: revise o conteúdo do arquivo Program.cs.

    O Program.cs inclui as seguintes seções de código:

    • Instruções de nível superior: as instruções de nível superior simulam uma série de transações usando uma matriz de testData ou um número maior de transações geradas aleatoriamente.
    • LoadTillEachMorning: o LoadTillEachMorning método é usado para configurar a caixa registradora com um número predefinido de notas em cada denominação.
    • MakeChange: o método é usado para gerenciar o caixa eletrônico durante as MakeChange transações de compra.
    • LogTillStatus: o LogTillStatus método é usado para exibir o número de notas de cada denominação atualmente no caixa.
    • TillAmountSummary: o TillAmountSummary método usado exibe uma mensagem mostrando a quantidade de dinheiro no caixa.
  2. Teste inicial: verifique se MakeChange equilibra com sucesso o dinheiro até ao usar o testData array para simular transações.

  3. Depuração de código: isole e corrija um problema de lógica exposto ao usar dados gerados aleatoriamente.

  4. Teste de verificação: execute um teste de verificação no código desenvolvido neste exercício.

Revise o conteúdo do arquivo de Program.cs

Nesta tarefa, você conclui um passo a passo do código do projeto Starter. O arquivo Program.cs contém um aplicativo que simula as condições para transações diárias. O aplicativo chama o MakeChange método para gerenciar o dinheiro até durante cada transação. Outros métodos são usados para inicializar o till e gerar mensagens de relatório.

  1. Verifique se a pasta GuidedProject está aberta no Visual Studio Code.

  2. Na visualização EXPLORER, expanda as pastas GuidedProject e Starter .

    A pasta Starter contém o aplicativo de exemplo para este módulo de projeto guiado.

  3. Abra o arquivo Program.cs no Editor de Códigos do Visual Studio.

  4. No menu Exibir, selecione Paleta de comandos.

  5. No prompt de comando, digite .net: g e selecione .NET: Gerar ativos para compilação e depuração.

  6. No prompt Selecione o projeto a ser iniciado, selecione o projeto inicial.

    O arquivo launch.json criado incluirá uma configuração para o projeto Starter.

  7. Reserve alguns minutos para revisar as instruções de nível superior para este aplicativo:

    /*
    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);
    

    O código de instruções de nível superior conclui as seguintes tarefas:

    • Configura os dados do aplicativo e as variáveis de ambiente usadas para testar o MakeChange método.
    • Chama o LoadTillEachMorning(), LogTillStatus()e TillAmountSummary() métodos para preparar o dinheiro e imprimir mensagens de status para o console.
    • Usa um while loop para simular uma série de transações.
    • Chama o MakeChange método de dentro do bloco de código do while loop.
    • Informa o status do dinheiro até depois de cada transação.

    Nota

    As declarações de nível superior incluem uma Console.ReadLine() instrução. O launch.json arquivo precisará ser atualizado antes da depuração.

  8. Reserve um momento para rever o LoadTillEachMorning() método.

    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. Reserve alguns minutos para rever o MakeChange() método.

    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;
    }
    

    O MakeChange método gerencia o dinheiro até durante cada transação de compra. O processo de transação depende dos seguintes recursos e condições:

    • Transação em dinheiro: O MakeChange método aceita um pagamento em dinheiro do cliente e, em seguida, determina quantas faturas de cada denominação devem ser devolvidas ao cliente em troca. MakeChange deve, em primeiro lugar, certificar-se de que o cliente disponibilizou dinheiro suficiente para cobrir a transação. Se o pagamento for suficiente, o processo de "fazer alteração" começa com a maior denominação da nota e vai até a menor denominação. Em cada fase, MakeChange garante que a denominação atual é inferior à variação devida. MakeChange também garante que uma fatura com a denominação exigida esteja disponível no caixa antes de adicioná-la à alteração devolvida ao cliente.

    • Parâmetros de entrada: O MakeChange método usa os seguintes parâmetros de entrada:

      • Um número inteiro que representa o custo do item que está sendo comprado: itemCost
      • Uma matriz inteira contendo o número de notas na caixa para cada denominação: cashTill
      • O pagamento oferecido pelo cliente, sempre que o número de faturas para cada denominação seja especificado separadamente: paymentTwenties, paymentTens, paymentFives, , paymentOnes
    • Dinheiro disponível em caixa: As contas oferecidas como pagamento pelo cliente devem ser incluídas nas faturas de cada denominação que estão disponíveis para fazer troco.

    • Alteração devida ao cliente: A alteração devida ao cliente é calculada utilizando o valor pago pelo cliente menos o custo do artigo.

    • Pagamento insuficiente: se o cliente não tiver fornecido pagamento suficiente, MakeChange devolve uma mensagem descritiva e a transação é cancelada.

    • Insuficiente até: Se o caixa não conseguir fazer a alteração exata, MakeChange retorna uma mensagem descritiva e a transação é cancelada.

  10. Reserve um momento para rever o LogTillStatus() método.

    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();
    }
    

    O LogTillStatus método usa a cashTill matriz para relatar o conteúdo atual do till.

  11. Reserve um momento para rever o TillAmountSummary() método.

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

    O TillAmountSummary método usa a cashTill matriz para calcular o saldo de caixa atual disponível no caixa.

Isso conclui sua revisão do projeto de código existente.

Verifique se MakeChange gerencia com êxito o dinheiro ao usar o testData array

Nesta tarefa, você simula transações usando a testData matriz e verifica se MakeChange equilibra com sucesso o dinheiro até.

  1. No menu Executar código do Visual Studio, selecione Iniciar depuração.

  2. Observe que ocorre um IOException erro.

    O DEBUG CONSOLE não suporta Console.Clear() nem Console.ReadLine() métodos. Você precisa atualizar o arquivo launch.json antes de depurar.

  3. Na barra de ferramentas Depurar, selecione Parar.

  4. Use o modo de exibição EXPLORER para abrir o arquivo launch.json.

  5. No arquivo launch.json, atualize o console atributo da seguinte maneira:

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

    O valor padrão para o console atributo é internalConsole, que se alinha ao painel DEBUG CONSOLE. Infelizmente, o painel DEBUG CONSOLE não suporta alguns métodos de console. A integratedTerminal configuração está alinhada ao painel TERMINAL, que suporta entrada e saída do console.

  6. Salve suas alterações no arquivo launch.json.

  7. No menu Executar código do Visual Studio, selecione Iniciar depuração.

  8. Analise a saída gerada pelo aplicativo no painel TERMINAL.

    Mude do painel DEBUG CONSOLE para o painel TERMINAL para rever a saída.

  9. Observe que MakeChange equilibra com êxito o till ao usar o testData array para simular transações.

    Você deve ver as seguintes linhas listadas na parte inferior da saída relatada:

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

    Observe que os valores relatados e esperados são ambos 551.

  10. Para sair do aplicativo, pressione Enter.

Identificar e corrigir problemas de lógica

Nesta tarefa, você usa transações simuladas para expor um problema de lógica de código e, em seguida, use as ferramentas de depurador de código do Visual Studio para isolar e corrigir o problema.

  1. Para executar o código usando transações geradas aleatoriamente, altere o valor atribuído a useTestDatafalse.

    Você pode encontrar a useTestData variável na parte superior das instruções de nível superior.

  2. Salve o arquivo Program.cs e execute o aplicativo no depurador.

  3. Analise a saída no painel TERMINAL.

  4. Observe a discrepância no saldo do caixa.

    O saldo final calculado e MakeChange o saldo mantido nas demonstrações de nível superior são relatados na parte inferior da produção. Por exemplo:

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

    Nota

    O aplicativo gera aleatoriamente o custo dos itens de compra. Portanto, os valores de till relatados em sua saída são diferentes.

  5. Para sair do aplicativo, pressione Enter.

  6. Feche o painel TERMINAL.

Depurar o código

Nesta tarefa, você usa as ferramentas de depurador de código do Visual Studio para isolar e, em seguida, corrigir o problema de lógica.

  1. Perto do final das instruções de nível superior, localize a seguinte linha de código:

    Console.WriteLine();
    
  2. Defina um ponto de interrupção na linha de código selecionada.

  3. No menu Executar código do Visual Studio, selecione Iniciar depuração.

  4. Observe que a execução de código pausa no ponto de interrupção.

  5. Na barra de ferramentas Controles de depuração, selecione Step Into.

  6. Analise a saída no painel TERMINAL.

  7. Se os valores até relatados e esperados forem iguais, selecione Continuar na barra de ferramentas Controles de depuração.

  8. Repita a etapa anterior até ver uma discrepância entre os valores relatados e esperados.

  9. Depois de ver uma discrepância, reserve um minuto para examinar os detalhes da transação.

  10. Observe que o dinheiro informado recebido e o troco devolvido estão corretos, mas o caixa é curto em cinco dólares.

    Essa escassez sugere que a cashTill matriz está sendo atualizada incorretamente, mesmo que o relatório esteja correto.

  11. Pare a sessão de depuração e feche o painel TERMINAL.

  12. Desloque-se para a parte inferior do MakeChange método.

    As while instruções usadas para "fazer alterações" estão localizadas no final do MakeChange método.

  13. Revise os blocos de código de while instrução usados para fazer alterações.

    Como o caixa está fora em cinco dólares, é provável que o problema esteja no while bloco de código que é usado para devolver notas de cinco dólares.

  14. Observe o seguinte código:

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

    A cashTill[] matriz é usada para armazenar o número de notas de cada denominação que estão atualmente disponíveis. O elemento 1 array é usado para gerenciar o número de notas de cinco dólares no caixa. A expressão na while declaração refere-se corretamente cashTill[1] . No entanto, a instrução dentro do bloco de código diminui cashTill[2] em vez de cashTill[1]. Especificar um valor de índice significa que uma nota de dez dólares está sendo removida do caixa, em vez de uma nota de 2 cinco dólares.

  15. Atualize o bloco de while código da seguinte maneira:

    while ((changeNeeded > 4) && (cashTill[1] > 0))
    {
        cashTill[1]--;
        changeNeeded -= 5;
        Console.WriteLine("\t A five");
    }    
    
  16. Guarde o ficheiro Program.cs.

Verifique o seu trabalho

Nesta tarefa, você executa seu aplicativo e verifica se o código atualizado funciona como pretendido.

  1. No menu Executar código do Visual Studio, selecione Remover todos os pontos de interrupção.

  2. No menu Executar, selecione Iniciar Depuração.

  3. Analise a saída no painel TERMINAL.

  4. Verifique se o valor till relatado é igual ao valor till esperado:

    O saldo final calculado e MakeChange o saldo mantido nas demonstrações de nível superior são relatados na parte inferior da produção. Por exemplo:

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

    O aplicativo gera aleatoriamente o custo dos itens de compra. Portanto, os valores de till relatados em sua saída são diferentes. Desde que os dois valores sejam iguais, você conseguiu corrigir o problema de lógica.