Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
37 changes: 37 additions & 0 deletions Homework2/StackCalculator/StackCalculator.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32210.238
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StackCalculator", "StackCalculator\StackCalculator.csproj", "{8DBDDAE0-E403-49E6-9223-5AC9BF60294F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestStackCalculator", "TestStackCalculator\TestStackCalculator.csproj", "{46FAACC4-DAD8-4735-943E-22F9ADAA23C6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stack", "..\..\Stack\Stack\Stack.csproj", "{C66F855E-3C30-4EA4-AFBC-87B64CBCB781}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8DBDDAE0-E403-49E6-9223-5AC9BF60294F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8DBDDAE0-E403-49E6-9223-5AC9BF60294F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8DBDDAE0-E403-49E6-9223-5AC9BF60294F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8DBDDAE0-E403-49E6-9223-5AC9BF60294F}.Release|Any CPU.Build.0 = Release|Any CPU
{46FAACC4-DAD8-4735-943E-22F9ADAA23C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{46FAACC4-DAD8-4735-943E-22F9ADAA23C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{46FAACC4-DAD8-4735-943E-22F9ADAA23C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{46FAACC4-DAD8-4735-943E-22F9ADAA23C6}.Release|Any CPU.Build.0 = Release|Any CPU
{C66F855E-3C30-4EA4-AFBC-87B64CBCB781}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C66F855E-3C30-4EA4-AFBC-87B64CBCB781}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C66F855E-3C30-4EA4-AFBC-87B64CBCB781}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C66F855E-3C30-4EA4-AFBC-87B64CBCB781}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F3D2B963-4468-436F-A5AE-D78F83C046C7}
EndGlobalSection
EndGlobal
125 changes: 125 additions & 0 deletions Homework2/StackCalculator/StackCalculator/Calculator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
using System;
using Stack;

namespace StackCalculator;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

namespace лучше в самом начале писать


/// <summary>
/// A class representing a stack calculator
/// </summary>
public class Calculator
{
private IStack<float> Stack = new StackOnLists<float>();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

По условию, в коде класса «Стековый калькулятор» не должно быть ни одного упоминания конкретных реализаций стека, даже если очень хочется.


/// <summary>
/// Function for counting expressions in postfix form
/// </summary>
/// <returns>Expression value</returns>
public float CountTheExpressionInPostfixForm(string[] inputString)
{
int number = 0;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Слишком рано объявлен. Надо его объявить в месте инициализации: if (int.TryParse(inputString[i], out int number))

for (int i = 0; i < inputString.Length; i++)
{
if (inputString[i] == "")
{
continue;
}
if (int.TryParse(inputString[i], out number))
{
Stack.Push(number);
continue;
}
try
{
if (Stack.ReturnNumberOfElements() < 2)
{
throw new IncorrectExpressionException("Incorrect expression");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

То, что Incorrect expression, понятно из типа исключения, тут Message не нужен

}
}
catch (IncorrectExpressionException exception)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Делается throw и тут же catch, то есть то самое, что я на паре говорил не делать :) Это бессмысленный код.

{
Console.WriteLine($"Ошибка: {exception.Message}");
throw;
}
float secondNumber = 0;
float firstNumber = 0;
try
{
secondNumber = Stack.Pop();
firstNumber = Stack.Pop();
}
catch (StackException)
{
Console.WriteLine("Incorrect expression");
throw;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если Вы собираетесь выкинуть исключение, то незачем тут что-то писать на консоль --- выше по стеку вызовов его поймают и напишут, если надо. Вообще. на консоль должен писать только Main и специально предназначенные для этого классы.

}
Comment on lines +41 to +44
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если вы думаете, что ваша жизнь бессмысленна, посмотрите на эти строки кода :)

if (inputString[i] == "+")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Это можно быть switch-ем сделать

{
Stack.Push(firstNumber + secondNumber);
continue;
}
if (inputString[i] == "-")
{
Stack.Push(firstNumber - secondNumber);
continue;
}
if (inputString[i] == "*")
{
Stack.Push(firstNumber * secondNumber);
continue;
}
if (inputString[i] == "/")
{
try
{
if (secondNumber.CompareTo(0) == 0)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
throw new DivideByZeroException("division by 0");
}
}
catch (DivideByZeroException exception)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:(

{
Console.WriteLine($"Ошибка: {exception.Message}");
throw;
}
Stack.Push(firstNumber / secondNumber);
}
else
{
try
{
throw new InvalidCharacterException("Invalid character");
}
catch(InvalidCharacterException exception)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
catch(InvalidCharacterException exception)
catch (InvalidCharacterException exception)

Ну и да, так нельзя

{
Console.WriteLine($"Ошибка: {exception.Message}");
throw;
}
}
}
try
{
if (Stack.ReturnNumberOfElements() > 1)
{
throw new IncorrectExpressionException("Incorrect expression");
}
}
catch (IncorrectExpressionException exception)
{
Console.WriteLine($"Ошибка: {exception.Message}");
throw;
}
try
{
if (Stack.ReturnNumberOfElements() < 1)
{
throw new IncorrectExpressionException("Empty string");
}
}
catch (IncorrectExpressionException exception)
{
Console.WriteLine($"Ошибка: {exception.Message}");
throw;
}
return Stack.Pop();
}
}
17 changes: 17 additions & 0 deletions Homework2/StackCalculator/StackCalculator/Solution.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace StackCalculator;

public class Solution
{
static void Main()
{
Console.WriteLine("Please, enter the expression");
var inputString = Console.ReadLine();
if (inputString == null)
{
return;
}
var subs = inputString.Split(' ');
Calculator stackCalculator = new Calculator();
Console.WriteLine($"{stackCalculator.CountTheExpressionInPostfixForm(subs)}");
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В C# 10 эти церемонии вообще не нужны:

Suggested change
namespace StackCalculator;
public class Solution
{
static void Main()
{
Console.WriteLine("Please, enter the expression");
var inputString = Console.ReadLine();
if (inputString == null)
{
return;
}
var subs = inputString.Split(' ');
Calculator stackCalculator = new Calculator();
Console.WriteLine($"{stackCalculator.CountTheExpressionInPostfixForm(subs)}");
}
}
namespace StackCalculator;
Console.WriteLine("Please, enter the expression");
var inputString = Console.ReadLine();
if (inputString == null)
{
return;
}
var subs = inputString.Split(' ');
Calculator stackCalculator = new Calculator();
Console.WriteLine($"{stackCalculator.CountTheExpressionInPostfixForm(subs)}");

15 changes: 15 additions & 0 deletions Homework2/StackCalculator/StackCalculator/StackCalculator.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

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

<ItemGroup>
<ProjectReference Include="..\..\..\Stack\Stack\Stack.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace StackCalculator;

/// <summary>
/// A class for creating custom exceptions
/// </summary>
public class InvalidCharacterException : Exception
{
public InvalidCharacterException(string? message) : base(message) { }
}

/// <summary>
/// A class for creating custom exceptions
/// </summary>
public class IncorrectExpressionException : Exception
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В одном файле должен быть один класс, причём файл должен называться как класс, который в нём содержится

{
public IncorrectExpressionException(string? message) : base(message) { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using NUnit.Framework;
using StackCalculator;
using System;

namespace TestStackCalculator;

/// <summary>
/// A class for testing a stack calculator
/// </summary>
public class TestsStackCalculator
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public class TestsStackCalculator
public class StackCalculatorTests

Так каноничнее

{
Calculator? stackCalculator;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Calculator? stackCalculator;
private Calculator? stackCalculator;

В сообществе принято писать модификаторы видимости всегда, даже если умолчания устраивают

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

И чтобы не делать его nullable, можно инициализировать его тут же new Calculator();-ом, который потом, правда, перезатрётся в SetUp, но это не страшно

[SetUp]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Calculator? stackCalculator;
[SetUp]
Calculator? stackCalculator;
[SetUp]

public void Setup()
{
stackCalculator = new Calculator();
}

[Test]
public void DevideByZero()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public void DevideByZero()
public void DivideByZero()

Кстати, вот хорошая статья про именование юнит-тестов: https://dzone.com/articles/7-popular-unit-test-naming. Как у Вас --- плохо

{
string[] firstArray = { "123", "0", "/" };
Assert.Throws<System.DivideByZeroException>(() => stackCalculator?.CountTheExpressionInPostfixForm(firstArray));
}

[Test]
public void ExpressionFromInvalidCharacter()
{
string[] firstArray = { "123", "0", "a" };
Assert.Throws<InvalidCharacterException> (() => stackCalculator?.CountTheExpressionInPostfixForm(firstArray));
}

[Test]
public void FirstIncorrectExpression()
{
string[] firstArray = { "123", "4", "*", "-" };
Assert.Throws<IncorrectExpressionException>(() => stackCalculator?.CountTheExpressionInPostfixForm(firstArray));
}

[Test]
public void SecondIncorrectExpression()
{
string[] firstArray = { "123", "4", "9", "23", "*", "-" };
Assert.Throws<IncorrectExpressionException>(() => stackCalculator?.CountTheExpressionInPostfixForm(firstArray));
}

[Test]
public void ValidOneCharacterExpression()
{
string[] firstArray = { "12"};
Assert.AreEqual(12, stackCalculator?.CountTheExpressionInPostfixForm(firstArray));
}


[Test]
public void ValidExpressionFromZeros()
{
string[] firstArray = { "0", "0", "+", "0", "-" };
Assert.AreEqual(0, stackCalculator?.CountTheExpressionInPostfixForm(firstArray));
}

[Test]
public void ExpressionWithoutNumbers()
{
string[] firstArray = {"+", "-"};
Assert.Throws<IncorrectExpressionException>(() => stackCalculator?.CountTheExpressionInPostfixForm(firstArray));
}

[Test]
public void EmptyString()
{
string[] firstArray = {" "};
Assert.Throws<IncorrectExpressionException>(() => stackCalculator?.CountTheExpressionInPostfixForm(firstArray));
}

[Test]
public void LongExpression()
{
string[] firstArray = { "0" , "120", "+", "45", "15", "/", "33", "+", "-5", "-13", "+", "9", "/", "/", "1", "123", "*", "+", "-" };
Assert.AreEqual(15, stackCalculator?.CountTheExpressionInPostfixForm(firstArray));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
<PackageReference Include="coverlet.collector" Version="3.1.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\StackCalculator\StackCalculator.csproj" />
</ItemGroup>

</Project>
47 changes: 47 additions & 0 deletions Stack/Stack/IStack.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
namespace Stack;

/// <summary>
/// A class representing the stack interface
/// </summary>
abstract public class IStack<T>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Это должен был быть интерфейс, а не абстрактный класс

{
/// <summary>
/// Function for checking the stack for emptiness
/// </summary>
/// <returns> True - if the stack is empty </returns>
abstract public bool IsEmpty();

/// <summary>
/// Function for adding an element to the stack
/// </summary>
/// <param name="value"> The value to add</param>
abstract public void Push(T value);

/// <summary>
/// Function for removing an element from the stack
/// </summary>
/// <returns> Remote value</returns>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remote --- это "удалённый" в смысле "на большой дистанции". Наверное, Removed?

abstract public T? Pop();

/// <summary>
/// Function that returns the number of elements in the stack
/// </summary>
/// <returns>Number of elements in stack</returns>
abstract public int ReturnNumberOfElements();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Идеологически правильнее NumberOfElements();, "Return" тут несколько избыточно.


/// <summary>
/// Function that returns the top of the stack
/// </summary>
/// <returns>Top of the stack</returns>
abstract public T? ReturnTopOfTheStack();

/// <summary>
/// Function for stack printing
/// </summary>
abstract public void PrintStack();

/// <summary>
/// Function for removing the stack
/// </summary>
abstract public void DeleteStack();
}
9 changes: 9 additions & 0 deletions Stack/Stack/Solution.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Stack;

public class Solution
{
static void Main()
{

}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если содержательный Main не написать, собирайте проект как библиотеку (настраивается в свойствах проекта). Библиотека --- это то же самое, но без точки входа (то есть как раз без Main)

}
10 changes: 10 additions & 0 deletions Stack/Stack/Stack.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не надо отдельного проекта для калькулятора и отдельного для стека, это как-то слишком мелкозернистое деление.


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

</Project>
Loading