From 6f01b26dfeb50b747ce9ed5531e7d08a99e8484e Mon Sep 17 00:00:00 2001 From: teabag Date: Sat, 18 Apr 2026 11:38:45 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B8=D1=82=D0=BE=D0=B3=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D1=8F=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D0=B5=D0=BA=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit комитить каждую функцию так себе идея учитывая маштабы проекта --- main.py | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 189 insertions(+), 11 deletions(-) diff --git a/main.py b/main.py index 2c94bc6..814a3ec 100644 --- a/main.py +++ b/main.py @@ -1,10 +1,10 @@ # 1. Читает текстовый файл с данными (каждая строка: имя,отдел,зарплата,стаж). # Возвращает список словарей: [{"name": str, "dept": str, "salary": float, "exp": float}, ...]. -from sys import exec_prefix + def load_data(filepath: str) -> list[dict]: employees = [] - filepath = "data/employees.txt" + #filepath = "data/employees.txt" try: with open(filepath, "r", encoding="utf-8") as file: for line_number, line in enumerate(file, 1): @@ -40,44 +40,222 @@ def load_data(filepath: str) -> list[dict]: return employees + # 2. Возвращает новый список, содержащий только сотрудников указанного отдела. def filter_by_department(employees: list[dict], department: str) -> list[dict]: - pass + filtered_list = [] + + if not isinstance(employees, list): + print("Ошибка: на вход филтру должен подаваться только список") + return [] + + for emp in employees: # По каждому сотруднику в исходном списке + # чекаем совпадает ли отдел, убираем пробелы и приводим к одному регистру на всякий пожарный + if emp.get ('dept', '').strip().lower() == department.strip().lower(): + filtered_list.append(emp) + + return filtered_list + + # 3. Возвращает новый список с сотрудниками, чей стаж (exp) не меньше min_years. def filter_by_experience(employees: list[dict], min_years: float) -> list[dict]: - pass + experienced_staff = [] + + # вдруг там не список + if not isinstance(employees, list): + print("Ошибка: На вход ожидался список сотрудников.") + return [] + + for emp in employees: + try: + # вытаскиваем стаж и смотрим чтоб не меньше мин ерс + if emp.get('exp', 0) >= min_years: + experienced_staff.append(emp) + + except TypeError: # Если в ехр лежит не число + print(f"Ошибка: Некорректный формат стажа у сотрудника {emp.get('name')}") + continue + return experienced_staff + + # 4. Вычисляет среднюю зарплату по переданному списку сотрудников. Если список пуст, возвращает 0.0. def calculate_average_salary(employees: list[dict]) -> float: - pass + # проверяем пустой ли список + if not employees: + return 0.0 + + total_sum = 0.0 + + # Сумируем зарплату каждого сотрудника + for emp in employees: + total_sum += emp.get('salary', 0.0) # get чтоб не упасть если ключа нет + + average = total_sum / len(employees) + return float(average) # 5. Возвращает словарь сотрудника с максимальной зарплатой. При пустом списке возвращает None. def find_highest_paid(employees: list[dict]) -> dict | None: - pass + if not employees: + return None + + highest_paid_emp = employees[0] + + for emp in employees: + if emp.get("salary", 0) > highest_paid_emp.get('salary', 0): + highest_paid_emp = emp + return highest_paid_emp + + # 6. Группирует сотрудников по отделам. Возвращает словарь, где ключ – название отдела, # значение – список сотрудников этого отдела. def group_by_department(employees: list[dict]) -> dict[str, list[dict]]: - pass + departments = {} + + for emp in employees: + dept_name = emp.get('dept', 'Unknown') + + # если такого отдела нет, создаём для него пустой список + if dept_name not in departments: + departments[dept_name] = [] + + departments[dept_name].append(emp) # добавляем текущего сотрудника в список его отдела + return departments + + # 7. Увеличивает значение salary каждого сотрудника в переданном списке на bonus_percent процентов. # Изменяет исходные словари (модификация на месте). Функция ничего не возвращает. def add_bonus(employees: list[dict], bonus_percent: float) -> None: - pass + # в кефах удобнее + multiplier = 1 + (bonus_percent / 100) + + for emp in employees: + if "salary" in emp: + emp["salary"] = round(emp["salary"] * multiplier, 2) # раунд тут если чё чтоб не вылезло чудо по типу 0.0000001 + # 8. Принимает словарь одного сотрудника, возвращает отформатированную строку: # "Имя: {name}, Отдел: {dept}, Зарплата: {salary:.2f} руб., Стаж: {exp} лет". def format_employee_string(employee: dict) -> str: - pass + formatted_str = ( + f"Имя: {employee.get('name', 'Не указано')}, " + f"Отдел: {employee.get('dept', 'Не указано')}, " + f"Зарплата: {employee.get('salary', 0.0):.2f} руб., " + f"Стаж: {employee.get('exp', 0)} лет" + ) + + return formatted_str # 9. Возвращает новый список сотрудников, отсортированный по зарплате # (по возрастанию, если reverse=False, иначе по убыванию). def sort_by_salary(employees: list[dict], reverse: bool = False) -> list[dict]: - pass + if not employees or not isinstance(employees, list): # Если пустой или ваще не список - вернём как есть + return [] + + sorted_list = sorted( + employees, + key=lambda emp: emp.get('salary', 0.0), + reverse=reverse + ) + + return sorted_list # 10. Сохраняет в файл по пути filepath текстовый отчёт: # для каждого сотрудника – строка, полученная функцией format_employee_string(). # Если список пуст, записывает строку "Нет данных". def save_report(employees: list[dict], filepath: str) -> None: - pass + try: + with open(filepath, "w", encoding="utf-8") as file: + # 1. Если список пуст, пишем "Нет данных" + if not employees: + file.write("Нет данных\n") + else: + # 2. Проходим по каждому сотруднику + for emp in employees: + # Используем твою функцию форматирования + line = format_employee_string(emp) + # Записываем строку и добавляем перенос на новую строку + file.write(line + "\n") + print(f"Отчет успешно сохранен в файл: {filepath}") + + except Exception as e: + print(f"Ошибка при сохранении файла: {e}") + + +def main(): + # Главная функция, демонстрирующая работу всех функций обработки данных сотрудников + + print("=" * 37) + print("ОБРАБОТКА ДАННЫХ СОТРУДНИКОВ КОМПАНИИ") + print("=" * 37) + + # 1. Загружаем данные из файла + filepath = "data/employees.txt" + print(f"\n1. Загрузка данных из файла '{filepath}'...") + employees = load_data(filepath) + print(f" Загружено сотрудников: {len(employees)}") + for emp in employees: + print(f" - {emp['name']}, отдел: {emp['dept']}") + + # 2. Демонстрация filter_by_experience - сотрудники со стажем >= 5 лет + print("\n2. Сотрудники со стажем >= 5 лет:") + experienced = filter_by_experience(employees, 5.0) + if experienced: + for emp in experienced: + print(f" - {emp['name']} (стаж: {emp['exp']} лет)") + else: + print(" Нет сотрудников с таким стажем.") + + # 3. Фильтруем сотрудников отдела Sales + print("\n3. Фильтрация сотрудников отдела 'Sales'...") + sales_employees = filter_by_department(employees, "Sales") + print(f" Найдено сотрудников в отделе Sales: {len(sales_employees)}") + + # 4. Назначаем бонус 10% сотрудникам отдела Sales + print("\n4. Начисление бонуса 10% сотрудникам отдела Sales...") + add_bonus(sales_employees, 10.0) + print(" Бонус начислен. Зарплаты после бонуса:") + for emp in sales_employees: + print(f" - {emp['name']}: {emp['salary']:.2f} руб.") + + # 5. Сортируем сотрудников Sales по убыванию зарплаты + print("\n5. Сортировка сотрудников Sales по убыванию зарплаты...") + sorted_sales = sort_by_salary(sales_employees, reverse=True) + print(" Отсортированный список:") + for emp in sorted_sales: + print(f" - {emp['name']}: {emp['salary']:.2f} руб.") + + # 6. Вычисляем среднюю зарплату после бонуса + print("\n6. Средняя зарплата в отделе Sales после бонуса:") + avg_salary = calculate_average_salary(sorted_sales) + print(f" {avg_salary:.2f} руб.") + + # 7. Находим сотрудника с самой высокой зарплатой + print("\n7. Сотрудник с самой высокой зарплатой в отделе Sales:") + highest_paid = find_highest_paid(sorted_sales) + if highest_paid: + print(f" {highest_paid['name']} - {highest_paid['salary']:.2f} руб.") + + # 8. Группируем ВСЕХ сотрудников по отделам и выводим количество + print("\n8. Группировка всех сотрудников по отделам:") + grouped = group_by_department(employees) + for dept, staff in grouped.items(): + print(f" Отдел '{dept}': {len(staff)} чел.") + for emp in staff: + print(f" - {emp['name']}") + + # 9. Сохраняем итоговый отчёт по отделу Sales + print("\n9. Сохранение отчёта по отделу Sales...") + report_path = "report_sales.txt" + save_report(sorted_sales, report_path) + + print("\n" + "=" * 60) + print("ОБРАБОТКА ЗАВЕРШЕНА") + print("=" * 60) + + +if __name__ == "__main__": + main() \ No newline at end of file