Files
TIMP-LABS/lab3/main.py
T

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