Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

19 KiB

Отчет по теме 7

Махнов Георгий, А-01-23

Тема 7. Создание пользовательских функций

2. Создание пользовательской функции.

2.1. Первый пример: функция – без аргументов.

>>> def uspeh():
...     """Подтверждение успеха операции"""
...     print('Выполнено успешно!')
... 
>>> uspeh()  
Выполнено успешно!
>>> dir()
['PS1', 'REPLHooks', '__annotations__', '__builtins__', '__cached__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'get_last_command', 'is_wsl', 'original_ps1', 'platform', 'sys', 'uspeh']
>>> help(uspeh)
Help on function uspeh in module __main__:

uspeh()
    юфЄтхЁцфхэшх єёяхїр юяхЁрЎшш

Вывелась надпись "Подтверждение успешно". В комментариях стоит писать назначение функции и переменные, которые нужно подавать в неё (при надобности)

2.2. Пример функции с аргументами.

>>> def sravnenie(a,b):
...     """Сравнение a и b"""
...     if a>b:
...         print(a,' больше ',b)
...     elif a<b:
...         print(a, ' меньше ',b)
...     else:
...         print(a, ' равно ',b)
... 
>>> n,m=16,5;sravnenie(n,m)
16  больше  5
>>> sravnenie('aaa', 'bbb') 
aaa  меньше  bbb

Функция сравнивает символы по лексикографическому порядку, начиная с самого первого символа. Лексикографический порядок служит для того, чтобы сравнивать последовательности символом по алфавитному порядку

2.3. Пример функции, содержащей return.

>>> def logistfun(b,a):
...     import math
...     return a/(1+math.exp(-b))
... 
>>> v,w=1,0.7;z=logistfun(w,v)
>>> print(z)
0.6681877721681662

2.4. Сложение для разных типов аргументов

>>> def slozh(a1,a2,a3,a4):
...         """ Сложение значений четырех аргументов"""
...         return a1+a2+a3+a4
... 
>>> slozh(1,2,3,4)
10
>>> slozh('1','2','3','4')
'1234'
>>> b1=[1,2];b2=[-1,-2];b3=[0,2];b4=[-1,-1]
>>> q=slozh(b1,b2,b3,b4)
>>> q
[1, 2, -1, -2, 0, 2, -1, -1]
b1={9:12};b2={1:-3};b3={4:6};b4={-2:8}
>>> b1={9,12};b2={1,-3};b3={4,6};b4={-2,8}
>>> slozh(b1,b2,b3,b4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in slozh
TypeError: unsupported operand type(s) for +: 'set' and 'set'
>>> b1={9:12};b2={1:-3};b3={4:6};b4={-2:8}
>>> slozh(b1,b2,b3,b4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in slozh
TypeError: unsupported operand type(s) for +: 'dict' and 'dict'

2.5. Функция, реализующая модель некоторого устройства, на вход которого в текущий момент поступает сигнал х, на выходе получается сигнал y:

>>> def inerz(x,T,ypred):
...         """ Модель устройства с памятью:
...     x- текущее значение вх.сигнала,
...         T -постоянная времени,
...         ypred - предыдущее значение выхода устройства"""
...         y=(x+T*ypred)/(T+1)
...         return y
... 
>>> sps=[0]+[1]*100
>>> spsy=[] 
>>> TT=20
>>> yy=0 
>>> for xx in sps:
...         yy=inerz(xx,TT,yy)
...         spsy.append(yy)
... 
>>> import pylab
>>> pylab.plot(spsy,sps)  
[<matplotlib.lines.Line2D object at 0x000001663A9DD5C8>]
>>> pylab.show()

Изображение графика

3. Функции как объекты.

3.1. Получение списка атрибутов объекта-функции.

>>> dir(inerz)      
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
>>> inerz.__doc__
' Модель устройства с памятью:\n    x- текущее значение вх.сигнала,\n        T -постоянная времени,\n        ypred - предыдущее значение выхода устройства'
>>> help(inerz)
Help on function inerz in module __main__:

inerz(x, T, ypred)
    юфхы єёЄЁющёЄтр ё ярь Є№■:
    x- Єхъєхх чэрўхэшх тї.ёшуэрыр,
        T -яюёЄю ээр  тЁхьхэш,
        ypred - яЁхффєхх чэрўхэшх тїюфр єёЄЁющёЄтр

3.2. Сохранение ссылки на объект-функцию в другой переменной.

>>> fnkt=sravnenie
>>> v=16
>>> fnkt(v,23)
16  меньше  23

3.3. Возможность альтернативного определения функции в программе.

>>> typ_fun=8
>>> if typ_fun==1:
...         def func():
...                 print('Функция 1')
... else:
...         def func():
...                 print('Функция 2')
... 
>>> func()
Функция 2

Вывелось надпись "Функция 2", т.к. typ_fun не равна 1.

4. Аргументы функции.

4.1. Изучите возможность использования функции в качестве аргумента другой функции

>>> def fun_arg(fff,a,b,c):
...     """fff-имя функции, используемой 
...     в качестве аргумента функции fun_arg"""
...     return a+fff(c,b)
... 
>>> zz=fun_arg(logistfun,-3,1,0.7)
>>> zz
-2.3318122278318336

4.2. Обязательные и необязательные аргументы.

>>> def logistfun(a,b=1):
...     """Вычисление логистической функции"""
...     import math
...     return b/(1+math.exp(-a))
... 
>>> logistfun(0.7) 
0.6681877721681662
>>> logistfun(0.7,2)
1.3363755443363323

4.3. Изучите возможность обращения к функции с произвольным (непозиционным) расположением аргументов. При этом надо в обращении к функции указывать имена аргументов:

>>> logistfun(b=0.5,a=0.8)
0.34498724056380625

4.4. Пример со значениями аргументов функции, содержащимися в списке или кортеже.

>>> b1234=[b1,b2,b3,b4]
>>> qq=slozh(*b1234)
>>> qq
[1, 2, -1, -2, 0, 2, -1, -1]

4.5. Пример со значениями аргументов функции, содержащимися в словаре

>>> dic4={"a1":1,"a2":2,"a3":3,"a4":4}
>>> qqq=slozh(**dic4)
>>> qqq
10

4.6. Смешанные ссылки

>>> e1=(-1,6);dd2={'a3':3,'a4':9}
>>> qqqq=slozh(*e1,**dd2)
>>> qqqq
17

*args **kwargs используются при передаче неопределенного количества аргументов. **kwargs в функции slozh распаковывает именованные объекты в соответствии с именами переменных в функции (в def slozh(a1,a2,a3,a4) **dd2 распакует из словаря значения по их именам, иначе выйдет ошибка)

4.7. Переменное число аргументов у функции.

>>> def func4(*kort7):
...     smm = 0
...     for elt in kort7:
...             smm+=elt
...     return smm
... 
>>> func4(-1,2)
1
>>> func4(-1,2,0,3,6) 
10

4.8. Комбинация аргументов

>>> def func4(a,b=7,*kort7):
...     """Кортеж - сборка аргументов - должен быть последним!"""
...     smm=0
...     for elt in kort7:
...             smm+=elt
...     return a*smm+b
... 
>>> func4(-1,2,0,3,6)
-7

4.9. Изменение значений объектов, используемых в качестве аргументов функции.

>>> a = 90
>>> def func3(b):
...     b-5*b+67
...    
>>> func3(a)
>>> a
90

Не изменилось, переменная изменялась только в функции, в которой она не была вызвана как глобальная переменная

>>> sps1=[1,2,3,4] 
>>> def func2(sps):                                 
...     sps[1]=99
... 
>>> func2(sps1)
>>> sps1
[1, 99, 3, 4]
>>> print(sps1)
[1, 99, 3, 4]

Изменилось, т.к. список передается по ссылке.

>>> kort=(1,2,3,4) 
>>> func2(kort)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in func2
TypeError: 'tuple' object does not support item assignment

5. Специальные типы пользовательских функций

5.1. Анонимные функции.

>>> import math
>>> anfun1=lambda: 1.5+math.log10(17.23)
>>> anfun1()
2.7362852774480286
>>> anfun2=lambda a,b : a+math.log10(b)
>>> anfun2(17,234)
19.369215857410143
>>> anfun3=lambda a,b=234: a+math.log10(b)
>>> anfun3(100)
102.36921585741014

5.2. Функции-генераторы.

>>> def func5(diap,shag):
...     """ Итератор, возвращающий значения
...     из диапазона от 1 до diap с шагом shag"""
...     for j in range(1,diap+1,shag):
...             yield j
...  
>>> for mm in func5(7,3):
...     print(mm)
... 
1
4
7
>>> alp=func5(7,3)
>>> print(alp.__next__())
1
>>> print(alp.__next__())
4
>>> print(alp.__next__())
7
>>> print(alp.__next__())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Функция дошла до конца итерации, и вывелась ошибка, обозначающее это.

6. Локализация объектов в функциях.

6.1. Примеры на локализацию объектов.

>>> def func7(arg):
...     loc1=15
...     glb=8
...     return loc1*arg
... 
>>> glb=10
>>> res=func7(glb)
>>> res
150
>>> glb
10

glb не изменилось

>>> def func8(arg):
...     loc1=15
...     print(glb)
...     glb=8
...     return loc1*arg
...
>>> res=func8(glb)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in func8
UnboundLocalError: local variable 'glb' referenced before assignment

Мы не обозначили glb в функции до вывода этой переменной, отсюда и ошибка.

>>> glb=11
>>> def func7(arg):
...     loc1=15
...     global glb
...     print(glb)
...     glb=8
...     return loc1*arg
... 
>>> res=func7(glb)
11
>>> res
165
>>> glb
8

Теперь glb изменилась - мы взяли её как глобальную переменную, и в функции изменили значение переменной

6.2. Выявление локализации объекта с помощью функций locals() и globals() из builtins.

>>> globals().keys()
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__cached__', 'platform', 'sys', 'original_ps1', 'is_wsl', 'REPLHooks', 'get_last_command', 'PS1', 'inerz', 'sps', 'spsy', 'TT', 'yy', 'xx', 'pylab', 'sravnenie', 'fnkt', 'v', 'typ_fun', 'func', 'logistfun', 'w', 'z', 'fun_arg', 'zz', 'b1', 'b2', 'b3', 'b4', 'b1234', 'slozh', 'qq', 'dic4', 'qqq', 'e1', 'dd2', 'qqqq', 'func4', 'a', 'func3', 'sps1', 'func2', 'kort', 'math', 'anfun1', 'anfun2', 'anfun3', 'func5', 'mm', 'alp', 'func7', 'glb', 'res', 'func8'])
>>> locals().keys()
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__cached__', 'platform', 'sys', 'original_ps1', 'is_wsl', 'REPLHooks', 'get_last_command', 'PS1', 'inerz', 'sps', 'spsy', 'TT', 'yy', 'xx', 'pylab', 'sravnenie', 'fnkt', 'v', 'typ_fun', 'func', 'logistfun', 'w', 'z', 'fun_arg', 'zz', 'b1', 'b2', 'b3', 'b4', 'b1234', 'slozh', 'qq', 'dic4', 'qqq', 'e1', 'dd2', 'qqqq', 'func4', 'a', 'func3', 'sps1', 'func2', 'kort', 'math', 'anfun1', 'anfun2', 'anfun3', 'func5', 'mm', 'alp', 'func7', 'glb', 'res', 'func8'])

Различий нет, т.к. мы находимся в рабочем пространстве, и все переменные в нем будут как глобальными, так и локальными (т.е. локальные и глобальные переменные будут совпадать).

>>> def func8(arg):
...     loc1=15
...     glb=8
...     print(globals().keys())
...     print(locals().keys())
...     return loc1*arg
... 
>>> hh=func8(glb)
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__cached__', 'platform', 'sys', 'original_ps1', 'is_wsl', 'REPLHooks', 'get_last_command', 'PS1', 'inerz', 'sps', 'spsy', 'TT', 'yy', 'xx', 'pylab', 'sravnenie', 'fnkt', 'v', 'typ_fun', 'func', 'logistfun', 'w', 'z', 'fun_arg', 'zz', 'b1', 'b2', 'b3', 'b4', 'b1234', 'slozh', 'qq', 'dic4', 'qqq', 'e1', 'dd2', 'qqqq', 'func4', 'a', 'func3', 'sps1', 'func2', 'kort', 'math', 'anfun1', 'anfun2', 'anfun3', 'func5', 'mm', 'alp', 'func7', 'glb', 'res', 'func8'])
dict_keys(['arg', 'loc1', 'glb'])
>>> 'glb' in globals().keys() 
True

Теперь мы вывели глобальные и локальные переменные в пространстве функции. Глобальные переменные останутся неизменными, а локальные переменные будут соответствовать тем локальным переменным, что были заданы в самой функции.

6.3. Локализация объектов при использовании вложенных функций.

>>> def func9(arg2,arg3):
...     def func9_1(arg1):
...         loc1=15
...         glb1=8
...         print('glob_func9_1:',globals().keys())
...         print('locl_func9_1:',locals().keys())
...         return loc1*arg1
...     loc1=5
...     glb=func9_1(loc1)
...     print('loc_func9:',locals().keys())
...     print('glob_func9:',globals().keys())
...     return arg2+arg3*glb
... 
>>> kk=func9(10,1)
glob_func9_1: dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__cached__', 'platform', 'sys', 'original_ps1', 'is_wsl', 'REPLHooks', 'get_last_command', 'PS1', 'inerz', 'sps', 'spsy', 'TT', 'yy', 'xx', 'pylab', 'sravnenie', 'fnkt', 'v', 'typ_fun', 'func', 'logistfun', 'w', 'z', 'fun_arg', 'zz', 'b1', 'b2', 'b3', 'b4', 'b1234', 'slozh', 'qq', 'dic4', 'qqq', 'e1', 'dd2', 'qqqq', 'func4', 'a', 'func3', 'sps1', 'func2', 'kort', 'math', 'anfun1', 'anfun2', 'anfun3', 'func5', 'mm', 'alp', 'func7', 'glb', 'res', 'func8', 'hh', 'func9'])
locl_func9_1: dict_keys(['arg1', 'loc1', 'glb1'])
loc_func9: dict_keys(['arg2', 'arg3', 'func9_1', 'loc1', 'glb'])
glob_func9: dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__cached__', 'platform', 'sys', 'original_ps1', 'is_wsl', 'REPLHooks', 'get_last_command', 'PS1', 'inerz', 'sps', 'spsy', 'TT', 'yy', 'xx', 'pylab', 'sravnenie', 'fnkt', 'v', 'typ_fun', 'func', 'logistfun', 'w', 'z', 'fun_arg', 'zz', 'b1', 'b2', 'b3', 'b4', 'b1234', 'slozh', 'qq', 'dic4', 'qqq', 'e1', 'dd2', 'qqqq', 'func4', 'a', 'func3', 'sps1', 'func2', 'kort', 'math', 'anfun1', 'anfun2', 'anfun3', 'func5', 'mm', 'alp', 'func7', 'glb', 'res', 'func8', 'hh', 'func9'])

Были выведены локальные и глобальные переменные внутренней функции (func9_1) и внешней функции (func9).

6.4. Большой пример – моделирование системы, состоящей из последовательного соединения ре-ального двигателя, охваченного отрицательной обратной связью с тахогенератором в ней, и нели-нейного звена типа «зона нечувствительности», при подаче на неё синусоидального входного сигнала.

>>> znach=input('k1,T,k2,Xm,A,F,N=').split(',')
k1,T,k2,Xm,A,F,N=8,5,3,10,2,0.5,1000
>>> k1=float(znach[0])
>>> T=float(znach[1])
>>> k2=float(znach[2])
>>> Xm=float(znach[3])
>>> A=float(znach[4])
>>> F=float(znach[5])
>>> N=int(znach[6])
>>> N=int(znach[6])

>>> import math
>>> vhod = []
>>> for i in range(N):                       
...     vhod.append(A*math.sin((2*i*math.pi)/F))
...
>>> vhod
[0.0, -9.797174393178826e-16, -1.959434878635765e-15, -2.9391523179536475e-15, -3.91886975727153e-15, -4.898587196589413e-15, -5.878304635907295e-15, -6.858022075225178e-15, -7.83773951454306e-15, -8.817456953860943e-15, -9.797174393178826e-15, -3.919860126290071e-14, -1.175660927181459e-14, 1.5685382719271533e-14, ...]

Полнst полученные данные входа в этом файле

>>> def realdvig(xtt,kk1,TT,yti1,ytin1):
...         #Модель реального двигателя
...         yp=kk1*xtt  #усилитель
...         yti1=yp+yti1  #Интегратор
...         ytin1=(yti1+TT*ytin1)/(TT+1)
...         return [yti1,ytin1]
... 
>>> def tahogen(xtt,kk2,yti2):
...         #Модель тахогенератора
...         yp=kk2*xtt   #усилитель
...         yti2=yp+yti2 #интегратор
...         return yti2
... 
>>> def nechus(xtt,gran):
...     #зона нечувствит
...     if xtt<gran and xtt>(-gran):
...         ytt=0
...     elif xtt>=gran:
...         ytt=xtt-gran
...     elif xtt<=(-gran):
...         ytt=xtt+gran
...     return ytt
...
>>> yi1=0;yin1=0;yi2=0
>>> vyhod=[]
>>> for xt in vhod:
...         xt1=xt-yi2   #отрицательная обратная связь
...         [yi1,yin1]=realdvig(xt1,k1,T,yi1,yin1)
...         yi2=tahogen(yin1,k2,yi2)
...         yt=nechus(yin1,Xm)
...         vyhod.append(yt)
... 
>>> print('y=',vyhod)

Полнst полученные данные выхода в этом файле