Skip to content

Actual Project Version (10/05/24) #9

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/CrocTestTask2024.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

101 changes: 99 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,105 @@ CodeKiller777

Ручной ввод пути к файлу (через консоль, через правку переменной в коде и т.д.) недопустим. Необходимость любых ручных действий с файлами в процессе работы программы будут обнулять решение.

## Автор решения

## Описание реализации

Сам проект небольшой, содержит всего два класса: ``Main`` и ``Commits``.

### 1. ``Commits``

#### Атрибуты:
* ``nickname`` типа ``String`` — хранит никнейм сделавшего коммит, не может быть изменена после создания;
* ``commitDate`` типа ``LocalDateTime`` — хранит дату и время последнего коммита того или иного человека;
* ``commitCount`` типа ``int`` — хранит количество коммитов, сделанным тем или иным человеком.

У них всех идентификатор доступа ``private`` (согласно принципу инкапсуляции в ООП).

#### Методы:
Для каждого из полей есть по геттеру, а сеттеры есть только у ``commitDate`` и ``commitCount``, так как ``nickname`` — неизменяемая переменная.

#### Создание нового объекта:
При создании нового объекта в конструктор обязательно нужно внести два значения:
* никнейм человека;
* дату и время коммита.

Счетчик инициализируется автоматически.

### 2. ``Main``

Стоит упомянуть про принцип отбора трех отличившихся в спринте.
Первенство отдается тому, кто сделал больше всего коммитов.
Но если возникла такая ситуация,
что претендентов на почетные места больше, чем самих почетных мест (например, первое и второе места определены однозначно, а на третье претендует два человека с одинаковым количеством коммитов),
то учитывается дата и время подачи последнего коммита (вплоть до миллисекунд).

Это не самый справедливый метод, но важно соблюсти условие про трех победителей спринта (хоть в реальности и возможно, что какое-то место делят двое-трое).
Тем более, у нас не имеется информация о победителях прошлого спринта (иначе можно было бы сделать что-то типа накопленного рейтинга).

Также стоит объяснить отсутствие проверки данных тем, что данные создаются автоматически, а не человеком.
Если в данных есть ошибка, то это проблема генератора, и их надо править на той стороне.

Что насчет самого класса, там нет переменных (только если внутри методов),
так что есть смысл рассмотреть только сами методы.

* #### ``public static void main(String[] args)``

Самый главный метод, отправная точка программы.
Открывает поток ``BufferedReader``,
передавая все операции с ним функции ``getBufferedReader()``,
затем его закрывает.

* #### ``BufferedReader getBufferedReader()``

Создает контейнер ``data`` типа ``ArrayList``.
Открывает поток чтения данных из файла ``commits.txt`` (в программе есть этот файл чисто для примера).
Затем читает построчно данные из файла в цикле.
В ``data`` добавляется новый никнейм вместе с датой и временем коммита, если его там не обнаружено,
и дополняется свежей датой вместе с обновлением счетчика коммитов, если человек уже записан. В этом помогает метод ``isInData``.
Контейнер передается функции ``writeResults``.

После выполнения всех функций возвращает поток ``BufferedReader`` (который затем закрывается в методе ``main``).

* #### ``isInData(ArrayList<Commits> data, String nick)``

Ищет наличие человека в контейнере по никнейму.
Возвращает индекс, под которым находятся о нем данные,
и ``-1``, если ничего не найдено.

* #### `` public static void writeResults(ArrayList<Commits> data)``

Открывает поток записи в файл ``result.txt``.
Получает с помощью метода ``getResults`` трех победителей в виде массива строк (``String[]``) и печатает их в файл.
Выводит в консоль сообщение успешности об записи в файл.
При успешном варианте еще и выводит путь к файлу ``result.txt``.

* #### ``public static String[] getResults (ArrayList<Commits> data)``

Если контейнер ``data``, принятый методом, пустой, то возвращается массив строк с одной записью: ``"Победителей нет."``.

Если в контейнере всего одна запись, тогда возвращается массив строк с одним никнеймом.

Программа сортирует ``data`` по убыванию по параметрам ``getCommitsCount`` и ``getCommitDate``.
Затем создается массив строк ``ans``.

Если размер контейнера равен двум, то вносится две записи в ``ans``. Иначе — все три.
Затем метод возвращает ``ans``.

## Инструкция по сборке и запуску решения

Как выполнить программу:
1) открыть консоль;
2) убедиться, что файл ``commits.txt`` находится в папке src проекта: ``..\CrocTestTask2024\test_project\src``;
3) в этой же папке (перейти в нее можно с помощью команды ``cd``) скомпилировать программу командой ``javac Main.java``;
4) запустить программу командой ``java Main``.

Если консоль пишет, что не знает команду ``javac``, тогда нужно:

*(для Windows)*
1) установить JDK (https://www.oracle.com/java/technologies/downloads/#jdk21-windows);
2) *(если все еще не заработало)* перейти в: Параметры -> Система -> О программе -> Дополнительные параметры системы -> Переменные среды — создать новую системную переменную JAVA_HOME, указав для нее путь папки с ранее установленной JDK;
3) проверить, что javac теперь работает должным образом.

*(для Linux)*
* обычно консоль сразу пишет, какую команду надо выполнить для установки необходимых компонент (например, ``sudo apt install default-jdk``).

Результат работы: если консоль не вернула сообщение с ошибкой, то создается файл result.txt в рабочей папке. Путь к этому файлу будет также выведен в консоль.
29 changes: 29 additions & 0 deletions test project/.gitignore
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions test project/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions test project/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions test project/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions test project/commits.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
JSmith 3a7b2f4 2023-09-11T08:24:17.123
MMiller c8e9a1d 2022-11-30T15:42:59.876
LWilson 6f1a8e2 2021-05-02T10:10:05.321
KBrown 9d3c7b5 2020-12-15T18:37:45.654
RJones 1b5e8d7 2019-07-28T09:56:32.987
JGarcia f2c4e6a 2018-03-19T14:20:55.234
APerez a9b3c5d 2017-06-10T16:48:39.765
EAdams 4e7f2a1 2016-01-25T11:30:20.098
DScott b8d3e9c 2015-08-03T22:45:13.432
THall e1f4b7c 2014-04-12T07:59:48.876
SYoung 7c2f9a3 2013-10-29T19:12:37.219
NGonzalez 2d5a8c6 2012-12-05T13:28:59.543
REvans h6j9k2l 2011-06-18T08:36:40.876
CClark p3q7r5s 2010-02-23T17:50:25.345
BAllen x4z8y3w 2009-09-01T21:04:11.678
QBaker l9m4n7o 2008-05-04T12:15:33.987
VGomez u5v8w3x 2007-03-08T23:40:59.123
HHernandez i1j5k8l 2006-01-12T06:55:42.456
YMorris n4o7p2q 2005-08-27T14:33:27.789
UKing r8s3t6u 2004-04-09T09:18:50.234
3 changes: 3 additions & 0 deletions test project/result.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
JSmith
MMiller
LWilson
Binary file added test project/src/Commits.class
Binary file not shown.
27 changes: 27 additions & 0 deletions test project/src/Commits.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class Commits
{
private final String nickname;
private LocalDateTime commitDate;
private int commitsCount;

public Commits(String n, LocalDateTime date)
{
this.nickname = n;
this.commitDate = date;
this.commitsCount = 1;
}

public void setCommitsCount (int i) { this.commitsCount = i; }
public void setCommitDate (LocalDateTime date)
{
if (date.isAfter(this.commitDate)) this.commitDate = date;
}
public int getCommitsCount() { return commitsCount; }

public LocalDateTime getCommitDate() { return commitDate; }
public String getNickname() { return nickname; }
}
Binary file added test project/src/Main.class
Binary file not shown.
104 changes: 104 additions & 0 deletions test project/src/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import java.io.*;
import java.lang.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;

public class Main {
public static void main(String[] args)
{
//файл commits.txt должен лежать в одной папке с приложением
try {
BufferedReader bufferedReader = getBufferedReader();
bufferedReader.close();
} catch (IOException e) {
System.err.println("Ошибка чтения файла: " + e.getMessage());
}
}
//считаем, что раз файл commits.txt создается сам, то проверку данных не устраиваем
public static BufferedReader getBufferedReader() throws IOException
{
ArrayList<Commits> data = new ArrayList<>();
File file = new File("commits.txt");
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);

String line;
while ((line = bufferedReader.readLine()) != null)
{
String[] tmp = line.split(" ");
//на дату проверять не надо
//так как владеем информацией только по поводу последнего спринта
int targetIndex = isInData(data, tmp[0]);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
LocalDateTime tempDate = LocalDateTime.parse(tmp[2], formatter);
if (targetIndex == -1) data.add(new Commits(tmp[0], tempDate));
else
{
data.get(targetIndex).setCommitsCount(data.get(targetIndex).getCommitsCount() + 1);
data.get(targetIndex).setCommitDate(LocalDateTime.parse(tmp[2], formatter));
//увеличиваем счетчик коммитов на 1 и дату на более актуальную (проверяется в сеттере)
}
}
writeResults(data);
return bufferedReader;
}

public static int isInData(ArrayList<Commits> data, String nick)
{
for (int i = 0; i < data.size(); i++)
if (data.get(i).getNickname().equals((nick)))
return i;
return -1;
}

//здесь можно рассмотреть все случаи первенств
//три случая первенства: очевидное; больше трех людей в равных ситуациях; людей слишком мало (два человека)
//— и результаты уже записать в results.txt
//насчет второго случая: пусть выше в приоритете те, кто сделал коммит позже
//логика такая: человек, сделавший один коммит в начале спринта, почти наверняка сделал меньше (и неважно, если он опоздал на пару минут со вторым коммитом)
//чем тот, кто сделал коммит в конце спринта
public static void writeResults(ArrayList<Commits> data) throws FileNotFoundException
{
try {
FileOutputStream outputStream = new FileOutputStream("result.txt");
String[] result = getResults(data);
for (String i : result)
{
outputStream.write(i.getBytes());
outputStream.write("\n".getBytes());
}
outputStream.close();
System.out.println("Файл успешно записан: " + new File("result.txt").getAbsolutePath());
} catch (IOException e) {
System.err.println("Ошибка при записи файла: " + e.getMessage());
}
}

public static String[] getResults (ArrayList<Commits> data)
{
if (data.isEmpty()) return new String[] {"Победителей нет."};
else if (data.size() == 1) return new String[] {data.get(0).getNickname()};

data.sort(Comparator
.comparing(Commits::getCommitsCount).reversed()
.thenComparing(Commits::getCommitDate, Comparator.reverseOrder()));

String[] ans;
if (data.size() == 2)
{
ans = new String[2];
for (int i = 0; i < 2; i++)
ans[i] = data.get(i).getNickname();
}

else
{
ans = new String[3];
for (int i = 0; i < 3; i++)
ans[i] = data.get(i).getNickname();
}
return ans;
}
}
20 changes: 20 additions & 0 deletions test project/src/commits.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
JSmith 3a7b2f4 2023-09-11T08:24:17.123
MMiller c8e9a1d 2022-11-30T15:42:59.876
LWilson 6f1a8e2 2021-05-02T10:10:05.321
KBrown 9d3c7b5 2020-12-15T18:37:45.654
RJones 1b5e8d7 2019-07-28T09:56:32.987
JGarcia f2c4e6a 2018-03-19T14:20:55.234
APerez a9b3c5d 2017-06-10T16:48:39.765
EAdams 4e7f2a1 2016-01-25T11:30:20.098
DScott b8d3e9c 2015-08-03T22:45:13.432
THall e1f4b7c 2014-04-12T07:59:48.876
SYoung 7c2f9a3 2013-10-29T19:12:37.219
NGonzalez 2d5a8c6 2012-12-05T13:28:59.543
REvans h6j9k2l 2011-06-18T08:36:40.876
CClark p3q7r5s 2010-02-23T17:50:25.345
BAllen x4z8y3w 2009-09-01T21:04:11.678
QBaker l9m4n7o 2008-05-04T12:15:33.987
VGomez u5v8w3x 2007-03-08T23:40:59.123
HHernandez i1j5k8l 2006-01-12T06:55:42.456
YMorris n4o7p2q 2005-08-27T14:33:27.789
UKing r8s3t6u 2004-04-09T09:18:50.234
3 changes: 3 additions & 0 deletions test project/src/result.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
JSmith
MMiller
LWilson
Loading