-
Notifications
You must be signed in to change notification settings - Fork 303
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
base: master
Are you sure you want to change the base?
Ренат Зубакин #207
Conversation
|
||
namespace TagsCloud.ColorGenerators; | ||
|
||
public class RandomColorGenerator: IColorGenerator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Пройдись форматтером по файликам, нужно поправить отступы, после класса должен быть пробел, потом двоеточие, потом снова пробел и класс или интерфейс, от которого наследуешься. В других местах лишние пробелы после ключевых слов или лишние пустые строки в конце файлов. В общем, пофикси, пожалуйста
private double Angle { get; set; } | ||
private double AngleStep { get; set; } | ||
private double RadiusStep { get; set; } | ||
private Point Center { get; set; } | ||
private double Radius { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Приватные свойства пишутся с маленькой буквы
TagsCloud/Entities/Tag.cs
Outdated
using (Graphics g = Graphics.FromImage(new Bitmap(1,1))) | ||
{ | ||
size = g.MeasureString(content, font); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Такие вычисления не должны делаться в конструкторе. Конструктор - это просто способ "собрать" объект на основе тех данных, что пришли ему извне, поэтому в идеале он не должен делать ничего подобного
TagsCloud/Entities/Tag.cs
Outdated
public RectangleF TagRectangle; | ||
public Color Color; | ||
public string Content; | ||
public Font Font; | ||
public SizeF size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Не очень хорошо делать публичные поля - любой, кто захочет, в любой момент выполнения программы сможет их поменять и сломать тебе это поведение
|
||
public class CircularCloudLayouter:ILayouter | ||
{ | ||
public List<Tag> Tags { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
По той же причине не очень хорошо выставлять наружу List, [], HashSet и др
, даже если там будет стоять private set
- да, инициализировать заново ты коллекцию не сможешь, а вот сделать извне layouter.Tags.Add(new Tag)
- вполне - и это сломает выполнение программы
var maxX = tags.Select(rec => rec.TagRectangle.X + rec.TagRectangle.Width / 2).Max(); | ||
var minX = tags.Select(rec => rec.TagRectangle.X - rec.TagRectangle.Width / 2).Min(); | ||
var maxY = tags.Select(rec => rec.TagRectangle.Y + rec.TagRectangle.Height / 2).Max(); | ||
var minY = tags.Select(rec => rec.TagRectangle.Y - rec.TagRectangle.Height / 2).Min(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Можно ли определить эти значения за один проход по коллекции тегов, их ведь могут быть десятки и сотни миллионов, не слишком оптимально получится
|
||
public Tuple<string,int>[] GetWords(string filePath) | ||
{ | ||
var words = File.ReadAllText(filePath).Split('\n'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Давай обработаем все возможные переносы строк, вдруг файл был сохранен на другой системе - \n
и \r\n
public Tuple<string,int>[] GetWords(string filePath) | ||
{ | ||
var words = File.ReadAllText(filePath).Split('\n'); | ||
return words.Where(w=>validator.IsWordValid(w)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.Where
тоже на новую строчку нужно, как и ToArray
ниже
var words = File.ReadAllText(filePath).Split('\n'); | ||
return words.Where(w=>validator.IsWordValid(w)) | ||
.GroupBy(word => word) | ||
.Select(group => Tuple.Create(group.Key, group.Count())).ToArray(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А почему ты используешь тут массив таплов, а не словарь, где ключом будет слово, а значением - его количество?
TagsCloud/Program.cs
Outdated
var o = scope.Resolve<Options>().PartsOfSpeech.Count(); | ||
Console.WriteLine(o); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Эти строчки кажутся тут лишними
TagsCloud/Program.cs
Outdated
var options = CommandLine.Parser.Default.ParseArguments<Options>(args).Value; | ||
var container = ContainerConfig.Configure(options); | ||
|
||
using (var scope = container.BeginLifetimeScope()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Можно подсыпать сахарку немного и написать так:
using var scope = container.BeginLifetimeScope();
Тогда можно будет убрать лишнюю вложенность в фигурных скобках
@@ -0,0 +1,8 @@ | |||
using TagsCloud.WordValidators; | |||
|
|||
namespace TagsCloud.TextReaders; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Неймспейс интерфейса и класса в этой папке не соответствуют ожидаемому (скорее всего просто папку переименовал, а неймспейсы нет)
public double Angle { get; private set; } | ||
public double Radius { get; private set; } | ||
public readonly double AngleStep; | ||
public readonly double RadiusStep; | ||
public readonly Point Center; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А почему часть значений сделана свойствами, а часть - полями?
Давай придерживаться практики, что полями должны быть только зависимости, прилетающие в конструкторе (и возможно некоторые приватные компоненты)
var changes = 1; | ||
while (changes > 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Логика с changes
тут выглядить немного лишней, так как вызов CompressByAxis по идее должен выглядеть как-то так:
rectangle = CompressByAxis(rectangle, true);
rectangle = CompressByAxis(rectangle, false);
Условно - пожали по X, пожали по Y, вроде бы changes
тут даже и не нужно
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
это сделано для того чтобы если мы не можем допустим сдвинуть по X, но можем по Y, проверить можем ли мы после сдвига все таки еще подвинуть по X. Например такая вообразимая ситуация: у нас есть свободное пространство в виде лесенки, где мы можем сместить объект по Х затем по Y, потом опять по X и только если мы будем делать это по очереди, с этой штукой я максимально как бы убеждаюсь, что я максимально возможно сдвинул все к центру. Возможно это немного лишнее, но вот просто в голове возник такой кейс и я решил немного логику усложнить
bottomBorder = bottom < bottomBorder ? bottom : bottomBorder; | ||
} | ||
|
||
private bool CheckIntersection(Rectangle currRectangle) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
От сокращения мы тут даже немного проиграли, чем выиграли, давай полностью пропишем, за читаемость никто по рукам не ударит))
this.backgroundColor = Color.FromName(options.Background); | ||
} | ||
|
||
public void DrawCloud(ILayouter layouter) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Не очень хорошей практикой считается передача зависимостей в методы, лучше получить все то, что тебе нужно непосредственно для работы метода до его вызова, а потом передать это в него вместо зависимости
throw new ArgumentException(); | ||
var bitmapsize = imageSize.IsEmpty ? layouter.GetImageSize() : imageSize; | ||
|
||
using (var bitmap = new Bitmap(bitmapsize.Width, bitmapsize.Height)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Тут можно провернуть аналогичный трюк с using, получится покрасивше
using System.Drawing; | ||
using TagsCloud.ConsoleCommands; | ||
|
||
namespace TagsCloud.WordSizeCalculators; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Неймспейсы класса и интерфейса в папке тоже не совпадают с ожидаемыми
[TestCase(0, 1, TestName = "When_AngleStep_Is_Zero")] | ||
[TestCase(0.6, -1, TestName = "When_Radius_Is_Negative")] | ||
[TestCase(0.6, 0, TestName = "When_Radius_Is_Zero")] | ||
public void SpiralDistribution_Initialize_Throw_ArgumentException(double angleStep, double radiusStep) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Нужно поработать над названиями всех тестов в проекте. Ты придерживаешься подхода
Action_Should..._When/On...
, то естьопределенное действие_должно сделать то-то_при таких то условиях
. Давай рассмотрим это на примере этого теста: тут ты работаешь с конструктором, проверяешь именно его, поэтому Action-Constructor; что должен сделать? должен упасть с эксепшном, поэтому ShouldThrowArgumentException, и условия падения прописаны в тесткейсах, тут норм. В итоге будетConstuctor_ShouldThrowArgumentException
. - Давай подчеркивания использовать только для разделения трех частей в названии. Каждое слово отделять не нужно
No description provided.