итоговая версия проекта

комитить каждую функцию так себе идея учитывая маштабы проекта
This commit is contained in:
teabag 2026-04-18 11:38:45 +03:00
parent 4a45166c01
commit 6f01b26dfe

200
main.py
View File

@ -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()