145 lines
4.9 KiB
Python
145 lines
4.9 KiB
Python
import math
|
|
from decimal import Decimal, InvalidOperation
|
|
|
|
|
|
class Worker:
|
|
def __init__(self, surname: str, position: str, salary: float):
|
|
self.surname = None
|
|
self.position = None
|
|
self.salary = None
|
|
self.set_surname(surname)
|
|
self.set_position(position)
|
|
self.set_salary(salary)
|
|
|
|
# -----------------------
|
|
# проверка фамилии
|
|
def set_surname(self, surname: str):
|
|
self.surname = self.validate_surname(surname)
|
|
|
|
@staticmethod
|
|
def validate_surname(surname: str) -> str:
|
|
surname = surname.strip()
|
|
if len(surname) < 2:
|
|
raise ValueError("Фамилия слишком короткая")
|
|
if not surname.isalpha():
|
|
raise ValueError("Фамилия должна содержать только буквы")
|
|
return surname.capitalize()
|
|
|
|
# проверка должности
|
|
def set_position(self, position: str):
|
|
self.position = self.validate_position(position)
|
|
|
|
@staticmethod
|
|
def validate_position(position: str) -> str:
|
|
position = position.strip()
|
|
if len(position) < 2:
|
|
raise ValueError("Должность слишком короткая")
|
|
if not all(x.isalpha() or x.isspace() for x in position):
|
|
raise ValueError("Должность должна содержать только буквы и пробелы")
|
|
return position.lower()
|
|
|
|
# проверка оклада
|
|
def set_salary(self, salary: float):
|
|
self.salary = self.validate_salary(salary)
|
|
|
|
@staticmethod
|
|
def validate_salary(salary: float) -> float:
|
|
if not isinstance(salary, (int, float)):
|
|
raise ValueError("Оклад должен быть числом")
|
|
if not math.isfinite(salary):
|
|
raise ValueError("Оклад не может быть NaN или бесконечностью")
|
|
|
|
salary_decimal = Decimal(str(salary))
|
|
if salary_decimal.as_tuple().exponent < -2:
|
|
raise ValueError("Оклад должен содержать не более 2 знаков после запятой")
|
|
|
|
if salary < 1000:
|
|
raise ValueError("Оклад слишком маленький (<1000)")
|
|
if salary > 10_000_000:
|
|
raise ValueError("Оклад слишком большой (>10_000_000)")
|
|
return float(salary)
|
|
|
|
# метод №1 — увеличить оклад на 15%
|
|
def increase_salary(self):
|
|
self.salary *= 1.15
|
|
|
|
# метод №2 — если фамилия начинается с "Иван", присвоить должность "инженер"
|
|
def assign_engineer_if_ivan(self):
|
|
if self.surname.lower().startswith("иван"):
|
|
self.position = "инженер"
|
|
|
|
# строка информации об объекте
|
|
def info(self) -> str:
|
|
return f"Фамилия: {self.surname}, Должность: {self.position}, Оклад: {self.salary:.2f}"
|
|
|
|
|
|
# -----------------------
|
|
# функции ввода с проверкой
|
|
def input_surname() -> str:
|
|
while True:
|
|
surname = input("Введите фамилию: ").strip()
|
|
try:
|
|
return Worker.validate_surname(surname)
|
|
except ValueError as e:
|
|
print("Ошибка:", e)
|
|
|
|
|
|
def input_position() -> str:
|
|
while True:
|
|
position = input("Введите должность: ").strip()
|
|
try:
|
|
return Worker.validate_position(position)
|
|
except ValueError as e:
|
|
print("Ошибка:", e)
|
|
|
|
|
|
def input_salary() -> float | None:
|
|
while True:
|
|
salary_str = input("Введите оклад: ").strip().replace(",", ".")
|
|
try:
|
|
salary_decimal = Decimal(salary_str)
|
|
except InvalidOperation:
|
|
print("Ошибка: оклад должен быть числом")
|
|
continue
|
|
|
|
try:
|
|
return Worker.validate_salary(float(salary_decimal))
|
|
except ValueError as e:
|
|
print("Ошибка:", e)
|
|
|
|
|
|
def input_worker() -> Worker:
|
|
surname = input_surname()
|
|
position = input_position()
|
|
salary = input_salary()
|
|
return Worker(surname, position, salary)
|
|
|
|
|
|
# -----------------------
|
|
def main():
|
|
print("Создание работника с клавиатуры:")
|
|
worker_from_input = input_worker()
|
|
|
|
# работники-константы
|
|
worker1 = Worker("Иванов", "менеджер", 50000)
|
|
worker2 = Worker("Петров", "аналитик", 60000)
|
|
|
|
workers = [worker_from_input, worker1, worker2]
|
|
|
|
print("\nИсходные данные:")
|
|
for w in workers:
|
|
print(w.info())
|
|
|
|
# обработка данных
|
|
for w in workers:
|
|
w.increase_salary()
|
|
w.assign_engineer_if_ivan()
|
|
|
|
print("\nПосле обработки:")
|
|
for w in workers:
|
|
print(w.info())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|