Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Черных Илья #243

Open
wants to merge 33 commits into
base: master
Choose a base branch
from
Open

Черных Илья #243

wants to merge 33 commits into from

Conversation

Ilya4rh
Copy link

@Ilya4rh Ilya4rh commented Nov 13, 2024

Так как изначально угол и радиус спирали равны нулю, то центр будет в прямоугольнике.
Copy link

@GarageManager GarageManager left a comment

Choose a reason for hiding this comment

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

Круто, что разбил на отдельные коммиты, сразу видно, что старался делать задачу используя TDD

addedRectangles = new List<Rectangle>();
}

public Rectangle PutNextRectangle(Size rectangleSize)

Choose a reason for hiding this comment

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

Сейчас твой метод кладет прямоугольники всегда одним и тем же способом, но в идеале было бы хорошо алгоритм раскладки вынести куда-то в сторону и передавать его в конструктор, чтобы разные экземпляры CircularCloudLayouter могли раскладывать разными способами. Конкретно в этой задаче способ нужен только один, но на будущее лучше сделать класс гибче, и чтобы он почти ничего не знал о том, по какому алгоритму выбираются точки для прямоугольников

currentAngleOfSpiral += Math.PI / 180;

// проверяем не прошли ли целый круг
if (currentAngleOfSpiral > 2 * Math.PI)

Choose a reason for hiding this comment

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

У тебя тут получилась не совсем спираль, т.к. ты сначала пытаешься расположить прямоугольники по периметру круга, и только если по периметру укладывать больше нельзя увеличиваешь радиус, тем самым создавая новый круг. Я не требую что-то менять в логике, но нейминг точно стоит поправить, потому что он не соответствует алгоритму

rectangle = new Rectangle(new Point(x, y), rectangleSize);

// увеличиваем угол на 1 градус
currentAngleOfSpiral += Math.PI / 180;

Choose a reason for hiding this comment

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

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


public class VisualizationCircularCloudLayout
{
public static void DrawAndSaveLayout(List<Rectangle> rectangles, string fileName, string filePath)

Choose a reason for hiding this comment

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

По названию можно заметить, что метод выполняет сразу 2 функции: генерирует графическое представление нашего облака и сохраняет его в какой-то файл по переданному пути и имени. Такого в идеале быть не должно, у одного метода должно быть одно назначение. Так что предлагаю разбить на две части: одна вернет графическое представление, другая - сохранит его в файл

{
public static void DrawAndSaveLayout(List<Rectangle> rectangles, string fileName, string filePath)
{
const int padding = 10;

Choose a reason for hiding this comment

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

Эту константу можно передавать параметром или в метод или в конструктор, чтобы можно было отступ кастомизировать

graphics.DrawRectangle(Pens.Black, shiftedRectangle);
}

bitmap.Save(Path.Combine(filePath, fileName), ImageFormat.Png);

Choose a reason for hiding this comment

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

Формат изображения тоже было бы хорошо передавать параметром, чтобы пользователь мог сам выбирать, в каком формате его сохранять

Choose a reason for hiding this comment

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

Мелочь, но названия проектов лучше всегда делать понятными, даже для тестовых или учебных заданий, это развивает привычку использовать хорошие называния

var testName = TestContext.CurrentContext.Test.Name;

VisualizationCircularCloudLayout.DrawAndSaveLayout(addedRectangles, $"{testName}.png",
pathImageStored);

Choose a reason for hiding this comment

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

Если переносишь один параметр в методе, то лучше переносить сразу все

}


private static List<Size> GetGeneratedRectangleSizes(int countRectangles, int minSideLength, int maxSideLength)

Choose a reason for hiding this comment

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

Get тут не очень хорошо подходит, т.к. он подразумевает, что мы откуда-то что-то берем, когда на самом деле мы вычисляем (других методов тоже касается)

}

return generatedSizes;
}

Choose a reason for hiding this comment

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

Как будто весь метод можно свернуть в компактную Linq-цепочку


private bool IntersectWithAddedRectangles(Rectangle rectangle)
{
return addedRectangles.Any(addedRectangle => addedRectangle.IntersectsWith(rectangle));

Choose a reason for hiding this comment

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

В этом классе нужно оставить только вычисление точек, а логику с прямоугольниками унести в CircularCloudLayouter

// увеличиваем угол на 1 градус
currentAngleOfCircle += OneDegree;

// проверяем не прошли ли целый круг

Choose a reason for hiding this comment

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

Было бы круто, если бы шаг радиуса и шаг угла пользователь мог сам выбирать. Например, вводя эти параметры в конструкторе. Но чтобы не нужно было это всегда делать, можно значения по умолчанию поставить

return CalculateDistanceBetweenPoints(centerRectangle1, centerRectangle2);
}

private static double CalculateDistanceBetweenPoints(Point point1, Point point2)

Choose a reason for hiding this comment

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

У тебя ту довольно много статических методов, которые можно вынести в отдельный статический класс-хелпер

{
var random = new Random();

var generatedSizes = Enumerable.Range(0, countRectangles)

Choose a reason for hiding this comment

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

Мелочь. В Linq цепочке лучше все элементы переносить на новую строчку, включая первый

center,
stepIncreasingRadius: stepIncreasingRadius,
stepIncreasingAngle: stepIncreasingAngle
);

Choose a reason for hiding this comment

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

Мелочь. Скобочка далеко уехала куда-то, ее не нужно отдельно переносить


[TestCase(Math.PI / 4)]
[TestCase(Math.PI / 2)]
public void CalculateNextPoint_ShouldIncreaseAngle_WhenCalculateThreePoints(double stepIncreasingAngle)

Choose a reason for hiding this comment

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

Мне не очень нравится название теста.
Во-первых, тут есть магическое число 3, и без знания реализации алгоритма не понятно почему оно именно такое
Во-вторых, тут довольно слабые проверки на неравенство и больше/меньше. Мы по идее знаем, как должен работать алгоритм, соответственно мы можем написать более точные ассерты. Мне кажется, что раз есть возможность, то лучше сравнивать прям покоординатно точки, а возможность есть, т.к. мы шаг для радиуса и угла прям в конструктор в класса проверяемого передаем.
Т.е. мы можем так же получить три точки и проверить каждую на точное соответствие ожидаемой координате.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants