1

https://github.com/FaisalRana/CSharp.Bakery <-- here is a link to my repo.

Recently I started a project with the following prompt: Create a bakery in c# that a user can order bread or pastries from. The program outputs the total price based on the menu.

I am learning Test Driven Development and I was able to successfully write my tests and functions and follow the red green refactor workflow.

Furthermore, I was able to handle the errors for putting in a negative number by using an if statement. I tried to do error handling for when someone types in a string instead of an integer for their order input.. but

if (typof(input) !== integer) { } <-- this does not work in c#. The error I get when I put a non-int input in the console:

Handled exception. System.FormatException: Input string was not in a correct format.

THANK YOU

using System;
using System.Collections.Generic;

namespace Bakery.Models
{
  public class Program
  {
    public static void Main()
    {
      Console.ForegroundColor = ConsoleColor.DarkGray;
      Console.BackgroundColor = ConsoleColor.Blue;
      Console.WriteLine("Welcome to Brother Lasif's Bakery!");
      string bakeryAscii = @"
                          ....
                      .'      `.
                    .' .-'``-._ `.
                    |  / -    - ` |
                    / |'<o>  <o> | \
                  | (|    '`    |) |
                  |   \  -==-  /   |
                  |    `.____.'    |
                  \     |    |     |
                  _\_.'`-.__.-'`._/_
                .'| |`-.  /\  .-'| |`.
              _.'   \ \  `'  `'  / /   `._
            { `.    | `-.____.-' |    .' }
            /`. `./ /   __  __   \ \.' .'\
            /   `.| |   /  \/  \   | |.'   \
          (    (  \ \  \      /  / /  )    )
            `.   \  Y|   `.  .'   |Y  /   .'
              \   \ ||_ _ _\/_ _ _|| /   /
              `.  \|'            `|/  .'
        _______/  _ >--------------< _  \______.##._
              ((((_(                )_))))   .##. |
            / ```` `--------------' ''''\   |  | |
            (                             \  |  |-'
            )                             ) `--'
            (          _        _.---.__.-'
            `-.___.--' `------'

        ";
      Console.WriteLine(bakeryAscii);
      Console.WriteLine("Please [y] to place your order, [m] to view the menu and [n] to exit");
      string  continueAnswer = Console.ReadLine().ToLower();
      if (continueAnswer == "y") {
          Console.WriteLine("How many loaves of bread would you like to purchase today?");
          int breadInput = Convert.ToInt32(Console.ReadLine()); 
            if (breadInput > 0 ) {
              Bread testBread = new Bread();
              int breadPrice = testBread.CalcBread(breadInput);
              Console.WriteLine("You have bought " + breadInput + " loaves of bread for: $" + breadPrice);
              Console.WriteLine("Would you like to buy some Pastry's today? [y] or [n]");
              string pastryAnswer = Console.ReadLine().ToLower();
              if (pastryAnswer == "y") {
                Console.WriteLine("Please enter the amount of pastry's you would like to buy:");
                int pastryInput = Convert.ToInt32(Console.ReadLine()); 
                  if (pastryInput >= 0) {
                    Pastry testPastry = new Pastry();
                    int pastryPrice = testPastry.CalcPastry(pastryInput);
                    Console.WriteLine("You have bought " + pastryInput + " pastry's");
                    Console.BackgroundColor = ConsoleColor.DarkGray;
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("Your total bill is $" + breadPrice + pastryPrice);
                } 
                  else {            
                  negativeNumberError();    
                } 

                  } 
                  else if (pastryAnswer == "n") {
                    Console.WriteLine("Thank you for Coming in, your total bill is $" + breadPrice);
                    Console.WriteLine("Goodbye");
                  }
  
            } else {   
              negativeNumberError();      
            }
      } else if (continueAnswer == "m") {
        Menu();
    } else if (continueAnswer == "n") {
      Console.WriteLine("Goodbye");
    } else {
      Console.WriteLine("Invalid Input");
      Main();
    }
}

    public static void Menu() {
      Console.WriteLine("--------------------------------");
        string menu = @"Fresh Bread: $5 each (loaf)
        Delicious Pastry: $2 each

        ** Special of the week **
        Bread: Buy 2, get 1 free!
        Pastry: 3 for $5!";
        Console.WriteLine(menu);
        Console.WriteLine("--------------------------------");
        Console.WriteLine("Press enter to continue");
        string menuAnswer = Console.ReadLine();
        Main();
    }
        public static void negativeNumberError() {
          Console.ForegroundColor = ConsoleColor.Red;
          Console.WriteLine("Error, please try again and enter a number greater than 0");
          Console.ReadLine();
          Main();
    }
    }
}

Krishna Majgaonkar
  • 1,532
  • 14
  • 25
Laysif Rana
  • 31
  • 1
  • 6
  • Does this answer your question? [Input string was not in a correct format](https://stackoverflow.com/questions/8321514/input-string-was-not-in-a-correct-format) – Yong Shun Apr 25 '21 at 03:04
  • 1
    Use [`Int32.TryParse`](https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryparse?view=net-5.0) to convert input to number, it will return false if received input is not an integer. For return `true`, you get the converted integer with `out` param. – Yong Shun Apr 25 '21 at 03:15
  • I read all your code. I'm a picky and grumpy C# developer, but great job so far. Keep learning and keep going. – Adam Vincent Apr 25 '21 at 03:49
  • thank you Yong. Please check out my repo for the updated code. Next thing is.. seperating business and UI logic. I feel like my main function is way too messy.. it was easy for me in javascript but I had a hard time with it here. – Laysif Rana Apr 25 '21 at 10:47

1 Answers1

3

Instead of

int breadInput = Convert.ToInt32(Console.ReadLine());

you probably need something similar to

int breadInput;
do
{
    Console.WriteLine("How many loaves of bread would you like to purchase today?");
}
while (!int.TryParse(Console.ReadLine(), out breadInput));

I chose do...while, instead of while (while is by far more common) because we need to ask the question before evaluating the response.

If I chose while then I would have to repeat the WriteLine line. Let's try with while:

Console.WriteLine("How many loaves of bread would you like to purchase today?");

int breadInput;
while (!int.TryParse(Console.ReadLine(), out breadInput));
{
    Console.WriteLine("How many loaves of bread would you like to purchase today?");
}

That's not beautiful, but the biggest problem is that one day I could change the question in one place and then forget to update the 2nd WriteLine.

< 1

Please note that the condition inside while can be expanded to deal with negative numbers. Anything that can go inside an if can go inside a while:

while (!int.TryParse(Console.ReadLine(), out breadInput) || (breadInput <= 0));

Helper methods

I would encourage you to create a helper method that you can reuse. This will keep you main logic looking clean. Here's an example:

// Concise code I can reuse for multiple questions
var ok = AskPositiveInt("How many loaves of bread would you like to purchase today?"
 , max: 100
 , out int breadInput);
if(!ok) 
{
   // todo  
}

(...)

static bool AskPositiveInt(string question, int max, out int number )
{
    // Here we can add as much validation as we wish
    Console.WriteLine(question);

    int numberOfTries = 5; //Number of tries before giving up
    for( int i = 0; i < numberOfTries; i++ )
    {
        
        var answer = Console.ReadLine();

        if(!int.TryParse(answer, out number))
        {
            Console.WriteLine("Please provide a number.");
            continue; // go back to 'for'
        } 

        if (number <= 0)
        {
            Console.WriteLine("Please provide a number.");
            continue; // go back to 'for'
        }

        if (number > max)
        {
            Console.WriteLine($"Insufficient stock. Please provide a number <{max}");
            continue; // go back to 'for'
        }

        //Everything OK
        return true;
    }
    
    number = 0;
    return false;
}

Error handling

In your code you call Main in your negativeNumberError handler.

This won't work long term because you never leave the original Main.

If the number keeps being negative you are adding to the chain Main->Main->Main->Main. You have to come up with a better strategy.

tymtam
  • 31,798
  • 8
  • 86
  • 126
  • 1
    Great answer! Clear and concise. An explanation of a `do` `while` loop may be helpful as they are not common in C# applications – Beckam White Apr 25 '21 at 03:47
  • WOW!!!! This website is amazing. Thank you SO much. I learned about while in javascript but I havent seen them yet in c#. My project deadline is this week and I managed to get everything working with error handling but I still have 2 big problems. 1. Using Auto-implemented properties is a requirement. 2. Everything is in my main like you said.. I'm struggling to seperate User Logic from Business logic.. especially because I thought everything that had a read console goes in main.. THANK YOU – Laysif Rana Apr 25 '21 at 10:21
  • https://github.com/FaisalRana/CSharp.Bakery <-- here is a link to the updated REPO – Laysif Rana Apr 25 '21 at 10:21
  • Oh okay. I understand about the error handling. I will be sure to work on that in my next project. Im in 1 year coding program.. this is our second week in c# so I still have a lot to learn. Any idea how I can add auto implemented properties to this? first I gotta separate out the logic better and I think it will automatically be more apparent. – Laysif Rana Apr 25 '21 at 10:51