# Отчет по Теме 7 Зеленкина Ксения, А-02-23 ## 1. Начало работы. Запустила интерактивную оболочку IDLE и открыла окно текстового редактора, куда буду фиксировать мои дальнейшие действия. ## 2. Создание пользовательской функции. #### 2.1. Первый пример: функция – без аргументов. Проверим функцию: _Код:_ ```py def uspeh(): """Подтверждение успеха операции""" print('Выполнено успешно!') uspeh() ``` _Вывод:_ ```py Выполнено успешно! ``` Определим класс объекта с именем __uspeh__. _Код:_ ```py print(type(uspeh)) ``` _Вывод:_ ```py ``` С помощью инструкции _dir()_ убедимся, что имя функции появилось в пространстве имен. _Код:_ ```py if 'uspeh' in dir(): print("Функция 'uspeh' присутствует в пространстве имен") ``` _Вывод:_ ```py Функция 'uspeh' присутствует в пространстве имен ``` Введём инструкцию _help(uspeh):_ _Код:_ ```py help(uspeh) ``` _Вывод:_ ```py Help on function uspeh in module __main__: uspeh() Подтверждение успеха операции ``` Помощь организуется через docstring - строку документации в тройных кавычках сразу после объявления функции. Python автоматически использует ее для вывода в help(). #### 2.2 Пример функции с аргументами. _Код:_ ```py def sravnenie(a,b): """Сравнение a и b""" if a>b: print(a,' больше ',b) elif a ## 3. Функции как объекты. #### 3.1. Получение списка атрибутов объекта-функции. _Код:_ ```py print(dir(inerz)) ``` _Вывод:_ ```py ['__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__'] ``` Пример использования атрибута функции: _Код:_ ```py print(inerz.__doc__) ``` _Вывод:_ ```py Модель устройства с памятью: x- текущее значение вх.сигнала, T -постоянная времени, ypred - предыдущее значение выхода устройства ``` Даннаяя функция берется непосредственно из строки документации в тройных кавычках внутри функции. Для сравнения, введём инструкцию: _Код:_ ```py help(inerz) ``` _Вывод:_ ```py Help on function inerz in module __main__: inerz(x, T, ypred) Модель устройства с памятью: x- текущее значение вх.сигнала, T -постоянная времени, ypred - предыдущее значение выхода устройства ``` __help()__ - форматирует информацию из __doc__ и добавляет служебные данные о функции #### 3.2. Сохранение ссылки на объект-функцию в другой переменной. _Код:_ ```py fnkt=sravnenie v=16 fnkt(v,23) ``` _Вывод:_ ```py 16 меньше 23 ``` Создали вторую переменную для функции (псевдоним) и применили её. Произошло сравнения числа 16 (записанного в переменную v) и сравнили с числом 23. #### 3.3. Возможность альтернативного определения функции в программе. _Код:_ ```py typ_fun=8 if typ_fun==1: def func(): print('Функция 1') else: def func(): print('Функция 2') func() ``` _Вывод:_ ```py Функция 2 ``` Выводится "Функция 2", потому что условие typ_fun==1 ложно. ## 4. Аргументы функции. #### 4.1. Использование функции в качестве аргумента другой функции _Код:_ ```py 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) ``` _Вывод:_ ```py -2.3318122278318336 ``` #### 4.2. Обязательные и необязательные аргументы Переопределим вычисление логистической функции следующим образом: _Код:_ ```py 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 ``` _Вывод:_ ```py 0.6681877721681662 1.3363755443363323 ``` #### 4.3. Обращения к функции с произвольным (непозиционным) расположением аргументов Изучим возможность обращения к функции с произвольным (непозиционным) расположением аргументов. При этом надо в обращении к функции указывать имена аргументов: _Код:_ ```py print(logistfun(b=0.5, a=0.8)) # Аргументы поменялись местами print(logistfun(a=0.8, b=0.5)) # То же самое, но в другом порядке ``` _Вывод:_ ```py 0.34498724056380625 0.34498724056380625 ``` Все вызовы работают корректно, так как при именованном указании аргументов их порядок не имеет значения. #### 4.4 Пример со значениями аргументов функции, содержащимися в списке или кортеже. _Код:_ ```py b1234 = [b1, b2, b3, b4] # Список списков из п.2.4 qq = slozh(*b1234) # Перед ссылкой на список или кортеж надо ставить звездочку print(qq) ``` _Вывод:_ ```py [1, 2, -1, -2, 0, 2, -1, -1] ``` #### 4.5. Пример со значениями аргументов функции, содержащимися в словаре _Код:_ ```py dic4={"a1":1,"a2":2,"a3":3,"a4":4} qqq=slozh(**dic4) #Перед ссылкой на словарь надо ставить две звездочки print(qqq) ``` _Вывод:_ ```py 10 ``` #### 4.6. Смешанные ссылки _Код:_ ```py e1=(-1,6);dd2={'a3':3,'a4':9} qqqq=slozh(*e1,**dd2) print(qqqq) ``` _Вывод:_ ```py 17 ``` #### 4.7. Переменное число аргументов у функции _Код:_ ```py 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 аргументами ``` _Вывод:_ ```py 1 10 ``` #### 4.8. Комбинация аргументов _Код:_ ```py 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)) ``` _Вывод:_ ```py -7 ``` Для словаря: _Код:_ ```py def func4_dict(a, b=7, **slovar): # a-позиционный, b- по умолчанию, **slovar-словарь """Словарь - сборка именованных аргументов - должен быть последним!""" smm = 0 for key, value in slovar.items(): smm += value return a * smm + b # Вызов функции: print(func4_dict(-1, 2, x=0, y=5, z=6)) ``` _Вывод:_ ```py -9 ``` Функция func4_dict принимает позиционный аргумент a, необязательный b и произвольные именованные аргументы **slovar, которые автоматически собираются в словарь, где ключи - имена аргументов, а значения - их значения, затем суммирует все значения словаря, умножает на a и прибавляет b. #### 4.9. Изменение значений объектов, используемых в качестве аргументов функции. Такое изменение возможно только у объектов изменяемого типа. Пример с числовым объектом^ _Код:_ ```py a=90 # Числовой объект – не изменяемый тип def func3(b): b=5*b+67 print(func3(a)) ``` _Вывод:_ ```py None ``` Исходное значение a осталось 90 - неизменяемые объекты не меняются при передаче в функцию. Пример со списком: _Код:_ ```py sps1=[1,2,3,4] #Список – изменяемый тип объекта def func2(sps): sps[1]=99 print(func2(sps1)) print(sps1) ``` _Вывод:_ ```py None [1, 99, 3, 4] ``` Список изменился, так как списки - изменяемый тип объекта. Кортеж: _Код:_ ```py kort = (1, 2, 3, 4) # Кортеж – неизменяемый тип объекта print(func2(kort)) ``` _Вывод:_ ```py TypeError: 'tuple' object does not support item assignment ``` Кортеж не изменится и возникнет ошибка. ## 5. Специальные типы пользовательских функций #### 5.1. Анонимные функции. Анонимные функции или по-другому их называют лямбда-функциями – это функции без имени. _Код:_ ```py 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)) ``` _Вывод:_ ```py 2.7362852774480286 19.369215857410143 102.36921585741014 ``` #### 5.2. Функции-генераторы. Это – такие функции, которые используются в итерационных процессах, позволяя на каждой итерации получать одно из значений. _Код:_ ```py 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) ``` _Вывод:_ ```py 1 4 7 ``` Здесь при каждом обращении к функции будет генерироваться только одно очередное значение. При программировании задач у таких функций часто используют метод __next__, активирующий очередную итерацию выполнения функции. Например: _Код:_ ```py alp=func5(7,3) print(alp.__next__()) print(alp.__next__()) print(alp.__next__()) ``` _Вывод:_ ```py 1 4 7 ``` попрогбуем вызвать ещё раз _Код:_ ```py alp=func5(7,3) print(alp.__next__()) print(alp.__next__()) print(alp.__next__()) print(alp.__next__()) ``` _Вывод:_ ```py StopIteration ``` При четвертом вызове alp.__next__() возникнет ошибка StopIteration, потому что генератор func5(7,3) уже исчерпал все свои значения (1, 4, 7) и не может произвести следующее значение. ## 6. Локализация объектов в функциях. По отношению к функции все объекты подразделяются на локальные и глобальные. Локальными являются объекты, которые создаются в функциях присваиванием им некоторых значений. Они записываются в пространство имен, создаваемое в функции. Глобальные – это те объекты, значения которых заданы вне функции. Они определены в пространствах имен вне функции. Локализация может быть переопределена путем прямого объявления объектов как глобальных с помощью дескриптора __global.__ #### 6.1. Примеры на локализацию объектов Пример 1. Одноименные локальный и глобальный объекты. _Код:_ ```py glb=10 def func7(arg): loc1=15 glb=8 return loc1*arg res=func7(glb) print(res) ``` _Вывод:_ ```py 150 ``` При вычислении результата использовались локальная переменная loc1=15 и глобальная переменная glb=10 (переданная как аргумент arg), результат 150, при этом значение глобальной переменной glb не изменилось и осталось 10, так как внутри функции glb=8 создала новую локальную переменную, а не изменила глобальную. Пример 2. Ошибка в использовании локального объекта. _Код:_ ```py def func8(arg): loc1=15 print(glb) glb=8 return loc1*arg res=func8(glb) print(res) ``` _Вывод:_ ```py UnboundLocalError: cannot access local variable 'glb' where it is not associated with a value ``` Ошибка возникает потому что Python обнаруживает операцию присваивания glb=8 внутри функции и поэтому считает glb локальной переменной, но при этом выполняется попытка печати значения print(glb) до инициализации этой локальной переменной. Пример 3. Переопределение локализации объекта _Код:_ ```py glb=11 def func7(arg): loc1=15 global glb print(glb) glb=8 return loc1*arg res=func7(glb) print(res) ``` _Вывод:_ ```py 11 165 ``` Значение изменилось #### 6.2. Выявление локализации объекта с помощью функций __locals()__ и __globals()__ из __builtins__. Эти функции возвращают словари, ключами в которых будут имена объектов, являющихся, соответственно, локальными или глобальными на уровне вызова этих функций. Примеры. В командной строке введем инструкции: _Код:_ ```py print(globals().keys()) #Перечень глобальных объектов print(locals().keys()) #Перечень локальных объектов ``` _Вывод:_ ```py #Перечень глобальных объектов dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', 'uspeh', 'sravnenie', 'n', 'm', 'logistfun', 'v', 'w', 'z', 'slozh', 'b1', 'b2', 'b3', 'b4', 'q', 't1', 't2', 't3', 't4', 'inerz', 'sps', 'spsy', 'TT', 'yy', 'xx', 'plt', 'fnkt', 'typ_fun', 'func', 'fun_arg', 'zz', 'b1234', 'qq', 'dic4', 'qqq', 'e1', 'dd2', 'qqqq', 'func4', 'func4_dict', 'a', 'func3', 'sps1', 'func2', 'math', 'anfun1', 'anfun2', 'anfun3', 'func5', 'mm', 'alp', 'glb', 'func7', 'res']) #Перечень локальных объектов dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', 'uspeh', 'sravnenie', 'n', 'm', 'logistfun', 'v', 'w', 'z', 'slozh', 'b1', 'b2', 'b3', 'b4', 'q', 't1', 't2', 't3', 't4', 'inerz', 'sps', 'spsy', 'TT', 'yy', 'xx', 'plt', 'fnkt', 'typ_fun', 'func', 'fun_arg', 'zz', 'b1234', 'qq', 'dic4', 'qqq', 'e1', 'dd2', 'qqqq', 'func4', 'func4_dict', 'a', 'func3', 'sps1', 'func2', 'math', 'anfun1', 'anfun2', 'anfun3', 'func5', 'mm', 'alp', 'glb', 'func7', 'res']) ``` Различий в перечнях нет - в основном режиме выполнения (не внутри функции) глобальная и локальная области видимости совпадают, поэтому globals().keys() и locals().keys() показывают одинаковый набор объектов, так как выполняются в одной области видимости. _Код:_ ```py def func8(arg): loc1=15 glb=8 print(globals().keys()) #Перечень глобальных объектов «изнутри» функции print(locals().keys()) #Перечень локальных объектов «изнутри» функции return loc1*arg hh=func8(glb) ``` _Вывод:_ ```py dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', 'uspeh', 'sravnenie', 'n', 'm', 'logistfun', 'v', 'w', 'z', 'slozh', 'b1', 'b2', 'b3', 'b4', 'q', 't1', 't2', 't3', 't4', 'inerz', 'sps', 'spsy', 'TT', 'yy', 'xx', 'plt', 'fnkt', 'typ_fun', 'func', 'fun_arg', 'zz', 'b1234', 'qq', 'dic4', 'qqq', 'e1', 'dd2', 'qqqq', 'func4', 'func4_dict', 'a', 'func3', 'sps1', 'func2', 'math', 'anfun1', 'anfun2', 'anfun3', 'func5', 'mm', 'alp', 'glb', 'func7', 'res', 'func8']) dict_keys(['arg', 'loc1', 'glb']) ``` __Глобальные объекты__ - все переменные модуля уровня __Локальные объекты__ - только параметры функции (arg) и переменные, созданные внутри функции (loc1, glb) Проверка наличия объекта __glb__ в перечне глобальных объектов: _Код:_ ```py print('glb' in globals().keys()) ``` _Вывод:_ ```py True ``` #### 6.3. Локализация объектов при использовании вложенных функций. Пример: _Код:_ ```py 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) ``` _Вывод:_ ```py 85 ``` Каждая функция имеет свою локальную область видимости: вложенная функция func9_1 видит только свои локальные объекты (arg1, loc1, glb1) и глобальные объекты модуля, но не видит локальные объекты внешней функции func9 (arg2, arg3, loc1), при этом переменная loc1 существует независимо в обеих функциях со своими значениями. #### 6.4 Большой пример ```py 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]) # Создание входного сигнала import math vhod=[] for i in range(N): vhod.append(A*math.sin((2*i*math.pi)/F)) print("Входной сигнал:", vhod) # Функции компонентов системы 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) ``` _Вывод:_ ```py k1,T,k2,Xm,A,F,N=1.5,0.1,0.8,0.2,1.0,10,50 Входной сигнал: [0.0, 0.5877852522924731, 0.9510565162951535, 0.9510565162951536, 0.5877852522924732, 1.2246467991473532e-16, -0.587785252292473, -0.9510565162951535, -0.9510565162951536, -0.5877852522924734, -2.4492935982947064e-16, 0.5877852522924722, 0.9510565162951535, 0.9510565162951536, 0.5877852522924734, 3.6739403974420594e-16, -0.5877852522924728, -0.9510565162951534, -0.9510565162951538, -0.5877852522924735, -4.898587196589413e-16, 0.5877852522924727, 0.9510565162951529, 0.9510565162951538, 0.5877852522924736, 6.123233995736766e-16, -0.5877852522924726, -0.9510565162951534, -0.9510565162951538, -0.5877852522924737, -7.347880794884119e-16, 0.5877852522924725, 0.9510565162951533, 0.9510565162951539, 0.5877852522924738, 8.572527594031472e-16, -0.5877852522924725, -0.9510565162951533, -0.9510565162951539, -0.5877852522924739, -9.797174393178826e-16, 0.5877852522924695, 0.9510565162951533, 0.9510565162951539, 0.5877852522924769, 1.102182119232618e-15, -0.5877852522924722, -0.9510565162951543, -0.951056516295154, -0.587785252292477] y= [0, 0.6015253440351906, 1.096895249493391, 0.14963802472452992, -1.4055603261317517, -2.5023946767056238, -1.3746543603374242, 0.7777548679354078, 2.3930377777245795, 1.589728806501168, -0.18435823514401645, -1.262236228089791, -0.1499221532340092, 1.1432335494953787, 0.9284774407601177, -1.092316839336339, -3.1053851997702706, -1.9708827095800603, 1.4179982683905918, 4.178467267009747, 2.8704598657124154, -0.9554762632284055, -3.6907891747930823, -2.0460936031856565, 1.5516985830908399, 3.050939390566601, 0, -3.803109375076022, -3.7144283665966316, 1.1278012079884292, 6.1915501329945455, 5.067998743352809, -1.4695723076381413, -7.114338992237411, -5.15766901200028, 2.1332451522780023, 6.998570550403378, 3.258668282071149, -4.636620081834843, -7.5743517324240575, -0.7423964478503129, 8.407306390701049, 9.309658304307437, -0.5482852890529228, -11.499859882265268, -10.552533675209967, 2.0050221789726197, 13.153568445829352, 9.570130082024441, -5.115533432227267] ``` # Завершение работы