diff --git a/Calculator.Kunikazu723/CalculatorLibrary/CalculatorLibrary.cs b/Calculator.Kunikazu723/CalculatorLibrary/CalculatorLibrary.cs new file mode 100644 index 00000000..fff62ea6 --- /dev/null +++ b/Calculator.Kunikazu723/CalculatorLibrary/CalculatorLibrary.cs @@ -0,0 +1,113 @@ +using System.Diagnostics; +using Newtonsoft.Json; +namespace CalculatorLibrary +{ + public class Calculator + { + JsonWriter _writer; + + public Calculator() + { + StreamWriter logFile = File.CreateText("calcuator.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); + + double radians = num1 * (Math.PI / 180.00); + + + char symbol = ' '; + // Use a switch statement to do the math. + switch (op) + { + case "a": + result = num1 + num2; + symbol = '+'; + break; + case "s": + result = num1 - num2; + symbol = '-'; + break; + case "m": + result = num1 * num2; + symbol = '*'; + break; + case "d": + // Ask the user to enter a non-zero divisor. + if (num2 != 0) + { + result = num1 / num2; + symbol = '/'; + } + break; + case "sqrt": + result = Math.Sqrt(num1); + symbol = '√'; + break; + case "pow": + result = Math.Pow(num1, num2); + symbol = '^'; + break; + case "10x": + result = Math.Pow(10, num1); + symbol = 'E'; + break; + case "sin": + result = Math.Sin(radians); + symbol = 'S'; + break; + case "cos": + result = Math.Cos(radians); + symbol = 'C'; + break; + case "tg": + if (num1 == 90) + { + Console.WriteLine("Undefined"); + result = 0; + } + else + { + result = Math.Tan(radians); + symbol = 'T'; + } + break; + // Return text for an incorrect option entry. + default: + break; + } + _writer.WritePropertyName("Operation"); + _writer.WriteValue(symbol); + _writer.WritePropertyName("Result"); + _writer.WriteValue(result); + _writer.WriteEndObject(); + + Trace.WriteLine($"{num1} {symbol} {(double.IsNaN(num2) ? "" : num2)} = {result}"); + + return result; + } + + public void Finish() + { + _writer.WriteEndArray(); + _writer.WriteEndObject(); + _writer.Close(); + } + } +} diff --git a/Calculator.Kunikazu723/CalculatorLibrary/CalculatorLibrary.csproj b/Calculator.Kunikazu723/CalculatorLibrary/CalculatorLibrary.csproj new file mode 100644 index 00000000..181661d7 --- /dev/null +++ b/Calculator.Kunikazu723/CalculatorLibrary/CalculatorLibrary.csproj @@ -0,0 +1,13 @@ + + + + net9.0 + enable + enable + + + + + + + diff --git a/Calculator.Kunikazu723/SimpleCalculator/Calculation.cs b/Calculator.Kunikazu723/SimpleCalculator/Calculation.cs new file mode 100644 index 00000000..8de5627b --- /dev/null +++ b/Calculator.Kunikazu723/SimpleCalculator/Calculation.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SimpleCalculator +{ + internal class Calculation + { + public double Operand1 { get; init; } + public double Operand2 { get; init; } + public double Result { get; init; } + public string Operation { get; init; } = string.Empty; + + } +} diff --git a/Calculator.Kunikazu723/SimpleCalculator/Program.cs b/Calculator.Kunikazu723/SimpleCalculator/Program.cs new file mode 100644 index 00000000..259f9717 --- /dev/null +++ b/Calculator.Kunikazu723/SimpleCalculator/Program.cs @@ -0,0 +1,213 @@ +using System.ComponentModel; +using System.Text.RegularExpressions; +using CalculatorLibrary; +namespace SimpleCalculator +{ + class Program + { + static void Main(string[] args) + { + var calculations = new List(); + var calculator = new Calculator(); + CalculatorInterface(calculations, calculator); + calculator.Finish(); + return; + } + + static void CalculatorInterface(List calculations, Calculator calculator) + { + while (true) + { + // Display title as the C# console calculator app. + Console.WriteLine("Console Calculator in C#\r"); + Console.WriteLine("------------------------\n"); + Console.WriteLine($"Total Calculations Performed {calculations.Count}"); + + Console.WriteLine("What do you want to do?"); + Console.WriteLine("\tc - Calculator"); + Console.WriteLine("\ts - See previous results"); + Console.WriteLine("\tdel - Delete all previous results"); + + string? userChoice = Console.ReadLine(); + if (userChoice is null) + { + Console.WriteLine("Error: Option is null"); + continue; + } + + switch (userChoice) + { + case "c": + CalculatorLoop(calculator, calculations); + break; + case "s": + if (calculations.Count == 0) Console.WriteLine("No calculations available"); + else + { + for (int i = 0; i < calculations.Count; i++) + { + Console.WriteLine($"[{i}] -> Type {calculations[i].Operation}: {calculations[i].Operand1} and {calculations[i].Operand2} = {calculations[i].Result}"); + } + + Console.WriteLine("Select a result from the previous list: "); + string? chosenResultIndex = Console.ReadLine(); + int chosenResultIndexClean; + if (chosenResultIndex is null || !int.TryParse(chosenResultIndex, out chosenResultIndexClean) || chosenResultIndexClean > calculations.Count - 1) + { + Console.WriteLine("Invalid index"); + continue; + } + + CalculatorLoop(calculator, calculations, calculations[chosenResultIndexClean].Result); + } + break; + case "del": + Console.WriteLine("Deleting All History of Calculations"); + calculations.Clear(); + break; + default: + Console.WriteLine("Invalid Option"); + break; + } + + } + + + } + + + + private static void CalculatorLoop(Calculator calculator, List calculations, double previousResult = double.NaN) + { + bool endApp = false; + int calculatorUses = calculations.Count(); + + + while (!endApp) + { + // Declare variables and set to empty. + // Use Nullable types (with ?) to match type of System.Console.ReadLine + Console.Clear(); + string? numInput1 = ""; + string? numInput2 = ""; + double result = 0; + // Ask the user to type the first number. + double cleanNum1; + if (double.IsNaN(previousResult)) + { + Console.Write("Type a number, and then press Enter: "); + Console.WriteLine("For trig functions, input the angle in degrees"); + + numInput1 = Console.ReadLine(); + + cleanNum1 = 0; + while (!double.TryParse(numInput1, out cleanNum1)) + { + Console.Write("This is not valid input. Please enter a numeric value: "); + numInput1 = Console.ReadLine(); + } + + } + else + { + endApp = true; + Console.WriteLine($"Using {previousResult} as Operand 1"); + cleanNum1 = previousResult; + } + + + // 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("\tsqrt - Square Root"); + Console.WriteLine("\tpow - Exopnent"); + Console.WriteLine("\t10x - Power of 10"); + Console.WriteLine("\tsin - Sine"); + Console.WriteLine("\tcos - Cosine"); + Console.WriteLine("\ttg - Tangent"); + Console.Write("Your option? "); + + string? op = Console.ReadLine(); + + // Ask the user to type the second number. + double cleanNum2 = double.NaN; + if (op is null || !Regex.IsMatch(op, "^(a|s|m|d|sqrt|pow|10x|sin|cos|tg)$")) + { + Console.WriteLine("Error Invalid Input"); + continue; + } + else if (!Regex.IsMatch(op, "^(sqrt|10x|sin|cos|tg)$")) + { + Console.Write("Type another number, and then press Enter: "); + numInput2 = Console.ReadLine(); + + cleanNum2 = 0; + while (!double.TryParse(numInput2, out cleanNum2)) + { + Console.Write("This is not valid input. Please enter a numeric value: "); + numInput2 = Console.ReadLine(); + } + } + + // Validate input is not null, and matches the pattern + 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); + string operation = op switch + { + "a" => "Add", + "s" => "Subtract", + "m" => "Multiply", + "d" => "Divide", + "sqrt" => "Square Root", + "pow" => "Exponentiation", + "10x" => "Power of 10", + "sin" => "Sine", + "cos" => "Cosine", + "tg" => "Tangent", + _ => throw new ArgumentException() + }; + + calculations.Add( + new Calculation() + { + Operand1 = cleanNum1, + Operand2 = cleanNum2, + Result = result, + Operation = operation + } + ); + calculatorUses = calculations.Count(); + } + } + 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. + + string finalMessage = endApp ? "Press Any Key To Continue" : "Press 'n' and Enter to close the app, or press any other key and Enter to continue: "; + Console.Write(finalMessage); + if (Console.ReadLine() == "n") endApp = true; + + Console.WriteLine("\n"); // Friendly linespacing. + } + + return; + } + } + +} diff --git a/Calculator.Kunikazu723/SimpleCalculator/SimpleCalculator.csproj b/Calculator.Kunikazu723/SimpleCalculator/SimpleCalculator.csproj new file mode 100644 index 00000000..6337581d --- /dev/null +++ b/Calculator.Kunikazu723/SimpleCalculator/SimpleCalculator.csproj @@ -0,0 +1,14 @@ + + + + Exe + net9.0 + enable + enable + + + + + + + diff --git a/Calculator.Kunikazu723/SimpleCalculator/SimpleCalculator.sln b/Calculator.Kunikazu723/SimpleCalculator/SimpleCalculator.sln new file mode 100644 index 00000000..73e374d7 --- /dev/null +++ b/Calculator.Kunikazu723/SimpleCalculator/SimpleCalculator.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.37531.7 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleCalculator", "SimpleCalculator.csproj", "{230C3E79-9F6D-43A6-8F32-96B9403FC916}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalculatorLibrary", "..\CalculatorLibrary\CalculatorLibrary.csproj", "{514EC5D4-27E2-4D1F-8585-6E96D91D930F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {230C3E79-9F6D-43A6-8F32-96B9403FC916}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {230C3E79-9F6D-43A6-8F32-96B9403FC916}.Debug|Any CPU.Build.0 = Debug|Any CPU + {230C3E79-9F6D-43A6-8F32-96B9403FC916}.Release|Any CPU.ActiveCfg = Release|Any CPU + {230C3E79-9F6D-43A6-8F32-96B9403FC916}.Release|Any CPU.Build.0 = Release|Any CPU + {514EC5D4-27E2-4D1F-8585-6E96D91D930F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {514EC5D4-27E2-4D1F-8585-6E96D91D930F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {514EC5D4-27E2-4D1F-8585-6E96D91D930F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {514EC5D4-27E2-4D1F-8585-6E96D91D930F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {35D23E78-8EB0-40C7-8F9A-0F9DA8995BC3} + EndGlobalSection +EndGlobal