From e9266148167e7e7482b9a00f9e3dd7b23ab7b81a Mon Sep 17 00:00:00 2001 From: StasYarikov Date: Mon, 20 May 2024 14:43:54 +0300 Subject: [PATCH 1/3] First commit --- .gitignore | 29 +++++++++++++++++++++++++++++ .idea/.gitignore | 8 ++++++++ .idea/misc.xml | 6 ++++++ .idea/modules.xml | 8 ++++++++ .idea/vcs.xml | 6 ++++++ enteringTaskKROK.iml | 11 +++++++++++ src/Main.java | 5 +++++ 7 files changed, 73 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 enteringTaskKROK.iml create mode 100644 src/Main.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f68d109 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..4444b22 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..f3f6851 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/enteringTaskKROK.iml b/enteringTaskKROK.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/enteringTaskKROK.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/Main.java b/src/Main.java new file mode 100644 index 0000000..3e59c38 --- /dev/null +++ b/src/Main.java @@ -0,0 +1,5 @@ +public class Main { + public static void main(String[] args) { + System.out.println("Hello world!"); + } +} \ No newline at end of file From cb9902a177c04bbee116b66b51459b0437438c20 Mon Sep 17 00:00:00 2001 From: StasYarikov Date: Tue, 21 May 2024 16:01:34 +0300 Subject: [PATCH 2/3] Final --- README.md | 23 +++++++++++++ src/Main.java | 35 +++++++++++++++++++- src/Top3Contributors.java | 68 +++++++++++++++++++++++++++++++++++++++ src/files/commits.txt | 9 ++++++ src/files/paths.txt | 2 ++ src/files/result.txt | 3 ++ 6 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 src/Top3Contributors.java create mode 100644 src/files/commits.txt create mode 100644 src/files/paths.txt create mode 100644 src/files/result.txt diff --git a/README.md b/README.md index a2bc0aa..f03fa1d 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,29 @@ CodeKiller777 ## Автор решения +Яриков Станислав Сергеевич + ## Описание реализации +Решение реализовано с помощью двух классов: Main и Top3Contributors. +### Работа с файлами в классе Main +В первом классе в методе main реализован вход в программу: чтение коммитов из файла построчно в список, вызов статического метода нахождения самых популярных кодеров из класса Top3Contributors и запись имен топовых контрибьютеров в файл. + +Методы: + +_+ main(String[] args): void_ (статический, реализует чтение коммитов из файла, вызов метода по обработке коммитов и записи топовых контрибьютеров в файл) + +### Обработка коммитов в классе Top3Contributors +Класс Top3Contributors содержит в себе приватный статический метод оценки корректности коммитов и публичный статический метод нахождения наиболее активных контрибьютеров, который и вызывается из main, а также статические неизменяемые поля настроек требуемых данных. + +Методы: + +_+findByCommitsCount(List allCommits): List_ (статический, проверяет данные на корректность и формирует список из имен самых топовых контрибьютеров) + +_-validation(String commit): boolean_ (проверяет, валиден ли коммит) + +В реализации используются ООП, java streams, парсинг текстов, методы чтения и записи данных в файлы и из них, обработка исключений. ## Инструкция по сборке и запуску решения +В проекте по пути src/files/ лежит текстовый файл paths.txt, хранящий в себе путь к commits.txt и result.txt построчно. По умолчанию пути: "src/files/commits.txt" и "src/files/result.txt". + +Точка входа в программу в классе Main в методе main(String[] args): src/Main diff --git a/src/Main.java b/src/Main.java index 3e59c38..ec205bd 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,5 +1,38 @@ +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; + public class Main { + public static void main(String[] args) { - System.out.println("Hello world!"); + + try { + // чтение путей файла чтения и файла записи в список + List paths = Files.readAllLines(Paths.get("src/files/paths.txt")); + + // чтение строк из файла "commits.txt" в список + List allCommits = Files.readAllLines(Paths.get(paths.getFirst())); + + // вызов статического метода класса Top3Contributors для нахождения наиболее активных участников + // по количеству коммитов + List topContributors = Top3Contributors.findByCommitsCount(allCommits); + + BufferedWriter writer = new BufferedWriter(new FileWriter(paths.getLast())); + for (String contributor: topContributors) { + writer.write(contributor + "\n"); + } + // закрытие потока записи + writer.close(); + + } catch (IOException e) { + if (e.toString().contains("commits.txt")) + System.out.println("Error reading commits.txt"); + else + System.out.println("Error writing result.txt"); + e.getMessage(); + } } } \ No newline at end of file diff --git a/src/Top3Contributors.java b/src/Top3Contributors.java new file mode 100644 index 0000000..2181d76 --- /dev/null +++ b/src/Top3Contributors.java @@ -0,0 +1,68 @@ +import java.text.ParseException; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.text.SimpleDateFormat; + +public class Top3Contributors { + + private static final int kolElem = 3; + private static final int hashLength = 7; + private static final String dateFormat = "yyyy-MM-dd"; + private static final String timeFormat = "HH:mm:ss"; + + public static List findByCommitsCount(List allCommits) { + + // Получаем мапу с валидными коммитами с ключами из имен пользователей + // и значениями - количеством их коммитов + Map commitCounts = allCommits.stream() + .filter(Top3Contributors::validation) + .map((e) -> e.split(" ")[0]) + .collect(Collectors.groupingBy(String::valueOf, Collectors.counting())); + + // сортируем по убыванию количества коммитов и возвращаем 3 самых первых + return commitCounts.entrySet().stream() + .sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue())) + .limit(3) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + } + + // метод для проверки коммитов на правильность формата данных + private static boolean validation(String commit) throws IllegalArgumentException { + + boolean ind = true; + + String[] splitCommit = commit.split(" "); + + // Проверка, состоит ли строка коммита из 3 элементов + if (splitCommit.length != kolElem) { + return false; + } + + // Проверка, начинается ли имя пользователя с цифр + if (Character.isDigit(splitCommit[0].charAt(0))) { + return false; + } + + // Проверка, состоит ли сокращенный хэш коммита из 7 символов в нижнем регистре + if (splitCommit[1].length() != hashLength || !splitCommit[1].equals(splitCommit[1].toLowerCase())) { + return false; + } + + // Проверка, соответсвует ли формат даты и времени требуемым + if (splitCommit[2].length() > 10 && splitCommit[2].charAt(10) != 'T') + return false; + try { + SimpleDateFormat format = new SimpleDateFormat(); + format.applyPattern(dateFormat); + format.parse(splitCommit[2].substring(0, 10)); + format.applyPattern(timeFormat); + format.parse(splitCommit[2].substring(11)); + } catch (ParseException e) { + return false; + } + + return ind; + } +} diff --git a/src/files/commits.txt b/src/files/commits.txt new file mode 100644 index 0000000..b95e41c --- /dev/null +++ b/src/files/commits.txt @@ -0,0 +1,9 @@ +AIvanov 25ee001 2024-04-24T13:56:39.492 +Anatoliy2024 212ec01 2024-05-10T12:26:39.142 +AIvanov 21ew001 2024-05-04T12:16:19.492 +AKalinin 25ec001 2024-04-24T13:56:39.492 +Anatoliy2024 25ec001 2024-04-23T11:56:29.492 +AKalinin 25ec001 2024-04-13T09:56:39.492 +KrisVal 25ec001 2024-04-24T13:56:39.492 +KrisVal 25ec001 2024-04-24T13:56:39.492 +AIIIvanov 25ec001 2024-04-24T13:56:39.492 \ No newline at end of file diff --git a/src/files/paths.txt b/src/files/paths.txt new file mode 100644 index 0000000..cda884a --- /dev/null +++ b/src/files/paths.txt @@ -0,0 +1,2 @@ +src/files/commits.txt +src/files/result.txt \ No newline at end of file diff --git a/src/files/result.txt b/src/files/result.txt new file mode 100644 index 0000000..f25be8b --- /dev/null +++ b/src/files/result.txt @@ -0,0 +1,3 @@ +AIvanov +AKalinin +KrisVal From c9744520e39758df022053beb598a14d9c41ede5 Mon Sep 17 00:00:00 2001 From: StasYarikov Date: Wed, 22 May 2024 09:58:29 +0300 Subject: [PATCH 3/3] Fixed --- src/Main.java | 14 +++++++++----- src/Top3Contributors.java | 4 ++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Main.java b/src/Main.java index ec205bd..b5a46e1 100644 --- a/src/Main.java +++ b/src/Main.java @@ -9,9 +9,16 @@ public class Main { public static void main(String[] args) { + // чтение путей файла чтения и файла записи в список + List paths = null; try { - // чтение путей файла чтения и файла записи в список - List paths = Files.readAllLines(Paths.get("src/files/paths.txt")); + paths = Files.readAllLines(Paths.get("src/files/paths.txt")); + } catch (IOException e) { + System.out.println("Error reading paths.txt"); + throw new RuntimeException(e); + } + + try (BufferedWriter writer = new BufferedWriter(new FileWriter(paths.getLast()))) { // чтение строк из файла "commits.txt" в список List allCommits = Files.readAllLines(Paths.get(paths.getFirst())); @@ -20,12 +27,9 @@ public static void main(String[] args) { // по количеству коммитов List topContributors = Top3Contributors.findByCommitsCount(allCommits); - BufferedWriter writer = new BufferedWriter(new FileWriter(paths.getLast())); for (String contributor: topContributors) { writer.write(contributor + "\n"); } - // закрытие потока записи - writer.close(); } catch (IOException e) { if (e.toString().contains("commits.txt")) diff --git a/src/Top3Contributors.java b/src/Top3Contributors.java index 2181d76..5adc211 100644 --- a/src/Top3Contributors.java +++ b/src/Top3Contributors.java @@ -6,7 +6,7 @@ public class Top3Contributors { - private static final int kolElem = 3; + private static final int elemCount = 3; private static final int hashLength = 7; private static final String dateFormat = "yyyy-MM-dd"; private static final String timeFormat = "HH:mm:ss"; @@ -36,7 +36,7 @@ private static boolean validation(String commit) throws IllegalArgumentException String[] splitCommit = commit.split(" "); // Проверка, состоит ли строка коммита из 3 элементов - if (splitCommit.length != kolElem) { + if (splitCommit.length != elemCount) { return false; }