итоговая версия проекта
комитить каждую функцию так себе идея учитывая маштабы проекта
This commit is contained in:
parent
4a45166c01
commit
6f01b26dfe
200
main.py
200
main.py
@ -1,10 +1,10 @@
|
|||||||
# 1. Читает текстовый файл с данными (каждая строка: имя,отдел,зарплата,стаж).
|
# 1. Читает текстовый файл с данными (каждая строка: имя,отдел,зарплата,стаж).
|
||||||
# Возвращает список словарей: [{"name": str, "dept": str, "salary": float, "exp": float}, ...].
|
# Возвращает список словарей: [{"name": str, "dept": str, "salary": float, "exp": float}, ...].
|
||||||
from sys import exec_prefix
|
|
||||||
|
|
||||||
def load_data(filepath: str) -> list[dict]:
|
def load_data(filepath: str) -> list[dict]:
|
||||||
employees = []
|
employees = []
|
||||||
filepath = "data/employees.txt"
|
#filepath = "data/employees.txt"
|
||||||
try:
|
try:
|
||||||
with open(filepath, "r", encoding="utf-8") as file:
|
with open(filepath, "r", encoding="utf-8") as file:
|
||||||
for line_number, line in enumerate(file, 1):
|
for line_number, line in enumerate(file, 1):
|
||||||
@ -40,44 +40,222 @@ def load_data(filepath: str) -> list[dict]:
|
|||||||
return employees
|
return employees
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 2. Возвращает новый список, содержащий только сотрудников указанного отдела.
|
# 2. Возвращает новый список, содержащий только сотрудников указанного отдела.
|
||||||
def filter_by_department(employees: list[dict], department: str) -> list[dict]:
|
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.
|
# 3. Возвращает новый список с сотрудниками, чей стаж (exp) не меньше min_years.
|
||||||
def filter_by_experience(employees: list[dict], min_years: float) -> list[dict]:
|
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.
|
# 4. Вычисляет среднюю зарплату по переданному списку сотрудников. Если список пуст, возвращает 0.0.
|
||||||
def calculate_average_salary(employees: list[dict]) -> float:
|
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.
|
# 5. Возвращает словарь сотрудника с максимальной зарплатой. При пустом списке возвращает None.
|
||||||
def find_highest_paid(employees: list[dict]) -> dict | 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. Группирует сотрудников по отделам. Возвращает словарь, где ключ – название отдела,
|
# 6. Группирует сотрудников по отделам. Возвращает словарь, где ключ – название отдела,
|
||||||
# значение – список сотрудников этого отдела.
|
# значение – список сотрудников этого отдела.
|
||||||
def group_by_department(employees: list[dict]) -> dict[str, list[dict]]:
|
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 процентов.
|
# 7. Увеличивает значение salary каждого сотрудника в переданном списке на bonus_percent процентов.
|
||||||
# Изменяет исходные словари (модификация на месте). Функция ничего не возвращает.
|
# Изменяет исходные словари (модификация на месте). Функция ничего не возвращает.
|
||||||
def add_bonus(employees: list[dict], bonus_percent: float) -> None:
|
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. Принимает словарь одного сотрудника, возвращает отформатированную строку:
|
# 8. Принимает словарь одного сотрудника, возвращает отформатированную строку:
|
||||||
# "Имя: {name}, Отдел: {dept}, Зарплата: {salary:.2f} руб., Стаж: {exp} лет".
|
# "Имя: {name}, Отдел: {dept}, Зарплата: {salary:.2f} руб., Стаж: {exp} лет".
|
||||||
def format_employee_string(employee: dict) -> str:
|
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. Возвращает новый список сотрудников, отсортированный по зарплате
|
# 9. Возвращает новый список сотрудников, отсортированный по зарплате
|
||||||
# (по возрастанию, если reverse=False, иначе по убыванию).
|
# (по возрастанию, если reverse=False, иначе по убыванию).
|
||||||
def sort_by_salary(employees: list[dict], reverse: bool = False) -> list[dict]:
|
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 текстовый отчёт:
|
# 10. Сохраняет в файл по пути filepath текстовый отчёт:
|
||||||
# для каждого сотрудника – строка, полученная функцией format_employee_string().
|
# для каждого сотрудника – строка, полученная функцией format_employee_string().
|
||||||
# Если список пуст, записывает строку "Нет данных".
|
# Если список пуст, записывает строку "Нет данных".
|
||||||
def save_report(employees: list[dict], filepath: str) -> None:
|
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()
|
||||||
Loading…
Reference in New Issue
Block a user