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

Реализация функции анализа дизбаланса списаний #14

Open
wants to merge 4 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.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

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

4 changes: 4 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.

10 changes: 10 additions & 0 deletions .idea/school2024-test-task6.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/vcs.xml

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

49 changes: 48 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,55 @@ a30b4d51-11b4-49b2-b356-466e92a66df7 Иванов Иван Иванович 16.0

Примеры входного и выходного файлов приложены к настоящему техническому заданию.

# Анализ Дизбаланса Списаний Времени

## Автор решения
**ФИО**: Шилович Платон Юрьевич

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

## Инструкция по сборке и запуску решения
Программа для анализа дизбаланса списаний времени за рабочую неделю. Программа считывает данные из входного файла `report.txt`, рассчитывает дизбаланс времени для каждого сотрудника и сохраняет результаты в выходной файл `result.txt`.

### Основные этапы реализации:

1. **Чтение данных из файла**:
- Функция `read_report(file_path)` читает входной файл `report.txt`, извлекает недельную норму списаний и записи о списаниях сотрудников. Входной файл должен содержать информацию в формате:
```
<недельная норма>
<id сотрудника> <Фамилия> <Имя> <Отчество> <Дата списания> <количество часов>
```
- Первая строка файла указывает недельную норму списаний, а последующие строки содержат записи о списаниях сотрудников.

2. **Вычисление дизбаланса**:
- Функция `calculate_disbalance(weekly_norm, records)` обрабатывает записи, суммирует часы для каждого сотрудника и вычисляет дизбаланс (разницу между фактическими списаниями и недельной нормой). Дизбаланс считается значительным, если он превышает 10% от недельной нормы.
- Используются два словаря: `employee_hours` для хранения суммарных часов и `employee_info` для хранения информации о сотрудниках (ФИО).

3. **Запись результатов в файл**:
- Функция `write_result(disbalance, employee_info, output_file)` сортирует сотрудников по фамилии и записывает их в выходной файл `result.txt` в формате:
```
<Фамилия И.О.> <количество часов>
```
- Сначала записываются сотрудники с отрицательным дизбалансом, затем - с положительным.

### Структура кода:

- `read_report(file_path)`: Чтение входного файла и извлечение данных.
- `calculate_disbalance(weekly_norm, records)`: Вычисление дизбаланса времени для каждого сотрудника.
- `write_result(disbalance, employee_info, output_file)`: Запись результатов в выходной файл.
- `main()`: Основная функция, управляющая процессом выполнения.

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

### Требования:

- Python 3.x

### Запуск программы:

1. **Клонирование репозитория**:
```bash
git clone https://github.com/PlatonShilovich/school2024-test-task6.git
cd school2024-test-task6
1. **Запуск программы**:
```bash
python main.py
79 changes: 79 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
def read_report(file_path):
# Открываем файл для чтения в режиме чтения текста с кодировкой UTF-8.
with open(file_path, 'r', encoding='utf-8') as file:
# Читаем все строки из файла и сохраняем их в список.
lines = file.readlines()
# Первая строка содержит недельную норму списаний, конвертируем её в целое число.
weekly_norm = int(lines[0].strip())
# Создаём генератор, который будет возвращать список слов для каждой строки, начиная со второй.
records = (line.strip().split() for line in lines[1:])
# Возвращаем недельную норму и генератор записей.
return weekly_norm, records


def calculate_disbalance(weekly_norm, records):
# Создаём пустой словарь для хранения суммарных часов для каждого сотрудника.
employee_hours = {}
# Создаём пустой словарь для хранения информации о сотрудниках.
employee_info = {}
for record in records:
# Извлекаем поля из записи.
employee_id, surname, name, patronymic, date, hours = record[0], record[1], record[2], record[3], record[
4], float(record[5])
# Если employee_id отсутствует в словаре employee_hours, инициализируем его значением 0.0.
if employee_id not in employee_hours:
employee_hours[employee_id] = 0.0
# Также сохраняем информацию о сотруднике в словарь employee_info.
employee_info[employee_id] = (surname, name, patronymic)
# Добавляем часы к суммарным часам сотрудника.
employee_hours[employee_id] += hours

# Порог для определения дизбаланса (10% от недельной нормы).
threshold = weekly_norm * 0.1
# Создаём словарь с дизбалансом, фильтруя сотрудников с разницей больше порога.
disbalance = {employee_id: total_hours - weekly_norm
for employee_id, total_hours in employee_hours.items()
if abs(total_hours - weekly_norm) > threshold}
# Возвращаем словарь с дизбалансом и информацию о сотрудниках.
return disbalance, employee_info


def write_result(disbalance, employee_info, output_file):
# Сортируем и форматируем сотрудников с отрицательным дизбалансом.
negative_disbalance = sorted(
(
f"{employee_info[employee_id][0]} {employee_info[employee_id][1][0]}.{employee_info[employee_id][2][0]}. {int(hours)}"
for employee_id, hours in disbalance.items()
if hours < 0), key=lambda x: x.split()[0])
# Сортируем и форматируем сотрудников с положительным дизбалансом.
positive_disbalance = sorted(
(
f"{employee_info[employee_id][0]} {employee_info[employee_id][1][0]}.{employee_info[employee_id][2][0]}. +{int(hours)}"
for employee_id, hours in disbalance.items()
if hours > 0), key=lambda x: x.split()[0])

# Открываем файл для записи в режиме записи текста с кодировкой UTF-8.
with open(output_file, 'w', encoding='utf-8') as file:
# Записываем сотрудников с отрицательным дизбалансом.
for entry in negative_disbalance:
file.write(f"{entry}\n")
# Записываем сотрудников с положительным дизбалансом.
for entry in positive_disbalance:
file.write(f"{entry}\n")


def main():
# Задаём имена входного и выходного файлов.
input_file = 'report.txt'
output_file = 'result.txt'
# Читаем недельную норму и записи из входного файла.
weekly_norm, records = read_report(input_file)
# Вычисляем дизбаланс и получаем информацию о сотрудниках.
disbalance, employee_info = calculate_disbalance(weekly_norm, records)
# Записываем результаты в выходной файл.
write_result(disbalance, employee_info, output_file)


# Запускаем основную функцию, если файл исполняется как скрипт.
if __name__ == "__main__":
main()