diff --git a/TEMA9/Figure_1.png b/TEMA9/Figure_1.png new file mode 100644 index 0000000..88bb561 Binary files /dev/null and b/TEMA9/Figure_1.png differ diff --git a/TEMA9/Mod3.py b/TEMA9/Mod3.py new file mode 100644 index 0000000..bb1968b --- /dev/null +++ b/TEMA9/Mod3.py @@ -0,0 +1,10 @@ +class Class1: #Объявление класса Class1 в модуле + def zad_zn(self,znach): # 1 Метод класса + self.data=znach # self - ссылка на экземпляр класса Class1 + def otobrazh(self): # 2 Метод класса + print(self.data)#Отображение данных экземпляра +class Class2(Class1): #Class2 - наследник класса Class1 + def otobrazh(self): # Метод класса Class2 + print('значение=',self.data)#Отображение данных экземпляра +def otobrazh(objekt): #Объявление самостоятельной функции + print('значение объекта=',objekt) diff --git a/TEMA9/SAU.py b/TEMA9/SAU.py new file mode 100644 index 0000000..6f0cc48 --- /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] #Обр.связь с усилителем 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 otobraz(self): + print('y=',self.ypr[1]) diff --git a/TEMA9/main_SAU.py b/TEMA9/main_SAU.py new file mode 100644 index 0000000..51afef1 --- /dev/null +++ b/TEMA9/main_SAU.py @@ -0,0 +1,14 @@ +###main_SAU +prm=[2.5,4,1.3,0.8] #Параметры модели: коэф.усиления, 2 пост.времени, обратная связь +from SAU import * +xx=[0]+[1]*20 #Входной сигнал – «ступенька» +SAUe=SAU(prm) # Создаём экземпляр класса +yt=[] +for xt in xx: # Прохождение входного сигнала + SAUe.zdn_zn(xt) + SAUe.model() + SAUe.otobraz() + yt.append(SAUe.ypr[1]) +import pylab +pylab.plot(yt) +pylab.show() diff --git a/TEMA9/report.md b/TEMA9/report.md new file mode 100644 index 0000000..e9aa2ea --- /dev/null +++ b/TEMA9/report.md @@ -0,0 +1,292 @@ +# Отчёт по теме 9: Создание пользовательских классов и объектов + +Голощапов Д.Е., А-01-23 + +# 1. Запуск интерактивной оболочки IDLE + + >>> import os + >>> os.chdir('C:\\Users\\danii\\Desktop\\FilippovDY\\python-labs\\TEMA9') + +# 2. Создание классов и их наследников + +Класс - это элемент ПО, описывающий абстрактный тип данных и его частичную или полную реализацию. Он представляет собой шаблоны, образцы, по которым может быть создано множество объектов-экземпляров класса. У каждого класса есть уникальное имя и некоторый набор специфических для него атрибутов: полей (данных) и методов (функций), которые могут использоваться при работе с экземплярами класса. + +## 2.1 Создание автономного класса + + >>> class Class1: #Объявление класса + ... def zad_zn(self,znach): #Метод 1 класса1 – задание значения data + ... self.data=znach # self - ссылка на экземпляр класса + ... def otobrazh(self): # Метод 2 класса1 + ... print(self.data)#Отображение данных экземпляра класса + ... + +У этого класса есть два метода: zad_zn (устанавливает значение свойства объекта) и otobrazh (выводит это значение на экран). +Еще у него есть один атрибут - data. +self — это обязательный первый параметр всех методов в классе, ссылающийся на конкретный +экземпляр класса и нужный для определения обращения к атрибутам и методам. + + >>> z1=Class1() #Создаём 1-й экземпляр класса + >>> z2=Class1() #Создаём 2-й экземпляр класса + >>> z1.zad_zn('экз.класса 1') #Обращение к методу класса у 1-го экз. + >>> z2.zad_zn(-632.453) #Обращение к методу класса у 2-го экз. + >>> z1.otobrazh() # Обращение ко второму методу класса + экз.класса 1 + >>> z2.otobrazh() + -632.453 + >>> z1.data='Новое значение атрибута у экз.1' + >>> z1.otobrazh() + Новое значение атрибута у экз.1 + +## 2.2 Создание класса-наследника + + >>> class Class2(Class1): #Class2 - наследник класса Class1 + ... def otobrazh(self): # Метод класса Class2 – переопределяет метод родителя + ... print('значение=',self.data)#Отображение данных экземпляра + ... + ... + >>> z3=Class2() + >>> dir(z3) + ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__static_attributes__', '__str__', '__subclasshook__', '__weakref__', 'otobrazh', 'zad_zn'] + +Объекты с нижними подчеркиваниями - встроенные атрибуты и методы, которые есть у каждого класса. Кроме этого, есть унаследованные от родительского класса методы, один из которых переопределен. +При создании дочернего класса атрибуты и методы родительского класса переносятся дочернему. В дочернем классе методы могут быть переопределены. То есть метод с одинаковым именем в разных классах будет вести себя по-разному. + + >>> z3.zad_zn('Совсем новое') + >>> z3.otobrazh() + значение= Совсем новое + >>> z1.otobrazh() + Новое значение атрибута у экз.1 + >>> del z1,z2,z3 + +# 3. Использование классов, содержащихся в модулях + +Создадим модуль Mod3 со следующим содержанием: + + class Class1: #Объявление класса Class1 в модуле + def zad_zn(self,znach): # 1 Метод класса + self.data=znach # self - ссылка на экземпляр класса Class1 + def otobrazh(self): # 2 Метод класса + print(self.data)#Отображение данных экземпляра + class Class2(Class1): #Class2 - наследник класса Class1 + def otobrazh(self): # Метод класса Class2 + print('значение=',self.data)#Отображение данных экземпляра + def otobrazh(objekt): #Объявление самостоятельной функции + print('значение объекта=',objekt) + + + + >>> from Mod3 import Class1 #Частичный импорт содержимого модуля + >>> z4=Class1() + >>> z4.otobrazh() + Traceback (most recent call last): + File "", line 1, in + z4.otobrazh() + File "C:\Users\Дмитрий\OneDrive\Рабочий стол\Goloshchapov\python-labs\TEMA9\Mod3.py", line 5, in otobrazh + print(self.data)#Отображение данных экземпляра + AttributeError: 'Class1' object has no attribute 'data' + +Ошибка возникла потому, что otobrazh было вызвано раньше, чем метод, инициализирующий атрибут data, то есть мы пытаемся напечатать значение несуществующего объекта. + + + >>> import sys + >>> sys.modules.pop('Mod3') + + >>> from Mod3 import Class1 + >>> z4=Class1() + >>> z4.data='значение данного data у экз.4' + >>> z4.otobrazh() + значение данного data у экз.4 + +Здесь otobrazh - это метод класса Class2 и соответствующего ему экземпляра класса z2. Этот метод не принимает значимых параметров, кроме формального self. + + >>> del z4 + >>> import Mod3 #Полный импорт содержимого модуля + >>> z4=Mod3.Class2() + >>> z4.zad_zn('Класс из модуля') + >>> z4.otobrazh() + значение= Класс из модуля + >>> Mod3.otobrazh('Объект') + значение объекта= Объект + + +Здесь otobrazh - это уже просто функция, глобально определенная в модуле mod3. Она определена вне пользовательского класса, поэтому атрибута data в ее зоне доступа нет. Так что эта функция принимает один обязательный параметр - выводимую переменную. + + +# 4. Использование специальных методов + +Имена специальных методов предваряются одним или двумя подчерками и имеют вид: ```__<имя специального метода>__``` + + >>> class Class3(Class2): #Наследник класса Class2, а через него – и класса Class1 + ... def __init__(self,znach): #Конструктор-вызывается при создании нового экземпляра класса + ... self.data=znach + ... def __add__(self,drug_zn): #Вызывается, когда экземпляр участвует в операции «+» + ... return Class3(self.data+drug_zn) + ... def zad_dr_zn(self,povtor): #А это - обычный метод + ... self.data*=povtor + ... + +Метод __add__ - это один из методов, осуществляющих так называемую «перегрузку» операторов. +Для иллюстрации работы этих методов создадим экземпляр класса Class3 и отобразим его. + + >>> z5=Class3('abc') #При создании экземпляра срабатывает конструктор + >>> z5.otobrazh() + значение= abc + >>> z6=z5+'def' + >>> z6.otobrazh() + значение= abcdef + >>> z6.zad_dr_zn(3) + >>> z6.otobrazh() + значение= abcdefabcdefabcdef + + # 5. Присоединение атрибутов к классу + + >>> dir(Class3) + ['__add__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__static_attributes__', '__str__', '__subclasshook__', '__weakref__', 'otobrazh', 'zad_dr_zn', 'zad_zn'] + >>> Class3.fio='Иванов И.И.' + >>> dir(Class3) + ['__add__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__static_attributes__', '__str__', '__subclasshook__', '__weakref__', 'fio', 'otobrazh', 'zad_dr_zn', 'zad_zn'] + >>> z7=Class3(123) + >>> dir(z7) + ['__add__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__static_attributes__', '__str__', '__subclasshook__', '__weakref__', 'data', 'fio', 'otobrazh', 'zad_dr_zn', 'zad_zn'] + +В dir(z7), по сравнению с dir(Class3), указаны также атрибуты, относящиеся непосредственно к экземпляру. dir(Class3) показывает атрибуты класса Class3. Это включает методы, свойства, и встроенные специальные методы класса, но не атрибуты конкретных объектов, созданных на основе этого класса. +dir(z7) показывает атрибуты объекта z7. + + >>> dir(z7)==dir(Class3) + False + >>> z7.rozden='1987' # Добавим еще один атрибут + >>> dir(z7) + ['__add__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__static_attributes__', '__str__', '__subclasshook__', '__weakref__', 'data', 'fio', 'otobrazh', 'rozden', 'zad_dr_zn', 'zad_zn'] + >>> dir(Class3) # При этом у dir(Class3) его нет + ['__add__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__static_attributes__', '__str__', '__subclasshook__', '__weakref__', 'fio', 'otobrazh', 'zad_dr_zn', 'zad_zn'] + + +# 6. Выявление родительских классов + +Такое выявление делается с помощью специального атрибута ```__bases__```. + + >>> Class3.__bases__ + (,) + >>> Class2.__bases__ + (,) + >>> Class1.__bases__ + (,) + >>> object.__bases__ + () + +Полный порядок наследования: + + >>> Class3.__mro__ + (, , , ) + >>> ZeroDivisionError.__mro__ + (, , , , ) + +# 7. Создание свойства класса + +Свойство (property) класса – это особый атрибут класса, с которым можно производить операции чтения или задания его значения, а также удаление значения этого атрибута. Свойства нужны для того, чтобы ограничить прямой доступ к изменению атрибута. + + >>> class Class4: + ... def __init__(sam,znach): + ... sam.__prm=znach + ... def chten(sam): + ... return sam.__prm + ... def zapis(sam,znch): + ... sam.__prm=znch + ... def stiran(sam): + ... del sam.__prm + ... svojstvo=property(chten,zapis,stiran) + ... + ... + >>> exempl=Class4(12) + >>> exempl.svojstvo + 12 + >>> exempl.svojstvo=45 + >>> print(exempl.svojstvo) + 45 + >>> del exempl.svojstvo + >>> exempl.svojstvo + Traceback (most recent call last): + File "", line 1, in + exempl.svojstvo + File "", line 5, in chten + return sam.__prm + AttributeError: 'Class4' object has no attribute '_Class4__prm' + +Такой вывод происходит, потому что этот атрибут уже удален. + +# 8. Пример представления в виде класса модели системы автоматического регулирования (САР), состоящей из последовательного соединения усилителя и двух инерционных звеньев, охваченных отрицательной обратной связью с усилителем. + +Создадим модуль 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 otobraz(self): + print('y=',self.ypr[1]) +``` + +Тестирование класса произведём с помощью следующей программы, которая находится в модуле main_Sau.py + +``` +###main_SAU +prm=[2.5,4,1.3,0.8] #Параметры модели: коэф.усиления, 2 пост.времени, обратная связь +from SAU import * +xx=[0]+[1]*20 #Входной сигнал – «ступенька» +SAUe=SAU(prm) # Создаём экземпляр класса +yt=[] +for xt in xx: # Прохождение входного сигнала + SAUe.zdn_zn(xt) + SAUe.model() + SAUe.otobraz() + yt.append(SAUe.ypr[1]) +import pylab +pylab.plot(yt) +pylab.show() +``` + +Тестирование программы: +```py +>>> import main_SAU.py +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 +``` + +![График](Figure_1.png) + + + # 9. Завершение сеанса работы с IDLE + diff --git a/TEMA9/task.md b/TEMA9/task.md new file mode 100644 index 0000000..bcedd74 --- /dev/null +++ b/TEMA9/task.md @@ -0,0 +1,87 @@ +# Общее контрольное задание по теме 9 + +Голощапов Д.Е., А-01-23 + +# Задание: + +Создать и записать в модуль класс, содержащий следующие компоненты: + +- конструктор, задающий четырем атрибутам (fio, otdel, dolzhnost, oklad), представляющим фамилии сотрудников, название отделов, названия должностей сотрудников и размеры их окладов, некоторые начальные значения; + +- метод для обеспечения операции повышения оклада сотрудника на заданное значение; + +- метод для обеспечения перевода сотрудника из одного отдела в другой; + +- метод для изменения должности сотрудника; + +- свойство, содержащее перечень (список) поощрений сотрудника. + +Создать 2 экземпляра класса, задать им некоторые значения атрибутов и свойства. Отобразить эти значения. Попробовать с этими экземплярами операции перевода из отдела в отдел, изменения должности и оклада, объявления благодарности. + +# Решение + + >>> class Employee: + ... def __init__(self, fio="", otdel="", dolzhnost="", oklad=0): + ... self.fio = fio + ... self.otdel = otdel + ... self.dolzhnost = dolzhnost + ... self.oklad = oklad + ... self._pooshchreniya = [] + ... + ... def povyshenie_oklad(self, summa): + ... if summa > 0: + ... self.oklad += summa + ... return self.oklad + ... else: + ... print("Сумма для повышения оклада должна быть больше нуля.") + ... + ... def perevod(self, new_otdel): + ... self.otdel = new_otdel + ... return self.otdel + ... + ... def cmena_dolzhnosty(self, new_dolzhnost): + ... self.dolzhnost = new_dolzhnost + ... return self.dolzhnost + ... + ... @property + ... def pooshchrenia(self): + ... return self._pooshchreniya + ... + ... def add_pooshchrenie(self, pooshchrenie): + ... self._pooshchreniya.append(pooshchrenie) + ... print(f"Сотрудник {self.fio} теперь имеет поощрение: {pooshchrenie}") + ... + ... + >>> emp_1=Employee ("Толчеев В.О.", "Кафедра Управления и информационных технологий", "Профессор", 300000) + >>> emp_2=Employee ("Бобряков А.В.", "Кафедра Управления и информационных технологий", "Заведующий кафедрой", 1500000) + >>> print(f"{emp_1.fio}, {emp_1.otdel}, {emp_1.dolzhnost}, оклад: {emp_1.oklad}") + Толчеев В.О., Кафедра Управления и информационных технологий, Профессор, оклад: 300000 + >>> print(f"{emp_2.fio}, {emp_2.otdel}, {emp_2.dolzhnost}, оклад: {emp_2.oklad}") + Бобряков А.В., Кафедра Управления и информационных технологий, Заведующий кафедрой, оклад: 1500000 + >>> emp_2.perevod("МАИ") + 'МАИ' + >>> emp_1.povyshenie_oklad(20000) + 320000 + >>> emp_2.cmena_dolzhnosty("Ассистент") + 'Ассистент' + >>> emp_2.add_pooshchrenie("Выслуга лет") + Сотрудник Бобряков А.В. теперь имеет поощрение: Выслуга лет + >>> emp_1.add_pooshchrenie("Лучший ") + Сотрудник Толчеев В.О. теперь имеет поощрение: Лучший + >>> print(f"Поощрения {emp_1.fio}: {emp_1.pooshchrenia}") + Поощрения Толчеев В.О.: ['Лучший '] + >>> print(f"Поощрения {emp_2.fio}: {emp_2.pooshchrenia}") + + + + + + + + + + + + + +