Files
TIMP-LABS/lab3/main.py
T

177 lines
6.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import math
from decimal import Decimal, InvalidOperation
import unicodedata
class Worker:
SURNAME_SEPARATORS = {"-", "'"}
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 = unicodedata.normalize("NFKC", surname.strip())
surname = surname.replace("", "'").replace("`", "'").replace("", "-")
if len(surname) < 2:
raise ValueError("Фамилия слишком короткая")
if surname[0] in Worker.SURNAME_SEPARATORS or surname[-1] in Worker.SURNAME_SEPARATORS:
raise ValueError("Фамилия не может начинаться или заканчиваться разделителем")
previous_is_separator = False
for char in surname:
if char in Worker.SURNAME_SEPARATORS:
if previous_is_separator:
raise ValueError("Фамилия содержит подряд идущие разделители")
previous_is_separator = True
continue
if not char.isalpha():
raise ValueError("Фамилия может содержать только буквы, дефис и апостроф")
previous_is_separator = False
parts: list[str] = []
token = ""
for char in surname:
if char in Worker.SURNAME_SEPARATORS:
parts.append(token)
parts.append(char)
token = ""
else:
token += char
parts.append(token)
normalized_parts = [part[:1].upper() + part[1:].lower() if part not in Worker.SURNAME_SEPARATORS else part for part in parts]
return "".join(normalized_parts)
# проверка должности
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()