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

Большаков Николай #256

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

Conversation

stupidnessplusplus
Copy link

@stupidnessplusplus stupidnessplusplus commented Nov 13, 2024

@masssha1308
Copy link

Проекты не добавились в солюшн, давай поправим
image

namespace TagsCloud_Tests;

[TestFixture]
public class CircularCloudLayouter_Constructor_Tests

Choose a reason for hiding this comment

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

Как правило 1 класс на который пишутся тесты = 1 класс с тестами
Давай объединим классы с тестами на конструктор и на метод


[TestFixture]
public class CircularCloudLayouter_Constructor_Tests
{

Choose a reason for hiding this comment

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

Принято использовать UpperCamelCase для именования классов

private readonly SortedRectanglesList _rectangles;
private readonly List<Rectangle> _rectanglesSpiralStack;

public SpiralCircularCloudLayouter(

Choose a reason for hiding this comment

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

поправим форматирование?

Center = center;
}

public Point Center { get; }

Choose a reason for hiding this comment

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

можно сделать не публичным

Point center)
{
_rectangles = new SortedRectanglesList();
_rectanglesSpiralStack = [];

Choose a reason for hiding this comment

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

можно инициализировать при объявлении (на мой вкус так более читабельно)

{
[Test]
[Description("В конструкторе указывается центр первого прямоугольника")]
public void Constructor_SetsCenterOfFirstRectangle()

Choose a reason for hiding this comment

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

Описание теста не соответствует тому что в нем делается. Т.е. в нем тестируется не только конструктор, но и метод PutNextRectangle

Чтобы протестировать конструктор (хотя спорный вопрос нужно ли его вообще тестировать, в идеальном мире в конструкторе не должно быть логики которая нуждается тестах, только присвоение) нужно проверить что он корректно сеттит center, другой логики в нем нет :)

[Description("Прямоугольники не имеют пересечений")]
public void PutNextRectangle_ReturnsNonIntersectingWithEachOtherRectangles()
{
var count = 1_000;

Choose a reason for hiding this comment

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

а зачем нижнее подчеркивание?

Copy link
Author

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.

вкусовщина, мне кажется :) кому как, можно оставить

for (var i = 0; i < count; i++)
{
var size = new Size(random.Next(2, 100), random.Next(2, 100));
var putRectangle = PutNextRectangle(size);

Choose a reason for hiding this comment

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

а почему такой нейминг? этот метод возвращает rectangle, логичнее назвать rectangle (или что-то подобное)

rectangles[i] = putRectangle;
}

for (var i = 0; i < count; i++)

Choose a reason for hiding this comment

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

давай перепишем на linq

Rectangle rectangle,
Comparer<Rectangle>? comparer)
{
Debug.Assert(rectangles != null);

Choose a reason for hiding this comment

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

давай уберем дебаг ассерт из кода

Size rectangleSize,
out Rectangle result)
{
var (rectangle, direction) = GetInitialRectangleAndRotationDirection(

Choose a reason for hiding this comment

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

тут каждый раз вычисляется в каком направлении предыдущий прямоугольник к предпредыдущему и кажется на момент когда мы добавляем прямоугольник мы знаем в каком направлении он к предыдущему -> двойная работа. давай запоминать в каком прямоугольник к предыдущему чтобы не считать дважды

/// стоящий на границе с previousRectangle с той же стороны, что и prePreviousRectangle,
/// и изначальное направление поиска подходящей для него позиции.
/// </summary>
private static (Rectangle, Direction) GetInitialRectangleAndRotationDirection(

Choose a reason for hiding this comment

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

давай поделим на 2 метода, нарушается srp

direction = Direction.Left;
}

var rectangle = new Rectangle(position, rectangleSize);

Choose a reason for hiding this comment

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

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

Copy link
Author

Choose a reason for hiding this comment

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

Для нахождения такой позиции, чтобы прямоугольник был наиболее прижат к остальным. Нужно, чтобы новый прямоугольник был, если возможно, внутри спирали или на ней. У меня расположение прямоугольников идет по часовой стрелке и, если предполагать, что предыдущий и предпредыдущий оба находятся на спирали, обходя предыдущий прямоугольник против часовой стрелки от позиции предпредыдущего, мы в первую очередь проверяем позиции внутри спирали.

var target = GetTarget(rectangleSize, _rectanglesSpiralStack[^1], direction);
var hasIntersection = _rectangles.HasIntersection(rectangle, direction, 0, out var j);
var isTargetOvershot = false;

Choose a reason for hiding this comment

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

давай 82 и 83 строку не будем вычислять отдельно вне цикла, внесем в цикл (мб придется поправить методы и/или заменить на do while)

/// Вспомогательная структура для хранения прямоугольников, отсортированных по координатам сторон,
/// с возможностью получения прямоугольника по индексу в отсортированном списке.
/// </summary>
public class SortedRectanglesList
Copy link

@masssha1308 masssha1308 Nov 24, 2024

Choose a reason for hiding this comment

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

1 - давай перепишем с использованием sortedList
2 - не совсем поняла задумку: почему один и тот же прямоугольник храним четырежды? кажется все взаимодействие с этим классом сводится к проверке пересечения прямоугольников (но это можно проверить и без дублирования листов)

Copy link
Author

Choose a reason for hiding this comment

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

Я когда это решение писал, думал про SortedList, но почему-то подумал, что в нем взятие по индексу происходит за O(log(n)), что мне не подходило. Оказывается, нет.
Эта структура нужна только для оптимизации, чтобы избавиться от постоянной проверки пересечения со всеми прямоугольниками сразу. Она хранит прямоугольники, отсортированные по каждой из сторон, и при проверке на пересечение возвращает еще и индекс пересечения, чтобы потом, когда сдвинем прямоугольник, не проверять все прямоугольники сначала, а с этого индекса.

// 0: первую сторону в первый раз обходит только от изначальной позиции;
// 1-3: 3 другие стороны полностью;
// 4: первую сторону обходит от угла прямоугольника).
for (var i = 0; i < 5; i++)

Choose a reason for hiding this comment

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

кажется здесь i соответствует смене направления? давай заменим связку i + RotateCounterclockwise итерацией по направлениям

Debug.Assert(_rectangles.Count == 1
&& _rectangles.Get(Direction.Left, 0) == _rectanglesSpiralStack[0]);

return GetSecondRectangle(rectangleSize, _rectanglesSpiralStack[0]);

Choose a reason for hiding this comment

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

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

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