Ejercicio: Revisión y prueba de una aplicación de consola de C# con datos de ejemplo
En este ejercicio, revisará y probará el código del proyecto Starter, aislará y corregirá un problema de lógica y, después, comprobará que la aplicación actualizada funciona según lo previsto.
Durante este ejercicio realizará las siguientes tareas:
Revisión del código: revise el contenido del archivo Program.cs.
El archivo Program.cs incluye las siguientes secciones de código:
- Instrucciones de nivel superior: las instrucciones de nivel superior simulan una serie de transacciones con una matriz de
testDatao un número mayor de transacciones generadas aleatoriamente. - LoadTillEachMorning: el método
LoadTillEachMorningse utiliza para configurar la caja registradora con un número predefinido de billetes de cada valor. - MakeChange: el método
MakeChangese usa para administrar la caja registradora durante las transacciones de compra. - LogTillStatus: el método
LogTillStatusse utiliza para mostrar el número de billetes de cada valor que hay actualmente en la caja registradora. - TillAmountSummary: el método
TillAmountSummaryse usa para mostrar un mensaje que indica la cantidad de efectivo que hay en la caja.
- Instrucciones de nivel superior: las instrucciones de nivel superior simulan una serie de transacciones con una matriz de
Pruebas iniciales: compruebe que
MakeChangecuadra correctamente la caja registradora cuando se usa la matriztestDatapara simular transacciones.Depuración del código: aísle y corrija un problema de lógica que se expone al usar los datos generados aleatoriamente.
Prueba de comprobación: realice una prueba de comprobación en el código que desarrolla en este ejercicio.
Revisión del contenido del archivo Program.cs
En esta tarea, hace un recorrido por el código del proyecto Starter. El archivo Program.cs contiene una aplicación que simula las condiciones de las transacciones diarias. La aplicación llama al método MakeChange para administrar la caja registradora durante cada transacción. Se usan otros métodos para inicializar la caja y generar mensajes informativos.
Asegúrese de que la carpeta ChallengeProject está abierta en Visual Studio Code.
En la vista EXPLORADOR, expanda las carpetas ChallengeProject y Starter.
La carpeta Starter contiene la aplicación de ejemplo para este módulo de proyecto guiado.
Abra el archivo Program.cs en el editor de Visual Studio Code.
En el menú Vista, seleccione Paleta de comandos.
En el símbolo del sistema, escriba .net: g y, después, presione .NET: Generar recursos para compilar y depurar.
En el mensaje Seleccione el proyecto que desea iniciar, elija el proyecto Starter.
El archivo launch.json que se crea incluirá la configuración para el proyecto Starter.
Dedique unos minutos a revisar las instrucciones de nivel superior de esta aplicación:
/* 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);El código de las instrucciones de nivel superior lleva a cabo las siguientes tareas:
- Configura los datos de la aplicación y las variables de entorno que se usan para probar el método
MakeChange. - Llama a los métodos
LoadTillEachMorning(),LogTillStatus()yTillAmountSummary()para preparar la caja registradora e imprime los mensajes de estado en la consola. - Usa un bucle
whilepara simular una serie de transacciones. - Llama al método
MakeChangedesde el bloque de código del buclewhile. - Informa sobre del estado de la caja registradora después de cada transacción.
Nota
Las instrucciones de nivel superior incluyen una instrucción
Console.ReadLine(). Será necesario actualizar el archivolaunch.jsonantes de la depuración.- Configura los datos de la aplicación y las variables de entorno que se usan para probar el método
Dedique un momento a revisar el método
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]; }Dedique un par de minutos a revisar el método
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; }El método
MakeChangeadministra la caja registradora durante cada transacción de compra. El proceso de transacción se basa en los siguientes recursos y condiciones:Transacción en efectivo: el método
MakeChangeacepta un pago en efectivo del cliente y, después, determina cuántos billetes de cada valor deben devolverse al cliente como cambio.MakeChangedebe asegurarse primero de que el cliente ha proporcionado suficiente dinero para cubrir la transacción. Si el pago es suficiente, el proceso de "devolver el cambio" comienza con el billete de mayor valor y continúa hasta el billete de menor valor. En cada etapa,MakeChangese asegura de que el valor actual es menor que el cambio debido.MakeChangetambién se asegura de que haya un billete del valor necesario en la caja antes de agregarlo al cambio devuelto al cliente.Parámetros de entrada: el método
MakeChangeutiliza los siguientes parámetros de entrada:- Entero que representa el costo del artículo que se compra:
itemCost. - Matriz de enteros que contiene el número de billetes de cada valor que hay en la caja:
cashTill. - Pago que ofrece el cliente. El número de billetes de cada valor se especifica por separado:
paymentTwenties,paymentTens,paymentFives,paymentOnes.
- Entero que representa el costo del artículo que se compra:
Efectivo disponible en la caja: los billetes que el cliente ofrece como pago deben incluirse en los billetes de cada valor que hay disponibles para dar el cambio.
Cambio debido al cliente: el cambio que se le debe al cliente se calcula con el importe que paga el cliente menos el costo del artículo.
Pago insuficiente: si el cliente no proporciona un pago suficiente,
MakeChangedevuelve un mensaje descriptivo y se cancela la transacción.Caja insuficiente: si la caja registradora no puede proporcionar el cambio exacto,
MakeChangedevuelve un mensaje descriptivo y se cancela la transacción.
Dedique un momento a revisar el método
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(); }El método
LogTillStatususa la matrizcashTillpara informar del contenido actual de la caja.Dedique un momento a revisar el método
TillAmountSummary().static string TillAmountSummary(int[] cashTill) { return $"The till has {cashTill[3] * 20 + cashTill[2] * 10 + cashTill[1] * 5 + cashTill[0]} dollars"; }El método
TillAmountSummaryusa la matrizcashTillpara calcular el saldo en efectivo actual que hay disponible en la caja registradora.
Esto completa la revisión del proyecto de código.
Compruebe que MakeChange administra correctamente el dinero cuando se usa la matriz testData.
En esta tarea, simula transacciones con la matriz testData y comprueba que MakeChange cuadra correctamente la caja registradora.
En el menú Ejecutar de Visual Studio Code, seleccione Iniciar depuración.
Observe que se produce un error
IOException.La CONSOLA DE DEPURACIÓN no admite los métodos
Console.Clear()yConsole.ReadLine(). Debe actualizar el archivo launch.json antes de la depuración.En la barra de herramientas Depurar, seleccione Detener.
Use la vista EXPLORADOR para abrir el archivo launch.json.
En el archivo launch.json, actualice el atributo de la
consolesiguiente manera:// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console "console":"integratedTerminal",El valor predeterminado del atributo
consoleesinternalConsole, que concuerda con el panel CONSOLA DE DEPURACIÓN. Lamentablemente, el panel CONSOLA DE DEPURACIÓN no admite algunos métodos de consola. El valorintegratedTerminalconcuerda con el panel TERMINAL, que admite entradas y salidas de la consola.Guarde los cambios en el archivo launch.json.
En el menú Ejecutar de Visual Studio Code, seleccione Iniciar depuración.
Revise la salida generada por la aplicación en el panel TERMINAL.
Cambie del panel CONSOLA DE DEPURACIÓN al panel TERMINAL.
Observe que
MakeChangecuadra correctamente la caja cuando se usa la matriztestDatapara simular transacciones.Debería ver las siguientes líneas al final de la salida:
The till has 551 dollars Expected till value: 551 Press the Enter key to exitObserve que el valor notificado y el valor esperado de la caja son 551.
Presione Entrar para salir de la aplicación.
Identificación y corrección de problemas de lógica
En esta tarea, utiliza transacciones simuladas para exponer un problema de lógica del código y, después, usa las herramientas del depurador de Visual Studio Code para aislar y corregir el problema.
Para ejecutar el código usando transacciones generadas aleatoriamente, cambie el valor de
useTestDataafalse.La variable
useTestDatase encuentra cerca del principio de las instrucciones de nivel superior.Guarde el archivo Program.cs y ejecute la aplicación en el depurador.
Revise la salida en el panel TERMINAL.
Observe la discrepancia en el saldo de la caja.
Al final de la salida, se notifican el saldo final de la caja calculado por
MakeChangey el saldo mantenido en las instrucciones de nivel superior. Por ejemplo:Transaction successfully completed. The till has 379 dollars Expected till value: 434 Press the Enter key to exitNota
La aplicación genera aleatoriamente el costo de los artículos de compra. Por tanto, los valores de la caja notificados en la salida son diferentes.
Presione Entrar para salir de la aplicación.
Cierre el panel TERMINAL.
Depurar el código
En esta tarea, usa las herramientas del depurador de Visual Studio Code para aislar y corregir el problema de lógica.
Cerca del final de las instrucciones de nivel superior, busque la siguiente línea de código:
Console.WriteLine();Establezca un punto de interrupción en la línea de código seleccionada.
En el menú Ejecutar de Visual Studio Code, seleccione Iniciar depuración.
Observe que la ejecución del código se detiene en el punto de interrupción.
En la barra de herramientas Controles de depuración, seleccione Depurar paso a paso por instrucciones.
Revise la salida en el panel TERMINAL.
Si el valor notificado y el valor esperado de la caja son iguales, seleccione Continuar en la barra de herramientas Controles de depuración.
Repita el paso anterior hasta que vea una discrepancia entre el valor notificado y el valor esperado de la caja.
Cuando vea una discrepancia, dedique un minuto a examinar los detalles de la transacción.
Observe que el efectivo recibido y el cambio devuelto notificados son correctos, pero el valor de la caja es cinco dólares menor.
Esta diferencia sugiere que la matriz
cashTillse está actualizando incorrectamente, aunque las notificaciones sean correctas.Detenga la sesión de depuración y cierre el panel TERMINAL.
Desplácese hasta el final del método
MakeChange.Las instrucciones
whileque se usan para "devolver el cambio" están al final del métodoMakeChange.Revise los bloques de código de la instrucción
whileque se usan para devolver el cambio.Dado que la caja tiene un desfase de cinco dólares, es probable que el problema esté en el bloque de código
whileque se usa para devolver billetes de cinco dólares.Observe el siguiente código:
while ((changeNeeded > 4) && (cashTill[1] > 0)) { cashTill[2]--; changeNeeded -= 5; Console.WriteLine("\t A five"); }La matriz
cashTill[]se utiliza para almacenar el número de billetes de cada valor que hay disponibles actualmente. El elemento1de la matriz se usa para administrar los billetes de cinco dólares que hay en la caja. La expresión de la instrucciónwhilehace referencia acashTill[1]correctamente. Sin embargo, la instrucción que hay dentro del bloque de código disminuyecashTill[2]en lugar decashTill[1]. Especificar un valor de índice de2significa que se quita un billete de diez dólares de la caja en lugar de un billete de cinco dólares.Actualice el bloque de código
whilede la siguiente manera:while ((changeNeeded > 4) && (cashTill[1] > 0)) { cashTill[1]--; changeNeeded -= 5; Console.WriteLine("\t A five"); }Guarde el archivo Program.cs.
Comprobar el trabajo
En esta tarea, ejecuta la aplicación y comprueba que el código actualizado funciona según lo previsto.
En el menú Ejecutar de Visual Studio Code, seleccione Quitar todos los puntos de interrupción.
En el menú Ejecutar, seleccione Iniciar depuración.
Revise la salida en el panel TERMINAL.
Compruebe que el valor notificado de la caja registradora es igual al valor esperado:
Al final de la salida, se notifican el saldo final de la caja calculado por
MakeChangey el saldo mantenido en las instrucciones de nivel superior. Por ejemplo:Transaction successfully completed. The till has 452 dollars Expected till value: 452 Press the Enter key to exitLa aplicación genera aleatoriamente el costo de los artículos de compra. Por tanto, los valores de la caja notificados en la salida son diferentes. Si los dos valores son iguales, significa que ha corregido el problema de lógica.