Stanley Wang
Stanley Wang

Reputation: 67

I am wondering how to shorten the repeated use of if-statements in this code

I repeat a series of if-statements 3 times, and I'm wondering how to fix that. I tried making a method for updating the price, but it didn't let me call it. Is there a way to only write the series of price if-statements once, and call it within the size if-statements?

I'm pretty new to C#, so any help would be appreciated.

        Console.WriteLine("What size pizza would you like?\nSmall, Medium, or Large? (S, M, L)");
        string size = Console.ReadLine();

        if(size == "S" || size =="s")
        {
            decimal price = 5.00M;
            Console.WriteLine("How many toppings would you like?\n0, 1, or 2?");
            int topping = Convert.ToInt32(Console.ReadLine());
            if (topping == 0)
            {
                price = price + 0.00M;

            }
            else if (topping == 1)
            {
                price = price + 1.00M;
            }
            else if (topping == 2)
            {
                price = price + 1.50M;
            }
            price = Math.Round(price + (price * 0.10m), 2);
            Console.WriteLine("Including 10% tax, you total bill is ${0}", price);
        }
        else if(size == "M" || size == "m")
        {
            decimal price = 7.00M;
            Console.WriteLine("How many toppings would you like?\n0, 1, or 2?");
            int topping = Convert.ToInt32(Console.ReadLine());
            if (topping == 0)
            {
                price = price + 0.00M;

            }
            else if (topping == 1)
            {
                price = price + 1.00M;
            }
            else if (topping == 2)
            {
                price = price + 1.50M;
            }
            price = Math.Round(price + (price * 0.10m), 2);
            Console.WriteLine("Including 10% tax, you total bill is ${0}", price);
        }
        else if (size == "L" || size == "l")
        {
            decimal price = 9.00M;
            Console.WriteLine("How many toppings would you like?\n0, 1, or 2?");
            int topping = Convert.ToInt32(Console.ReadLine());
            if (topping == 0)
            {
                price = price + 0.00M;

            }
            else if (topping == 1)
            {
                price = price + 1.00M;
            }
            else if (topping == 2)
            {
                price = price + 1.50M;
            }


            // price = Math.Round(price + (price * 0.10m), 2);
            price = price + (price * 0.10m);

             Console.WriteLine("Including 10% tax, you total bill is ${0}", price);

        }

        

       

    

Upvotes: 0

Views: 99

Answers (3)

Ed'ka
Ed'ka

Reputation: 7130

If on C# 8 or later use switch expression with pattern matching:

using static System.Console;

WriteLine(@"What size pizza would you like?
Small, Medium, or Large? (S, M, L)");
var price = ReadLine() switch
{
    "S" or "s" => 5.00M,
    "M" or "m" => 7.00M,
    "L" or "l" => 9.00M,
    var invalid => throw new ($"Invalid pizza size: {invalid}")
};

WriteLine(@"How many toppings would you like?
0, 1, or 2?");
price += ReadLine() switch
{
    "0" => 0.00M,
    "1" => 1.00M,
    "2" => 1.50M,
    var invalid => throw new ($"Invalid number of toppings: {invalid}")
};
price *= 1.10M;

WriteLine($"Including 10% tax, you total bill is {price:C2}");

Upvotes: 0

Caius Jard
Caius Jard

Reputation: 74595

You can change the approach and do the whole thing in about 5 lines of code. This approach matches more like how it might be done in the real world where the prices would be in some configurable data store rather than baked into the code of the program:

var basePrices = new Dictionary<string, decimal>(){
  ["S"] = 5,
  ["M"] = 7,
  ["L"] = 9
};

string size = Console.ReadLine().ToUpper();
int topping = Convert.ToInt32(Console.ReadLine());

var price = (basePrices[size] + (topping > 0 ? topping * 0.5m + 0.5m : 0)) * 1.1m

Console.WriteLine("Including 10% tax, you total bill is ${0:0.00}", price);

There isn't any error checking here and I omitted the WriteLines for sake of brevity; exercise for the reader to restore them and do error checking, but the concepts conveyed are:

  • you can use a dictionary to map one value to another, in this case S => 5 etc

  • dictionaries are case sensitive, so we ToUpper the input

  • If your cheeky user will put something other than S, M or L in, you can use basePrices.TryGetValue(size, out var basePrice) - TryGet Value returns false if the size is not found so you can use that to give them an error message instead of a price. Similarly for the toppings, if they type alpha chars Convert.ToInt32 will throw an exception, so you can look at int.TryParse instead; same idea as TryGetValue, it returns a bool indicating success.

  • Your toppings are mathematical; they look like they cost 0.5 per topping plus 0.5 if the user wants them - that's what the test?true value:false value does in topping>0 ? ... : 0

  • Calculating the toppings price means they can be quoted for a million toppings. You can put an upper bound check

  • You could also use the same dictionary concept for your toppings prices

    var toppingPrices = new Dictionary<int, decimal>(){
      [0] = 0,
      [1] = 1,
      [2] = 1.5
    }
  • You can get the string formatting process to do your rounding: format with {0:0.00} and throw any old decimal in there

Upvotes: 0

pm100
pm100

Reputation: 50110

As far as I can see the code is the same but the price is different so do

   void GetOrder(decimal price){
      Console.WriteLine("How many toppings would you like?\n0, 1, or 2?");
      int topping = Convert.ToInt32(Console.ReadLine());
      if (topping == 0)
      {
           price = price + 0.00M;

      }
      else if (topping == 1)
      {
          price = price + 1.00M;
      }
      else if (topping == 2)
      {
            price = price + 1.50M;
      }
      price = Math.Round(price + (price * 0.10m), 2);
      Console.WriteLine("Including 10% tax, you total bill is ${0}", price);
 }

And then do

if(size == "S" || size =="s"){
   GetOrder(5.0m);
else if(size == "M" || size == "m")        
   GetOrder(7.0m)
 ....

Upvotes: 1

Related Questions