diff --git a/CalculatorApp/CalculatorApp.csproj b/CalculatorApp/CalculatorApp.csproj
new file mode 100644
index 00000000..8acb7da5
--- /dev/null
+++ b/CalculatorApp/CalculatorApp.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/CalculatorApp/CalculatorApp.slnx b/CalculatorApp/CalculatorApp.slnx
new file mode 100644
index 00000000..e4946298
--- /dev/null
+++ b/CalculatorApp/CalculatorApp.slnx
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/CalculatorApp/Program.cs b/CalculatorApp/Program.cs
new file mode 100644
index 00000000..a8d2044f
--- /dev/null
+++ b/CalculatorApp/Program.cs
@@ -0,0 +1,223 @@
+using System.Text.RegularExpressions;
+using System.Xml.Serialization;
+using CalculatorLibrary;
+
+class Program
+{
+ static void Main(string[] args)
+ {
+ bool endApp = false;
+ int count = 0;
+ // Display title as the C# console calculator app.
+ Console.WriteLine("Console Calculator in C#\r");
+ Console.WriteLine("------------------------\n");
+
+ Calculator calculator = new Calculator();
+
+ while (!endApp)
+ {
+ // Declare variables and set to empty.
+ // Use Nullable types (with ?) to match type of System.Console.ReadLine
+ string? numInput1 = "";
+ string? numInput2 = "";
+ double result = 0;
+
+ endApp = ShowMenu();
+ if (endApp == true)
+ { break; }
+
+ // Ask the user to type the first number.
+ Console.WriteLine("Collecting your first number...");
+ numInput1 = GetNumInput();
+
+ double cleanNum1 = 0;
+ while (!double.TryParse(numInput1, out cleanNum1))
+ {
+ Console.Write("This is not valid input. Please enter a numeric value: ");
+ numInput1 = Console.ReadLine();
+ }
+
+ // Ask the user to type the second number.
+ Console.WriteLine("Collecting your second number...");
+ numInput2 = GetNumInput();
+
+ double cleanNum2 = 0;
+ while (!double.TryParse(numInput2, out cleanNum2))
+ {
+ Console.Write("This is not valid input. Please enter a numeric value: ");
+ numInput2 = Console.ReadLine();
+ }
+
+ string? op = GetOperand();
+ // Validate input is not null, and matches the pattern
+ while (op == null || op == "exit")
+ {
+ if (op == "exit")
+ {
+ Console.WriteLine("You've chosen to close the app, press any key to close.");
+ Console.ReadKey();
+ return;
+ }
+ Console.WriteLine("Error: Unrecognized input. Try Again or type 'exit' to exit.");
+ op = GetOperand();
+
+
+ }
+ try
+ {
+ result = calculator.DoOperation(cleanNum1, cleanNum2, op);
+ if (double.IsNaN(result))
+ {
+ Console.WriteLine("This operation will result in a mathematical error.\n");
+ }
+ else
+ {
+
+ Console.WriteLine("Your result: {0:0.##}\n", result);
+ count++;
+ Console.WriteLine($"You have used the calculator {count} times.");
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Oh no! An exception occurred trying to do the math.\n - Details: " + e.Message);
+ }
+ Console.WriteLine("------------------------\n");
+
+ // Wait for the user to respond before closing.
+ Console.Write("Press 'n' and Enter to close the app, or press any other key and Enter to continue: ");
+ if (Console.ReadLine() == "n") endApp = true;
+
+ Console.WriteLine("\n"); // Friendly linespacing.
+ }
+ calculator.Finish();
+ return;
+
+ string GetOperand()
+ {
+
+ // Ask the user to choose an operator.
+ Console.WriteLine("Choose an operator from the following list:");
+ Console.WriteLine("\ta - Add");
+ Console.WriteLine("\ts - Subtract");
+ Console.WriteLine("\tm - Multiply");
+ Console.WriteLine("\td - Divide");
+ Console.Write("Your option? ");
+
+ string? input = Console.ReadLine()?.Trim()?.ToLower() switch
+ {
+ "a" or "add" => "a",
+ "s" or "subtract" => "s",
+ "m" or "multiply" => "m",
+ "d" or "divide" => "d",
+ "exit" => "exit",
+ _ => null
+ };
+ return input;
+ }
+
+
+ string GetNumInput()
+ {
+ if (calculator.History.Count > 0)
+ {
+ Console.WriteLine("Do you want to use a previous result as your number? Y/N");
+ bool? decision;
+ do
+ {
+ decision = Console.ReadLine()?.ToLower()?.Trim() switch
+ {
+ "y" => true,
+ "n" => false,
+ _ => null
+ };
+ } while (decision == null);
+
+ if (decision == true)
+ {
+ calculator.RecallMemory();
+ int choice;
+ while (true)
+ {
+ Console.Write($"Pick an entry (from 1 to {calculator.History.Count}) or 'c' to cancel: ");
+ string? input = Console.ReadLine()?.Trim().ToLower();
+
+ if (input == "c")
+ {
+ Console.WriteLine("Cancelled.");
+ Console.Write("Type a number, and then press Enter: ");
+ return Console.ReadLine();
+ }
+
+ if (int.TryParse(input, out choice) && choice >= 1 && choice <= calculator.History.Count)
+ {
+ return calculator.RecallResult(choice - 1).ToString();
+ }
+
+ Console.WriteLine("Invalid input, try again.");
+ }
+
+ }
+ else
+ {
+ Console.Write("Type a number, and then press Enter: ");
+ return Console.ReadLine();
+ }
+ }
+ else
+ {
+ Console.Write("Type a number, and then press Enter: ");
+ return Console.ReadLine();
+ }
+ }
+
+ bool ShowMenu()
+ {
+ while (true)
+ {
+ Console.Clear();
+ Console.WriteLine("What would you like to do?");
+ Console.WriteLine("1. Perform Calculation");
+ Console.WriteLine("2. Display Number of calculations performed");
+ Console.WriteLine("3. Display History");
+ Console.WriteLine("4. Clear History");
+ Console.WriteLine("5. Exit");
+ Console.Write("Enter the # for your choice: ");
+
+ switch (Console.ReadLine()?.Trim())
+ {
+ case "1":
+ return false;
+ case "2":
+ Console.WriteLine($"Calculations performed: {count}");
+ break;
+ case "3":
+ if (calculator.History.Count > 0)
+ calculator.RecallMemory();
+ else
+ Console.WriteLine("No history to display.");
+ break;
+ case "4":
+ if (calculator.History.Count > 0)
+ {
+ calculator.History.Clear();
+ Console.WriteLine("History has been cleared.");
+ }
+ else
+ {
+ Console.WriteLine("No history to clear.");
+ }
+ break;
+ case "5":
+ return true;
+ default:
+ Console.WriteLine("Invalid choice, please try again.");
+ break;
+ }
+
+ Console.WriteLine("Press any key to continue...");
+ Console.ReadKey();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/CalculatorLibrary/CalculatorLibrary.cs b/CalculatorLibrary/CalculatorLibrary.cs
new file mode 100644
index 00000000..c9033ddd
--- /dev/null
+++ b/CalculatorLibrary/CalculatorLibrary.cs
@@ -0,0 +1,105 @@
+using System.Diagnostics;
+using Newtonsoft.Json;
+namespace CalculatorLibrary
+{
+ public class Calculator
+ {
+ JsonWriter writer;
+ StreamWriter logFile;
+
+ public record Calculation(double Num1, double Num2, string Op, double Result)
+ {
+ public string Symbol => Op switch
+ {
+ "a" => "+",
+ "s" => "-",
+ "m" => "*",
+ "d" => "/",
+ _ => Op
+ };
+ }
+ public List History { get; private set; } = new();
+ public Calculator()
+ {
+ StartLog();
+ }
+ public double DoOperation(double num1, double num2, string op)
+ {
+ double result = double.NaN; // Default value is "not-a-number" if an operation, such as division, could result in an error.
+ writer.WriteStartObject();
+ writer.WritePropertyName("Operand1");
+ writer.WriteValue(num1);
+ writer.WritePropertyName("Operand2");
+ writer.WriteValue(num2);
+ writer.WritePropertyName("Operation");
+ // Use a switch statement to do the math.
+ switch (op)
+ {
+ case "a":
+ result = num1 + num2;
+ writer.WriteValue("Add");
+ break;
+ case "s":
+ result = num1 - num2;
+ writer.WriteValue("Subtract");
+ break;
+ case "m":
+ result = num1 * num2;
+ writer.WriteValue("Multiply");
+ break;
+ case "d":
+ // Ask the user to enter a non-zero divisor.
+ if (num2 != 0)
+ {
+ result = num1 / num2;
+ writer.WriteValue("Divide");
+ }
+ break;
+ // Return text for an incorrect option entry.
+ default:
+ break;
+ }
+ writer.WritePropertyName("Result");
+ writer.WriteValue(result);
+ writer.WriteEndObject();
+ History.Add(new Calculation(num1, num2, op, result));
+
+ return result;
+ }
+ public void Finish()
+ {
+ writer.WriteEndArray();
+ writer.WriteEndObject();
+ writer.Close();
+ }
+
+ public void ClearMemory()
+ {
+ History.Clear();
+ }
+
+ public void RecallMemory()
+ {
+ for (int i = 0; i < History.Count; i++)
+ {
+ Calculation calc = History[i];
+ Console.WriteLine($"{i + 1}. {calc.Num1} {calc.Symbol} {calc.Num2} = {calc.Result}");
+ }
+ }
+
+ public double RecallResult(int resultNum)
+ {
+ return History[resultNum].Result;
+ }
+ private void StartLog()
+ {
+ logFile = File.CreateText("calculatorlog.json");
+ logFile.AutoFlush = true;
+ writer = new JsonTextWriter(logFile);
+ writer.Formatting = Formatting.Indented;
+ writer.WriteStartObject();
+ writer.WritePropertyName("Operations");
+ writer.WriteStartArray();
+ }
+ }
+}
diff --git a/CalculatorLibrary/CalculatorLibrary.csproj b/CalculatorLibrary/CalculatorLibrary.csproj
new file mode 100644
index 00000000..22badd14
--- /dev/null
+++ b/CalculatorLibrary/CalculatorLibrary.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net10.0
+ enable
+ enable
+
+
+
+
+
+
+