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

Мажирин Александр #252

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

Conversation

Kexogg
Copy link

@Kexogg Kexogg commented Nov 13, 2024

No description provided.

</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.2"/>

Choose a reason for hiding this comment

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

Точно нужна эта зависимость здесь?


public CircularCloudLayouter(SKPoint center)
{
rectangles = [];

Choose a reason for hiding this comment

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

Да, но так лучше не делать.

  1. IDE младше 2024 это не распознают - плохо
  2. Создаём вроде список, а инициализируем около массив (стилистическая придирка)

Я бы рекомендовал всё-таки явно использовать new List<SKRect>()

public CircularCloudLayouter(SKPoint center)
{
rectangles = [];
positionGenerator = new SpiralLayoutPositionGenerator(center);

Choose a reason for hiding this comment

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

А вот здесь уже важно. Это получается жёсткая связь с использование генератора. Такое необходимо пробрасывать через конструктор в виде интерфейса. Блок по DI у вас будет позже, но я бы рекомендовал уже сейчас это посмотреть. Пример статьи про di в целом https://habr.com/ru/companies/hh/articles/783002/

Сейчас достаточно просто вынести интерфейс в конструктор, а при создании класса явно передавать в него new SpiralLayoutPositionGenerator

Copy link
Author

Choose a reason for hiding this comment

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

Поправлю. Сделал так, потому что по условию в HomeExercise.md сигнатура конструктора - CircularCloudLayouter(Point center).

Choose a reason for hiding this comment

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

Написал в ЛС


public interface IPositionGenerator
{
public SKPoint GetNextPosition();

Choose a reason for hiding this comment

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

У методов интерфейсов не принято писать модификатор доступа, по умолчанию он всегда public


namespace TagsCloudVisualization.PositionGenerator;

public class SpiralLayoutPositionGenerator(SKPoint center, double step = 0.01) : IPositionGenerator

Choose a reason for hiding this comment

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

Интересная конструкция )
Наблюдение: не 2024 райдер такое не поддерживает
Важный момент 1: в данном случае мы не можем добавлять модификатор доступа к этим полям. Очевидно, что center и step должны быть readonly, так как их нельзя изменять по ходу работы. Но здесь они просто компилируются как private. Потенциальное место для ошибки в большом проекте.
Важный момент 2: рекомендуется использовать primary конструктор только в классах, которые не содержать ничего больше в себе. Например в DataClasses. В противном случае высок риск ошибки

[TestCase(2, 0.019601332f, 0.0039733867f)]
[TestCase(50, 0.1418311f, -0.47946215f)]
[TestCase(100, -0.8390715f, -0.5440211f)]
public void GetNextPosition_ReturnsCorrectPosition_OnSubsequentCalls(int iterations, float x, float y)

Choose a reason for hiding this comment

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

Лучше x и y назвать expectedX и expectedY

Comment on lines 34 to 42
public void GetNextPosition_ReturnsCorrectPosition_WithNonZeroCenter()
{
var center = new SKPoint(10, 10);
var generator = new SpiralLayoutPositionGenerator(center, 0.1);

var position = generator.GetNextPosition();

position.Should().Be(new SKPoint(10, 10));
}

Choose a reason for hiding this comment

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

Выглядит как копия теста 1. Можно в него добавить просто несколько кейсов

Comment on lines 34 to 42
public void GetNextPosition_ReturnsCorrectPosition_WithNonZeroCenter()
{
var center = new SKPoint(10, 10);
var generator = new SpiralLayoutPositionGenerator(center, 0.1);

var position = generator.GetNextPosition();

position.Should().Be(new SKPoint(10, 10));
}

Choose a reason for hiding this comment

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

Выглядит как копия теста 1. Можно в него добавить просто несколько кейсов

}

[Test]
public void GetNextPosition_ReturnsCorrectPosition_WithDifferentStep()

Choose a reason for hiding this comment

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

Давай лучше укажем Specified, different не очень понятен

}

[Test]
public void GetNextPosition_ReturnsCorrectPosition_WithNonZeroCenter_OnSusequentCalls()

Choose a reason for hiding this comment

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

)
image

Comment on lines 25 to 32
if (TestContext.CurrentContext.Result.Outcome.Status != TestStatus.Failed) return;

if (!Directory.Exists("tests"))
Directory.CreateDirectory("tests");
var filename = "tests/layouter_" + TestContext.CurrentContext.Test.ID + ".png";
var renderer = new Renderer(new SKSize(1000, 1000));
renderer.CreateRectangles(layouter.GetRectangles());
renderer.CreateImage(filename);


if (TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Failed)
{
var filename = "tests/layouter_" + TestContext.CurrentContext.Test.ID + ".png";
SaveImage(filename);
}

Choose a reason for hiding this comment

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

if (!a) return
if (a) Foo()

Похоже, логика дублируется
А ещё имя файла можно унести в тот же метод сохранения, назвав как-нибудь SaveTestResultImage()

Comment on lines 33 to 56

[Test]
public void Constructor_ShouldCreateLayouter()
private SKSize[] GetRandomSizes(int count)
{
layouter.Should().NotBeNull();
var random = new Random();
var sizes = new SKSize[count];
for (var i = 0; i < count; i++)
{
var size = new SKSize(random.Next(10, 100), random.Next(10, 100));
sizes[i] = size;
}
return sizes;

Choose a reason for hiding this comment

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

Этот метод можно сделать ленивым, добавив yield конструкцию. Учитываю, что везде дальше он именно в таком ключе и используется. Урок

}

var maxDistanceFromCenter = rectangles.Max(DistanceToCenter);
const int expectedMaxDistance = 500;

Choose a reason for hiding this comment

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

Логика его определения всё равно осталась довольно сложной (через константу плотности и арифметику), но теперь точно стало лучше

Comment on lines 45 to 49
var image = renderer.GetEncodedImage();
using var stream = File.OpenWrite(DefaultFileName);
image.SaveTo(stream);

Assert.That(File.Exists(DefaultFileName));

Choose a reason for hiding this comment

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

Даже если нам вернётся пустое изображение, файл создастся. Давай лучше проверять, что возвращаемый объект не пуст

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