diff --git a/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests.sln b/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests.sln new file mode 100644 index 0000000..2d10881 --- /dev/null +++ b/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33403.182 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NewPostfixCalculatorWithModuleTests", "NewPostfixCalculatorWithModuleTests\NewPostfixCalculatorWithModuleTests.csproj", "{6D1F274D-7F63-4D3D-A1C1-39AD50776432}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestsStack", "TestsStack\TestsStack.csproj", "{1D426654-9F9F-48C0-B933-D02296C8D15C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestsStackCalculator", "TestsStackCalculator\TestsStackCalculator.csproj", "{6C39F55D-D4A9-438C-8CAA-7273737D1223}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6D1F274D-7F63-4D3D-A1C1-39AD50776432}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6D1F274D-7F63-4D3D-A1C1-39AD50776432}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6D1F274D-7F63-4D3D-A1C1-39AD50776432}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6D1F274D-7F63-4D3D-A1C1-39AD50776432}.Release|Any CPU.Build.0 = Release|Any CPU + {1D426654-9F9F-48C0-B933-D02296C8D15C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1D426654-9F9F-48C0-B933-D02296C8D15C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1D426654-9F9F-48C0-B933-D02296C8D15C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1D426654-9F9F-48C0-B933-D02296C8D15C}.Release|Any CPU.Build.0 = Release|Any CPU + {6C39F55D-D4A9-438C-8CAA-7273737D1223}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6C39F55D-D4A9-438C-8CAA-7273737D1223}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6C39F55D-D4A9-438C-8CAA-7273737D1223}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6C39F55D-D4A9-438C-8CAA-7273737D1223}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B6FC0766-8CAA-4DB9-B5D4-B9458F46BC15} + EndGlobalSection +EndGlobal diff --git a/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests.csproj b/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests/Program.cs b/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests/Program.cs new file mode 100644 index 0000000..1ad0a2d --- /dev/null +++ b/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests/Program.cs @@ -0,0 +1,18 @@ +using StackCalculator; + +Console.WriteLine("Enter an example in the postfix form"); +var stringWithExpression = Console.ReadLine(); + +if (stringWithExpression == null) +{ + return; +} + +var stackList = new StackWithList(); +(bool isCorrectWork, double result) = PostfixCalculator.Calculate(stringWithExpression, stackList); +if (!isCorrectWork) +{ + Console.WriteLine("Problems with expression or you tried to divide by zero!"); + return; +} +Console.WriteLine(result); \ No newline at end of file diff --git a/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests/StackCalculator.cs b/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests/StackCalculator.cs new file mode 100644 index 0000000..eb4515e --- /dev/null +++ b/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests/StackCalculator.cs @@ -0,0 +1,73 @@ +namespace StackCalculator; + +// Calculator that counts algebraic expressions in postfix form +public static class PostfixCalculator +{ + private const double delta = 0.0000000000001; + + // Receives the input string in which the expression is written in postfix form, finds the result + public static (bool, double) Calculate(string stringWithExpression, IStack stackExpression) + { + int i = 0; + string[] expressionArray = stringWithExpression.Split(' '); + while (i < expressionArray.Length) + { + var isCorrectNumber = Int32.TryParse(expressionArray[i], out var number); + if (isCorrectNumber) + { + stackExpression.Push(number); + } + else + { + if (expressionArray[i].Length != 1) + { + return (false, 0); + } + double numberAfter = 0; + (var isCorrect, var firstNumber) = stackExpression.Pop(); + + if (!isCorrect) + { + return (false, 0); + } + + (isCorrect, var secondNumber) = stackExpression.Pop(); + + if (!isCorrect) + { + return (false, 0); + } + + switch (expressionArray[i][0]) + { + case '*': + numberAfter = firstNumber * secondNumber; + break; + case '+': + numberAfter = firstNumber + secondNumber; + break; + case '-': + numberAfter = secondNumber - firstNumber; + break; + case '/': + if (Math.Abs(firstNumber) < delta) + { + return (false, 0); + } + numberAfter = secondNumber / firstNumber; + break; + default: + return (false, 0); + } + stackExpression.Push(numberAfter); + } + ++i; + } + (var isCorrectExpression, var result) = stackExpression.Pop(); + if (!isCorrectExpression) + { + return (false, 0); + } + return stackExpression.IsEmpty() ? (true, result) : (false, 0); + } +} \ No newline at end of file diff --git a/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests/StackWIthArray.cs b/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests/StackWIthArray.cs new file mode 100644 index 0000000..5efee76 --- /dev/null +++ b/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests/StackWIthArray.cs @@ -0,0 +1,56 @@ +namespace StackCalculator; + +// Stack implemented on an array +public class StackWithArray : IStack +{ + private double[] stackArray; + private int numberOfElements; + private int sizeStack = 10; + + public StackWithArray() + { + stackArray = new double[sizeStack]; + } + + private bool ChangeStackSize(int size) + { + if (size < sizeStack) + { + return false; + } + Array.Resize(ref stackArray, size); + return true; + } + + public void Push(double value) + { + if (numberOfElements == sizeStack) + { + ChangeStackSize(sizeStack * 2); + } + stackArray[numberOfElements] = value; + ++numberOfElements; + } + + public (bool, double) Pop() + { + if (numberOfElements == 0) + { + return (false, 0); + } + double result = stackArray[numberOfElements - 1]; + --numberOfElements; + return (true, result); + } + + public void PrintTheElements() + { + for (int i = 0; i < numberOfElements; i++) + { + Console.WriteLine(stackArray[i]); + } + } + + public bool IsEmpty() + => numberOfElements == 0; +} \ No newline at end of file diff --git a/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests/StackWithList.cs b/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests/StackWithList.cs new file mode 100644 index 0000000..54b71c0 --- /dev/null +++ b/NewPostfixCalculatorWithModuleTests/NewPostfixCalculatorWithModuleTests/StackWithList.cs @@ -0,0 +1,48 @@ +namespace StackCalculator; + +// Stack implemented on list +public class StackWithList : IStack +{ + private StackElement? headStack; + + public void Push(double value) + { + headStack = new StackElement(value, headStack); + } + + public (bool, double) Pop() + { + if (headStack == null) + { + return (false, 0); + } + double item = headStack.ValueStack; + StackElement? copy = headStack.Next; + headStack = copy; + return (true, item); + } + + public void PrintTheElements() + { + StackElement? walker = headStack; + while (walker != null) + { + Console.WriteLine(walker.ValueStack); + walker = walker.Next; + } + } + + public bool IsEmpty() => headStack == null; + + private class StackElement + { + public StackElement(double value, StackElement? next) + { + ValueStack = value; + Next = next; + } + + public double ValueStack { get; set; } + public StackElement? Next { get; set; } + } +} \ No newline at end of file diff --git a/NewPostfixCalculatorWithModuleTests/TestsStack/TestsStack.cs b/NewPostfixCalculatorWithModuleTests/TestsStack/TestsStack.cs new file mode 100644 index 0000000..2d050cf --- /dev/null +++ b/NewPostfixCalculatorWithModuleTests/TestsStack/TestsStack.cs @@ -0,0 +1,75 @@ +namespace TestsForStack; + +using StackCalculator; + +public class Tests +{ + [TestCaseSource(nameof(Stacks))] + public void StackShouldNotEmptyAfterPush(IStack stack) + { + stack.Push(1); + Assert.IsFalse(stack.IsEmpty()); + } + + [TestCaseSource(nameof(Stacks))] + public void StackShouldEmptyWhenCreated(IStack stack) + { + Assert.IsTrue(stack.IsEmpty()); + } + + [TestCaseSource(nameof(Stacks))] + public void StackShouldCorrectlyDeleteTheValue(IStack stack) + { + stack.Push(1); + var (isCorrect, _) = stack.Pop(); + Assert.IsTrue(isCorrect); + } + + [TestCaseSource(nameof(Stacks))] + public void StackShouldReturnTheLastValueThatWasAddedAndThenDeleted(IStack stack) + { + stack.Push(1); + var (_, number) = stack.Pop(); + Assert.That(number, Is.EqualTo(1)); + } + + [TestCaseSource(nameof(Stacks))] + public void WhenRemovedFromTheTopOfTheStackTheElementShouldBeErasedFromTheTop(IStack stack) + { + stack.Push(1); + var (_, _) = stack.Pop(); + Assert.IsTrue(stack.IsEmpty()); + } + + [TestCaseSource(nameof(Stacks))] + public void DeletingFromAnEmptyStackShouldCauseAnError(IStack stack) + { + var (isCorrect, _) = stack.Pop(); + Assert.IsFalse(isCorrect); + } + + [TestCaseSource(nameof(Stacks))] + public void WhenAddingConsecutiveValuesTheTopValueShouldBeTheLastOneAdded(IStack stack) + { + stack.Push(1); + stack.Push(2); + var (_, number) = stack.Pop(); + Assert.That(number, Is.EqualTo(2)); + } + + [TestCaseSource(nameof(Stacks))] + public void DeletingInAStackOfMultipleItemsShouldBeSuccessful(IStack stack) + { + stack.Push(1); + stack.Push(2); + var (isCorrect, _) = stack.Pop(); + Assert.IsTrue(isCorrect); + } + + private static IEnumerable Stacks + => new TestCaseData[] + { + new TestCaseData(new StackWithArray()), + new TestCaseData(new StackWithList()), + }; +} \ No newline at end of file diff --git a/NewPostfixCalculatorWithModuleTests/TestsStack/TestsStack.csproj b/NewPostfixCalculatorWithModuleTests/TestsStack/TestsStack.csproj new file mode 100644 index 0000000..564a5d7 --- /dev/null +++ b/NewPostfixCalculatorWithModuleTests/TestsStack/TestsStack.csproj @@ -0,0 +1,23 @@ + + + + net7.0 + enable + enable + + false + + + + + + + + + + + + + + + diff --git a/NewPostfixCalculatorWithModuleTests/TestsStack/Usings.cs b/NewPostfixCalculatorWithModuleTests/TestsStack/Usings.cs new file mode 100644 index 0000000..cefced4 --- /dev/null +++ b/NewPostfixCalculatorWithModuleTests/TestsStack/Usings.cs @@ -0,0 +1 @@ +global using NUnit.Framework; \ No newline at end of file diff --git a/NewPostfixCalculatorWithModuleTests/TestsStackCalculator/TestsStackCalculator.cs b/NewPostfixCalculatorWithModuleTests/TestsStackCalculator/TestsStackCalculator.cs new file mode 100644 index 0000000..d5429ce --- /dev/null +++ b/NewPostfixCalculatorWithModuleTests/TestsStackCalculator/TestsStackCalculator.cs @@ -0,0 +1,102 @@ +namespace TestsForStackCalculator; + +using StackCalculator; +using System.Numerics; + +public class Tests +{ + private const double delta = 0.0000000000001; + + + [TestCaseSource(nameof(Stacks))] + public void TheCalculatorShouldWorkCorrectlyToReturnTheCorrectValueOnASimpleExample(IStack stack) + { + var (isCorrect, number) = PostfixCalculator.Calculate("1 2 +", stack); + Assert.True(isCorrect); + Assert.That(number, Is.EqualTo(3)); + } + + [TestCaseSource(nameof(Stacks))] + public void OnTheWrongLineTheCalculatorShouldReturnAnError(IStack stack) + { + var (isCorrect, _) = PostfixCalculator.Calculate("1 2", stack); + Assert.IsFalse(isCorrect); + } + + [TestCaseSource(nameof(Stacks))] + public void TheFirstValueIsPositiveTheSecondIsNegativeTheCalculatorShouldReturnTheCorrectValue(IStack stack) + { + var (isCorrect, number) = PostfixCalculator.Calculate("1 -2 +", stack); + Assert.That(isCorrect); + Assert.That(number, Is.EqualTo(-1)); + } + + [TestCaseSource(nameof(Stacks))] + public void TheSecondValueIsPositiveTheFirstIsNegativeTheCalculatorShouldReturnTheCorrectValue(IStack stack) + { + var (isCorrect, number) = PostfixCalculator.Calculate("-1 2 +", stack); + Assert.That(isCorrect); + Assert.That(number, Is.EqualTo(1)); + } + + [TestCaseSource(nameof(Stacks))] + public void TheSecondValueIsNegativeTheFirstIsNegativeTheCalculatorShouldReturnTheCorrectValue(IStack stack) + { + var (isCorrect, number) = PostfixCalculator.Calculate("-1 -2 +", stack); + Assert.That(isCorrect); + Assert.That(number, Is.EqualTo(-3)); + } + + [TestCaseSource(nameof(Stacks))] + public void TheStackCalculatorShouldWorkCorrectlyWithTheDifference(IStack stack) + { + var (isCorrect, number) = PostfixCalculator.Calculate("1 2 -", stack); + Assert.That(isCorrect); + Assert.That(number, Is.EqualTo(-1)); + } + + [TestCaseSource(nameof(Stacks))] + public void TheStackCalculatorShouldWorkCorrectlyWithTheMultiplication(IStack stack) + { + var (isCorrect, number) = PostfixCalculator.Calculate("2 3 *", stack); + Assert.That(isCorrect); + Assert.That(number, Is.EqualTo(6)); + } + + [TestCaseSource(nameof(Stacks))] + public void TheStackCalculatorShouldWorkCorrectlyWithTheDivision(IStack stack) + { + var (isCorrect, number) = PostfixCalculator.Calculate("5 2 /", stack); + Assert.That(isCorrect); + Assert.That(Math.Abs(number - 2.5) < delta); + } + + [TestCaseSource(nameof(Stacks))] + public void TheStackCalculatorShouldGiveAnErrorWhenReceivingAnemptyString(IStack stack) + { + var (isCorrect, _) = PostfixCalculator.Calculate("", stack); + Assert.IsFalse(isCorrect); + } + + [TestCaseSource(nameof(Stacks))] + public void TheStackÑalculatorShouldCorrectlyCalculateComplexExpressions(IStack stack) + { + var (isCorrect, number) = PostfixCalculator.Calculate("1 2 + 3 *", stack); + Assert.That(isCorrect); + Assert.That(number, Is.EqualTo(9)); + } + + [TestCaseSource(nameof(Stacks))] + public void TheStackCalculatorShouldGiveAnErrorWhenReceivingAStringWithCharactersThatWereNotExpected(IStack stack) + { + var (isCorrect, _) = PostfixCalculator.Calculate("1 2 ` 3 *", stack); + Assert.IsFalse(isCorrect); + } + + private static IEnumerable Stacks + => new TestCaseData[] + { + new TestCaseData(new StackWithArray()), + new TestCaseData(new StackWithList()), + }; +} \ No newline at end of file diff --git a/NewPostfixCalculatorWithModuleTests/TestsStackCalculator/TestsStackCalculator.csproj b/NewPostfixCalculatorWithModuleTests/TestsStackCalculator/TestsStackCalculator.csproj new file mode 100644 index 0000000..564a5d7 --- /dev/null +++ b/NewPostfixCalculatorWithModuleTests/TestsStackCalculator/TestsStackCalculator.csproj @@ -0,0 +1,23 @@ + + + + net7.0 + enable + enable + + false + + + + + + + + + + + + + + + diff --git a/NewPostfixCalculatorWithModuleTests/TestsStackCalculator/Usings.cs b/NewPostfixCalculatorWithModuleTests/TestsStackCalculator/Usings.cs new file mode 100644 index 0000000..cefced4 --- /dev/null +++ b/NewPostfixCalculatorWithModuleTests/TestsStackCalculator/Usings.cs @@ -0,0 +1 @@ +global using NUnit.Framework; \ No newline at end of file