diff --git a/Calculator.aaronkagan/Calculator.aaronkagan.sln b/Calculator.aaronkagan/Calculator.aaronkagan.sln new file mode 100644 index 00000000..46db32aa --- /dev/null +++ b/Calculator.aaronkagan/Calculator.aaronkagan.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Calculator.aaronkagan", "Calculator.aaronkagan\Calculator.aaronkagan.csproj", "{ED336576-8AEF-470F-B8C6-A21AAC4453C1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalculatorLibrary", "CalculatorLibrary\CalculatorLibrary.csproj", "{D6629EDB-7357-4842-8923-F251BB16D010}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ED336576-8AEF-470F-B8C6-A21AAC4453C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ED336576-8AEF-470F-B8C6-A21AAC4453C1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ED336576-8AEF-470F-B8C6-A21AAC4453C1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ED336576-8AEF-470F-B8C6-A21AAC4453C1}.Release|Any CPU.Build.0 = Release|Any CPU + {D6629EDB-7357-4842-8923-F251BB16D010}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D6629EDB-7357-4842-8923-F251BB16D010}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D6629EDB-7357-4842-8923-F251BB16D010}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D6629EDB-7357-4842-8923-F251BB16D010}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/Calculator.aaronkagan/Calculator.aaronkagan/Calculation.cs b/Calculator.aaronkagan/Calculator.aaronkagan/Calculation.cs new file mode 100644 index 00000000..9eb859ac --- /dev/null +++ b/Calculator.aaronkagan/Calculator.aaronkagan/Calculation.cs @@ -0,0 +1,9 @@ +namespace CalculatorProgram; + +class Calculation(double leftNumber, double rightNumber, string @operation, double result) +{ + public readonly double LeftNumber = leftNumber; + public readonly double RightNumber = rightNumber; + public readonly string Operation = @operation; + public readonly double Result = result; +} \ No newline at end of file diff --git a/Calculator.aaronkagan/Calculator.aaronkagan/CalculationHistory.cs b/Calculator.aaronkagan/Calculator.aaronkagan/CalculationHistory.cs new file mode 100644 index 00000000..4e191dc8 --- /dev/null +++ b/Calculator.aaronkagan/Calculator.aaronkagan/CalculationHistory.cs @@ -0,0 +1,60 @@ +namespace CalculatorProgram; + +class CalculationHistory +{ + private readonly List History = []; + + public void Print() + { + if (History.Count == 0) + { + Console.WriteLine("There is no history to show"); + Console.WriteLine("Press Enter to continue"); + } + else + { + Console.WriteLine("HISTORY"); + Console.WriteLine("-----------------"); + foreach (var (index, calculation) in History.Index()) + { + char operation = calculation.Operation switch + { + "a" => '+', + "s" => '-', + "m" => '*', + "d" => '/', + _ => throw new InvalidOperationException() + }; + Console.WriteLine( + $"{index + 1}) {calculation.LeftNumber} {operation} {calculation.RightNumber} = {calculation.Result}"); + } + + Console.WriteLine("-----------------"); + Console.WriteLine("The calculator has been used " + History.Count + " " + + (History.Count == 1 ? "time" : "times")); + } + + } + + public void Add(Calculation calculation) + { + History.Add(calculation); + } + + public void Delete() + { + History.Clear(); + Console.WriteLine("History deleted"); + } + + public int Count() + { + return History.Count; + } + + public double GetResult(int index) + { + return History[index].Result; + } + +} \ No newline at end of file diff --git a/Calculator.aaronkagan/Calculator.aaronkagan/CalculationRequest.cs b/Calculator.aaronkagan/Calculator.aaronkagan/CalculationRequest.cs new file mode 100644 index 00000000..532d1433 --- /dev/null +++ b/Calculator.aaronkagan/Calculator.aaronkagan/CalculationRequest.cs @@ -0,0 +1,9 @@ +namespace CalculatorProgram; + +class CalculationRequest (double cleanNumber1, double cleanNumber2, string op) +{ + public double LeftNumber { get; } = cleanNumber1; + public double RightNumber { get; } = cleanNumber2; + public string Op { get; } = op; + +} \ No newline at end of file diff --git a/Calculator.aaronkagan/Calculator.aaronkagan/Calculator.aaronkagan.csproj b/Calculator.aaronkagan/Calculator.aaronkagan/Calculator.aaronkagan.csproj new file mode 100644 index 00000000..595f1500 --- /dev/null +++ b/Calculator.aaronkagan/Calculator.aaronkagan/Calculator.aaronkagan.csproj @@ -0,0 +1,14 @@ + + + + Exe + net10.0 + enable + enable + + + + + + + diff --git a/Calculator.aaronkagan/Calculator.aaronkagan/CalculatorApp.cs b/Calculator.aaronkagan/Calculator.aaronkagan/CalculatorApp.cs new file mode 100644 index 00000000..55e65d3d --- /dev/null +++ b/Calculator.aaronkagan/Calculator.aaronkagan/CalculatorApp.cs @@ -0,0 +1,101 @@ +using CalculatorLibrary; + +namespace CalculatorProgram; + +class CalculatorApp +{ + private readonly Calculator _calculator; + + public CalculatorApp(Calculator calculator) + { + _calculator = calculator; + } + + + public void Start() + { + CalculationHistory history = new(); + InputHandler inputHandler = new(); + bool endApp = false; + while (!endApp) + { + + var calculationRequest = ShowMainMenu(inputHandler, history); + RunCalculation(calculationRequest.LeftNumber, calculationRequest.RightNumber, calculationRequest.Op, history); + Console.WriteLine("------------------------\n"); + Console.Write("Press 'n' to exit, 'h' to show the calculation history or press Enter to continue: "); + + + var input = Console.ReadLine(); + Console.Clear(); + + if (HandleUserChoice(input, endApp, history)) + { + endApp = true; + } + + Console.WriteLine("\n"); + } + } + + + private bool HandleUserChoice(string? input, bool endApp, CalculationHistory history) + { + switch (input) + { + case "n": + endApp = true; + break; + case "h": + { + history.Print(); + Console.WriteLine(history.Count() == 0 + ? "Press Enter to continue" + : "Press 'd' then Enter to delete the history or Enter to continue"); + var answer = Console.ReadLine(); + Console.Clear(); + if (answer == "d") + { + history.Delete(); + } + + break; + } + } + + return endApp; + } + + private CalculationRequest ShowMainMenu(InputHandler inputHandler, CalculationHistory history) + { + double cleanNum1 = inputHandler.GetValidNumber(history); + double cleanNum2 = inputHandler.GetValidNumber(history); + string op = inputHandler.GetValidOperation(); + CalculationRequest calculationRequest = new(cleanNum1, cleanNum2, op); + return calculationRequest; + } + + private void RunCalculation(double cleanNum1, double cleanNum2, string op, CalculationHistory history) + { + try + { + double 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); + Calculation calculation = new(cleanNum1, cleanNum2, op, result); + history.Add(calculation); + } + + } + catch (Exception e) + { + Console.WriteLine("Oh no! An exception occurred trying to do the math.\n - Details: " + e.Message); + } + + } +} \ No newline at end of file diff --git a/Calculator.aaronkagan/Calculator.aaronkagan/InputHandler.cs b/Calculator.aaronkagan/Calculator.aaronkagan/InputHandler.cs new file mode 100644 index 00000000..d1e399b1 --- /dev/null +++ b/Calculator.aaronkagan/Calculator.aaronkagan/InputHandler.cs @@ -0,0 +1,71 @@ +using System.Text.RegularExpressions; + +namespace CalculatorProgram; + +class InputHandler +{ + public double GetValidNumber(CalculationHistory history) + { + if (history.Count() > 0) + { + Console.WriteLine("Would you like to get the number from results history? y for yes or any other key for no: "); + if (Console.ReadKey().Key == ConsoleKey.Y) + { + Console.WriteLine(); + double historyResult = GetValidHistoryResult(history); + return historyResult; + } + } + + Console.WriteLine(); + Console.WriteLine("Please enter a number: "); + string? numInput = Console.ReadLine(); + double cleanNum; + while (!double.TryParse(numInput, out cleanNum)) + { + Console.Write("This is not valid input. Please enter an integer value: "); + numInput = Console.ReadLine(); + } + return cleanNum; + } + private double GetValidHistoryResult(CalculationHistory history) + { + history.Print(); + Console.WriteLine("Which result from history would you like to use? Enter the line number then press enter: "); + string? input = Console.ReadLine(); + int cleanNum; + + while (!int.TryParse(input, out cleanNum) || cleanNum > history.Count() || cleanNum < 0) + { + Console.Write("This is not valid input. Please enter a line number that exists: "); + input = Console.ReadLine(); + + int.TryParse(input, out cleanNum); + } + + var index = cleanNum - 1; + + return history.GetResult(index); + } + + public string GetValidOperation() + { + 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? op; + do + { + op = Console.ReadLine(); + if (op == null || !Regex.IsMatch(op, "[a|s|m|d]")) + { + Console.WriteLine("Invalid Operation. Please try again."); + } + } while (op == null || !Regex.IsMatch(op, "[a|s|m|d]")); + + return op; + } +} \ No newline at end of file diff --git a/Calculator.aaronkagan/Calculator.aaronkagan/Program.cs b/Calculator.aaronkagan/Calculator.aaronkagan/Program.cs new file mode 100644 index 00000000..fb618d91 --- /dev/null +++ b/Calculator.aaronkagan/Calculator.aaronkagan/Program.cs @@ -0,0 +1,19 @@ +using CalculatorLibrary; + +namespace CalculatorProgram +{ + static class Program + { + static void Main() + { + Console.WriteLine("Console Calculator in C#\r"); + Console.WriteLine("------------------------\n"); + + Calculator calculator = new(); + CalculatorApp calculatorApp = new(calculator); + calculatorApp.Start(); + calculator.Finish(); + } + } +} + diff --git a/Calculator.aaronkagan/CalculatorLibrary/CalculatorLibrary.cs b/Calculator.aaronkagan/CalculatorLibrary/CalculatorLibrary.cs new file mode 100644 index 00000000..42afa1aa --- /dev/null +++ b/Calculator.aaronkagan/CalculatorLibrary/CalculatorLibrary.cs @@ -0,0 +1,69 @@ +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; + writer.WriteStartObject(); + writer.WritePropertyName("Operand1"); + writer.WriteValue(num1); + writer.WritePropertyName("Operand2"); + writer.WriteValue(num2); + writer.WritePropertyName("Operation"); + + 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": + if (num2 != 0) + { + result = num1 / num2; + } + writer.WriteValue("Divide"); + break; + default: + break; + } + writer.WritePropertyName("Result"); + writer.WriteValue(result); + writer.WriteEndObject(); + + return result; + } + + public void Finish() + { + writer.WriteEndArray(); + writer.WriteEndObject(); + writer.Close(); + } + } +} \ No newline at end of file diff --git a/Calculator.aaronkagan/CalculatorLibrary/CalculatorLibrary.csproj b/Calculator.aaronkagan/CalculatorLibrary/CalculatorLibrary.csproj new file mode 100644 index 00000000..b05421ed --- /dev/null +++ b/Calculator.aaronkagan/CalculatorLibrary/CalculatorLibrary.csproj @@ -0,0 +1,13 @@ + + + + net10.0 + enable + enable + + + + + + +