# 1. Читает текстовый файл с данными (каждая строка: имя,отдел,зарплата,стаж). # Возвращает список словарей: [{"name": str, "dept": str, "salary": float, "exp": float}, ...]. def load_data(filepath: str) -> list[dict]: employees = [] #filepath = "data/employees.txt" try: with open(filepath, "r", encoding="utf-8") as file: for line_number, line in enumerate(file, 1): # Чищу строку от пробелов по краям и скипаю пустые строки, а то хз кто там этот емплоес.тииксти писал line = line.strip() if not line: continue try: # делим строку по запятой parts = [p.strip() for p in line.split(",")] # зачем нейронки если всю эту строку мне пайчарм вставил после знака равно??? if len(parts) != 4: # ну вдруг там не 4 колонки print(f"Ошибка в строке {line_number}: надо 4 значения, а получил {len(parts)}.") continue employee = { "name": parts[0], "dept": parts[1], "salary": float(parts[2]), "exp": float(parts[3]) } employees.append(employee) except ValueError as e: print(f"Ошибка преобразования типов в строке {line_number}: {e}") except FileNotFoundError: print(f"Ошибка: Файл по адресу '{filepath}' не найден.") except Exception as e: print(f"Произошла непредвиденная ошибка: {e}") return employees # 2. Возвращает новый список, содержащий только сотрудников указанного отдела. def filter_by_department(employees: list[dict], department: str) -> list[dict]: 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]: 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: # проверяем пустой ли список 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: 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]]: 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: # в кефах удобнее 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: 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]: 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: 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()