форкнуто от main/python-labs
Вы не можете выбрать более 25 тем
Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
844 строки
35 KiB
Markdown
844 строки
35 KiB
Markdown
# Отчет по теме 7 "Создание пользовательских функций"
|
|
|
|
***Цель работы: получение навыков создания пользовательских функций для использования в программах на Python.***
|
|
|
|
Терехов Фёдор Валерьевич, А-01-23
|
|
|
|
|
|
>Пользовательская функция – это совокупность инструкций, которая выполняется при обращении к функции из любого места программы. Как и при использовании других языков программирования, в виде функции оформляются инструкции, которые могут многократно потребоваться при выполнении данной программы или могут быть использованы в других программах. Аргументы функции – это ссылки на объекты-источники данных, которые используются при её выполнении. Возвращаемые данные – это результаты вычисления функции, передаваемые в ту часть программы, из которой была вызвана функция. Функция является объектом класса function.
|
|
|
|
|
|
## 1. Создание пользовательской функции.
|
|
|
|
>*Создание функции предполагает выполнение трех операций: формирование функции, ее сохранение и использование.*
|
|
|
|
**В общем виде функция в языке Python представляется так:**
|
|
```python
|
|
def <Имя функции>([<Список аргументов >]):
|
|
[<отступы>″″″<Комментарий по назначению функции>″″″]
|
|
<отступы><Блок инструкций – тело функции>
|
|
[<отступы>return <Значение или вычисляемое выражение>]
|
|
```
|
|
|
|
>Именование функций должно производиться по тем же правилам задания имен: совокупность латинских букв, цифр, знаков подчеркивания. Имя должно начинаться с буквы или знака подчеркивания и не должно совпадать с зарезервированными идентификаторами или ключевыми словами, а также не должно содержать пробелов. Желательно использовать мнемонические имена, отражающие назначение функции. Функция считается оконченной, если в очередной строке нет отступов или их число меньше, чем в отступах в функции. Если при выполнении функции будет выполнена инструкция return, то выполнение функции прекращается с возвратом значения, следующего за этой инструкцией. Однако наличие этой инструкции в функции является необязательным.
|
|
Если в Блоке инструкций только одна инструкция, её можно записывать без отступов сразу за знаком «:».
|
|
|
|
Пример 1.1:
|
|
|
|
**Первый пример: функция – без аргументов.**
|
|
|
|
```python
|
|
def uspeh():
|
|
"""Подтверждение успеха операции"""
|
|
print('Выполнено успешно!')
|
|
uspeh()
|
|
print("Класс объекта uspeh:", type(uspeh))
|
|
print("Пространство имен:", dir())
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
Выполнено успешно!
|
|
Класс объекта uspeh: <class 'function'>
|
|
Пространство имен: ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'uspeh']
|
|
```
|
|
|
|
```python
|
|
help(uspeh)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
Help on function uspeh in module __main__:
|
|
|
|
uspeh()
|
|
Подтверждение успеха операции
|
|
```
|
|
|
|
Пример 1.2:
|
|
|
|
**Пример функции с аргументами.**
|
|
|
|
```python
|
|
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)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
16 больше 5
|
|
```
|
|
|
|
```python
|
|
def sravnenie(a,b):
|
|
"""Сравнение a и b"""
|
|
if a>b:
|
|
print(a,' больше ',b)
|
|
elif a<b:
|
|
print(a, ' меньше ',b)
|
|
else:
|
|
print(a, ' равно ',b)
|
|
n,m="wsd","wd"; sravnenie(n,m)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
wsd больше wd
|
|
```
|
|
|
|
*Объяснение поведения программы:*
|
|
*Сравниваются строки "wsd" и "wd". Строки сравниваются лексикографически (посимвольно). Первые символы 'w' и 'w' равны. Вторые символы 's' и 'd' - 's' имеет больший код, чем 'd'. Поэтому "wsd" > "wd". Выполняется условие a > b и выводится "wsd больше wd".*
|
|
|
|
Пример 1.3:
|
|
|
|
**Пример функции, содержащей return.**
|
|
|
|
```python
|
|
def logistfun(b,a):
|
|
"""Вычисление логистической функции"""
|
|
import math
|
|
return a/(1+math.exp(-b))
|
|
|
|
v,w=1,0.7; z=logistfun(w,v)
|
|
print(z)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
0.6681877721681662
|
|
```
|
|
|
|
Пример 1.4:
|
|
|
|
**Сложение для разных типов аргументов.**
|
|
|
|
```python
|
|
def slozh(a1,a2,a3,a4):
|
|
""" Сложение значений четырех аргументов"""
|
|
return a1+a2+a3+a4
|
|
print(slozh(1,2,3,4)) # Сложение чисел
|
|
print(slozh('1','2','3','4')) # Сложение строк
|
|
b1=[1,2];b2=[-1,-2];b3=[0,2];b4=[-1,-1]
|
|
q=slozh(b1,b2,b3,b4) #Сложение списков
|
|
print(q)
|
|
tuple1=(1,2);tuple2=(-1,-2);tuple3=(0,2);tuple4=(-1,-1)
|
|
print(slozh(tuple1,tuple2,tuple3,tuple4))
|
|
dict1={'a':1,'b':2};dict2={'a':-1,'b':-2};dict3={'a':0,'b':2};dict4={'a':-1,'b':-1}
|
|
print(slozh(dict1,dict2,dict3,dict4))
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
10
|
|
1234
|
|
[1, 2, -1, -2, 0, 2, -1, -1]
|
|
(1, 2, -1, -2, 0, 2, -1, -1)
|
|
Traceback (most recent call last):
|
|
File "/Users/fedorterekhov/Library/Mobile Documents/com~apple~CloudDocs/Учёба/3 курс/POAS_labs/python-labs/TEMA7/task1.4.py", line 12, in <module>
|
|
print(slozh(dict1,dict2,dict3,dict4))
|
|
File "/Users/fedorterekhov/Library/Mobile Documents/com~apple~CloudDocs/Учёба/3 курс/POAS_labs/python-labs/TEMA7/task1.4.py", line 3, in slozh
|
|
return a1+a2+a3+a4
|
|
TypeError: unsupported operand type(s) for +: 'dict' and 'dict'
|
|
```
|
|
|
|
*В Python словари напрямую не поддерживают операции сложения.*
|
|
|
|
Пример 1.5:
|
|
|
|
**Функция, реализующая модель некоторого устройства, на вход которого в текущий момент поступает сигнал х, на выходе получается сигнал y.**
|
|
|
|
```python
|
|
import matplotlib.pyplot as plt
|
|
|
|
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)
|
|
|
|
# Построение графика
|
|
plt.plot(sps, spsy)
|
|
plt.xlabel('Входное значение')
|
|
plt.ylabel('Выходное значение')
|
|
plt.title('График выходного сигнала')
|
|
plt.show()
|
|
```
|
|
|
|
Ответ программы:
|
|

|
|
|
|
## 2. Функции как объекты.
|
|
|
|
### 2.1. Получение списка атрибутов объекта-функции.
|
|
|
|
```python
|
|
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)
|
|
|
|
print(dir(inerz))
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
['__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__']
|
|
```
|
|
|
|
```python
|
|
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)
|
|
|
|
|
|
print(inerz.__doc__)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
Модель устройства с памятью:
|
|
x - текущее значение входного сигнала,
|
|
T - постоянная времени,
|
|
ypred - предыдущее значение выхода системы
|
|
```
|
|
|
|
```python
|
|
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)
|
|
|
|
|
|
print(inerz.__doc__)
|
|
help(inerz)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
Help on function inerz in module __main__:
|
|
|
|
inerz(x, T, ypred)
|
|
Модель устройства с памятью:
|
|
x - текущее значение входного сигнала,
|
|
T - постоянная времени,
|
|
ypred - предыдущее значение выхода системы
|
|
```
|
|
|
|
*Информация взята из описания функции в тройных кавычках.*
|
|
|
|
|
|
### 2.2. Сохранение ссылки на объект-функцию в другой переменной.
|
|
|
|
```python
|
|
def sravnenie(a,b):
|
|
"""Сравнение a и b"""
|
|
if a>b:
|
|
print(a,' больше ',b)
|
|
elif a<b:
|
|
print(a, ' меньше ',b)
|
|
else:
|
|
print(a, ' равно ',b)
|
|
fnkt=sravnenie
|
|
v=16
|
|
fnkt(v,23)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
16 меньше 23
|
|
```
|
|
|
|
### 2.3. Возможность альтернативного определения функции в программе.
|
|
|
|
```python
|
|
typ_fun=8
|
|
if typ_fun==1:
|
|
def func():
|
|
print('Функция 1')
|
|
else:
|
|
def func():
|
|
print('Функция 2')
|
|
|
|
func()
|
|
```
|
|
|
|
Ответ программы (1 попытка):
|
|
```shell
|
|
Функция 2
|
|
```
|
|
|
|
>В данном случае, функция func() определяется в зависимости от значения переменной typ_fun. Если typ_fun равно 1, то будет определена функция func(), которая выводит сообщение "Функция 1". Если typ_fun не равно 1, то будет определена функция func(), которая выводит сообщение "Функция 2".
|
|
|
|
## 3. Аргументы функции.
|
|
|
|
### 3.1. Возможность использования функции в качестве аргумента другой функции.
|
|
|
|
```python
|
|
def logistfun(b,a):
|
|
"""Вычисление логистической функции"""
|
|
import math
|
|
return a/(1+math.exp(-b))
|
|
def fun_arg(fff,a,b,c):
|
|
"""fff-имя функции, используемой
|
|
в качестве аргумента функции fun_arg"""
|
|
return a+fff(c,b)
|
|
|
|
zz=fun_arg(logistfun,-3,1,0.7)
|
|
print(zz)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
-2.3318122278318336
|
|
```
|
|
|
|
### 3.2. Обязательные и необязательные аргументы.
|
|
|
|
```python
|
|
def logistfun(a,b=1): #Аргумент b – необязательный; значение по умолчанию=1
|
|
"""Вычисление логистической функции"""
|
|
import math
|
|
return b/(1+math.exp(-a))
|
|
|
|
print(logistfun(0.7)) #Вычисление со значением b по умолчанию
|
|
print(logistfun(0.7,2)) #Вычисление с заданным значением b
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
0.6681877721681662
|
|
1.3363755443363323
|
|
```
|
|
|
|
### 3.3. Возможность обращения к функции с произвольным (непозиционным) расположением аргументов. При этом надо в обращении к функции указывать имена аргументов.
|
|
|
|
```python
|
|
def logistfun(a,b=1):
|
|
"""Вычисление логистической функции"""
|
|
import math
|
|
return b/(1+math.exp(-a))
|
|
|
|
print(logistfun(b=0.5,a=0.8)) # Ссылки на аргументы поменялись местами
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
0.34498724056380625
|
|
```
|
|
|
|
### 3.4. Пример со значениями аргументов функции, содержащимися в списке или кортеже.
|
|
|
|
```python
|
|
def slozh(a1,a2,a3,a4):
|
|
""" Сложение значений четырех аргументов"""
|
|
return a1+a2+a3+a4
|
|
b1=[1,2];b2=[-1,-2];b3=[0,2];b4=[-1,-1]
|
|
b1234=[b1,b2,b3,b4] # Список списков из п.2.4
|
|
qq=slozh(*b1234) #Перед ссылкой на список или кортеж надо ставить звездочку
|
|
print(qq)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
[1, 2, -1, -2, 0, 2, -1, -1]
|
|
```
|
|
|
|
### 3.5. Пример со значениями аргументов функции, содержащимися в словаре.
|
|
|
|
```python
|
|
def slozh(a1,a2,a3,a4):
|
|
""" Сложение значений четырех аргументов"""
|
|
return a1+a2+a3+a4
|
|
dic4={"a1":1,"a2":2,"a3":3,"a4":4}
|
|
qq=slozh(**dic4) #Перед ссылкой на словарь надо ставить две звездочки
|
|
print(qq)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
10
|
|
```
|
|
|
|
### 3.6. Смешанные ссылки.
|
|
|
|
```python
|
|
def slozh(a1,a2,a3,a4):
|
|
""" Сложение значений четырех аргументов"""
|
|
return a1+a2+a3+a4
|
|
e1=(-1,6);dd2={'a3':3,'a4':9}
|
|
qq=slozh(*e1,**dd2)
|
|
print(qq)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
17
|
|
```
|
|
|
|
### 3.7. Переменное число аргументов у функции.
|
|
|
|
```python
|
|
def func4(*kort7):
|
|
"""Произвольное число аргументов в составе кортежа"""
|
|
smm=0
|
|
for elt in kort7:
|
|
smm+=elt
|
|
return smm
|
|
|
|
print(func4(-1,2)) #Обращение к функции с 2 аргументами
|
|
print(func4(-1,2,0,3,6)) #Обращение к функции с 5 аргументами
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
1
|
|
10
|
|
```
|
|
|
|
### 3.8. Комбинация аргументов.
|
|
|
|
```python
|
|
def func4(a,b=7,*kort7): #Аргументы: a-позиционный, b- по умолчанию + кортеж
|
|
"""Кортеж - сборка аргументов - должен быть последним!"""
|
|
smm=0
|
|
for elt in kort7:
|
|
smm+=elt
|
|
return a*smm+b
|
|
print(func4(-1,2,0,3,6))
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
-7
|
|
```
|
|
|
|
### 3.9. Изменение значений объектов, используемых в качестве аргументов функции.
|
|
|
|
***Такое изменение возможно только у объектов изменяемого типа.***
|
|
|
|
**Пример с числовым объектом.**
|
|
|
|
```python
|
|
a=90 # Числовой объект – не изменяемый тип
|
|
def func3(b):
|
|
b=5*b+67
|
|
func3(a)
|
|
print(a)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
90
|
|
```
|
|
|
|
>Значение переменной a не изменилось. В данном коде, функция func3(b) принимает аргумент b и выполняет вычисления над ним. Изменения, внесенные в переменную b внутри функции, не влияют на значение переменной a вне функции. Значение переменной a остается неизменным со значением 90.
|
|
|
|
**Пример со списком.**
|
|
|
|
```python
|
|
sps1=[1,2,3,4] #Список – изменяемый тип объекта
|
|
def func2(sps):
|
|
sps[1]=99
|
|
func2(sps1)
|
|
print(sps1)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
[1, 99, 3, 4]
|
|
```
|
|
|
|
>Когда мы вызываем функцию func2(sps1), мы передаем список sps1 в качестве аргумента. Внутри функции, мы меняем значение элемента списка sps с индексом 1, что влечет за собой изменение значения элемента в списке sps1.
|
|
|
|
**Пример с кортежом.**
|
|
|
|
```python
|
|
kort=(1,2,3,4) #Кортеж – неизменяемый тип объекта
|
|
def func2(sps):
|
|
sps[1]=99
|
|
func2(kort)
|
|
print(kort)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
Traceback (most recent call last):
|
|
File "/Users/fedorterekhov/Library/Mobile Documents/com~apple~CloudDocs/Учёба/3 курс/POAS_labs/python-labs/TEMA7/task3.9.3.py", line 4, in <module>
|
|
func2(kort)
|
|
File "/Users/fedorterekhov/Library/Mobile Documents/com~apple~CloudDocs/Учёба/3 курс/POAS_labs/python-labs/TEMA7/task3.9.3.py", line 3, in func2
|
|
sps[1]=99
|
|
TypeError: 'tuple' object does not support item assignment
|
|
```
|
|
|
|
>Причина этой ошибки заключается в том, что кортеж (kort) является неизменяемым типом объекта, и поэтому мы не можем изменять его элементы.
|
|
|
|
## 4. Специальные типы пользовательских функций.
|
|
|
|
### 4.1. Анонимные функции.
|
|
|
|
*Анонимные функции или по-другому их называют лямбда-функциями – это функции без имени (поэтому их и называют анонимными), определяемые по следующей схеме:*
|
|
|
|
***Общее правило написания:***
|
|
lambda [<Аргумент1>[,<Аргумент2>,…]]:<Возвращаемое значение или выражение>
|
|
|
|
*Анонимная функция возвращает ссылку на объект-функцию, которую можно присвоить другому объекту.*
|
|
|
|
```python
|
|
import math
|
|
anfun1=lambda: 1.5+math.log10(17.23) #Анонимная функция без аргументов
|
|
print(anfun1()) # Обращение к объекту-функции
|
|
anfun2=lambda a,b : a+math.log10(b) #Анонимная функция с 2 аргументами
|
|
print(anfun2(17,234))
|
|
anfun3=lambda a,b=234: a+math.log10(b) #Функция с необязательным вторым аргументом
|
|
print(anfun3(100))
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
2.7362852774480286
|
|
19.369215857410143
|
|
102.36921585741014
|
|
```
|
|
|
|
### 4.2. Функции-генераторы.
|
|
|
|
*Это – такие функции, которые используются в итерационных процессах, позволяя на каждой итерации получать одно из значений. Для этого в функцию включают инструкцию yield приостанавливающую её выполнение и возвращающую очередное значение.*
|
|
|
|
```python
|
|
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)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
1
|
|
4
|
|
7
|
|
```
|
|
|
|
>Здесь при каждом обращении к функции будет генерироваться только одно очередное значение.
|
|
|
|
*При программировании задач у таких функций часто используют метод __next__, активирующий очередную итерацию выполнения функции.*
|
|
|
|
```python
|
|
def func5(diap,shag):
|
|
""" Итератор, возвращающий значения
|
|
из диапазона от 1 до diap с шагом shag"""
|
|
for j in range(1,diap+1,shag):
|
|
yield j
|
|
|
|
alp=func5(7,3)
|
|
print(alp.__next__())
|
|
print(alp.__next__())
|
|
print(alp.__next__())
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
1
|
|
4
|
|
7
|
|
```
|
|
|
|
Если попытаться выполнить ещё раз инструкцию print(alp.__next__()), выведется ошибка:
|
|
```shell
|
|
1
|
|
4
|
|
7
|
|
Traceback (most recent call last):
|
|
File "/Users/fedorterekhov/Library/Mobile Documents/com~apple~CloudDocs/Учёба/3 курс/POAS_labs/python-labs/TEMA7/task4.2.py", line 11, in <module>
|
|
print(alp.__next__())
|
|
StopIteration
|
|
```
|
|
|
|
*После получения значений 1, 4 и 7, вызов alp.__next__() возвращает ошибку StopIteration, потому что все значения из итератора уже получены.*
|
|
|
|
## 5. Локализация объектов в функциях.
|
|
|
|
>По отношению к функции все объекты подразделяются на локальные и глобальные. Локальными являются объекты, которые создаются в функциях присваиванием им некоторых значений. Они записываются в пространство имен, создаваемое в функции. Глобальные – это те объекты, значения которых заданы вне функции. Они определены в пространствах имен вне функции.
|
|
Локализация может быть переопределена путем прямого объявления объектов как глобальных с помощью дескриптора global.
|
|
|
|
### 5.1. Примеры на локализацию объектов.
|
|
|
|
***Одноименные локальный и глобальный объекты.***
|
|
|
|
```python
|
|
glb=10
|
|
def func7(arg):
|
|
loc1=15
|
|
glb=8
|
|
return loc1*arg
|
|
|
|
res=func7(glb)
|
|
print(res)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
150
|
|
```
|
|
|
|
* *Объект glb является глобальной переменной и используется внутри функции func7(arg). Внутри функции, значение переменной glb изменяется на 8. Однако, изменение значения глобальной переменной внутри функции не влияет на ее значение вне функции.*
|
|
* *Объект arg передается в качестве аргумента функции func7(arg) и используется внутри функции для вычисления результата. Значение arg остается неизменным вне функции.*
|
|
|
|
***Ошибка в использовании локального объекта.***
|
|
|
|
```python
|
|
glb=10
|
|
def func8(arg):
|
|
loc1=15
|
|
print(glb)
|
|
glb=8
|
|
return loc1*arg
|
|
|
|
res=func8(glb)
|
|
print(res)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
Traceback (most recent call last):
|
|
File "/Users/fedorterekhov/Library/Mobile Documents/com~apple~CloudDocs/Учёба/3 курс/POAS_labs/python-labs/TEMA7/task6.1.2.py", line 8, in <module>
|
|
res=func8(glb)
|
|
File "/Users/fedorterekhov/Library/Mobile Documents/com~apple~CloudDocs/Учёба/3 курс/POAS_labs/python-labs/TEMA7/task6.1.2.py", line 4, in func8
|
|
print(glb)
|
|
UnboundLocalError: local variable 'glb' referenced before assignment
|
|
```
|
|
|
|
>Ошибка UnboundLocalError возникает, когда переменная, используемая внутри функции, не была объявлена в области видимости функции или не была присвоена до использования. Переменная glb объявлена как глобальная переменная, но внутри функции func8(arg) она используется до того, как ей будет присвоено новое значение. Это вызывает ошибку UnboundLocalError, так как переменная glb не была объявлена в области видимости функции.
|
|
|
|
***Переопределение локализации объекта.***
|
|
|
|
```python
|
|
glb=11
|
|
def func7(arg):
|
|
loc1=15
|
|
global glb
|
|
print(glb)
|
|
glb=8
|
|
return loc1*arg
|
|
|
|
res=func7(glb)
|
|
print(res)
|
|
print(glb)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
11
|
|
165
|
|
8
|
|
```
|
|
|
|
### 5.2. Выявление локализации объекта с помощью функций locals() и globals() из builtins.
|
|
|
|
>Эти функции возвращают словари, ключами в которых будут имена объектов, являющихся, соответственно, локальными или глобальными на уровне вызова этих функций.
|
|
|
|
```python
|
|
glb=11
|
|
def func7(arg):
|
|
loc1=15
|
|
global glb
|
|
print(glb)
|
|
glb=8
|
|
return loc1*arg
|
|
|
|
res=func7(glb)
|
|
print(globals().keys()) #Перечень глобальных объектов
|
|
print(locals().keys()) #Перечень локальных объектов
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
11
|
|
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', 'glb', 'func7', 'res'])
|
|
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', 'glb', 'func7', 'res'])
|
|
```
|
|
|
|
*В этих перечнях нет различий, тк locals().keys() возвращает список имен локальных объектов. Это означает, что это список имен всех переменных, функций и других объектов, определенных в текущей функции или блока кода. В данном коде locals().keys() записана в основной блок кода. Поэтому перечни совпадают.*
|
|
|
|
```python
|
|
glb=11
|
|
def func8(arg):
|
|
loc1=15
|
|
glb=8
|
|
print(globals().keys()) #Перечень глобальных объектов
|
|
print(locals().keys()) #Перечень локальных объектов
|
|
return loc1*arg
|
|
|
|
res=func8(glb)
|
|
print('glb' in globals().keys())
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', 'glb', 'func8'])
|
|
dict_keys(['arg', 'loc1', 'glb'])
|
|
True
|
|
```
|
|
|
|
* *globals().keys() возвращает список имен глобальных объектов. Это означает, что это список имен всех глобальных переменных, функций, модулей и других объектов, доступных в текущем контексте.*
|
|
* *locals().keys() возвращает список имен локальных объектов. Это означает, что это список имен всех переменных, функций и других объектов, определенных в текущей функции или блока кода.*
|
|
|
|
### 5.3. Локализация объектов при использовании вложенных функций.
|
|
|
|
```python
|
|
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)
|
|
print(kk)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
glob_func9_1: dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', '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__', '__file__', '__cached__', 'func9'])
|
|
85
|
|
```
|
|
|
|
*Анализируя вывод на экран, мы можем увидеть, что:*
|
|
|
|
* *Внутри функции func9_1(arg1), переменная loc1 и глобальная переменная glb1 объявляются и используются. Вывод locals().keys() внутри func9_1(arg1) показывает, что arg1, loc1 и glb1 являются локальными объектами.*
|
|
* *Внутри функции func9(arg2, arg3), переменная loc1 и глобальная переменная glb объявляются и используются. Вывод locals().keys() внутри func9(arg2, arg3) показывает, что arg2, arg3, glb и loc1 являются локальными объектами.*
|
|
* *В глобальном контексте, функции func9(arg2, arg3) и func9_1(arg1) являются глобальными объектами. Вывод globals().keys() внутри func9_1(arg1) и func9(arg2, arg3) показывает, что arg2, arg3, func9 и kk являются глобальными объектами.*
|
|
|
|
### 5.4. Большой пример – моделирование системы, состоящей из последовательного соединения реального двигателя, охваченного отрицательной обратной связью с тахогенератором в ней, и нелинейного звена типа «зона нечувствительности», при подаче на неё синусоидального входного сигнала.
|
|
|
|
>Реальный двигатель: последовательное соединение усилителя с коэффициентом усиления k1,интегратора: y(t)=x(t)+y(t-1), и инерционного звена: y(t)=(x(t)+T*y(t-1)) / (T+1) с постоянной времени Т.
|
|
Тахогенератор: последовательное соединение усилителя с коэффициентом усиления k2 и интегратора: y(t)=x(t)+y(t-1).
|
|
Нелинейное звено типа «зона нечувствительности»: y=0 при -xm≤ x ≤xm, y=x-xm при x>xm, y=x+xm при x<-xm.
|
|
Таким образом, система характеризуется параметрами: k1, T, k2, xm. Входной сигнал характеризуется параметрами: A (амплитуда синусоиды) и F (период синусоиды).
|
|
Еще один параметр задачи : N – время (число тактов) подачи сигнала.
|
|
|
|
```python
|
|
import math
|
|
|
|
znach=input('k1,T,k2,Xm,A,F,N=').split(',')
|
|
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])
|
|
|
|
vhod=[]
|
|
for i in range(N):
|
|
vhod.append(A*math.sin((2*i*math.pi)/F))
|
|
|
|
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)
|
|
```
|
|
|
|
Ответ программы:
|
|
```shell
|
|
k1,T,k2,Xm,A,F,N=2.0,5.0,0.5,0.3,1.0,20.0,15
|
|
y= [0, 0, 0.06760452541690626, 0.4793408756948438, 0.931148162040943, 1.2274710293386355, 1.1233305479712674, 0.400902344081069, -0.42732659995249095, -2.4154244800859455, -4.520514725079971, -6.022685151402792, -6.061564289571653, -3.8945172200444302, 0.16254138526353118]
|
|
```
|