diff --git a/TEMA9/Employee.py b/TEMA9/Employee.py new file mode 100644 index 0000000..eb320b9 --- /dev/null +++ b/TEMA9/Employee.py @@ -0,0 +1,63 @@ +class Employee: + """Класс, описывающий основные данные о сотруднике организации""" + + def __init__(self, fio = "", otdel = "", dolzhnost = "", oklad = 0): + self.fio = fio + self.otdel = otdel + self.dolzhnost = dolzhnost + self.oklad = oklad + self.__pooshreniya = [] + self.pooshreniya = property( + self.get_pooshreniya, + self.set_pooshreniya, + self.del_pooshreniya + ) + + def change_oklad(self, diff): + if (self.oklad + diff <= 0): + print("Оклад сотрудника не может быть меньше либо равен 0") + else: + self.oklad += diff + print(f"Оклад сотрудника {self.fio} был {'увеличен' if diff >= 0 else 'уменьшен'} на {abs(diff)}") + + def change_otdel(self, new_otdel): + old_otdel = self.otdel + self.otdel = new_otdel + print(f"Сотрудник {self.fio} был переведен из отдела '{old_otdel}' в '{new_otdel}'") + + def change_dolzhnost(self, new_dolzhnost): + old_dolzhnost = self.dolzhnost + self.dolzhnost = new_dolzhnost + print(f"Должность сотрудника {self.fio} была изменена с '{old_dolzhnost}' на '{new_dolzhnost}'") + + def get_pooshreniya(self): + return list(self.__pooshreniya) + + def set_pooshreniya(self, value): + if isinstance(value, str): + self.__pooshreniya.append(value) + print(f"Добавлено поощрение для сотрудника {self.fio}: '{value}'") + elif isinstance(value, list): + self.__pooshreniya.extend(value) + print(f"Добавлены поощрения для сотрудника {self.fio}: {value}") + else: + print("Поощрение должно быть строкой или списком строк") + + def del_pooshreniya(self, item = ""): + if not item: + self.__pooshreniya.clear() + print(f"Список поощрений сотрудника {self.fio} очищен") + elif item in self.__pooshreniya: + self.__pooshreniya.remove(item) + print(f"Поощрение {item} сотрудника {self.fio} удалено") + else: + print(f"Такого поощрения нет в списке поощрений сотрудника {self.fio}") + + def get_employee_info(self): + print(f""" + ФИО: {self.fio} + Отдел: {self.otdel} + Должность: {self.dolzhnost} + Оклад: {self.oklad} руб. + Поощрения: {self.__pooshreniya if self.__pooshreniya else 'нет'} + """) diff --git a/TEMA9/Mod3.py b/TEMA9/Mod3.py new file mode 100644 index 0000000..4ce1489 --- /dev/null +++ b/TEMA9/Mod3.py @@ -0,0 +1,12 @@ +class Class1: + def zad_zn(self, znach): + self.data = znach + def otobrazh(self): + print(self.data) + +class Class2(Class1): + def otobrazh(self): + print("Значение =", self.data) + +def otobrazh(obj): + print("Значение объекта =", obj) diff --git a/TEMA9/SAU.py b/TEMA9/SAU.py new file mode 100644 index 0000000..dcf3ec8 --- /dev/null +++ b/TEMA9/SAU.py @@ -0,0 +1,21 @@ +class SAU: + def __init__ (self, zn_param): + self.param = zn_param + self.ypr = [0, 0] + + def zdn_zn(self, upr): + self.x = upr + + def model(self): + def inerz(x, T, yy): + return (x + T * yy) / (T + 1) + + y0 = self.x - self.ypr[1] * self.param[3] + y1 = self.param[0] * y0 + y2 = inerz(y1, self.param[1], self.ypr[0]) + y3 = inerz(y2, self.param[2], self.ypr[1]) + self.ypr[0] = y2 + self.ypr[1] = y3 + + def otobrazh(self): + print("y =", self.ypr[1]) diff --git a/TEMA9/main_SAU.py b/TEMA9/main_SAU.py new file mode 100644 index 0000000..72d0b60 --- /dev/null +++ b/TEMA9/main_SAU.py @@ -0,0 +1,19 @@ +from SAU import * +prm = [2.5, 4, 1.3, 0.8] +xx = [0] + [1] * 20 +SAUe = SAU(prm) +yt = [] + +for xt in xx: + SAUe.zdn_zn(xt) + SAUe.model() + SAUe.otobrazh() + yt.append(SAUe.ypr[1]) + +import pylab +pylab.plot(yt) +pylab.title("График выходного сигнала") +pylab.xlabel("Время - t") +pylab.ylabel("Выходной сигнал - y(t)") +pylab.grid(True) +pylab.show() diff --git a/TEMA9/pictures/figure0.png b/TEMA9/pictures/figure0.png new file mode 100644 index 0000000..4ecc8f9 Binary files /dev/null and b/TEMA9/pictures/figure0.png differ diff --git a/TEMA9/pictures/figure1.png b/TEMA9/pictures/figure1.png new file mode 100644 index 0000000..1a9e986 Binary files /dev/null and b/TEMA9/pictures/figure1.png differ diff --git a/TEMA9/report.md b/TEMA9/report.md new file mode 100644 index 0000000..e7107fc --- /dev/null +++ b/TEMA9/report.md @@ -0,0 +1,300 @@ +# Отчет по теме 9 + +Степанов Артём, А-02-23 + +## Создание пользовательских классов и объектов + +### 1. Установка рабочего каталога. Создание рабочего протокола. + +В оболочке IDLE установил актуальный рабочий каталог, а затем в нём создал рабочий протокол. + +![Скриншот созданного рабочего протокола](pictures/figure0.png) + +### 2. Создание классов и их наследников. + +Класс в Python, как и в других языках программирования, - это элемент ПО, описывающий абстрактный тип данных и его частичную или полную реализацию. Классы – это основные инструменты объектно-ориентированного программирования (ООП) в языке Python. Они представляют собой шаблоны, образцы, по которым может быть создано множество объектов-экземпляров класса. У каждого класса есть уникальное имя и некоторый набор специфических для него атрибутов: полей и методов, которые могут использоваться при работе с экземплярами класса. + +#### 2.1. Создание автономного класса. + +Классы могут быть автономными, т.е. независящими от других классов: + +```py +>>> class Class1: # Объявление класса +... def zad_zn(self, znach): # Метод класса для задания значения поля data +... self.data = znach +... def otobrazh(self): # Метод класса для отображения значения поля data +... print(self.data) +... +>>> z1 = Class1() # Создание 1-го экземпляра класса +>>> z2 = Class1() # Создание 2-го экземпляра класса +>>> z1.zad_zn("Экземпляр класса 1") +>>> z2.zad_zn(-632.453) +>>> z1.otobrazh() + Экземпляр класса 1 +>>> z2.otobrazh() + -632.453 +>>> z1.data = "Новое значение атрибута у экземпляра 1" +>>> z1.otobrazh() + Новое значение атрибута у экземпляра 1 +``` + +#### 2.2. Создание класса-наследника. + +Также классы могут наследоваться от других классов, т.е. иметь такие же поля данных как и класс-родитель и имплементировать его методы, которые можно переопределять. + +```py +>>> class Class2(Class1): # Объявление класса-наследника другого класса +... def otobrazh(self): # Переопределение метода класса-родителя +... print("Значение =", self.data) +... +>>> z3 = Class2() +>>> dir(z3) + ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'otobrazh', 'zad_zn'] +>>> z3.zad_zn("Совсем новое") +>>> z3.otobrazh() # Сработал переопределенный метод otobrazh класса Class2 + Значение = Совсем новое +>>> z1.otobrazh() # Значение поля data класса Class1 не изменилось + Новое значение атрибута у экземпляра 1 +>>> del z1, z2, z3 +``` + +### 3. Использование классов, содержащихся в модулях. + +Классы могут быть описаны в модулях, которые потом должны быть подключены к основной программе, чтобы реализовать объекты соответствующего класса. Так, например, в модуле __"Mod3.py"__ описано обявление класса Class1: + +```py +class Class1: + def zad_zn(self, znach): + self.data = znach + def otobrazh(self): + print(self.data) + +class Class2(Class1): + def otobrazh(self): + print("Значение =", self.data) + +def otobrazh(obj): + print("Значение объекта =", obj) +``` + +Пример частичного импорта модуля и последующего создания объекта класса Class1: + +```py +>>> from Mod3 import Class1 +>>> z4 = Class1() +>>> z4.otobrazh() # Поле data класса не было инициализировано, поэтому его еще нет в классе + Traceback (most recent call last): + File "", line 1, in + z4.otobrazh() + File "C:\Users\User\Desktop\StepanovAV\python-labs\TEMA9\Mod3.py", line 5, in otobrazh + print(self.data) + AttributeError: 'Class1' object has no attribute 'data' +>>> z4.data = "Значение поля data у экземпляра 4" # Прямая инициализация поля data +>>> z4.otobrazh() # Использован метод для отображения значения поля, описанный в Class1 + Значение поля data у экземпляра 4 +``` + + + +```py +>>> del z4 +>>> import Mod3 +>>> z4 = Mod3.Class2() +>>> z4.zad_zn("Класс из модуля") +>>> z4.otobrazh() # Использован метод для отображения значения поля, описанный в Class2 + Значение = Класс из модуля +>>> Mod3.otobrazh("Объект") # Использована функция otobrazh + Значение объекта = Объект +``` + +### 4. Использование специальных методов. + +Имена специальных методов предваряются одним или двумя подчерками и имеют вид: + __<имя специального метода>__. +Пример класса, содержащего два специальных метода: + +```py +>>> class Class3(Class2): +... def __init__(self, znach): # Специальный метод-конструктор +... self.data = znach +... def __add__(self, another_zn): # Специальный метод для сложения +... return Class3(self.data + another_zn) +... def zad_another_zn(self, povtor): # Обычный пользовательский метод +... self.data *= povtor +... +>>> z5 = Class3("abc") +>>> z5.otobrazh() + Значение = abc +>>> z6 = z5 + "def" +>>> z6.otobrazh() + Значение = abcdef +>>> z6.zad_another_zn(3) +>>> z6.otobrazh() + Значение = abcdefabcdefabcdef +``` + +### 5. Присоединение атрибутов к классу. + +Каждый класс обладает определенными атрибутами, список которыхможно получить с помощью ранее изученной команды __dir()__. + +```py +>>> dir(Class3) + ['__add__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'otobrazh', 'zad_another_zn', 'zad_zn'] +>>> Class3.fio = "Иванов И.И." +>>> z7 = Class3(123) +>>> dir(z7) # Отображение списка атрибутов объекта класса после добавления в него поля fio + ['__add__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'data', 'fio', 'otobrazh', 'zad_another_zn', 'zad_zn'] +>>> dir(z7) == dir(Class3) + False +>>> z7.fio + 'Иванов И.И.' +>>> Class3.fio + 'Иванов И.И.' +>>> z7.rozden = "1987" +>>> "rozden" in dir(z7) # Проверка того, что поле rozden появилось в объекте класса + True +>>> "rozden" in dir(Class3) # Проверка того, что поле rozden не появилось в самом классе + False +``` + +### 6. Выявление родительских классов. + +Чтобы узнать наследуется ли класс от какого-либо другого класса можно рассмотреть атрибут __bases__, который отображает соответствующий родительский класс: + +```py +>>> Class3.__bases__ + (,) +>>> Class2.__bases__ + (,) +>>> Class1.__bases__ + (,) +``` + +Для получения полной цепочки наследований нужно использовать атрибут __mro__: + +```py +>>> Class3.__mro__ + (, , , ) +>>> ZeroDivisionError.__mro__ + (, , , , ) +``` + +### 7. Создание свойств класса. + +Свойство (property) класса – это особый атрибут класса, с которым можно производить операции чтения или задания его значения, а также удаление значения этого атрибута. +Пример класса с определенным в нём свойством: + +```py +>>> class Class4: +... def __init__ (self, znach): +... self.__prm = znach +... def chten(self): +... return self.__prm +... def zapis(self, znch): +... self.__prm = znch +... def stiran(self): +... del self.__prm +... svojstvo = property(chten, zapis, stiran) +... +>>> example = Class4(12) +>>> example.svojstvo + 12 +>>> example.svojstvo = 45 +>>> print(example.svojstvo) + 45 +>>> del example.svojstvo +>>> example.svojstvo # Отображения отсутсвующего в объекте класса свойства вызывает ошибку + Traceback (most recent call last): + File "", line 1, in + example.svojstvo + File "", line 5, in chten + return self.__prm + AttributeError: 'Class4' object has no attribute '_Class4__prm' +``` + +### 8. Представление некоторой модели в виде класса. + +Различные модели можно представлять в виде отдельных классов. Пример создания класса для модели, состоящей из последовательного соединения усилителя и двух инерционных звеньев, охваченных отрицательной обратной связью с усилителем, представлен ниже. + +Содержимое модуля __SAU.py__ с классом __SAU__: + +```py +class SAU: + def __init__ (self, zn_param): + self.param = zn_param + self.ypr = [0, 0] + + def zdn_zn(self, upr): + self.x = upr + + def model(self): + def inerz(x, T, yy): + return (x + T * yy) / (T + 1) + + y0 = self.x - self.ypr[1] * self.param[3] # Обратная связь с усилителем 2 + y1 = self.param[0] * y0 # Усилитель 1 + y2 = inerz(y1, self.param[1], self.ypr[0]) # Инерционное звено 1 + y3 = inerz(y2, self.param[2], self.ypr[1]) # Инерционное звено 2 + self.ypr[0] = y2 + self.ypr[1] = y3 + + def otobrazh(self): + print("y =", self.ypr[1]) +``` + +Содержимое модуля-программы __main_SAU.py__ с тестированием класса: + +```py +from SAU import * +prm = [2.5, 4, 1.3, 0.8] # Параметры модели: K1, T1, T2, K2 +xx = [0] + [1] * 20 # Входной сигнал – «ступенька» +SAUe = SAU(prm) +yt = [] + +for xt in xx: + SAUe.zdn_zn(xt) + SAUe.model() + SAUe.otobrazh() + yt.append(SAUe.ypr[1]) + +import pylab +pylab.plot(yt) +pylab.title("График выходного сигнала") +pylab.xlabel("Время - t") +pylab.ylabel("Выходной сигнал - y(t)") +pylab.grid(True) +pylab.show() +``` + +Результат выполнения программы и построенный график: + +```py +>>> import main_SAU + y = 0.0 + y = 0.2173913043478261 + y = 0.4763705103969754 + y = 0.686594887811293 + y = 0.8199324616478645 + y = 0.8837201137353929 + y = 0.8994188484874774 + y = 0.8892777072047301 + y = 0.870097963179993 + y = 0.8518346102696789 + y = 0.8387499784485772 + y = 0.8314204114211459 + y = 0.8286051955249649 + y = 0.8285656555914835 + y = 0.8297915186846528 + y = 0.8312697736438287 + y = 0.8324765218921963 + y = 0.8332456979978418 + y = 0.8336163607592184 + y = 0.8337101315489143 + y = 0.833654237067147 +``` + +![Скриншот построенного графика](pictures/figure1.png) + +### 9. Завершение работы со средой. + +Сохранил файлы отчета в своем рабочем каталоге и закончил сеанс работы с IDLE. diff --git a/TEMA9/task.md b/TEMA9/task.md new file mode 100644 index 0000000..c8bb01a --- /dev/null +++ b/TEMA9/task.md @@ -0,0 +1,141 @@ +# Общее контрольное задание по теме 9 + +Степанов Артём, А-02-23 + +## Задание + +Создайте и запишите в модуль класс, содержащий следующие компоненты: +* конструктор, задающий четырем атрибутам (fio, otdel, dolzhnost, oklad), представляющим фамилии сотрудников, название отделов, названия должностей сотрудников и размеры их окладов, некоторые начальные значения; +* метод для обеспечения операции повышения оклада сотрудника на заданное значение; +* метод для обеспечения перевода сотрудника из одного отдела в другой; +* метод для изменения должности сотрудника; +* свойство, содержащее перечень (список) поощрений сотрудника. + +Создайте 2 экземпляра класса, задайте им некоторые значения атрибутов и свойства. Отобразите эти значения. Попробуйте с этими экземплярами операции перевода из отдела в отдел, изменения должности и оклада, объявления благодарности. + +## Решение + +Содержимое модуля __Employee.py__: + +```py +class Employee: + """Класс, описывающий основные данные о сотруднике организации""" + + def __init__(self, fio = "", otdel = "", dolzhnost = "", oklad = 0): + self.fio = fio + self.otdel = otdel + self.dolzhnost = dolzhnost + self.oklad = oklad + self.__pooshreniya = [] + self.pooshreniya = property( + self.get_pooshreniya, + self.set_pooshreniya, + self.del_pooshreniya + ) + + def change_oklad(self, diff): + if (self.oklad + diff <= 0): + print("Оклад сотрудника не может быть меньше либо равен 0") + else: + self.oklad += diff + print(f"Оклад сотрудника {self.fio} был {'увеличен' if diff >= 0 else 'уменьшен'} на {abs(diff)}") + + def change_otdel(self, new_otdel): + old_otdel = self.otdel + self.otdel = new_otdel + print(f"Сотрудник {self.fio} был переведен из отдела '{old_otdel}' в '{new_otdel}'") + + def change_dolzhnost(self, new_dolzhnost): + old_dolzhnost = self.dolzhnost + self.dolzhnost = new_dolzhnost + print(f"Должность сотрудника {self.fio} была изменена с '{old_dolzhnost}' на '{new_dolzhnost}'") + + def get_pooshreniya(self): + return list(self.__pooshreniya) + + def set_pooshreniya(self, value): + if isinstance(value, str): + self.__pooshreniya.append(value) + print(f"Добавлено поощрение для сотрудника {self.fio}: '{value}'") + elif isinstance(value, list): + self.__pooshreniya.extend(value) + print(f"Добавлены поощрения для сотрудника {self.fio}: {value}") + else: + print("Поощрение должно быть строкой или списком строк") + + def del_pooshreniya(self, item = ""): + if not item: + self.__pooshreniya.clear() + print(f"Список поощрений сотрудника {self.fio} очищен") + elif item in self.__pooshreniya: + self.__pooshreniya.remove(item) + print(f"Поощрение '{item}' сотрудника {self.fio} удалено") + else: + print(f"Такого поощрения нет в списке поощрений сотрудника {self.fio}") + + def get_employee_info(self): + print(f""" + ФИО: {self.fio} + Отдел: {self.otdel} + Должность: {self.dolzhnost} + Оклад: {self.oklad} руб. + Поощрения: {self.__pooshreniya if self.__pooshreniya else 'нет'} + """) +``` + +Проверка класса на работоспособность: + +```py +>>> from Employee import Employee +>>> employee1 = Employee("Иванов И.И.", "IT-отдел", "Программист", 75000) +>>> employee2 = Employee("Смирнов С.С.", "Отдел продаж", "Менеджер", 50000) +>>> employee1.get_employee_info() # Отображение полной информации об экземпляре класса + + ФИО: Иванов И.И. + Отдел: IT-отдел + Должность: Программист + Оклад: 75000 руб. + Поощрения: нет + +>>> employee2.get_employee_info() + + ФИО: Смирнов С.С. + Отдел: Отдел продаж + Должность: Менеджер + Оклад: 50000 руб. + Поощрения: нет + +>>> employee1.change_otdel("Административный отдел") # Изменение отдела + Сотрудник Иванов И.И. был переведен из отдела 'IT-отдел' в 'Административный отдел' +>>> employee2.change_oklad(-5000) # Изменение оклада (отрицательное число) + Оклад сотрудника Смирнов С.С. был уменьшен на 5000 +>>> employee2.change_oklad(7500) # Изменение оклада (положительное число) + Оклад сотрудника Смирнов С.С. был увеличен на 7500 +>>> employee2.change_dolzhnost("Аналитик продаж") # Изменение должности +>>> Должность сотрудника Смирнов С.С. была изменена с 'Менеджер' на 'Аналитик продаж' +>>> employee1.set_pooshreniya("Почетная грамота") # Добавление поощрения + Добавлено поощрение для сотрудника Иванов И.И.: 'Почетная грамота' +>>> employee1.set_pooshreniya(["Медаль", "Сертификат"]) # Добавление списка поощрений + Добавлены поощрения для сотрудника Иванов И.И.: ['Медаль', 'Сертификат'] +>>> employee1.get_pooshreniya() # Отображение списка поощрений + ['Почетная грамота', 'Медаль', 'Сертификат'] +>>> employee1.del_pooshreniya("Медаль") # Удаление определенного поощрения + Поощрение 'Медаль' сотрудника Иванов И.И. удалено +>>> employee1.del_pooshreniya() # Удаление всех поощрений + Список поощрений сотрудника Иванов И.И. очищен +>>> employee1.get_employee_info() + + ФИО: Иванов И.И. + Отдел: Административный отдел + Должность: Программист + Оклад: 75000 руб. + Поощрения: нет + +>>> employee2.get_employee_info() + + ФИО: Смирнов С.С. + Отдел: Отдел продаж + Должность: Аналитик продаж + Оклад: 52500 руб. + Поощрения: нет +``` \ No newline at end of file