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

Добавлена реализация решения задачи по анализу рабочего времени сотрудников #10

Open
wants to merge 1 commit 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
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,25 @@ a30b4d51-11b4-49b2-b356-466e92a66df7 Иванов Иван Иванович 16.0
Примеры входного и выходного файлов приложены к настоящему техническому заданию.

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

Подколзин Алексей Алексеевич
## Описание реализации

Программа предназначена для анализа рабочего времени сотрудников на основе данных из файла report.txt. Она выполняет следующие действия:
1. Программа читает файл report.txt, который содержит записи о списании рабочего времени сотрудниками. Каждая строка файла содержит информацию в формате: <UUID сотрудника> <Фамилия> <Имя> <Отчество> <Дата списания> <Часы>.
2. Программа группирует данные по сотрудникам и суммирует количество отработанных часов за неделю. Сравнивается суммарное количество часов с недельной нормой. Определяется дисбаланс рабочего времени, превышающий 10% от нормы.
3. Сотрудники с отрицательным и положительным дисбалансом записываются в файл result.txt в формате: <Фамилия И.О.> <количество часов с указанием знака>. Сотрудники с отрицательным дисбалансом сортируются в алфавитном порядке и записываются первыми, за ними следуют сотрудники с положительным дисбалансом, также отсортированные по алфавиту.
4. Программа использует файл config.properties для указания путей к входному (report.txt) и выходному (result.txt) файлам.
## Инструкция по сборке и запуску решения
Предварительные требования:
JDK 11 или выше, Maven

1. Клонируйте репозиторий:
git clone https://github.com/theinlaoq/school2024-test-task6.git

2. Измените файл конфигурации
В папке resources проекта измените данные файла config.properties на свои.

3. Соберите проект
В корне проекта выполнить mvn clean install

4. Запустите программу
java -jar target/TestCroc-1.0-SNAPSHOT.jar
38 changes: 38 additions & 0 deletions TestCroc/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
target/

Choose a reason for hiding this comment

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

Молодец, что добавил .gitignore.
сам писал или автоснегерированный?

!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/

### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/

### VS Code ###
.vscode/

### Mac OS ###
.DS_Store
3 changes: 3 additions & 0 deletions TestCroc/.idea/.gitignore

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

413 changes: 413 additions & 0 deletions TestCroc/.idea/dbnavigator.xml

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions TestCroc/.idea/encodings.xml

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

14 changes: 14 additions & 0 deletions TestCroc/.idea/misc.xml

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

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

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

43 changes: 43 additions & 0 deletions TestCroc/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>TestCroc</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>org.example.DisbalanceCounter</mainClass>
<packageName>test</packageName>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.source>20</maven.compiler.source>
<maven.compiler.target>20</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
143 changes: 143 additions & 0 deletions TestCroc/src/main/java/org/example/DisbalanceCounter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package org.example;

import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.stream.*;
import java.util.List;

public class DisbalanceCounter{

private static double weeklyNorm;
private static String reportPath;
private static String resultPath;

public static void main(String[] args) {
Properties properties = new Properties();

//взятие путей к файлам из конфига и обработка ошибок
try(InputStream input = DisbalanceCounter.class.getClassLoader().getResourceAsStream("config.properties");) {
properties.load(input);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
//инициализация путей к файлам
reportPath = properties.getProperty("reportPath");
resultPath = properties.getProperty("resultPath");
//доп проверка
if (reportPath == null || resultPath == null) {
System.out.println("конфигурация должна содержать файлы ввода и вывода");
System.exit(1);
}

try {
//инициализация переменных, для работы с файлами и данными
File reportFile = new File(reportPath);
File resultFile = new File(resultPath);

Path resultPath = resultFile.toPath();
Path reportPath = reportFile.toPath();

//чтение каждой строки из файла в список
List<String> textLines = Files.readAllLines(reportPath);

Choose a reason for hiding this comment

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

тут не принципиально скорее всего, но что если у тебя размер файла превышает размер памяти? Я бы делал через FileReader (погугли примеры)

Map<String, Employee> employeeMap = new HashMap<>();

//сохранение недельной нормы(первая строка файла)
weeklyNorm = Double.parseDouble(textLines.get(0));

Choose a reason for hiding this comment

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

Ты подразумеваешь тут, что у тебя чистые данные. parseDouble throws exception надо обрабатывать


//цикл со 2 строки по списку из строк файла report.txt
//каждая строка разбивается на отдельные данные
//собирается полное имя в соответсвии с выходными данными
//работник помещается в мапу с (K, V) -> (UID, Employee), Employee - статический вложенный класс
for(int i = 1; i < textLines.size(); i++) {
String[] parts = textLines.get(i).split(" ");

Choose a reason for hiding this comment

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

мож ты не доделал еще, но как-будто у тебя схема данных в файле не совсем совпадает с тем, что ты тут процессишь? ID я например в файле вообще не вижу. Использовать пробел в качестве разделителя это опасно (если только это прям не требование), потому что например добавится город в файл, или например фамилия сложная (какой нить Хаджи Магомедов) - твой парсинг посыпется сразу. Используй запятую лучше, csv (comma delimited values) очень распространенный формат данных как раз для таких задач

String id = parts[0];
String lastName = parts[1];
String firstName = parts[2];
String patronymic = parts[3];
String date = parts[4];
double hours = Double.parseDouble(parts[5]);
String fullName = lastName + " " + firstName.charAt(0) + "." + patronymic.charAt(0) + ".";
employeeMap.putIfAbsent(id, new Employee(id, fullName));
employeeMap.get(id).addHours(hours);
}

//создаются два отдельных списка для работников с позитивным и негативным дизбалансом
//открывается поток из мапы, список фильтруется по тз
//сортируется по имени
//к каждому объекту класса Employee применяется метод toString()
//данные собираются в созданный список
List<String> negativeDisbalance = employeeMap.values().stream()
.filter(e -> e.getHours() <= weeklyNorm - (0.1 * weeklyNorm))
.sorted(Comparator.comparing(Employee::getName))
.map(Employee::toString)
.collect(Collectors.toList());

List<String> positiveDisbalance = employeeMap.values().stream()
.filter(e -> e.getHours() >= weeklyNorm + (0.1 * weeklyNorm))
.sorted(Comparator.comparing(Employee::getName))
.map(Employee::toString)
.collect(Collectors.toList());

//результирующий список
List<String> results = new ArrayList<>();
results.addAll(negativeDisbalance);
results.addAll(positiveDisbalance);

//запись списка в файл result.txt с опцией append(файл не будет перезаписываться)
Files.write(resultPath, results, StandardOpenOption.APPEND);

//обработка исключений
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

//вспомогательный класс
static class Employee{

Choose a reason for hiding this comment

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

Почему статик, почему не выделил в отдельный .java file?

private String UID;
private String name;
private double totalHours;

public Employee(String UID, String name) {
this.UID = UID;
this.name = name;
this.totalHours = 0.0;
}

public void addHours(double hours) {
this.totalHours += hours;
}

public String getName() {
return name;
}

public String getUID() {
return UID;
}

public double getHours() {
return totalHours;
}

public double getDisbalance() {
return totalHours - weeklyNorm;
}

@Override
public String toString() {
double disbalance = getDisbalance();
String sign = disbalance > 0 ? "+" : "-";
return String.format("%s %s%.2f", name, sign, Math.abs(disbalance));
}
}
}



2 changes: 2 additions & 0 deletions TestCroc/src/main/resources/config.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
reportPath=your_report_file_path
resultPath=your_result_file_path
8 changes: 6 additions & 2 deletions result.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
Петров А.С. -3
Журавлева Е.А. +4
Петров А.С. -3,00
Журавлева Е.А. +4,00
Петров А.С. -3,00
Журавлева Е.А. +4,00
Петров А.С. -3,00
Журавлева Е.А. +4,00