Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions CodeReviews.Console.Calculator.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{827E0CD3-B72D-47B6-A68D-7590B98EB39B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Calculator", "src\Calculator.csproj", "{23269A6C-8755-4F73-98C1-FEB1E64BE94C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lib", "lib", "{3A8DF596-E814-FECC-DD4B-D8EF8AAC1A0D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalculatorLibrary", "lib\CalculatorLibrary.csproj", "{D2B87518-0CC2-4DF9-B257-5FBBFB7BE093}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{23269A6C-8755-4F73-98C1-FEB1E64BE94C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23269A6C-8755-4F73-98C1-FEB1E64BE94C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23269A6C-8755-4F73-98C1-FEB1E64BE94C}.Debug|x64.ActiveCfg = Debug|Any CPU
{23269A6C-8755-4F73-98C1-FEB1E64BE94C}.Debug|x64.Build.0 = Debug|Any CPU
{23269A6C-8755-4F73-98C1-FEB1E64BE94C}.Debug|x86.ActiveCfg = Debug|Any CPU
{23269A6C-8755-4F73-98C1-FEB1E64BE94C}.Debug|x86.Build.0 = Debug|Any CPU
{23269A6C-8755-4F73-98C1-FEB1E64BE94C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23269A6C-8755-4F73-98C1-FEB1E64BE94C}.Release|Any CPU.Build.0 = Release|Any CPU
{23269A6C-8755-4F73-98C1-FEB1E64BE94C}.Release|x64.ActiveCfg = Release|Any CPU
{23269A6C-8755-4F73-98C1-FEB1E64BE94C}.Release|x64.Build.0 = Release|Any CPU
{23269A6C-8755-4F73-98C1-FEB1E64BE94C}.Release|x86.ActiveCfg = Release|Any CPU
{23269A6C-8755-4F73-98C1-FEB1E64BE94C}.Release|x86.Build.0 = Release|Any CPU
{D2B87518-0CC2-4DF9-B257-5FBBFB7BE093}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D2B87518-0CC2-4DF9-B257-5FBBFB7BE093}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D2B87518-0CC2-4DF9-B257-5FBBFB7BE093}.Debug|x64.ActiveCfg = Debug|Any CPU
{D2B87518-0CC2-4DF9-B257-5FBBFB7BE093}.Debug|x64.Build.0 = Debug|Any CPU
{D2B87518-0CC2-4DF9-B257-5FBBFB7BE093}.Debug|x86.ActiveCfg = Debug|Any CPU
{D2B87518-0CC2-4DF9-B257-5FBBFB7BE093}.Debug|x86.Build.0 = Debug|Any CPU
{D2B87518-0CC2-4DF9-B257-5FBBFB7BE093}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D2B87518-0CC2-4DF9-B257-5FBBFB7BE093}.Release|Any CPU.Build.0 = Release|Any CPU
{D2B87518-0CC2-4DF9-B257-5FBBFB7BE093}.Release|x64.ActiveCfg = Release|Any CPU
{D2B87518-0CC2-4DF9-B257-5FBBFB7BE093}.Release|x64.Build.0 = Release|Any CPU
{D2B87518-0CC2-4DF9-B257-5FBBFB7BE093}.Release|x86.ActiveCfg = Release|Any CPU
{D2B87518-0CC2-4DF9-B257-5FBBFB7BE093}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{23269A6C-8755-4F73-98C1-FEB1E64BE94C} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
{D2B87518-0CC2-4DF9-B257-5FBBFB7BE093} = {3A8DF596-E814-FECC-DD4B-D8EF8AAC1A0D}
EndGlobalSection
EndGlobal
10 changes: 10 additions & 0 deletions calculator.qua9k.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
112 changes: 112 additions & 0 deletions src/Calculator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using System.Text;
using System.Text.Json;

namespace calculator.qua9k.lib;

public class Calculator
{
private readonly Utf8JsonWriter _writer;
private readonly List<string> _history = [];

public Calculator()
{
var logFile = File.OpenWrite(path: "calculator_log.json");
_writer = new Utf8JsonWriter(logFile);
_writer.WriteStartObject();
_writer.WritePropertyName("Operations");
_writer.WriteStartArray();
}

public double DoOperation(double num1, double num2, string op)
{
var result = double.NaN;
StringBuilder operation = new();

_writer.WriteStartObject();
_writer.WritePropertyName("Operand1");
_writer.WriteNumberValue(num1);
_writer.WritePropertyName("Operand2");
_writer.WriteNumberValue(num2);
_writer.WritePropertyName("Operation");

switch (op)
{
case "+":
result = num1 + num2;
_writer.WriteStringValue("Add");
break;
case "-":
result = num1 - num2;
_writer.WriteStringValue("Subtract");
break;
case "*":
result = num1 * num2;
_writer.WriteStringValue("Multiply");
break;
case "/":
if (num2 != 0)
{
result = num1 / num2;
}
_writer.WriteStringValue("Divide");
break;
case "^":
result = Math.Pow(num1, num2);
_writer.WriteStringValue("Exponentiate");
break;
case "log":
result = Math.Log(num1, num2);
_writer.WriteStringValue("Logarithm");
break;
}
result = Math.Round(result, 2);
_writer.WritePropertyName("Result");
_writer.WriteNumberValue(result);
_writer.WriteEndObject();

operation.Append($"{num1} {op} {num2} = {result}");
_history.Add(operation.ToString());

return result;
}

public void PrintHistory()
{
if (_history.Count <= 0)
{
Console.WriteLine("The history is empty.");
return;
}

Console.WriteLine(
"""
History

"""
);

for (var i = 0; i < _history.Count; i++)
{
Console.WriteLine($"{i}: {_history[i]}");
}
}

public void ClearHistory()
{
Console.WriteLine(
"""
History cleared.

"""
);
_history.Clear();
}

public void Finish()
{
_writer.WriteEndArray();
_writer.WriteEndObject();
_writer.Flush();
_writer.Dispose();
}
}
14 changes: 14 additions & 0 deletions src/Calculator.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<ProjectReference Include="..\lib\CalculatorLibrary.csproj" />
</ItemGroup>

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
112 changes: 112 additions & 0 deletions src/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using calculator.qua9k.lib;

namespace calculator.qua9k;

internal class Program
{
private static void Main()
{
Calculator calc = new();
Dictionary<string, string> operatorMap = new()
{
{ "+", "Add" },
{ "-", "Subtract" },
{ "*", "Multiply" },
{ "/", "Divide" },
{ "^", "Exponentiate" },
{ "log", "Logarithm" }
};

var validOperand1 = double.MinValue;
var postCalcChoice = "";
var endApp = false;

while (!endApp)
{
Console.Clear();
UserInterface.PrintHeader();

if (postCalcChoice == "p")
{
Console.WriteLine($"Previous result: {validOperand1}");
}
else
{
Console.Write("Enter the first operand: ");
GetOperand(out validOperand1);
}

Console.Write("Enter the second operand: ");
GetOperand(out var validOperand2);

Console.WriteLine("Choose an operator:");
UserInterface.PrintOperations(operatorMap);

Console.Write("Your option? ");
var op = Console.ReadLine();
var result = double.MinValue;

if (op == null || !operatorMap.ContainsKey(op))
Console.WriteLine("Error: Unrecognized input.");
else
try
{
result = calc.DoOperation(validOperand1, validOperand2, 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);
}
catch (Exception e)
{
Console.WriteLine("An exception occurred.\n - Details: " + e.Message);
}

UserInterface.Pause();
UserInterface.PrintMenuOptions();

postCalcChoice = Console.ReadLine();

while (postCalcChoice is "h" or "d")
{
Console.Clear();
UserInterface.PrintHeader();

if (postCalcChoice == "h")
calc.PrintHistory();
else
calc.ClearHistory();

UserInterface.Pause();
UserInterface.PrintMenuOptions();

postCalcChoice = Console.ReadLine();
}

switch (postCalcChoice)
{
case "p":
validOperand1 = result;
break;
case "n":
Console.WriteLine("Goodbye!");
endApp = true;
break;
}
}

calc.Finish();
}

private static void GetOperand(out double validNum)
{
var userInput = Console.ReadLine();

while (!double.TryParse(userInput, out validNum))
{
Console.Write("Invalid input. Enter a numeric value: ");
userInput = Console.ReadLine();
}
}
}
36 changes: 36 additions & 0 deletions src/UserInterface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace calculator.qua9k;

internal static class UserInterface
{
public static void PrintOperations(Dictionary<string, string> operatorMap)
{
foreach (var kvp in operatorMap) Console.WriteLine($" {kvp.Key} : {kvp.Value}");
}

public static void Pause()
{
Console.WriteLine();
Console.Write("Press any key to continue.");
Console.ReadKey();
}

public static void PrintMenuOptions()
{
Console.Write(
"""
- 'n' + Enter : close the app.
- 'p' + Enter : use the previous result as the first operand.
- 'h' + Enter : view operation history.
- 'd' + Enter : delete operation history.
- Any other key to perform a new calculation.

"""
);
}

public static void PrintHeader()
{
Console.WriteLine("Console Calculator in C#\r");
Console.WriteLine("------------------------\n");
}
}
1 change: 1 addition & 0 deletions src/calculator_log.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Operations":[{"Operand1":3,"Operand2":3,"Operation":"Add","Result":6}]}