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

Шмаков Данил #207

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

Conversation

Reltig
Copy link

@Reltig Reltig commented Dec 2, 2023

No description provided.

@Reltig
Copy link
Author

Reltig commented Dec 2, 2023

@gisinka

@gisinka
Copy link

gisinka commented Dec 5, 2023

Все комменты обсуждаемы - можем обсуждать или в тредах, или в личке в телеге
За количество комментов не парься - это нормально, процесс обучения, повышения скилла, ревью именно для этого и нужно

На пофикшенные комментарии можно ставить реакции или писать пометочки, что сделал и почему

this.deltaAngle = deltaAngle;
currentAngle = 0;
}
public Rectangle GetNextPossibleRectangle(Size size)

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

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

Предполагается, что некоторые Shaper'ы могут использовать Size для просчёта следующей точки, но ладно, убрал.


namespace TagCloud;

public interface ICloudShaper

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

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

Сделал

}

[TestCase(5, 10, 10, 20, 100)]
public void AlwaysFail(int widthMin, int widthMax, int heightMin, int heightMax, int count)

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

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

Этот тест вызывался для проверки, что провалившиеся тесты сохраняются в папку Fails, убрал.


public SpiralCloudShaper(Point center, double coefficient = 1, double deltaAngle = 0.1)
{
this.center = center;

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

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

Сделано

Copy link

Choose a reason for hiding this comment

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

Считаю, что конструктор должен быть максимально простым, никаких проверок внутри не должно быть, его задача - инициализировать объект, если хочешь сделать проверку на входные параметры, то лучше сделать статичный метод который это будет проверять, и потом сам вызовет тебе приватный конструктор,
Ну и декомпозиция, все дела
Да и тесты так как то приятнее писать когда вызываешь какой нибудь метод Create вместо new

Как вариант валидацию выносить в отдельный приватный метод

Copy link
Author

Choose a reason for hiding this comment

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

Сделал через Create

Copy link

Choose a reason for hiding this comment

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

Так же это работает и для других классов

private const string RelativePathToFailDirectory = @"..\..\..\Fails";

private CircularCloudLayouter layouter;
private Point center = new Point(0, 0);

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

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

Убрал

Copy link

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.

Для этого, по крайней мере для SpiralCloudShaper, придётся для каждого прямоугольника возвращать возможные позиции начинаю с центральной точки, а не с последней вычисленной (т.е. функция становиться квадратичной по времени)

Copy link

Choose a reason for hiding this comment

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

Разве в условии есть ограничения на сложность вычислений?

Но ограничение на "Форма итогового облака должна быть близка к кругу с центром в точке center." и "Облако должно быть плотным, чем плотнее, тем лучше."

Кажется, это требование должно быть приоритетнее

Помимо этого, можно придумать сжатие, которое отрабатывает после размещения конкретного прямоугольника

Потести на квадратиках и посмотри, какая картинка получится, должно что-то похожее на это получится
image

Copy link
Author

Choose a reason for hiding this comment

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

Уплотнил, пример в TagCloudTest/Examples

[Test]
public void ThrowException_ThenEmptyOrConainsOneElement()
{
Assert.Throws<ArgumentException>(() => Array.Empty<Rectangle>().HasIntersectedRectangles());

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

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

Разделил


private void SaveIncorrectResultsToJpg()
{
var rectangles = layouter.Rectangles;

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

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

Вынес в TagCloudDrawer

layouter.PutNextRectangle(new Size(1, 1));
layouter.PutNextRectangle(new Size(1, 1));
layouter.Rectangles.Count().Should().Be(2);
NotIntersectedAssetration();

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

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

Исправил

shaper = new SpiralCloudShaper(this.center);
}

public Rectangle PutNextRectangle(Size rectangleSize)

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

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

Сегодня узнал, что возможно создавать Size с отрицательными width и height. Тесты добавил в CloudTests_Should

{
#region TestData

public static IEnumerable<TestCaseData> intersectedRectanglesTestCases =

This comment was marked as resolved.

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

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

Вынес

NotIntersectedAssetration();
}

[TestCase(5, 10, 2, 4, 100)]

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

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

Добавил новые кейсы

Copy link

Choose a reason for hiding this comment

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

А в чем различие тесткейсов? Неочевидно, тогда уж разницу надо в TestName объяснить

Copy link
Author

Choose a reason for hiding this comment

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

Оставил один


using var bitmap = new Bitmap(maxX - minX + 2, maxY - minY + 2);
using var graphics = Graphics.FromImage(bitmap);
graphics.DrawRectangles(new Pen(Color.Red, 1),

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

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

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

[TestCase(-1, 1, TestName = "NegativeCoefficient")]
[TestCase(1, -1, TestName = "NegativeDeltaAngle")]
[TestCase(-1, -1, TestName = "NegativeDeltaAngleAndCoefficient")]
public void Throw_OnCreationWith(double coefficient, double deltaAngle)
Copy link

Choose a reason for hiding this comment

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

А тестирование валидных сценариев?

Copy link

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.

Добавил тесты

Copy link

Choose a reason for hiding this comment

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

Не увидел тесты на уникальность точек


public class IntersectedRectanglesTestCases : IEnumerable
{
private static TestCaseData[] data = new[]

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

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

Сделал, хотя предполагаю, что не совсем правильно понял идею

Copy link

Choose a reason for hiding this comment

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

Да, вот так норм с тесткейссорс, правда имя последовательности можно было понятное дать, но в целом ок

layouter.PutNextRectangle(new Size(1, 1));
layouter.PutNextRectangle(new Size(1, 1));
layouter.Rectangles.Count().Should().Be(2);
NotIntersectedAssertation();
Copy link

@gisinka gisinka Dec 10, 2023

Choose a reason for hiding this comment

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

Assertion тогда уж, но тут лучше оставить layouter.Rectangles.HasIntersectedRectangles().Should().BeFalse();

Благодаря FluentAssertions данная проверка читается легко, как предложение + неявная передача данных через поля ухудшает читаемость и поддержку

Copy link
Author

Choose a reason for hiding this comment

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

Переименовал, но оставил метод, потому что DRY и логика работы NotIntersectedAssertion понятна из названия

.ToArray());

var pathToFile = @$"{RelativePathToFailDirectory}\{TestContext.CurrentContext.Test.FullName}.jpg";
var absolutePath = Path.GetFullPath(pathToFile);

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

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

Декомпозировал

var pathToFile = @$"{RelativePathToFailDirectory}\{TestContext.CurrentContext.Test.FullName}.jpg";
var absolutePath = Path.GetFullPath(pathToFile);
bitmap.Save(pathToFile);
Console.WriteLine($"Tag cloud visualization saved to file {absolutePath}");
Copy link

@gisinka gisinka Dec 10, 2023

Choose a reason for hiding this comment

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

Если ты про задание 3, то такой код будет писать в консоль сохранение любой раскладки, а там просилось сохранение раскладок упавших тестов

Copy link
Author

Choose a reason for hiding this comment

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

Не уверен, что это принципиально важно, т.к. метод и так запускается только после упавших тестов

Copy link

Choose a reason for hiding this comment

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

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


namespace TagCloud;

public static class TagCloudDrawer

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

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

Сделал через интерфейс

{
private const string RelativePathToFailDirectory = @"..\..\..\Fails";

public static void Draw(CircularCloudLayouter layouter)

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

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

Исправил

rectangles.Select(rect => rect with { X = -minX + rect.X, Y = -minY + rect.Y })
.ToArray());

var pathToFile = @$"{RelativePathToFailDirectory}\{TestContext.CurrentContext.Test.FullName}.jpg";
Copy link

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.

Комментировал выше

[TestCase(1, 1, 100, TestName = "WithSquareShape")]
[TestCase(20, 10, 100, TestName = "WithRectangleShape")]
public void AddManyRectangles_WithConstantSize(int width, int height, int count)
{
Copy link

@gisinka gisinka Dec 10, 2023

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.

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

Copy link

Choose a reason for hiding this comment

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

А на плотность?

{
return rectangles
.SelectMany(
(x, i) => rectangles.Skip(i + 1),
Copy link

@gisinka gisinka Dec 12, 2023

Choose a reason for hiding this comment

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

Слишком сложно, rectangles.Any(rectangle.IntersectsWith) для проверки пересечения текущего прямоугольника с последовательностью или пересечение пар layout.Any(x => layout.Any(y => x.IntersectsWith(y) && x != y));


public static class Extensions
{
public static IEnumerable<Tuple<T, T>> CartesianProduct<T>(this IEnumerable<T> source)
Copy link

Choose a reason for hiding this comment

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

Неиспользуемое - можно удалить

{
this.center = center;
rectangles = new List<Rectangle>();
shaper = SpiralCloudShaper.Create(this.center);
Copy link

@gisinka gisinka Dec 12, 2023

Choose a reason for hiding this comment

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

Зачем делать интерфейс и жестко привязываться к реализации в конструкторе? Через конструктор можно принимать ICloudShaper

Copy link

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