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

Косторной Дмитрий #32

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7e4d7a8
Создал проекты
Kostornoj-Dmitrij Dec 25, 2024
21e6ae9
Добавил классы для считывания слов из .txt формата
Kostornoj-Dmitrij Dec 25, 2024
571c9c6
Добавил классы кругового алгоритма разметки
Kostornoj-Dmitrij Dec 25, 2024
23f435f
Добавил классы для обработки текста
Kostornoj-Dmitrij Dec 25, 2024
4d4f218
Добавил класс и интерфейс для круговой разметки облака тегов
Kostornoj-Dmitrij Dec 25, 2024
19d6a0f
Добавил класс тега и классы для разметки тегов
Kostornoj-Dmitrij Dec 25, 2024
7c7fdf6
Добавил классы и интерфейс для генератора цветов
Kostornoj-Dmitrij Dec 25, 2024
f69f15d
Добавил классы и интерфейс для сохранения файлов (изображений)
Kostornoj-Dmitrij Dec 25, 2024
3fc9f4a
Добавил классы и интерфейс для рисования изображений
Kostornoj-Dmitrij Dec 25, 2024
b7bc873
Добавил класс для создания облака тегов
Kostornoj-Dmitrij Dec 25, 2024
a6304fc
Вспомнил и переименовал проект обратно
Kostornoj-Dmitrij Dec 25, 2024
766f0cf
Добавил класс опций для командной строки, сделал один градус константой
Kostornoj-Dmitrij Dec 25, 2024
efb0a79
Добавил классы для считывания слов из doc и docx форматов
Kostornoj-Dmitrij Dec 25, 2024
8d51d52
Добавил di-контейнер для регистрации зависимостей
Kostornoj-Dmitrij Dec 25, 2024
373baca
Добавил тесты для CircularCloudLayouter и CircularLayout
Kostornoj-Dmitrij Dec 26, 2024
2d94720
Добавил файл со скучными словами
Kostornoj-Dmitrij Dec 26, 2024
f1b2627
Изменил Program, исправил namespace в CommandLineOptions
Kostornoj-Dmitrij Dec 26, 2024
60b271a
Исправил ошибки
Kostornoj-Dmitrij Dec 26, 2024
cf743fe
Добавил тесты для считывания разных форматов
Kostornoj-Dmitrij Dec 26, 2024
84d1ede
Добавил слова для основного облака тегов
Kostornoj-Dmitrij Dec 26, 2024
ddcd546
Исправления
Kostornoj-Dmitrij Dec 26, 2024
326bf3c
Фиксы неправильно работающих тестов
Kostornoj-Dmitrij Dec 26, 2024
9dab01d
Финальные исправления, добавил результат выполнения с командами на см…
Kostornoj-Dmitrij Dec 26, 2024
105de9f
Добавил информацию в выбросы исключений
Kostornoj-Dmitrij Dec 27, 2024
fcf59f2
Перенёс запуск приложения в отдельный метод
Kostornoj-Dmitrij Dec 27, 2024
455f5e1
Заменил регулярное выражение на split
Kostornoj-Dmitrij Dec 27, 2024
a4c4cc3
Добавил класс с кастомными названиями цветов
Kostornoj-Dmitrij Dec 27, 2024
2bdb449
Добавил проверку строки формата на null или пустоту
Kostornoj-Dmitrij Dec 27, 2024
2bef965
Сгруппировал настройки, относящиеся к реализации алгоритма
Kostornoj-Dmitrij Dec 27, 2024
0af9f1b
Убрал неиспользуемый using
Kostornoj-Dmitrij Dec 27, 2024
b3256dd
Пофиксил генерацию рандомного цвета
Kostornoj-Dmitrij Dec 27, 2024
e3486ed
Добавил автоматическую обрезку границ до облака
Kostornoj-Dmitrij Dec 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
492 changes: 492 additions & 0 deletions TagsCloudVisualization/BoringWords.txt

Large diffs are not rendered by default.

39 changes: 39 additions & 0 deletions TagsCloudVisualization/CloudLayouters/CircularCloudLayouter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Drawing;
using TagsCloudVisualization.Layouts;

namespace TagsCloudVisualization.CloudLayouters;

public class CircularCloudLayouter : ICircularCloudLayouter
{
private readonly ILayout _layout;
private readonly List<Rectangle> _rectangles = [];

public CircularCloudLayouter(ILayout layout)
{
_layout = layout;
}

public Rectangle PutNextRectangle(Size rectangleSize)
{
Rectangle rectangle;

do
{
var nextPoint = _layout.CalculateNextPoint();

var rectanglePosition = nextPoint - rectangleSize / 2;

rectangle = new Rectangle(rectanglePosition, rectangleSize);

} while (IsIntersectWithOtherRectangles(rectangle));

_rectangles.Add(rectangle);

return rectangle;
}

private bool IsIntersectWithOtherRectangles(Rectangle rectangle)
{
return _rectangles.Any(addedRectangle => addedRectangle.IntersectsWith(rectangle));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Drawing;

namespace TagsCloudVisualization.CloudLayouters;

public interface ICircularCloudLayouter
{
Rectangle PutNextRectangle(Size rectangleSize);
}
31 changes: 31 additions & 0 deletions TagsCloudVisualization/ColorGetter/ColorGetter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Drawing;
using TagsCloudVisualization.Properties;

namespace TagsCloudVisualization.ColorGetter;

public class ColorGetter : IColorGetter
{
private readonly ColorGetterProperties _colorGetterProperties;
private readonly Random _random;

public ColorGetter(ColorGetterProperties colorGetterProperties)
{
_colorGetterProperties = colorGetterProperties;
_random = new Random();
}

public Color GetColor()
{
if (_colorGetterProperties.ColorName == "random")

Choose a reason for hiding this comment

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

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

{
return Color.FromArgb(_random.Next(255), _random.Next(255), _random.Next(255));
}

if (WellKnownColors.Colors.TryGetValue(_colorGetterProperties.ColorName, out var customColor))
{
return customColor;
}

return Color.FromName(_colorGetterProperties.ColorName);
}
}
8 changes: 8 additions & 0 deletions TagsCloudVisualization/ColorGetter/IColorGetter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Drawing;

namespace TagsCloudVisualization.ColorGetter;

public interface IColorGetter
{
Color GetColor();
}
22 changes: 22 additions & 0 deletions TagsCloudVisualization/ColorGetter/WellKnownColors.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Drawing;

namespace TagsCloudVisualization.ColorGetter;

public static class WellKnownColors
{
public static readonly Dictionary<string, Color> Colors = new()
{
{ "customRed", Color.FromArgb(200, 30, 30) },
{ "customGreen", Color.FromArgb(30, 200, 30) },
{ "customBlue", Color.FromArgb(30, 30, 200) },
{ "customYellow", Color.FromArgb(230, 230, 50) },
{ "customCyan", Color.FromArgb(50, 230, 230) },
{ "customMagenta", Color.FromArgb(230, 50, 230) },
{ "customBlack", Color.FromArgb(30, 30, 30) },
{ "customWhite", Color.FromArgb(250, 250, 250) },
{ "customGray", Color.FromArgb(100, 100, 100) },
{ "customOrange", Color.FromArgb(255, 140, 0) },
{ "customPurple", Color.FromArgb(150, 0, 150) },
{ "customBrown", Color.FromArgb(150, 75, 0) },
};
}
66 changes: 66 additions & 0 deletions TagsCloudVisualization/DiConfiguration/DiContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using Autofac;
using TagsCloudVisualization.CloudLayouters;
using TagsCloudVisualization.ColorGetter;
using TagsCloudVisualization.Handlers;
using TagsCloudVisualization.Layouts;
using TagsCloudVisualization.Options;
using TagsCloudVisualization.Properties;
using TagsCloudVisualization.Readers;
using TagsCloudVisualization.TagLayouters;
using TagsCloudVisualization.Visualization;

namespace TagsCloudVisualization.DiConfiguration;

public class DiContainer
{
public static IContainer Configure(CommandLineOptions options)
{
var builder = new ContainerBuilder();

builder.RegisterType<CircularLayout>().As<ILayout>();
builder.RegisterType<CircularCloudLayouter>().As<ICircularCloudLayouter>();
builder.RegisterType<ColorGetter.ColorGetter>().As<IColorGetter>();
builder.RegisterType<TxtReader>().As<IReader>();
builder.RegisterType<DocReader>().As<IReader>();
builder.RegisterType<DocxReader>().As<IReader>();
builder.RegisterType<CommonImageDrawer>().As<IImageDrawer>();
builder.RegisterType<CommonImageSaver>().As<IImageSaver>();
builder.RegisterType<TextHandler>().As<ITextHandler>();
builder.RegisterType<TagLayouter>().As<ITagLayouter>();
builder.RegisterType<TagsCloudMaker>();

builder.RegisterType<TextHandlerProperties>().WithParameters([
new NamedParameter("pathToBoringWords", options.PathToBoringWords),
new NamedParameter("pathToText", options.PathToText)
]);

builder.RegisterType<ColorGetterProperties>().WithParameters([
new NamedParameter("colorName", options.Color)
]);

builder.RegisterType<SaveProperties>().WithParameters([
new NamedParameter("filePath", options.PathToSaveDirectory),
new NamedParameter("fileName", options.FileName),
new NamedParameter("fileFormat", options.FileFormat)
]);

builder.RegisterType<ImageProperties>().WithParameters([
new NamedParameter("width", options.ImageWidth),
new NamedParameter("height", options.ImageHeight),
new NamedParameter("colorName", options.BackgroundColor)
]);

builder.RegisterType<CircularLayoutProperties>().WithParameters([
new NamedParameter("AngleIncreasingStep", options.SpiralLayout.AngleIncreasingStep),
new NamedParameter("RadiusIncreasingStep", options.SpiralLayout.RadiusIncreasingStep)
]);

builder.RegisterType<TagLayouterProperties>().WithParameters([
new NamedParameter("fontName", options.Font),
new NamedParameter("minSize", options.MinFontSize),
new NamedParameter("maxSize", options.MaxFontSize)
]);

return builder.Build();
}
}
6 changes: 6 additions & 0 deletions TagsCloudVisualization/Handlers/ITextHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace TagsCloudVisualization.Handlers;

public interface ITextHandler
{
Dictionary<string, int> GetWordsCount();
}
54 changes: 54 additions & 0 deletions TagsCloudVisualization/Handlers/TextHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using TagsCloudVisualization.Readers;
using TagsCloudVisualization.Properties;

namespace TagsCloudVisualization.Handlers;

public class TextHandler : ITextHandler
{
private readonly IReader[] _readers;
private readonly TextHandlerProperties _properties;

public TextHandler(IReader[] readers, TextHandlerProperties properties)
{
_readers = readers;
_properties = properties;
}

public Dictionary<string, int> GetWordsCount()
{
var reader = GetReader(_properties.PathToText);
var words = reader.Read(_properties.PathToText);
var boringWordsReader = GetReader(_properties.PathToBoringWords);
var boringWords = boringWordsReader.Read(_properties.PathToBoringWords).ToHashSet();
var wordsCount = new Dictionary<string, int>();

foreach (var word in words.Select(word => word.ToLower()))
{
if (wordsCount.TryGetValue(word, out var value))
{
wordsCount[word] = ++value;
continue;
}

if (!boringWords.Contains(word))
{
wordsCount[word] = 1;
}
}

return words

Choose a reason for hiding this comment

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

Еще вкину чисто на подумать. Слова могут иметь разную форму. "сделал" и "сделали" у тебя будут как 2 разных слова записаны. Возможно стоит приводить их к начальной форме. Есть например вот такая либа (для русского языка) - https://yandex.ru/dev/mystem/ . Ну или можно свои эвристики для этого какие-то придумать

.Select(word => word.ToLower())
.Where(word => !boringWords.Contains(word))
.GroupBy(word => word)
.ToDictionary(group => group.Key, group => group.Count())
.OrderByDescending(pair => pair.Value)
.ToDictionary(pair => pair.Key, pair => pair.Value);
}

private IReader GetReader(string path)
{
var reader = _readers.FirstOrDefault(r => r.CanRead(path));

return reader ?? throw new ArgumentException($"There is no file in {path}");
}
}
Binary file added TagsCloudVisualization/Images/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions TagsCloudVisualization/Layouts/CircularLayout.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using TagsCloudVisualization.Properties;
using System.Drawing;

namespace TagsCloudVisualization.Layouts;

public class CircularLayout : ILayout
{
private readonly Point _center;
private readonly double _angleIncreasingStep;
private readonly int _radiusIncreasingStep;
private double _circleAngle;
private double _circleRadius;

public CircularLayout(CircularLayoutProperties properties)
{
if (properties.AngleIncreasingStep == 0)
throw new ArgumentException($"AngleIncreasingStep should not be zero. Provided value: {properties.AngleIncreasingStep}");

if (properties.RadiusIncreasingStep <= 0)

This comment was marked as resolved.

throw new ArgumentException($"RadiusIncreasingStep should be positive. Provided value: {properties.RadiusIncreasingStep}");

_center = new Point(0, 0);
_radiusIncreasingStep = properties.RadiusIncreasingStep;
_angleIncreasingStep = properties.AngleIncreasingStep;
}

public Point CalculateNextPoint()
{
var x = _center.X + (int)(_circleRadius * Math.Cos(_circleAngle));
var y = _center.Y + (int)(_circleRadius * Math.Sin(_circleAngle));

_circleAngle += _angleIncreasingStep;
if (_circleAngle > 2 * Math.PI || _circleRadius == 0)
{
_circleAngle = 0;
_circleRadius += _radiusIncreasingStep;
}

return new Point(x, y);
}
}
8 changes: 8 additions & 0 deletions TagsCloudVisualization/Layouts/ILayout.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Drawing;

namespace TagsCloudVisualization.Layouts;

public interface ILayout
{
Point CalculateNextPoint();
}
45 changes: 45 additions & 0 deletions TagsCloudVisualization/Options/CommandLineOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using CommandLine;

namespace TagsCloudVisualization.Options;

public class CommandLineOptions
{
[Option('t', "pathToText", Default = "textForCloud.txt", HelpText = "Path to text for tags cloud")]
public string? PathToText { get; set; }

[Option('s', "pathToSaveDirectory", Default = "/Images",
HelpText = "Where we will save images to")]
public string? PathToSaveDirectory { get; set; }

[Option('n', "fileName", Default = "image", HelpText = "Name of the file to save")]
public string? FileName { get; set; }

[Option('b', "backgroundColor", Default = "white", HelpText = "Color of image background")]
public string? BackgroundColor { get; set; }

[Option("color", Default = "random", HelpText = "Color of the words (Random by default)")]
public string? Color { get; set; }

[Option("fileFormat", Default = "png", HelpText = "Format of file to save (.png by default)")]
public string? FileFormat { get; set; }

[Option("imageWidth", Default = 1920, HelpText = "Width of image")]
public int ImageWidth { get; set; }

[Option("imageHeight", Default = 1080, HelpText = "Height of image")]
public int ImageHeight { get; set; }

[Option("pathToBoringWords", Default = "BoringWords.txt", HelpText = "Path to boring words for skip")]
public string? PathToBoringWords { get; set; }

[Option("font", Default = "Times New Roman", HelpText = "Font of the words")]
public string? Font { get; set; }

[Option("minFontSize", Default = 10, HelpText = "Minimum font size for word")]
public int MinFontSize { get; set; }

[Option("maxFontSize", Default = 50, HelpText = "Maximum word font size for word")]
public int MaxFontSize { get; set; }

public SpiralLayoutOptions SpiralLayout { get; set; } = new SpiralLayoutOptions();
}
14 changes: 14 additions & 0 deletions TagsCloudVisualization/Options/SpiralLayoutOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using CommandLine;
using TagsCloudVisualization.Properties;

namespace TagsCloudVisualization.Options;

public class SpiralLayoutOptions
{
[Option("angleIncreasingStep", Default = CircularLayoutProperties.OneDegree,
HelpText = "Delta angle for the spiral")]
public double AngleIncreasingStep { get; set; }

[Option("radiusIncreasingStep", Default = 1, HelpText = "Delta radius for the spiral")]
public double RadiusIncreasingStep { get; set; }
}
Loading