From ba411ec2bc20ea4d82f5801621613a527158b152 Mon Sep 17 00:00:00 2001 From: Niels Stubbe Date: Wed, 18 Dec 2024 11:40:42 +0100 Subject: [PATCH 1/2] Add initial implementation of ShoppingCart and Receipt classes, and include sample recipe JSON --- csharp/SupermarketReceipt/Receipt.cs | 1 + csharp/SupermarketReceipt/ShoppingCart.cs | 11 ++- csharp/SupermarketReceipt/readme.md | 1 + csharp/test.json | 89 +++++++++++++++++++++++ 4 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 csharp/SupermarketReceipt/readme.md create mode 100644 csharp/test.json diff --git a/csharp/SupermarketReceipt/Receipt.cs b/csharp/SupermarketReceipt/Receipt.cs index 6b4b38e..912d302 100644 --- a/csharp/SupermarketReceipt/Receipt.cs +++ b/csharp/SupermarketReceipt/Receipt.cs @@ -1,3 +1,4 @@ + using System.Collections.Generic; namespace SupermarketReceipt diff --git a/csharp/SupermarketReceipt/ShoppingCart.cs b/csharp/SupermarketReceipt/ShoppingCart.cs index 72b6b4a..b242dac 100644 --- a/csharp/SupermarketReceipt/ShoppingCart.cs +++ b/csharp/SupermarketReceipt/ShoppingCart.cs @@ -3,13 +3,13 @@ namespace SupermarketReceipt { + public class ShoppingCart { private readonly List _items = new List(); private readonly Dictionary _productQuantities = new Dictionary(); private static readonly CultureInfo Culture = CultureInfo.CreateSpecificCulture("en-GB"); - - + public List GetItems() { return new List(_items); @@ -23,16 +23,15 @@ public void AddItem(Product product) public void AddItemQuantity(Product product, double quantity) { - _items.Add(new ProductQuantity(product, quantity)); if (_productQuantities.ContainsKey(product)) { - var newAmount = _productQuantities[product] + quantity; - _productQuantities[product] = newAmount; + _productQuantities[product] += quantity; } else { - _productQuantities.Add(product, quantity); + _productQuantities[product] = quantity; } + _items.Add(new ProductQuantity(product, quantity)); } public void HandleOffers(Receipt receipt, Dictionary offers, SupermarketCatalog catalog) diff --git a/csharp/SupermarketReceipt/readme.md b/csharp/SupermarketReceipt/readme.md new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/csharp/SupermarketReceipt/readme.md @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/csharp/test.json b/csharp/test.json new file mode 100644 index 0000000..a8f0d2c --- /dev/null +++ b/csharp/test.json @@ -0,0 +1,89 @@ +{ + "recipe": { + "name": "Lasagna", + "ingredients": [ + { + "name": "Lasagna noodles", + "quantity": "12", + "unit": "pieces" + }, + { + "name": "Ground beef", + "quantity": "1", + "unit": "pound" + }, + { + "name": "Onion", + "quantity": "1", + "unit": "medium, chopped" + }, + { + "name": "Garlic", + "quantity": "2", + "unit": "cloves, minced" + }, + { + "name": "Tomato sauce", + "quantity": "24", + "unit": "ounces" + }, + { + "name": "Tomato paste", + "quantity": "6", + "unit": "ounces" + }, + { + "name": "Ricotta cheese", + "quantity": "15", + "unit": "ounces" + }, + { + "name": "Egg", + "quantity": "1", + "unit": "large" + }, + { + "name": "Mozzarella cheese", + "quantity": "16", + "unit": "ounces, shredded" + }, + { + "name": "Parmesan cheese", + "quantity": "3/4", + "unit": "cup, grated" + }, + { + "name": "Salt", + "quantity": "1", + "unit": "teaspoon" + }, + { + "name": "Black pepper", + "quantity": "1/2", + "unit": "teaspoon" + }, + { + "name": "Dried basil", + "quantity": "1", + "unit": "teaspoon" + }, + { + "name": "Dried oregano", + "quantity": "1", + "unit": "teaspoon" + } + ], + "instructions": [ + "Preheat oven to 375°F (190°C).", + "Cook lasagna noodles according to package instructions. Drain and set aside.", + "In a large skillet, cook ground beef, onion, and garlic over medium heat until meat is browned. Drain excess fat.", + "Stir in tomato sauce and tomato paste. Season with salt, pepper, basil, and oregano. Simmer for 15 minutes.", + "In a mixing bowl, combine ricotta cheese, egg, and 1/2 cup of Parmesan cheese.", + "Spread a thin layer of meat sauce in the bottom of a 9x13 inch baking dish.", + "Layer with 1/3 of the lasagna noodles, 1/3 of the ricotta mixture, 1/3 of the mozzarella cheese, and 1/3 of the meat sauce. Repeat layers twice more.", + "Top with remaining mozzarella and Parmesan cheese.", + "Cover with aluminum foil and bake in preheated oven for 25 minutes. Remove foil and bake for an additional 25 minutes, or until cheese is bubbly and slightly browned.", + "Let stand for 10 minutes before serving." + ] + } +} \ No newline at end of file From e03f1c8f591103dc6b716b022bb617b5d8a36e70 Mon Sep 17 00:00:00 2001 From: Niels Stubbe Date: Mon, 6 Jan 2025 14:00:53 +0100 Subject: [PATCH 2/2] Refactor --- csharp/.github/copilot-instructions.md | 4 ++ csharp/SupermarketReceipt/Receipt.cs | 2 + csharp/SupermarketReceipt/ShoppingCart.cs | 85 +++++++++++++---------- csharp/test.txt | 0 4 files changed, 53 insertions(+), 38 deletions(-) create mode 100644 csharp/.github/copilot-instructions.md create mode 100644 csharp/test.txt diff --git a/csharp/.github/copilot-instructions.md b/csharp/.github/copilot-instructions.md new file mode 100644 index 0000000..56a22da --- /dev/null +++ b/csharp/.github/copilot-instructions.md @@ -0,0 +1,4 @@ +Make sure the code you return is secure. +Keep explanations of the code your return to a minimum. +Use .NET and Azure as default technology stack. +Please explain step by step how you reach your result. \ No newline at end of file diff --git a/csharp/SupermarketReceipt/Receipt.cs b/csharp/SupermarketReceipt/Receipt.cs index 912d302..d75c299 100644 --- a/csharp/SupermarketReceipt/Receipt.cs +++ b/csharp/SupermarketReceipt/Receipt.cs @@ -8,6 +8,8 @@ public class Receipt private readonly List _discounts = new List(); private readonly List _items = new List(); + + public double GetTotalPrice() { var total = 0.0; diff --git a/csharp/SupermarketReceipt/ShoppingCart.cs b/csharp/SupermarketReceipt/ShoppingCart.cs index b242dac..3c82bf9 100644 --- a/csharp/SupermarketReceipt/ShoppingCart.cs +++ b/csharp/SupermarketReceipt/ShoppingCart.cs @@ -3,13 +3,16 @@ namespace SupermarketReceipt { - public class ShoppingCart { private readonly List _items = new List(); private readonly Dictionary _productQuantities = new Dictionary(); private static readonly CultureInfo Culture = CultureInfo.CreateSpecificCulture("en-GB"); + /// + /// Gets the list of items in the shopping cart. + /// + /// A new list containing the items in the shopping cart. public List GetItems() { return new List(_items); @@ -20,7 +23,6 @@ public void AddItem(Product product) AddItemQuantity(product, 1.0); } - public void AddItemQuantity(Product product, double quantity) { if (_productQuantities.ContainsKey(product)) @@ -31,6 +33,7 @@ public void AddItemQuantity(Product product, double quantity) { _productQuantities[product] = quantity; } + _items.Add(new ProductQuantity(product, quantity)); } @@ -38,50 +41,56 @@ public void HandleOffers(Receipt receipt, Dictionary offers, Sup { foreach (var p in _productQuantities.Keys) { + if (!offers.ContainsKey(p)) continue; + var quantity = _productQuantities[p]; - var quantityAsInt = (int) quantity; - if (offers.ContainsKey(p)) + var quantityAsInt = (int)quantity; + var offer = offers[p]; + var unitPrice = catalog.GetUnitPrice(p); + + int x = offer.OfferType switch { - var offer = offers[p]; - var unitPrice = catalog.GetUnitPrice(p); - Discount discount = null; - var x = 1; - if (offer.OfferType == SpecialOfferType.ThreeForTwo) - { - x = 3; - } - else if (offer.OfferType == SpecialOfferType.TwoForAmount) - { - x = 2; - if (quantityAsInt >= 2) - { - var total = offer.Argument * (quantityAsInt / x) + quantityAsInt % 2 * unitPrice; - var discountN = unitPrice * quantity - total; - discount = new Discount(p, "2 for " + PrintPrice(offer.Argument), -discountN); - } - } + SpecialOfferType.ThreeForTwo => 3, + SpecialOfferType.TwoForAmount => 2, + SpecialOfferType.FiveForAmount => 5, + _ => 1 + }; - if (offer.OfferType == SpecialOfferType.FiveForAmount) x = 5; - var numberOfXs = quantityAsInt / x; - if (offer.OfferType == SpecialOfferType.ThreeForTwo && quantityAsInt > 2) - { - var discountAmount = quantity * unitPrice - (numberOfXs * 2 * unitPrice + quantityAsInt % 3 * unitPrice); - discount = new Discount(p, "3 for 2", -discountAmount); - } + var numberOfXs = quantityAsInt / x; + var remainder = quantityAsInt % x; + double discountAmount = 0.0; - if (offer.OfferType == SpecialOfferType.TenPercentDiscount) discount = new Discount(p, offer.Argument + "% off", -quantity * unitPrice * offer.Argument / 100.0); - if (offer.OfferType == SpecialOfferType.FiveForAmount && quantityAsInt >= 5) - { - var discountTotal = unitPrice * quantity - (offer.Argument * numberOfXs + quantityAsInt % 5 * unitPrice); - discount = new Discount(p, x + " for " + PrintPrice(offer.Argument), -discountTotal); - } + switch (offer.OfferType) + { + case SpecialOfferType.TwoForAmount when quantityAsInt >= 2: + discountAmount = unitPrice * quantity - (offer.Argument * numberOfXs + remainder * unitPrice); + break; + case SpecialOfferType.ThreeForTwo when quantityAsInt > 2: + discountAmount = quantity * unitPrice - (numberOfXs * 2 * unitPrice + remainder * unitPrice); + break; + case SpecialOfferType.TenPercentDiscount: + discountAmount = quantity * unitPrice * offer.Argument / 100.0; + break; + case SpecialOfferType.FiveForAmount when quantityAsInt >= 5: + discountAmount = unitPrice * quantity - (offer.Argument * numberOfXs + remainder * unitPrice); + break; + } - if (discount != null) - receipt.AddDiscount(discount); + if (discountAmount != 0.0) + { + var description = offer.OfferType switch + { + SpecialOfferType.TwoForAmount => $"2 for {PrintPrice(offer.Argument)}", + SpecialOfferType.ThreeForTwo => "3 for 2", + SpecialOfferType.TenPercentDiscount => $"{offer.Argument}% off", + SpecialOfferType.FiveForAmount => $"{x} for {PrintPrice(offer.Argument)}", + _ => string.Empty + }; + receipt.AddDiscount(new Discount(p, description, -discountAmount)); } } } - + private string PrintPrice(double price) { return price.ToString("N2", Culture); diff --git a/csharp/test.txt b/csharp/test.txt new file mode 100644 index 0000000..e69de29