diff --git a/.gitignore b/.gitignore index 5a62da38..c8b9f4e7 100644 --- a/.gitignore +++ b/.gitignore @@ -454,4 +454,3 @@ $RECYCLE.BIN/ !.vscode/extensions.json /Calculator.TomDonegan/TextFile1.txt /Calculator.TomDonegan/Calculator.TomDonegan/Notes.txt -/Calculator diff --git a/Calculator/Calculator.slnx b/Calculator/Calculator.slnx new file mode 100644 index 00000000..1597745b --- /dev/null +++ b/Calculator/Calculator.slnx @@ -0,0 +1,4 @@ + + + + diff --git a/Calculator/CalculatorApp/CalculatorApp.csproj b/Calculator/CalculatorApp/CalculatorApp.csproj new file mode 100644 index 00000000..8acb7da5 --- /dev/null +++ b/Calculator/CalculatorApp/CalculatorApp.csproj @@ -0,0 +1,14 @@ + + + + Exe + net10.0 + enable + enable + + + + + + + diff --git a/Calculator/CalculatorApp/Program.cs b/Calculator/CalculatorApp/Program.cs new file mode 100644 index 00000000..be6c9fd1 --- /dev/null +++ b/Calculator/CalculatorApp/Program.cs @@ -0,0 +1,135 @@ +// Program.cs +using System.Text.RegularExpressions; +using CalculatorLibrary; + +namespace CalculatorProgram; + +class Program +{ + static void Main(string[] args) + { + bool endApp = false; + List calcHistory = new(); + + // 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; + + // Ask the user to type the first number. + Console.Write("Type a number, and then press Enter (or press [ x ] to use last calculation result): "); + numInput1 = Console.ReadLine(); + + if (numInput1 == "x" && calcHistory.Count >= 1) + { + numInput1 = calcHistory[calcHistory.Count - 1].Result.ToString(); + Console.WriteLine($"Your first number is {numInput1}"); + } + else if (numInput1 == "x" && calcHistory.Count < 1) + { + Console.WriteLine("No history exists..."); + } + + double cleanNum1 = 0; + while (!double.TryParse(numInput1, out cleanNum1)) + { + Console.Write("This is not valid input. Please enter an integer value: "); + numInput1 = Console.ReadLine(); + } + + // Ask the user to type the second number. + Console.Write("Type another number, and then press Enter (or press [ x ] to use last calculation result): "); + numInput2 = Console.ReadLine(); + + if (numInput2 == "x" && calcHistory.Count >= 1) + { + numInput2 = calcHistory[calcHistory.Count - 1].Result.ToString(); + Console.WriteLine($"Your first number is {numInput1}"); + } + else if (numInput2 == "x" && calcHistory.Count < 1) + { + Console.WriteLine("No history exists..."); + } + + double cleanNum2 = 0; + while (!double.TryParse(numInput2, out cleanNum2)) + { + Console.Write("This is not valid input. Please enter an integer value: "); + numInput2 = Console.ReadLine(); + } + + // 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.WriteLine("\tp - Power (first number to power of second number)"); + + Console.Write("Your option? "); + + string? op = Console.ReadLine(); + + // Validate input is not null, and matches the pattern + if (op == null || !Regex.IsMatch(op, "[a|s|m|d|p]")) + { + Console.WriteLine("Error: Unrecognized input."); + } + else + { + try + { + result = calculator.DoOperation(cleanNum1, cleanNum2, op); + if (double.IsNaN(result)) + { + Console.WriteLine("This operation will result in a mathematical error.\n"); + } + else + { + calcHistory.Add(new Calculation() + { + FirstNum = cleanNum1, + SecondNum = cleanNum2, + Result = result + }); + Console.WriteLine("Your result: {0:0.##}\n", result); + Console.WriteLine($"You have used the calculator {calcHistory.Count} times"); + if (calcHistory.Count > 0) + { + Console.WriteLine("Would you like to clear the history [Y/N]?"); + string userInput = Console.ReadLine().ToLower(); + if (userInput == "y") + { + calcHistory.Clear(); + Console.WriteLine("History cleared!"); + } + } + } + } + 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 'x' and Enter to close the app, or press any other key and Enter to continue: "); + if (Console.ReadLine() == "x") endApp = true; + + Console.WriteLine("\n"); // Friendly linespacing. + } + calculator.Finish(); + return; + } +} diff --git a/Calculator/CalculatorLibrary/CalculatorLibrary.cs b/Calculator/CalculatorLibrary/CalculatorLibrary.cs new file mode 100644 index 00000000..9b7a1a87 --- /dev/null +++ b/Calculator/CalculatorLibrary/CalculatorLibrary.cs @@ -0,0 +1,81 @@ +// CalculatorLibrary.cs +using Newtonsoft.Json; + +namespace CalculatorLibrary; + +public class Calculator +{ + JsonWriter writer; + + public Calculator() + { + StreamWriter logFile = File.CreateText("calculatorlog.json"); + logFile.AutoFlush = true; + writer = new JsonTextWriter(logFile); + writer.Formatting = Formatting.Indented; + writer.WriteStartObject(); + writer.WritePropertyName("Operations"); + writer.WriteStartArray(); + } + + 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; + case "p": + result = Math.Pow(num1, num2); + writer.WriteValue("Power"); + break; + // Return text for an incorrect option entry. + default: + break; + } + writer.WritePropertyName("Result"); + writer.WriteValue(result); + writer.WriteEndObject(); + + return result; + } + + public void Finish() + { + writer.WriteEndArray(); + writer.WriteEndObject(); + writer.Close(); + } +} + +public class Calculation +{ + public double FirstNum { get; set; } + public double SecondNum { get; set; } + public double Result { get; set; } +} diff --git a/Calculator/CalculatorLibrary/CalculatorLibrary.csproj b/Calculator/CalculatorLibrary/CalculatorLibrary.csproj new file mode 100644 index 00000000..22badd14 --- /dev/null +++ b/Calculator/CalculatorLibrary/CalculatorLibrary.csproj @@ -0,0 +1,13 @@ + + + + net10.0 + enable + enable + + + + + + +