# Отчет по теме 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: Пространство имен: ['__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 ab: print(a,' больше ',b) elif a "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 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() ``` Ответ программы: ![График ступенька](images/Figure_1.5.png) ## 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В данном случае, функция 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 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 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 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): 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] ```