25 KiB
Отчет по теме 7. Создание пользовательских функций.
Филиппова Евгения, А-01-23
1. Запуск интерактивной оболочки IDLE
import os
os.chdir(r'C:\Users\filip\Desktop\python-labs\TEMA7')
os.getcwd()
'C:\\Users\\filip\\Desktop\\python-labs\\TEMA7'
Пользовательская функция – это совокупность инструкций, которая выполняется при обращении к функции из любого места программы. . Аргументы функции – это ссылки на объекты-источники данных, которые используются при её выполнении. Возвращаемые данные – это результаты вычисления функции, передаваемые в ту часть программы, из которой была вызвана функция. Функция является объектом класса function.
2. Создание пользовательской функции
Создание функции в 3 этапах:
- формирование функции;
- её сохранение;
- использование функции.
В общем виде: def <Имя функции>([<Список аргументов >]): [<отступы><Комментарий по назначению функции>] <отступы><Блок инструкций – тело функции> [<отступы>return <Значение или вычисляемое выражение>]
2.1 Функция без аргументов
def uspeh():
"""Подтверждение успеха операции""" #docstring строка документации
print('Выполнено успешно!')
uspeh()
Выполнено успешно!
type(uspeh)
<class 'function'>
dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'os', 'uspeh']
help(uspeh)
Help on function uspeh in module __main__:
uspeh()
Подтверждение успеха операции
В качестве помощи выведена информация о предназначении созданной функции.
В docstring следует добавить информацию об аргументах и возврате значений:
def uspeh():
"""
Функция для подтверждения успешного выполнения операции.
Выводит на экран сообщение 'Выполнено успешно!'
без возврата какого-либо значения.
Args:
Нет аргументов
Returns:
None
"""
print('Выполнено успешно!')
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
Проверка, можно ли выполнить с аргументами - символьными строками:
n,m='16','5';sravnenie(n,m)
16 меньше 5
Сравнение происходит по коду из Unicode посимвольно. 1<5, поэтому такой результат.
2.3 Пример функции, содержащей return
def logistfun(b,a):
"""Вычисление логистической функции"""
import math
return a/(1+math.exp(-b))
v,w=1,0.7;z=logistfun(w,v)
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]
2.5. Функция, реализующая модель некоторого устройства, на вход которого в текущий момент поступает сигнал х, на выходе получается сигнал y:
import pylab
pylab.plot(spsy)
[<matplotlib.lines.Line2D object at 0x0000023A29215590>]
pylab.title('Выходной сигнал фильтра')
Text(0.5, 1.0, 'Выходной сигнал фильтра')
pylab.xlabel('Номер отсчета')
Text(0.5, 0, 'Номер отсчета')
pylab.ylabel('Значение сигнала')
Text(0, 0.5, 'Значение сигнала')
pylab.plot(sps)
[<matplotlib.lines.Line2D object at 0x0000023A292156D0>]
pylab.show()
3. Функции как объекты.
3.1. Получение списка атрибутов объекта - функции.
Получение списка атрибутов объекта - функции
dir(inerz)
['__annotations__', '__builtins__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__getstate__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__type_params__']
Пример использования атрибута функции (документация из справки по функции):
inerz.__doc__
'Модель устройства с памятью:\nx- текущее значение вх.сигнала,\nT -постоянная времени,\nypred - предыдущее значение выхода устройства'
Справка по объекту:
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" вывыдится так как условие о значении переменной не выполнено. Сработала инструкция else.
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): #Аргумент b – необязательный; значение по умолчанию=1
"""Вычиление логистической функции"""
import math
return b/(1+math.exp(-a))
logistfun(0.7) #Вычисление со значением b по умолчанию
0.6681877721681662
logistfun(0.7,2) #Вычисление с заданным значением b
1.3363755443363323
4.3. Изучение возмозность обращения к функции с непозиционным расположением аргументов.
Необходимо в образении функции указать имена аргументов:
logistfun(b=0.5,a=0.8) # Ссылки на аргументы поменялись местами
0.34498724056380625
4.4. Пример со значениями аргументов функции, содержащимися в списке или кортеже.
b1234=[b1,b2,b3,b4] # Список списков из п.2.4
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}
qqq=slozh(*e1,**dd2)
qqq
17
4.8. Комбинация аргументов.
def func4(a,b=7,*kort7): #Аргументы: a-позиционный, b- по умолчанию + кортеж
"""Кортеж - сборка аргументов - должен быть последним!"""
smm=0
for elt in kort7:
smm+=elt
return a*smm+b
func4(-1,2,0,3,6)
-7
Здесь кортеж собирает дополнительные позиционные аргументы переданные в функцию. -1 = a, 2 = b, (0,3,6) = kort7.
Пример, когда в качестве аргументов функции в комбинации используется словарь.
def func_dict(a, b=7, **kort_dict):
if 'x' in kort_dict:
print(kort_dict['x'])
return a + b + sum(kort_dict.values())
result = func_dict(5, 3, x=10, y=20, z=30)
10
4.9. Изменение значений объектов, используемых в качестве аргументов функции.
Это возможно только у объектов изменяемого типа.
a=90
def func3(b):
a=5*b+67
func3(a)
a
90
Значение а - не изменилось, так как числа в Python относятся к неизменяемым типам данных. Когда мы передаем число в функцию и присваиваем параметру новое значение, создается новый объект, а исходный остается без изменений.
sps1=[1,2,3,4]
def func2(sps):
sps[1]=99
func2(sps1)
print(sps1)
[1, 99, 3, 4]
Список относится к изменяемым объектам.
Пример с кортежем:
kort=(1,2,3,4) #Кортеж – неизменяемый тип объекта
func2(kort)
TypeError: 'tuple' object does not support item assignment
Кортеж не изменился, потому что даже код не выполнился. Кортеж не поддерживает присваивание элементам, так как они не изменяемые.
5. Специальные типы пользовательских функций.
5.1. Анонимные функциию
Анонимные функции/лямбда-функциями – это функции без имени (поэтому и анонимные), определяемые по следующей схеме:
lambda [<Аргумент1>[,<Аргумент2>,…]]:<Возвращаемое значение или выражение>
Анонимная функция возвращает ссылку на объект-функцию, которую можно присвоить другому объекту.
anfun1=lambda: 1.5+math.log10(17.23) #Анонимная функция без аргументов
anfun1()
2.7362852774480286
anfun2=lambda a,b : a+math.log10(b) #Анонимная функция с 2 аргументами
anfun2(17,234)
19.369215857410143
anfun3=lambda a,b=234: a+math.log10(b) #Функция с необязательным вторым аргументом
anfun3(100)
102.36921585741014
5.2. Функции - генераторы.
Функции, используемые в итерационных процессах, позволяя на каждой итерации получать одно из значений. Для этого в функцию включают инструкцию yield приостанавливающую её выполнение и возвращающую очередное значение. Пример:
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 "<pyshell#232>", line 1, in <module>
print(alp.__next__())
StopIteration
# StopIteration - значения кончились
6. Локализация объектов в функциях.
6.1. Примеры на локализацию объектов.
Пример 1. Одноименные локальный и глобальный объекты.
glb=10
def func7(arg):
loc1=15
glb=8
return loc1*arg
res=func7(glb)
res
150
glb
10
При получении результата использовались loc1 и arg=10. Значение glb не изменилось так как созданная внутри функции локальная переменная glb никак не связана с глобальной переменной glb.
Пример 2. Ошибка в использовании локального объекта:
def func8(arg):
loc1=15
print(glb)
glb=8
return loc1*arg
res=func8(glb)
Traceback (most recent call last):
File "<pyshell#249>", line 1, in <module>
res=func8(glb)
File "<pyshell#248>", line 3, in func8
print(glb)
UnboundLocalError: cannot access local variable 'glb' where it is not associated with a value
Ошибка возникает из-за того, что интерпретатор считает переменную glb локальной внутри функции, но пытается использовать её до присваивания значения.
Пример 3. Переопределение локализации объекта:
glb=11
def func7(arg):
loc1=15
global glb
print(glb)
glb=8
return loc1*arg
res=func7(glb)
11
print(res)
165
glb
8
Значение glb после завершения работы функции изменилось благодаря global glb внутри функции. Числа неизменяемы, но ссылка на них может меняться.
6.2. Выявление локализации объекта с помощью функций locals(), globals() из builtins().
globals().keys()
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', 'os', 'uspeh', 'sravnenie', 'n', 'm', 'logistfun', 'v', 'w', 'z', 'math', 'slozh', 'b1', 'b2', 'b3', 'b4', 'q', 'inerz', 'sps', 'spsy', 'TT', 'yy', 'xx', 'matplotlib', 'pylab', 'fnkt', 'typ_fun', 'func', 'fun_arg', 'zz', 'b1234', 'qq', 'dic4', 'qqq', 'e1', 'dd2', 'func4', 'func_dict', 'result', 'a', 'func3', 'sps1', 'func2', 'kort', 'anfun1', 'anfun2', 'anfun3', 'func5', 'mm', 'alp', 'glb', 'func7', 'res', 'func8'])
locals().keys()
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', 'os', 'uspeh', 'sravnenie', 'n', 'm', 'logistfun', 'v', 'w', 'z', 'math', 'slozh', 'b1', 'b2', 'b3', 'b4', 'q', 'inerz', 'sps', 'spsy', 'TT', 'yy', 'xx', 'matplotlib', 'pylab', 'fnkt', 'typ_fun', 'func', 'fun_arg', 'zz', 'b1234', 'qq', 'dic4', 'qqq', 'e1', 'dd2', 'func4', 'func_dict', 'result', 'a', 'func3', 'sps1', 'func2', 'kort', 'anfun1', 'anfun2', 'anfun3', 'func5', 'mm', 'alp', 'glb', 'func7', '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__', 'os', 'uspeh', 'sravnenie', 'n', 'm', 'logistfun', 'v', 'w', 'z', 'math', 'slozh', 'b1', 'b2', 'b3', 'b4', 'q', 'inerz', 'sps', 'spsy', 'TT', 'yy', 'xx', 'matplotlib', 'pylab', 'fnkt', 'typ_fun', 'func', 'fun_arg', 'zz', 'b1234', 'qq', 'dic4', 'qqq', 'e1', 'dd2', 'func4', 'func_dict', 'result', 'a', 'func3', 'sps1', 'func2', 'kort', 'anfun1', 'anfun2', 'anfun3', 'func5', 'mm', 'alp', 'glb', 'func7', 'res', 'func8'])
dict_keys(['arg', 'loc1', 'glb'])
Проверка наличия объекта в перечне глобальных объектов:
'glb' in globals().keys()
True
На инструкцию print(locals().keys()) внутри функции получен соответствующий список локальных объектов. Список глобальных объектов остался неизменным.
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('glob_func9:',globals().keys())
print('locl_func9:',locals().keys())
return arg2+arg3*glb
kk=func9(10,1)
glob_func9_1: dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', 'os', 'uspeh', 'sravnenie', 'n', 'm', 'logistfun', 'v', 'w', 'z', 'math', 'slozh', 'b1', 'b2', 'b3', 'b4', 'q', 'inerz', 'sps', 'spsy', 'TT', 'yy', 'xx', 'matplotlib', 'pylab', 'fnkt', 'typ_fun', 'func', 'fun_arg', 'zz', 'b1234', 'qq', 'dic4', 'qqq', 'e1', 'dd2', 'func4', 'func_dict', 'result', 'a', 'func3', 'sps1', 'func2', 'kort', 'anfun1', 'anfun2', 'anfun3', 'func5', 'mm', 'alp', 'glb', 'func7', 'res', 'func8', 'hh', 'func9'])
locl_func9_1: dict_keys(['arg1', 'loc1', 'glb1'])
glob_func9: dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', 'os', 'uspeh', 'sravnenie', 'n', 'm', 'logistfun', 'v', 'w', 'z', 'math', 'slozh', 'b1', 'b2', 'b3', 'b4', 'q', 'inerz', 'sps', 'spsy', 'TT', 'yy', 'xx', 'matplotlib', 'pylab', 'fnkt', 'typ_fun', 'func', 'fun_arg', 'zz', 'b1234', 'qq', 'dic4', 'qqq', 'e1', 'dd2', 'func4', 'func_dict', 'result', 'a', 'func3', 'sps1', 'func2', 'kort', 'anfun1', 'anfun2', 'anfun3', 'func5', 'mm', 'alp', 'glb', 'func7', 'res', 'func8', 'hh', 'func9'])
locl_func9: dict_keys(['arg2', 'arg3', 'func9_1', 'loc1', 'glb'])
Каждая функция имеет своё локальное пространство имён. Вложенная функция не видит переменные внешней функции, глобальные переменные видны всем функциям, одинаковые имена в разных функциях — разные объекты.
6.4 Моделирование системы
znach=input('k1,T,k2,Xm,A,F,N=').split(',')
k1,T,k2,Xm,A,F,N=2, 5, 0.5, 0.2, 5, 20, 100
znach
['2', ' 5', ' 0.5', ' 0.2', ' 5', ' 20', ' 100']
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])
import math
vhod=[]
for i in range(N):
vhod.append(A*math.sin((2*i*math.pi)/F))
vhod
[0.0, 1.545084971874737, 2.938926261462366, 4.045084971874737, 4.755282581475767, 5.0, 4.755282581475768, 4.045084971874737, 2.9389262614623664, 1.5450849718747375, 6.123233995736766e-16, -1.5450849718747346, -2.938926261462365, -4.045084971874736, -4.755282581475767, -5.0, -4.755282581475768, -4.045084971874738, -2.938926261462367, -1.5450849718747384, -1.2246467991473533e-15, 1.545084971874736, 2.9389262614623615, 4.045084971874736, 4.755282581475767, 5.0, 4.755282581475768, 4.045084971874738, 2.938926261462367, 1.545084971874739, 1.8369701987210296e-15, -1.5450849718747353, -2.938926261462364, -4.045084971874736, -4.755282581475767, -5.0, -4.755282581475769, -4.045084971874738, -2.9389262614623672, -1.5450849718747395, -2.4492935982947065e-15, 1.5450849718747262, 2.9389262614623632, 4.0450849718747355, 4.755282581475765, 5.0, 4.755282581475769, 4.045084971874734, 2.9389262614623677, 1.5450849718747484, 3.061616997868383e-15, -1.5450849718747257, -2.938926261462363, -4.045084971874741, -4.755282581475767, -5.0, -4.755282581475769, -4.045084971874744, -2.9389262614623686, -1.5450849718747488, -3.673940397442059e-15, 1.545084971874742, 2.9389262614623624, 4.04508497187474, 4.755282581475766, 5.0, 4.755282581475769, 4.045084971874745, 2.938926261462369, 1.5450849718747328, 4.2862637970157365e-15, -1.5450849718747415, -2.9389262614623624, -4.045084971874729, -4.755282581475766, -5.0, -4.755282581475769, -4.045084971874735, -2.9389262614623695, -1.5450849718747333, -4.898587196589413e-15, 1.545084971874724, 2.9389262614623473, 4.04508497187474, 4.755282581475766, 5.0, 4.755282581475769, 4.045084971874745, 2.9389262614623846, 1.545084971874734, 5.5109105961630896e-15, -1.5450849718747235, -2.9389262614623615, -4.045084971874728, -4.755282581475772, -5.0, -4.75528258147577, -4.045084971874745, -2.938926261462385, -1.5450849718747346]
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)
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)
y= [0, 0.3150283239582457, 1.6380226270845315, 3.6967043784742186, 5.955740810204715, 7.437355146693178, 6.916652739856338, 3.3045117204053454, -3.436632999762453, -13.377122400429725, -23.902573625399846, -31.413425757013954, -31.607821447858264, -20.772586100222156, 2.11270692631765, 35.30602439138285, 70.91993062949682, 96.93440494343562, 99.12900473346, 65.38348872784154, -8.327676904827948, -114.14057608527706, -226.85021011146713, -307.0967019203927, -308.8377256916654, -193.5696660101084, 51.01933507765006, 395.33583228776763, 756.133884648419, 1004.146305096583, 990.2646197776188, 592.5453813658195, -223.89399528084132, -1353.0198741465508, -2517.0845917069096, -3290.799148701165, -3190.6404746339663, -1830.2106297066937, 885.4823487918924, 4584.145494231121, 8338.074558072989, 10748.861155895518, 10249.31678648254, 5616.61253286302, -3395.8903138692544, -15492.862030077773, -27577.795704976375, -35056.60179382386, -32854.53664822822, -17109.753979655143, 12771.37059301769, 52304.40329194675, 91162.46093366834, 114263.89381920217, 105190.55370550934, 51773.02890240319, -47226.37305314174, -176340.0737276588, -301158.2756604727, -372203.3514180253, -336403.0484315321, -155497.20672475465, 172246.2163168153, 593647.6564708133, 994156.0382059023, 1211560.9131300563, 1074452.5986176156, 462840.9230725401, -621330.3758980577, -1995747.4630206777, -3279411.6114615267, -3940880.1907856367, -3427039.528661954, -1362601.5792743566, 2221100.4359796937, 6700673.051886699, 10810025.37459586, 12809190.093940038, 10915000.463542966, 3957182.5623847847, -7879855.109776793, -22469600.257783413, -35608334.0947499, -41603169.08800506, -34710893.26010073, -11294209.422974238, 27775182.21076063, 75259300.4364765, 117212473.34737757, 135021112.4400896, 110205787.39593415, 31502860.45670514, -97356878.23581645, -251787814.75216538, -385563446.86640865, -437865750.882735, -349295989.55543554, -85116841.91247615, 339589601.3143321, 841470525.1399062]
