Сравнить коммиты
34 Коммитов
ac2fd98764
...
main
| Автор | SHA1 | Дата | |
|---|---|---|---|
| e1d0599622 | |||
| e67b412977 | |||
| 69a9d61875 | |||
| 7c1552aa67 | |||
| b3bd732ba8 | |||
| 6053fbe787 | |||
| bdeb1c27f1 | |||
| f6ed84af3d | |||
| d8f5f5b631 | |||
| b643e0a0b2 | |||
| f1e43207fc | |||
| c5bca092a1 | |||
| 0bb5224e01 | |||
| 4bfdf950b8 | |||
| d5e5e9b5d3 | |||
| 3920c08f52 | |||
| 6de200f325 | |||
| ce72d1f7b1 | |||
| 4363aa2fa2 | |||
| fd2984bcdf | |||
| 6160c052b9 | |||
| cae5dea1a4 | |||
| ae4e396508 | |||
| a621ace813 | |||
| f307214522 | |||
| b74c73fe72 | |||
| 1e1fd17e90 | |||
| e827cd0d89 | |||
| 4e69415fd4 | |||
| e9950f74f7 | |||
| 13cc4d3748 | |||
| a915bf70e4 | |||
| 03d8d26d94 | |||
| 5c03990cec |
Двоичные данные
TEMA4/Ris2.png
Обычный файл
|
После Ширина: | Высота: | Размер: 26 KiB |
Двоичные данные
TEMA4/Ris3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 15 KiB |
Двоичные данные
TEMA4/Ris4.png
Обычный файл
|
После Ширина: | Высота: | Размер: 7.2 KiB |
27
TEMA5/17.md
Обычный файл
@@ -0,0 +1,27 @@
|
||||
17. Создайте список с 20 комплексными числами, у которых вещественная и мнимая части – слу-чайные, нормально распределенные числа с математическим ожиданием 15 и стандартным отклонением 8. Рассчитайте среднее значение фаз по элементам множества и отобразите ре-зультат с округлением до 2-х знаков после точки в виде строки вида: «Среднее фаз = ХХХ.ХХ».
|
||||
```py
|
||||
>>> import random
|
||||
>>> import math
|
||||
>>> import cmath
|
||||
# Создаем список с 20 комплексными числами
|
||||
>>> compl_n=[]
|
||||
>>> for _ in range(20):
|
||||
# Генерируем вещественную и мнимую части с нормальным распределением
|
||||
... p1=random.gauss(15,8) # мат. ожидание = 15, стандартное отклонение = 8
|
||||
... p2=random.gauss(15,8) # мат. ожидание = 15, стандартное отклонение = 8
|
||||
... c=complex(p1,p2)
|
||||
... compl_n.append(c)
|
||||
...
|
||||
# Рассчитываем фазы для каждого комплексного числа
|
||||
>>> phases=[]
|
||||
>>> for n in compl_n:
|
||||
... phase = cmath.phase(n)
|
||||
... phases.append(phase)
|
||||
...
|
||||
# Вычисляем среднее значение фаз
|
||||
>>> average_phase = sum(phases) / len(phases)
|
||||
#Округляем до 2-х знаков после точки
|
||||
>>> result = f"Среднее фаз = {average_phase:.2f}"
|
||||
>>> result
|
||||
'Среднее фаз = 0.92'
|
||||
```
|
||||
Двоичные данные
TEMA5/Figure_1.png
Обычный файл
|
После Ширина: | Высота: | Размер: 30 KiB |
Двоичные данные
TEMA5/Figure_2.png
Обычный файл
|
После Ширина: | Высота: | Размер: 18 KiB |
432
TEMA5/Lab5.md
Обычный файл
@@ -0,0 +1,432 @@
|
||||
### Отчет тема 5
|
||||
## Пункт 2. Изучите ветвление по условию – управляющая инструкция if.
|
||||
Общий вид выглядит так:
|
||||
|
||||
```py
|
||||
if <условие>:
|
||||
<отступы> <Блок инструкций, выполняемый, если условие истинно>
|
||||
[elif <условие2>:
|
||||
<отступы><Блок инструкций2, выполняемый, если условие2 истинно>
|
||||
]
|
||||
[else:
|
||||
< отступы><Блок инструкций3, выполняемый, если условие ложно>
|
||||
]
|
||||
```
|
||||
Причем elif и else вместе или по отдельности могут отсуствовать.
|
||||
|
||||
Пример
|
||||
```py
|
||||
>>> prog=4
|
||||
>>> rashod1 = 8
|
||||
>>> rashod2 = 5
|
||||
>>> if rashod1 >= prog:
|
||||
... dohod=12
|
||||
... elif rashod2==prog:
|
||||
... dohod=0
|
||||
... else:
|
||||
... dohod=8
|
||||
...
|
||||
>>> dohod
|
||||
12
|
||||
```
|
||||
Посмотрим другой цикл
|
||||
```py
|
||||
>>> rashod2 = 4
|
||||
>>> porog = 4
|
||||
>>> if rashod1>=3 and rashod2==4:
|
||||
... dohod=rashod1
|
||||
... if rashod2==porog or rashod1<rashod2:
|
||||
... dohod=porog
|
||||
...
|
||||
>>> dohod
|
||||
4
|
||||
```
|
||||
И ещё одна операция с множественным ветвлением линий потока:
|
||||
```py
|
||||
>>> if porog==3:
|
||||
... dohod=1
|
||||
... elif porog==4:
|
||||
... dohod=2
|
||||
... elif porog==5:
|
||||
... dohod=3
|
||||
... else:
|
||||
... dohod=0
|
||||
...
|
||||
>>> dohod
|
||||
2
|
||||
```
|
||||
Еще одна форма записи условных управляющих инструкций - тернарный оператор (от лат. "тройной"):
|
||||
<Объект> = <значение 1> if <условие> else <значение 2>
|
||||
или ещё:
|
||||
```py
|
||||
if <условие>: <инструкция1>[;<инструкция2>….]
|
||||
```
|
||||
```py
|
||||
>>> dohod=2 if porog>=4 else 0
|
||||
>>> dohod
|
||||
2
|
||||
```
|
||||
Эквивалент
|
||||
```py
|
||||
if porog >= 4:
|
||||
dohod = 2
|
||||
else:
|
||||
dohod = 0
|
||||
```
|
||||
Если в блоке инструкций всего одна строка, можно записать всё в одну строку:
|
||||
```py
|
||||
>>> porog = 2
|
||||
>>> if porog >= 5 : rashod1 = 6; rashod2 = 0
|
||||
...
|
||||
>>> rashod1
|
||||
8
|
||||
>>> rashod2
|
||||
4
|
||||
```
|
||||
Тк условие не было выполнено рассмотрим другой пример
|
||||
```py
|
||||
>>> porog = 7
|
||||
>>> if porog >= 5 : rashod1 = 6; rashod2 = 0
|
||||
...
|
||||
>>> rashod1
|
||||
6
|
||||
>>> rashod2
|
||||
0
|
||||
```
|
||||
## Пункт 3. Цикл по перечислению (for)
|
||||
|
||||
Общее правило написания:
|
||||
```py
|
||||
for <Объект-переменная цикла> in <объект>:
|
||||
<отступы><Блок инструкций 1 – тело цикла>
|
||||
[else:
|
||||
< отступы ><Блок инструкций 2 – если в цикле не сработал break>]
|
||||
```
|
||||
Здесь <объект> - любой определенный до начала цикла объект из классов строка, список, кортеж, множество, словарь. <Объект-переменная цикла> - объект, в качестве значений которого пооче-редно будут задаваться элементы объекта, которые могут быть объектами любого типа. <Блок инструкций 1 – тело цикла> - совокупность инструкций, которая может содержать или не содер-жать инструкцию break, вызывающую досрочное завершение цикла при некоторых условиях. Блок инструкций 1 обычно выполняется многократно по мере того, как объект-переменная цикла принимает значения из сложного объекта. Если в цикле имеется необязательная часть: else и Блок инструкций 2, то он будет выполняться перед завершением цикла только в том случае, если при выполнении цикла не было его прерывания по инструкции break.
|
||||
Если Блоке инструкций 1 или в Блоке инструкций 2 только одна инструкция, то её можно запи-сывать без отступов сразу за двоеточием.
|
||||
|
||||
## 3.1. Простой цикл.
|
||||
```py
|
||||
>>> temperatura=5
|
||||
>>> for i in range(3,18,3):
|
||||
... temperatura+=i
|
||||
...
|
||||
>>> temperatura
|
||||
50
|
||||
```
|
||||
## 3.2. Более сложный цикл
|
||||
```py
|
||||
>>> sps=[2,15,14,8]
|
||||
>>> for k in sps:
|
||||
... if len(sps)<=10:sps.append(sps[0])
|
||||
... else:break
|
||||
...
|
||||
>>> sps
|
||||
[2, 15, 14, 8, 2, 2, 2, 2, 2, 2, 2]
|
||||
```
|
||||
Как видно, в конец цикла добавляется двойка до тех пор, пока длина не превысит 10. Важно
|
||||
понимать, что sps - это и объект, по которому проходит k, и объект, изменяющийся
|
||||
внутри цикла. То есть k будет двигаться по циклу бесконечно, и выполнение останавливается
|
||||
именно из-за условия if - else.
|
||||
(При этом else в данном случае относится к if, а не к for (это можно понять не только по
|
||||
смыслу, но и по табуляции)
|
||||
|
||||
Рассмотрим другой вариант:
|
||||
```py
|
||||
>>> sps=[2,15,14,8]
|
||||
>>> for k in sps[:]:
|
||||
... if len(sps)<=10:sps.append(sps[0])
|
||||
... else:break
|
||||
...
|
||||
>>> sps
|
||||
[2, 15, 14, 8, 2, 2, 2, 2]
|
||||
|
||||
```
|
||||
Как видно, итог другой, и вот почему. Операция взятия среза sps[:] создает полную копию
|
||||
исходного списка (грубо говоря, срез от начала до конца включительно).
|
||||
Теперь список, по которому пробегается k, и список, изменяющийся внутри цикла - это объекты,
|
||||
имеющие разные адреса. Это можно проверить:
|
||||
```py
|
||||
>>> id(sps)
|
||||
1684034116672
|
||||
>>> id(sps[:])
|
||||
1684069134400
|
||||
```
|
||||
|
||||
## Пункт 3.3
|
||||
```py
|
||||
>>> sps5=[]
|
||||
>>> for i in range(10):
|
||||
... sps5.append(rn.randint(1,100))
|
||||
... ss=sum(sps5)
|
||||
... if ss>500: break
|
||||
... else:
|
||||
... print(ss)
|
||||
...
|
||||
```
|
||||
Программа ничего не вывела. Посмотрим, почему именно:
|
||||
```py
|
||||
>>> sps5
|
||||
[89, 38, 86, 57, 21, 44, 43, 32, 13, 88]
|
||||
>>> ss
|
||||
511
|
||||
>>> sps5 = []
|
||||
>>> for i in range(10):
|
||||
... sps5.append(rn.randint(1,100))
|
||||
... ss = sum(sps5)
|
||||
... else:
|
||||
... print(ss)
|
||||
...
|
||||
517
|
||||
>>> sps5
|
||||
[11, 75, 48, 46, 3, 67, 78, 92, 63, 34]
|
||||
```
|
||||
В этот раз программа вывела ответ самостоятельно, потому что сработал else, потому что
|
||||
за все десять итераций цикла так и не успел выполниться break по условию if.
|
||||
|
||||
## Пункт 3.4. Пример с символьной строкой
|
||||
```py
|
||||
>>> stroka='Это - автоматизированная система'
|
||||
>>> stroka1=""
|
||||
>>> for ss in stroka:
|
||||
... stroka1+=" "+ss
|
||||
...
|
||||
>>> stroka
|
||||
'Это - автоматизированная система'
|
||||
>>> stroka1
|
||||
' Э т о - а в т о м а т и з и р о в а н н а я с и с т е м а'
|
||||
```
|
||||
Переменная ss проходит по всему строковому объекту, на каждой итерации принимая значение
|
||||
одного знака. Этот знак с предшествующим пробелом дописывается в конец другой, изначально
|
||||
пустой строки. Цикл закончится, когда закончится исходная строка.
|
||||
|
||||
## 3.5. Запись цикла в строке. Пример: создание списка с синусоидальным сигналом.
|
||||
```py
|
||||
>>> import math
|
||||
>>> sps2=[math.sin(i*math.pi/5+2) for i in range(100)]
|
||||
>>> sps2
|
||||
[0.9092974268256817, 0.49103209793281005, -0.11479080280322804, -0.6767675184643197, -0.9802420445539634, -0.9092974268256817, -0.49103209793281016, 0.11479080280322791, 0.6767675184643196, 0.9802420445539634, 0.9092974268256818, 0.4910320979328103, -0.1147908028032278, -0.6767675184643196, -0.9802420445539632, -0.9092974268256818, -0.4910320979328104, 0.11479080280322768, 0.6767675184643195, 0.9802420445539632, 0.9092974268256819, 0.4910320979328105, -0.11479080280322579, -0.6767675184643194, -0.9802420445539632, -0.9092974268256819, -0.4910320979328106, 0.11479080280322743, 0.6767675184643193, 0.9802420445539632, 0.909297426825682, 0.49103209793281066, -0.1147908028032273, -0.6767675184643192, -0.9802420445539632, -0.909297426825682, -0.4910320979328108, 0.11479080280322719, 0.6767675184643192, 0.9802420445539631, 0.9092974268256822, 0.491032097932814, -0.11479080280322707, -0.676767518464319, -0.9802420445539625, -0.9092974268256822, -0.491032097932811, 0.11479080280323047, 0.6767675184643189, 0.9802420445539625, 0.9092974268256822, 0.4910320979328142, -0.11479080280322682, -0.6767675184643215, -0.9802420445539631, -0.9092974268256808, -0.4910320979328112, 0.11479080280322317, 0.6767675184643187, 0.9802420445539624, 0.9092974268256823, 0.4910320979328082, -0.11479080280322658, -0.6767675184643213, -0.980242044553963, -0.9092974268256838, -0.49103209793281144, 0.11479080280322293, 0.6767675184643186, 0.9802420445539637, 0.9092974268256824, 0.49103209793280844, -0.11479080280322633, -0.6767675184643158, -0.980242044553963, -0.9092974268256839, -0.49103209793281166, 0.11479080280322974, 0.6767675184643184, 0.9802420445539637, 0.9092974268256825, 0.4910320979328149, -0.11479080280321903, -0.6767675184643209, -0.9802420445539629, -0.909297426825681, -0.4910320979328119, 0.11479080280322244, 0.6767675184643129, 0.9802420445539636, 0.9092974268256826, 0.49103209793281505, -0.11479080280322584, -0.6767675184643155, -0.9802420445539644, -0.9092974268256812, -0.49103209793281205, 0.1147908028032222, 0.6767675184643127, 0.980242044553965]
|
||||
```
|
||||
|
||||
Эту синусоиду можно отобразить на графике:
|
||||
```py
|
||||
>>> import pylab
|
||||
>>> pylab.plot(sps2, label='Синусоидальный сигнал', color = 'green')
|
||||
[<matplotlib.lines.Line2D object at 0x000002B914A005D0>]
|
||||
>>> pylab.show()
|
||||
```
|
||||
График прикреплен отдельным файлом Figure_1.png
|
||||
|
||||

|
||||
|
||||
## Пункт 4. Цикл "пока истинно условие" (while)
|
||||
|
||||
Общий вид:
|
||||
```py
|
||||
while <Условие>:
|
||||
<отступы><Блок инструкций 1 – тело цикла>
|
||||
[else:
|
||||
<отступы><Блок инструкций 2 – если в цикле не сработал break>]
|
||||
```
|
||||
break и else работают аналогично предыдущему случаю.
|
||||
## 4.1. Цикл со счетчиком.
|
||||
```py
|
||||
>>> rashod=300
|
||||
>>> while rashod:
|
||||
... print("Расход=",rashod)
|
||||
... rashod-=50
|
||||
...
|
||||
Расход= 300
|
||||
Расход= 250
|
||||
Расход= 200
|
||||
Расход= 150
|
||||
Расход= 100
|
||||
Расход= 50
|
||||
```
|
||||
Как именно произошло завершение цикла? Нужно вспомнить, что все числа, кроме нуля, при
|
||||
конвертации в логический тип данных имеют логическое значение True:
|
||||
```py
|
||||
>>> bool(50)
|
||||
True
|
||||
```
|
||||
|
||||
И только нуль имеет значение False:
|
||||
```py
|
||||
>>> bool(0)
|
||||
False
|
||||
```
|
||||
Сравниваемая в управляющей инструкции переменная уменьшается в самом цикле, поэтому, когда
|
||||
строка со сравнением обнаружит 0, то воспримет это как False, и действия по выводу
|
||||
и уменьшению числа выполняться больше не будут.
|
||||
## Пункт 4.2. Пример с символьной строкой
|
||||
```py
|
||||
>>> import math
|
||||
>>> stroka='Расчет процесса в объекте регулирования'
|
||||
>>> i=0
|
||||
>>> sps2=[]
|
||||
>>> while i<len(stroka):
|
||||
... r=1-2/(1+math.exp(0.1*i))
|
||||
... sps2.append(r)
|
||||
... print('Значение в момент',i,"=",r)
|
||||
... i+=1
|
||||
...
|
||||
Значение в момент 0 = 0.0
|
||||
Значение в момент 1 = 0.049958374957880025
|
||||
Значение в момент 2 = 0.09966799462495568
|
||||
Значение в момент 3 = 0.14888503362331795
|
||||
Значение в момент 4 = 0.197375320224904
|
||||
Значение в момент 5 = 0.2449186624037092
|
||||
Значение в момент 6 = 0.2913126124515909
|
||||
Значение в момент 7 = 0.3363755443363322
|
||||
Значение в момент 8 = 0.3799489622552249
|
||||
Значение в момент 9 = 0.421899005250008
|
||||
Значение в момент 10 = 0.4621171572600098
|
||||
Значение в момент 11 = 0.5005202111902354
|
||||
Значение в момент 12 = 0.5370495669980353
|
||||
Значение в момент 13 = 0.5716699660851172
|
||||
Значение в момент 14 = 0.6043677771171636
|
||||
Значение в момент 15 = 0.6351489523872873
|
||||
Значение в момент 16 = 0.6640367702678489
|
||||
Значение в момент 17 = 0.6910694698329307
|
||||
Значение в момент 18 = 0.7162978701990245
|
||||
Значение в момент 19 = 0.7397830512740043
|
||||
Значение в момент 20 = 0.7615941559557649
|
||||
Значение в момент 21 = 0.7818063576087741
|
||||
Значение в момент 22 = 0.8004990217606297
|
||||
Значение в момент 23 = 0.8177540779702878
|
||||
Значение в момент 24 = 0.8336546070121553
|
||||
Значение в момент 25 = 0.8482836399575129
|
||||
Значение в момент 26 = 0.8617231593133063
|
||||
Значение в момент 27 = 0.874053287886007
|
||||
Значение в момент 28 = 0.8853516482022625
|
||||
Значение в момент 29 = 0.8956928738431645
|
||||
Значение в момент 30 = 0.9051482536448664
|
||||
Значение в момент 31 = 0.9137854901178277
|
||||
Значение в момент 32 = 0.9216685544064713
|
||||
Значение в момент 33 = 0.9288576214547277
|
||||
Значение в момент 34 = 0.935409070603099
|
||||
Значение в момент 35 = 0.9413755384972874
|
||||
Значение в момент 36 = 0.9468060128462683
|
||||
Значение в момент 37 = 0.9517459571646616
|
||||
Значение в момент 38 = 0.9562374581277391
|
||||
```
|
||||
У цикла 38 повторений, по числу элементов в строке, но на 1 меньше. На каждой итерации
|
||||
значение i на единицу меньше, чем в предыдущей.
|
||||
```py
|
||||
>>> pylab.plot(sps2, label='Сигнал выхода', color='red')
|
||||
[<matplotlib.lines.Line2D object at 0x000002B9191077D0>]
|
||||
>>> pylab.title("Сигнал на выходе инерционного звена")
|
||||
Text(0.5, 1.0, 'Сигнал на выходе инерционного звена')
|
||||
>>> pylab.show()
|
||||
```
|
||||

|
||||
График прикреплен файлом Figure_2.png
|
||||
## Пункт 4.3. Определение, является ли число простым (делится только на самого себя или 1).
|
||||
```py
|
||||
>>> chislo = 267
|
||||
>>> kandidat = chislo // 2
|
||||
>>> while kandidat > 1:
|
||||
if chislo % kandidat == 0:
|
||||
print(chislo, ' имеет множитель ', kandidat)
|
||||
break
|
||||
kandidat -= 1
|
||||
else:
|
||||
print(chislo, ' является простым!')
|
||||
|
||||
|
||||
267 имеет множитель 89
|
||||
```
|
||||
|
||||
Программа работает так: переменная kandidat отвечает за потенциальный делитель заданного
|
||||
числа. Изначально мы задаем половину от заданного числа, потому что у числа не может быть
|
||||
делителя большего, чем половина от него. Далее мы последовательно уменьшаем потенциальный
|
||||
множитель, каждый раз проверяя, получилось ли поделить без остатка. Если получилось, то
|
||||
число непростое, и цикл можно прекращать досрочно. Если цикл отработал до конца, не
|
||||
прервавшись, то число простое.
|
||||
|
||||
Дополниим программу так, чтобы она проверяла все числа от 250 до 300.
|
||||
```py
|
||||
>>> chislo = [x for x in range (250, 301)]
|
||||
>>> for now in chislo:
|
||||
kandidat = now // 2
|
||||
while kandidat > 1:
|
||||
if now % kandidat == 0:
|
||||
print(now, ' имеет множитель ', kandidat)
|
||||
break
|
||||
kandidat -= 1
|
||||
else: #ОБЯЗАТЕЛЬНО относится не к if и не к for, а к while
|
||||
print(now, " является простым!")
|
||||
|
||||
|
||||
250 имеет множитель 125
|
||||
251 является простым!
|
||||
252 имеет множитель 126
|
||||
253 имеет множитель 23
|
||||
254 имеет множитель 127
|
||||
255 имеет множитель 85
|
||||
256 имеет множитель 128
|
||||
257 является простым!
|
||||
258 имеет множитель 129
|
||||
259 имеет множитель 37
|
||||
260 имеет множитель 130
|
||||
261 имеет множитель 87
|
||||
262 имеет множитель 131
|
||||
263 является простым!
|
||||
264 имеет множитель 132
|
||||
265 имеет множитель 53
|
||||
266 имеет множитель 133
|
||||
267 имеет множитель 89
|
||||
268 имеет множитель 134
|
||||
269 является простым!
|
||||
270 имеет множитель 135
|
||||
271 является простым!
|
||||
272 имеет множитель 136
|
||||
273 имеет множитель 91
|
||||
274 имеет множитель 137
|
||||
275 имеет множитель 55
|
||||
276 имеет множитель 138
|
||||
277 является простым!
|
||||
278 имеет множитель 139
|
||||
279 имеет множитель 93
|
||||
280 имеет множитель 140
|
||||
281 является простым!
|
||||
282 имеет множитель 141
|
||||
283 является простым!
|
||||
284 имеет множитель 142
|
||||
285 имеет множитель 95
|
||||
286 имеет множитель 143
|
||||
287 имеет множитель 41
|
||||
288 имеет множитель 144
|
||||
289 имеет множитель 17
|
||||
290 имеет множитель 145
|
||||
291 имеет множитель 97
|
||||
292 имеет множитель 146
|
||||
293 является простым!
|
||||
294 имеет множитель 147
|
||||
295 имеет множитель 59
|
||||
296 имеет множитель 148
|
||||
297 имеет множитель 99
|
||||
298 имеет множитель 149
|
||||
299 имеет множитель 23
|
||||
300 имеет множитель 150
|
||||
```
|
||||
## Пункт 4.4. Инструкция continue.
|
||||
|
||||
Она используется, когда надо при определенном условии не завершить весь цикл, а завершить
|
||||
только текущую итерацию.
|
||||
|
||||
Пример (вывести только нечетные числа):
|
||||
```py
|
||||
>>> n=[1,2,3,4,5,6,7,8,9,10]
|
||||
>>> for k in n:
|
||||
... if k%2==0:
|
||||
... continue
|
||||
... print(k)
|
||||
...
|
||||
1
|
||||
3
|
||||
5
|
||||
7
|
||||
9
|
||||
```
|
||||
|
||||
102
TEMA5/task.md
Обычный файл
@@ -0,0 +1,102 @@
|
||||
|
||||
### ОБЩЕЕ КОНТРОЛЬНОЕ ЗАДАНИЕ
|
||||
|
||||
• Для заданной символьной строки с англоязычным текстом (его можно заимствовать из помощи)
|
||||
определите порядковый номер каждой буквы в английском алфавите.
|
||||
```py
|
||||
>>> text = "There is a house in New Orleans, They call The Rising Sun"
|
||||
>>> for now in range(len(text)):
|
||||
low = text.lower()
|
||||
letter = low[now]
|
||||
if not letter in alphabet:
|
||||
continue
|
||||
else:
|
||||
print("Буква ", letter, " имеет ", alphabet.index(letter) + 1,
|
||||
"порядковый номер в алфавите")
|
||||
|
||||
Буква t имеет 20 порядковый номер в алфавите
|
||||
Буква h имеет 8 порядковый номер в алфавите
|
||||
Буква e имеет 5 порядковый номер в алфавите
|
||||
Буква r имеет 18 порядковый номер в алфавите
|
||||
...
|
||||
Буква g имеет 7 порядковый номер в алфавите
|
||||
Буква s имеет 19 порядковый номер в алфавите
|
||||
Буква u имеет 21 порядковый номер в алфавите
|
||||
Буква n имеет 14 порядковый номер в алфавите
|
||||
```
|
||||
• Создайте список со словами из задания данного пункта. Для этого списка – определите,
|
||||
есть ли в нем некоторое заданное значение, и выведите соответствующее сообщение: либо о
|
||||
нахождении элемента, либо о его отсутствии в списке (проверить как с имеющимся, так и с
|
||||
отсутствующим словом).
|
||||
```py
|
||||
>>> text = """Создайте список со словами из задания данного пункта Для этого
|
||||
списка определите есть ли в нем некоторое заданное значение и выведите соответствующее
|
||||
сообщение либо о нахождении элемента либо о его отсутствии в списке проверить как с
|
||||
имеющимся так и с отсутствующим словом"""
|
||||
>>> lst = text.split(" ")
|
||||
>>> lst
|
||||
['Создайте', 'список', 'со', 'словами', 'из', 'задания', 'данного', 'пункта', 'Для', 'этого',
|
||||
'списка', 'определите', 'есть', 'ли', 'в', 'нем', 'некоторое', 'заданное', 'значение', 'и',
|
||||
'выведите', 'соответствующее', 'сообщение', 'либо', 'о', 'нахождении', 'элемента', 'либо',
|
||||
'о', 'его', 'отсутствии', 'в', 'списке', 'проверить', 'как', 'с', 'имеющимся', 'так', 'и',
|
||||
'с', 'отсутствующим', 'словом']
|
||||
|
||||
>>> target = "либо"
|
||||
>>> for now in lst:
|
||||
if now == target:
|
||||
print ("Слово есть")
|
||||
break
|
||||
else:
|
||||
print("Слова нет")
|
||||
|
||||
Слово есть
|
||||
|
||||
|
||||
>>> target = "дом"
|
||||
>>> for now in lst:
|
||||
if now == target:
|
||||
print ("Слово есть")
|
||||
break
|
||||
else:
|
||||
print("Слова нет")
|
||||
|
||||
Слова нет
|
||||
```
|
||||
|
||||
• Создайте список студентов вашей группы (3-4 фамилии) и список их средних баллов в
|
||||
летней сессии – в порядке перечисления студентов в первом списке. Создайте еще 2 аналогичных
|
||||
списка для тех же студентов, но в другом порядке, по зимней сессии. Напишите инструкции,
|
||||
позволяющие по указанной (запрошенной и введенной) фамилии студента вывести его средние
|
||||
баллы по двум сессиям.
|
||||
```py
|
||||
>>> studs = ["Snegura", "Turov", "Zelenkina1", "Zelenkina2"]
|
||||
>>> summer_marks = [4.75, 4.13, 4.24, 4.32]
|
||||
>>> studs2 = ["Zelenkina1", "Turov", "Zelenkina2", "Snegura"]
|
||||
>>> winter_marks = [4.3, 4.23, 4.16, 4.82]
|
||||
|
||||
>>> student = input("Введите фамилию: ")
|
||||
Введите фамилию: Zelenkina2
|
||||
>>> while student != "q":
|
||||
if (student in studs) and (student in studs2):
|
||||
sum_answer = summer_marks[studs.index(student)]
|
||||
win_answer = winter_marks[studs2.index(student)]
|
||||
print("Балл летом: ", sum_answer, "\nЗимой: ", win_answer, "\nСредний :",
|
||||
(sum_answer + win_answer)/2)
|
||||
else:
|
||||
print("Такого студента нет")
|
||||
student = input("Введите фамилию (q для выхода): ")
|
||||
|
||||
|
||||
Балл летом: 4.32
|
||||
Зимой: 4.16
|
||||
Средний : 4.24
|
||||
Введите фамилию (q для выхода): Snegura
|
||||
Балл летом: 4.75
|
||||
Зимой: 4.82
|
||||
Средний : 4.78
|
||||
Введите фамилию (q для выхода): Tsvetkova
|
||||
Такого студента нет
|
||||
Введите фамилию (q для выхода): q
|
||||
```
|
||||
|
||||
|
||||
90
TEMA6/7.md
Обычный файл
@@ -0,0 +1,90 @@
|
||||
1) С помощью текстового редактора создайте текстовый файл с некоторым именем, в котором будет 4 строки и на каждой строке будет по 3 числа, разделенных запятыми.
|
||||
```py
|
||||
>>> import os
|
||||
>>> os.getcwd()
|
||||
'C:\\WINDOWS\\System32'
|
||||
>>> os.chdir(r'C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA6')
|
||||
>>> f = 'data.txt'
|
||||
>>> fp = open(f, 'w')
|
||||
>>> fp.write("1, 2, 3\n")
|
||||
8
|
||||
>>> fp.write("4, 5, 6\n")
|
||||
8
|
||||
>>> fp.write("7, 8, 9\n")
|
||||
8
|
||||
>>> fp.close()
|
||||
>>> fp = open(f, 'r')
|
||||
>>> sod = fp.read()
|
||||
>>> fp.close()
|
||||
>>> print('Содержание лабы:')
|
||||
Содержание лабы:
|
||||
>>> print(sod)
|
||||
1, 2, 3
|
||||
4, 5, 6
|
||||
7, 8, 9
|
||||
```
|
||||
|
||||
2) Запросите у пользователя и введите имя файла с данными для обработки. Обеспечьте вывод сообщения при вводе пустой строки и повторный ввод.
|
||||
```py
|
||||
>>> while True:
|
||||
... f = input("Введите имя файла с данными для обработки: ")
|
||||
... f_cl = f.strip() # Убираем пробелы в начале и конце строки
|
||||
... if f_c != "":
|
||||
... f = f_c
|
||||
... break
|
||||
... print("Ошибка: введена пустая строка. Повторите ввод.")
|
||||
...
|
||||
Введите имя файла с данными для обработки:
|
||||
Ошибка: введена пустая строка. Повторите ввод.
|
||||
Введите имя файла с данными для обработки: data.txt
|
||||
>>> print(f)
|
||||
data.txt
|
||||
```
|
||||
3) Введите данные из указанного файла и представьте их в виде списка.
|
||||
```py
|
||||
>>> f='data.txt'
|
||||
>>> numbers = []
|
||||
>>> fp = open(f, 'r')
|
||||
SyntaxError: invalid syntax
|
||||
>>> for line in fp:
|
||||
... for num_str in line.strip().split(','): #убираем пробелы, разбиваем по запятым
|
||||
... numbers.append(float(num_str))
|
||||
...
|
||||
>>> fp.close()
|
||||
>>> print(numbers)
|
||||
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
|
||||
```
|
||||
|
||||
4) Рассчитайте по введенным данным среднее значение синусов элементов списка.
|
||||
```py
|
||||
>>> import math
|
||||
>>> s=[]
|
||||
>>> for number in numbers:
|
||||
... ss=math.sin(number)
|
||||
... s.append(ss)
|
||||
... print(number)
|
||||
...
|
||||
1.0
|
||||
2.0
|
||||
3.0
|
||||
4.0
|
||||
5.0
|
||||
6.0
|
||||
7.0
|
||||
8.0
|
||||
9.0
|
||||
>>> sum_s=sum(s)
|
||||
>>> sum_s
|
||||
1.9552094821073802
|
||||
>>> count_s=len(s)
|
||||
>>> count_s
|
||||
9
|
||||
>>> sr=sum_s/count_s
|
||||
>>> sr
|
||||
0.21724549801193113
|
||||
```
|
||||
5) Выведите рассчитанное значение на экран по шаблону: " По <число элементов в списке> элементам среднее синусов = <рассчитанное среднее>". При этом значение среднего должно быть округлено до двух знаков после точки.
|
||||
```py
|
||||
>>> print("По", count_s, "элементам среднее синусов =", round(sr, 2))
|
||||
```
|
||||
По 9 элементам среднее синусов = 0.22
|
||||
135
TEMA6/lab6.md
Обычный файл
@@ -0,0 +1,135 @@
|
||||
# Пункт 2. Вывод данных на экран дисплея.
|
||||
##Пункт 2.1. Вывод данных в командной строке.
|
||||
|
||||
Эхо-вывод в терминал (не работает в файлах!)
|
||||
>>> stroka='Автоматизированная система управления'
|
||||
>>> stroka
|
||||
'Автоматизированная система управления'
|
||||
##Пункт 2.2 Вывод с использованием функции print
|
||||
>>> fff=234.5;gg='Значение температуры = '
|
||||
>>> print(gg, fff)
|
||||
Значение температуры = 234.5
|
||||
По умолчанию выводимые объекты разделяются одним пробелом. Если нужен другой разде-литель его можно указать в отдельном аргументе sep, например,
|
||||
>>> print(gg, fff, sep='/')
|
||||
Значение температуры = /234.5
|
||||
После вывода автоматически осуществляется переход на другую строку. Если курсор надо оста-вить в той же строке, то следует использовать еще один аргумент, например,
|
||||
|
||||
>>> print(gg, fff,sep='/',end='***'); print('____')
|
||||
Значение температуры = /234.5***____
|
||||
|
||||
После end= надо указать какими символами должна закончиться выводимая строка или ука-зать пустую строку. Наоборот, если в какой-то момент требуется просто перейти на новую стро-ку, можно использовать такое обращение к функции:
|
||||
|
||||
>>> print()
|
||||
|
||||
Если текст большой, можно расположить его в несколько строк с использованием тройных кавычек
|
||||
>>> print(""" Здесь может выводиться
|
||||
... большой текст,
|
||||
... занимающий несколько строк""")
|
||||
Здесь может выводиться
|
||||
большой текст,
|
||||
занимающий несколько строк
|
||||
|
||||
Или переносить отдельные объекты, разделенные запятой:
|
||||
|
||||
>>> print("Здесь может выводиться",
|
||||
... "большой текст,",
|
||||
... "занимающий несколько строк")
|
||||
Здесь может выводиться большой текст, занимающий несколько строк
|
||||
|
||||
Разница в том, что в первом случае тройные кавычки воспроизводят текст ровно так, как он был
|
||||
введен. В тексте были введены переносы строки, но они были введены не как символ \n, а
|
||||
в обычном человекопонятном виде. Тем не менее, при желании на них можно посмотреть:
|
||||
|
||||
>> print(repr(""" Здесь может выводиться
|
||||
большой текст,
|
||||
занимающий несколько строк"""))
|
||||
' Здесь может выводиться\nбольшой текст,\nзанимающий несколько строк'
|
||||
|
||||
(Функция repr() показывает то, как объект видит python, а не человек, отображая все символы
|
||||
табуляции)
|
||||
Во втором случае три выводимых объекта-строки перечисленны через запятую, и это работает как
|
||||
обычный print(), разделяющий объекты с помощью пробелов, если не указано иное.
|
||||
|
||||
## Пункт 2.3. Вывод с использованием write объекта stdout (поток стандартного вывода) модуля sys.
|
||||
>>> import sys
|
||||
>>> sys.stdout.write('Функция write')
|
||||
Функция write13
|
||||
>>> sys.stdout.write('Функция write\n')
|
||||
Функция write
|
||||
14
|
||||
|
||||
Важно отметить, что функция выводит текст, но возвращает число. Это число - количество
|
||||
введенных символов, причем \n считается за один символ, а не за два.
|
||||
|
||||
>>> type(sys.stdout.write("Функция write"))
|
||||
Функция write<class 'int'>
|
||||
|
||||
Если вызвать эту функцию без аргументов, вернется ошибка:
|
||||
|
||||
>>> sys.stdout.write()
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TypeError: write() missing 1 required positional argument: 's'
|
||||
|
||||
Если сообщить пустую строку, то, соответственно, 0.
|
||||
|
||||
>>> sys.stdout.write("")
|
||||
0
|
||||
|
||||
## Пункт 3. Ввод данных с клавиатуры.
|
||||
>>> psw=input('Введите пароль:')
|
||||
Введите пароль:sewfx
|
||||
>>> psw
|
||||
'sewfx'
|
||||
>>> type(psw)
|
||||
<class 'str'>
|
||||
|
||||
input() не воспринимает символы табуляции, считывая их как обычные строки. Более того, возможно
|
||||
такое:
|
||||
|
||||
>>> input()
|
||||
dpdpdp\n
|
||||
'dpdpdp\\n'
|
||||
|
||||
Так происходит из-за того, что input() считал все символы как символы, то есть "p", "d", ... "\",
|
||||
"n". Но при выводе в консоль внутри самой функции input() используется вышеупомянутое
|
||||
"техническое" отображение repr(). Оно всегда дублирует ("экранирует") бэкслеш, чтобы не дать
|
||||
python'у воспринять его как символ табуляции.
|
||||
|
||||
|
||||
>>> while True:
|
||||
... znach=float(input('Задайте коэф. усиления= '))
|
||||
... if znach<17.5 or znach>23.8:
|
||||
... print('Ошибка!')
|
||||
... else:
|
||||
... break
|
||||
...
|
||||
Задайте коэф. усиления= 16
|
||||
Ошибка!
|
||||
Задайте коэф. усиления= 26.7
|
||||
Ошибка!
|
||||
Задайте коэф. усиления= 20
|
||||
|
||||
|
||||
>>> import math
|
||||
>>> print(eval(input('введите выражение для расчета=')))
|
||||
введите выражение для расчета=math.log10(23/(1+math.exp(-3.24)))
|
||||
1.34504378689765
|
||||
|
||||
Введенная через input() строка преобразуется в исполнительные инструкции с помощью eval(),
|
||||
они потом выполняются и результат выводится на экран. Строка имеет тип, соответствующий
|
||||
результату вычислений и задаваемый автоматически:
|
||||
>>> type(eval(input('введите выражение для расчета = ')))
|
||||
введите выражение для расчета = 2+3
|
||||
<class 'int'>
|
||||
|
||||
>>> type(eval(input('введите выражение для расчета = ')))
|
||||
введите выражение для расчета = math.log10(23/(1+math.exp(-3.24)))
|
||||
<class 'float'>
|
||||
|
||||
# Пункт 4. Ввод-вывод при работе с файлами.
|
||||
## Пункт 4.1. Функции для работы с путём к файлу.
|
||||
|
||||
>>> import os
|
||||
>>> os.getcwd()
|
||||
'C:\\WINDOWS\\System32'
|
||||
624
TEMA6/laba5.md
Обычный файл
@@ -0,0 +1,624 @@
|
||||
# Пункт 2. Вывод данных на экран дисплея.
|
||||
## Пункт 2.1. Вывод данных в командной строке.
|
||||
|
||||
Эхо-вывод в терминал (не работает в файлах!)
|
||||
```py
|
||||
>>> stroka='Автоматизированная система управления'
|
||||
>>> stroka
|
||||
'Автоматизированная система управления'
|
||||
```
|
||||
# Пункт 2.2 Вывод с использованием функции print
|
||||
```py
|
||||
>>> fff=234.5;gg='Значение температуры = '
|
||||
>>> print(gg, fff)
|
||||
Значение температуры = 234.5
|
||||
```
|
||||
По умолчанию выводимые объекты разделяются одним пробелом. Если нужен другой разде-литель его можно указать в отдельном аргументе sep, например,
|
||||
```py
|
||||
>>> print(gg, fff, sep='/')
|
||||
Значение температуры = /234.5
|
||||
```
|
||||
После вывода автоматически осуществляется переход на другую строку. Если курсор надо оста-вить в той же строке, то следует использовать еще один аргумент, например,
|
||||
```py
|
||||
>>> print(gg, fff,sep='/',end='***'); print('____')
|
||||
Значение температуры = /234.5***____
|
||||
```
|
||||
После end= надо указать какими символами должна закончиться выводимая строка или ука-зать пустую строку. Наоборот, если в какой-то момент требуется просто перейти на новую стро-ку, можно использовать такое обращение к функции:
|
||||
```py
|
||||
>>> print()
|
||||
```
|
||||
Если текст большой, можно расположить его в несколько строк с использованием тройных кавычек
|
||||
```py
|
||||
>>> print(""" Здесь может выводиться
|
||||
... большой текст,
|
||||
... занимающий несколько строк""")
|
||||
Здесь может выводиться
|
||||
большой текст,
|
||||
занимающий несколько строк
|
||||
```
|
||||
Или переносить отдельные объекты, разделенные запятой:
|
||||
```py
|
||||
>>> print("Здесь может выводиться",
|
||||
... "большой текст,",
|
||||
... "занимающий несколько строк")
|
||||
Здесь может выводиться большой текст, занимающий несколько строк
|
||||
```
|
||||
Разница в том, что в первом случае тройные кавычки воспроизводят текст ровно так, как он был
|
||||
введен. В тексте были введены переносы строки, но они были введены не как символ \n, а
|
||||
в обычном человекопонятном виде. Тем не менее, при желании на них можно посмотреть:
|
||||
```py
|
||||
>> print(repr(""" Здесь может выводиться
|
||||
большой текст,
|
||||
занимающий несколько строк"""))
|
||||
' Здесь может выводиться\nбольшой текст,\nзанимающий несколько строк'
|
||||
```
|
||||
(Функция repr() показывает то, как объект видит python, а не человек, отображая все символы
|
||||
табуляции)
|
||||
Во втором случае три выводимых объекта-строки перечисленны через запятую, и это работает как
|
||||
обычный print(), разделяющий объекты с помощью пробелов, если не указано иное.
|
||||
|
||||
## Пункт 2.3. Вывод с использованием write объекта stdout (поток стандартного вывода) модуля sys.
|
||||
```py
|
||||
>>> import sys
|
||||
>>> sys.stdout.write('Функция write')
|
||||
Функция write13
|
||||
>>> sys.stdout.write('Функция write\n')
|
||||
Функция write
|
||||
14
|
||||
```
|
||||
Важно отметить, что функция выводит текст, но возвращает число. Это число - количество
|
||||
введенных символов, причем \n считается за один символ, а не за два.
|
||||
```py
|
||||
>>> type(sys.stdout.write("Функция write"))
|
||||
Функция write<class 'int'>
|
||||
```
|
||||
Если вызвать эту функцию без аргументов, вернется ошибка:
|
||||
```py
|
||||
>>> sys.stdout.write()
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TypeError: write() missing 1 required positional argument: 's'
|
||||
```
|
||||
Если сообщить пустую строку, то, соответственно, 0.
|
||||
```py
|
||||
>>> sys.stdout.write("")
|
||||
0
|
||||
```
|
||||
## Пункт 3. Ввод данных с клавиатуры.
|
||||
```py
|
||||
>>> psw=input('Введите пароль:')
|
||||
Введите пароль:sewfx
|
||||
>>> psw
|
||||
'sewfx'
|
||||
>>> type(psw)
|
||||
<class 'str'>
|
||||
```
|
||||
input() не воспринимает символы табуляции, считывая их как обычные строки. Более того, возможно
|
||||
такое:
|
||||
```py
|
||||
>>> input()
|
||||
dpdpdp\n
|
||||
'dpdpdp\\n'
|
||||
```
|
||||
Так происходит из-за того, что input() считал все символы как символы, то есть "p", "d", ... "\",
|
||||
"n". Но при выводе в консоль внутри самой функции input() используется вышеупомянутое
|
||||
"техническое" отображение repr(). Оно всегда дублирует ("экранирует") бэкслеш, чтобы не дать
|
||||
python'у воспринять его как символ табуляции.
|
||||
|
||||
```py
|
||||
>>> while True:
|
||||
... znach=float(input('Задайте коэф. усиления= '))
|
||||
... if znach<17.5 or znach>23.8:
|
||||
... print('Ошибка!')
|
||||
... else:
|
||||
... break
|
||||
...
|
||||
Задайте коэф. усиления= 16
|
||||
Ошибка!
|
||||
Задайте коэф. усиления= 26.7
|
||||
Ошибка!
|
||||
Задайте коэф. усиления= 20
|
||||
```
|
||||
```py
|
||||
>>> import math
|
||||
>>> print(eval(input('введите выражение для расчета=')))
|
||||
введите выражение для расчета=math.log10(23/(1+math.exp(-3.24)))
|
||||
1.34504378689765
|
||||
```
|
||||
Введенная через input() строка преобразуется в исполнительные инструкции с помощью eval(),
|
||||
они потом выполняются и результат выводится на экран. Строка имеет тип, соответствующий
|
||||
результату вычислений и задаваемый автоматически:
|
||||
```py
|
||||
>>> type(eval(input('введите выражение для расчета = ')))
|
||||
введите выражение для расчета = 2+3
|
||||
<class 'int'>
|
||||
```
|
||||
```py
|
||||
>>> type(eval(input('введите выражение для расчета = ')))
|
||||
введите выражение для расчета = math.log10(23/(1+math.exp(-3.24)))
|
||||
<class 'float'>
|
||||
```
|
||||
# Пункт 4. Ввод-вывод при работе с файлами.
|
||||
## Пункт 4.1. Функции для работы с путём к файлу.
|
||||
```py
|
||||
>>> import os
|
||||
>>> os.getcwd()
|
||||
'C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA6'
|
||||
>>> tsvetkova=os.getcwd()
|
||||
>>> print(tsvetkova)
|
||||
C:\Users\Admin\Documents\Tsvetkova\python-labs\TEMA6
|
||||
>>> print(type(tsvetkova))
|
||||
<class 'str'>
|
||||
```
|
||||
По умолчанию:
|
||||
```py
|
||||
>>> import os
|
||||
>>> os.getcwd()
|
||||
'C:\\WINDOWS\\System32'
|
||||
```
|
||||
Сменим директорию и посмотрим, что смена произошла:
|
||||
```py
|
||||
>>> os.chdir(r'C:\Users\Admin\Documents\Tsvetkova\python-labs\TEMA1')
|
||||
>>> os.getcwd()
|
||||
'C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA1'
|
||||
```
|
||||
Сменим директорию на верную:
|
||||
```py
|
||||
os.chdir(r'C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA6')
|
||||
```
|
||||
познкомимся с другими командами модуля os
|
||||
```py
|
||||
>>>help(os.mkdir)
|
||||
Help on built-in function mkdir in module nt:
|
||||
|
||||
mkdir(path, mode=511, *, dir_fd=None)
|
||||
Create a directory.
|
||||
|
||||
If dir_fd is not None, it should be a file descriptor open to a directory,
|
||||
and path should be relative; path will then be relative to that directory.
|
||||
dir_fd may not be implemented on your platform.
|
||||
If it is unavailable, using it will raise a NotImplementedError.
|
||||
|
||||
The mode argument is ignored on Windows. Where it is used, the current umask
|
||||
value is first masked out.
|
||||
```
|
||||
Создание каталога (mkdir)
|
||||
```py
|
||||
>>> os.mkdir('lalala')
|
||||
>>> os.getcwd()
|
||||
'C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA6'
|
||||
>>> os.listdir()
|
||||
['.gitkeep', 'lab5.txt', 'lalala']
|
||||
```
|
||||
удаление папки
|
||||
```py
|
||||
>>> help(os.rmdir)
|
||||
Help on built-in function rmdir in module nt:
|
||||
|
||||
rmdir(path, *, dir_fd=None)
|
||||
Remove a directory.
|
||||
|
||||
If dir_fd is not None, it should be a file descriptor open to a directory,
|
||||
and path should be relative; path will then be relative to that directory.
|
||||
dir_fd may not be implemented on your platform.
|
||||
If it is unavailable, using it will raise a NotImplementedError.
|
||||
```
|
||||
```py
|
||||
>>> os.rmdir('lalala')
|
||||
>>> os.listdir()
|
||||
['.gitkeep', 'lab5.txt']
|
||||
```py
|
||||
Одако, если мы будем находиться в самой папке, которую хотим удалить, то у нас это не получится и питон выведет ошибку. Чтобы это исправить необходимо сменить путь и выйти из папки. Можно использовать команду
|
||||
```py
|
||||
os.chdir('../') # Поднимает нас на одну папку выше. ../../ - для двух папок и т.д.
|
||||
```
|
||||
Просмотр списка директории
|
||||
```py
|
||||
>>> os.listdir()
|
||||
['.gitkeep', 'lab5.txt']
|
||||
```
|
||||
Проверка существования каталога
|
||||
```py
|
||||
>>> help(os.path.isdir)
|
||||
Help on function isdir in module genericpath:
|
||||
|
||||
isdir(s)
|
||||
Return true if the pathname refers to an existing directory.
|
||||
```
|
||||
Функция isdir() модуля os.path возвращает True если путь path существует и является каталогом,
|
||||
False в противном случае.
|
||||
```py
|
||||
>>> os.path.isdir('gagagaga')
|
||||
False
|
||||
>>> os.mkdir('lalala')
|
||||
>>> os.path.isdir('lalala')
|
||||
True
|
||||
```
|
||||
Функция os.path.abspath() в Python преобразует путь, переданный в качестве аргумента, в
|
||||
абсолютный путь
|
||||
```py
|
||||
>>> fil=os.path.abspath("oplata.dbf")
|
||||
>>> fil
|
||||
'C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA6\\oplata.dbf'
|
||||
>>> fil=os.path.abspath("lalala")
|
||||
>>> fil
|
||||
'C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA6\\lalala'
|
||||
```
|
||||
Абсолютный путь — это полный путь к файлу или каталогу, начиная от
|
||||
корневого каталога системы, а не относительный путь (который зависит от текущего рабочего
|
||||
каталога)
|
||||
|
||||
Если передать в os.path.abspath() несуществующий файл или каталог, функция не проверяет
|
||||
наличие этого файла в файловой системе. Она просто преобразует путь в абсолютный, не
|
||||
проверяя его существование.
|
||||
|
||||
Отделение из абсолютного пути только каталога/только имени файла
|
||||
Функция os.path.dirname() из абсолютного пути выделяется путь доступа (от диска до последней
|
||||
папки). Функция os.path.basename(), наоборот, убирает из абсолютного пути все, кроме имени
|
||||
файла.
|
||||
|
||||
Выделите путь доступа к файлу из строки, содержащей и этот путь, и имя файла с помощью функции os.path.dirname
|
||||
```py
|
||||
>>> drkt = os.path.dirname(fil)
|
||||
>>> print(drkt)
|
||||
C:\Users\Admin\Documents\Tsvetkova\python-labs\TEMA6
|
||||
```
|
||||
Bыделить имя файла из этой строки с отбрасыванием пути можно с помощью функции os.path.basename
|
||||
```py
|
||||
>>> bsnm=os.path.basename(fil)
|
||||
>>> print(bsnm)
|
||||
lalala
|
||||
```
|
||||
Разделение на кортеж из пути и из имени файла
|
||||
```py
|
||||
>>> help(os.path.split)
|
||||
Help on function split in module ntpath:
|
||||
|
||||
split(p)
|
||||
Split a pathname.
|
||||
|
||||
Return tuple (head, tail) where tail is everything after the final slash.
|
||||
Either part may be empty.
|
||||
```
|
||||
```py
|
||||
>>> os.path.split(fil)
|
||||
('C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA6', 'lalala')
|
||||
>>> type(os.path.split(fil))
|
||||
<class 'tuple'>
|
||||
```
|
||||
Проверка существования любого объекта (пути или файла)
|
||||
```py
|
||||
>>> os.path.exists("D:/GAMES") # Такой каталог есть на ПК
|
||||
True
|
||||
>>> os.path.exists("D:/Arts")
|
||||
False
|
||||
>>> os.path.exists("D:/Games/Heavy Rain/unins000.exe") # Такой файл есть
|
||||
True
|
||||
>>> os.path.exists("D:/Games/Heavy Rain/unins00000.exe")
|
||||
False
|
||||
>>> os.path.isfile("D:/Games/Sid Meiers Civilization VI/unins000.exe") # Это есть и это файл
|
||||
True
|
||||
>>> os.path.isfile("D:/Games/Sid Meiers Civilization VI/") # Это есть, но это не файл!
|
||||
False
|
||||
>>> os.path.isfile("D:/Games/sss.jpg") # Это файл, но это не существует
|
||||
False
|
||||
```
|
||||
## Пункт 4.2 Общая схема работы с файлом
|
||||
Для обмена данными с файлом необходимо выполнить следующие операции:
|
||||
• Открытие файла с указанием его имени и цели (чтение, запись, добавление данных);
|
||||
• Выполнение одной или нескольких операций обмена данными с файлом;
|
||||
• Закрытие файла.
|
||||
|
||||
4.3. Открытие файла для записи или чтения данных – функция open.
|
||||
При открытии файла необходимо указать имя файлы (с путем, если он не в рабочем каталоге) и цель работы с ним. Для открытия используется функция open. Запросите помощь по этой функ-ции, обратите внимание на возможные аргументы этой функции.
|
||||
```py
|
||||
>>> fp = open(file = drkt+'\\zapis1.txt', mode='w')
|
||||
>>> type(fp)
|
||||
<class '_io.TextIOWrapper'>
|
||||
```
|
||||
Объект класса _io.TextIOWrapper - файловый объект для текстовых данных, имеющий ряд атрибутов
|
||||
и методов.
|
||||
```py
|
||||
>>> fp
|
||||
<_io.TextIOWrapper name='C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA6\\zapis1.txt' mode='w' encoding='cp1251'>
|
||||
```
|
||||
Здесь перечислены атрибуты объекта:
|
||||
name - абсолютный путь
|
||||
mode - режим:
|
||||
r - чтение
|
||||
w - запись (если такой файл уже есть, его содержимое будет удалено, если нет,
|
||||
создается. Содержимое удаляется в момент открытия, а не в момент первой
|
||||
записи)
|
||||
a - дозапись (в конец)
|
||||
x - открывает для записи, но только если файл есть, иначе FileExistsError.
|
||||
+ - чтение и запись:
|
||||
r+ - чтение и запись, файл должен существовать.
|
||||
w+ - запись и чтение, файл создаётся или перезаписывается.
|
||||
a+ - добавление и чтение, файл создаётся, если не существует.
|
||||
|
||||
rb, wb, ab, xb - все то же, но в бинарном режиме (читаются байты)
|
||||
|
||||
encoding - кодировка:
|
||||
В Windows в консоли по умолчанию cp1251 или cp1252 в зависимости от языка системы.
|
||||
В файлах чаще UTF-8
|
||||
Linux, MacOS - UTF-8.
|
||||
Еще есть атрибут-флаг closed: True, если файл закрыт, False, если открыт.
|
||||
```py
|
||||
>>> fp.closed
|
||||
False
|
||||
```
|
||||
Если имя файла на первом месте, а режим на втором, то имена можно не указывать. (позиционные аргументы
|
||||
всегда должны идти первыми, а именованные — после них)
|
||||
|
||||
Путь можно опустить, если он совпадает с текущей рабочей директории:
|
||||
```py
|
||||
>>> fp = open('zapis1.txt','w')
|
||||
>>> fp
|
||||
<_io.TextIOWrapper name='zapis1.txt' mode='w' encoding='cp1251'>
|
||||
```
|
||||
Список атрибутов объекта fp:
|
||||
```py
|
||||
>>> dir(fp)
|
||||
['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__',
|
||||
'__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__',
|
||||
'__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__',
|
||||
'__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
|
||||
'__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable',
|
||||
'_checkSeekable', '_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach',
|
||||
'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name',
|
||||
'newlines', 'read', 'readable', 'readline', 'readlines', 'reconfigure', 'seek', 'seekable',
|
||||
'tell', 'truncate', 'writable', 'write', 'write_through', 'writelines']
|
||||
```
|
||||
Пример открытия бинарного файла:
|
||||
```py
|
||||
>>> fp1 = open(drkt + '\\zapis2.bin', mode = 'wb+')
|
||||
>>> fp1
|
||||
<_io.BufferedRandom name='C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA6\\zapis2.bin'>
|
||||
```
|
||||
## Пункт 4.4. Закрытие файла.
|
||||
Когда файл успешно открывается / создается и открывается, ему задается целочисленный
|
||||
номер, называемый файловым дескриптором. Он создается только на один сеанс работы и указывает,
|
||||
с каким именно файлом нужно работать.
|
||||
|
||||
После того, как программа отработала, надо очистить ресурсы, связанные с файлом (область
|
||||
в оперативной памяти, в буфере при буферизации), и удалить дескриптор. Если не закрыть
|
||||
файл, это может его повредить, данные могут быть утеряны или система может быть перегружена,
|
||||
т.к. исчерпается ресурс оперативной памяти. Для закрытия есть метод close().
|
||||
|
||||
После закрытия на объект все еще можно посмотреть:
|
||||
```py
|
||||
>>> fp.close()
|
||||
>>> fp
|
||||
<_io.TextIOWrapper name='C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA6\\zapis1.txt' mode='w' encoding='cp1251'>
|
||||
```
|
||||
Но значение атрибута closed сменится на True:
|
||||
```py
|
||||
>>> fp.closed
|
||||
True
|
||||
```
|
||||
|
||||
## 4.5. Запись информации в файл с помощью метода write.
|
||||
Пример 1
|
||||
```py
|
||||
>>> sps=list(range(1,13))
|
||||
>>> fp2=open('zapis3.txt','w')
|
||||
>>> fp2.write(str(sps[:4])+'\n')
|
||||
13
|
||||
>>> fp2.write(str(sps[4:8])+'\n')
|
||||
13
|
||||
>>> fp2.write(str(sps[8:])+'\n')
|
||||
16
|
||||
>>> fp2.close()
|
||||
```
|
||||
открыли файл и увидели
|
||||
```py
|
||||
[1, 2, 3, 4]
|
||||
[5, 6, 7, 8]
|
||||
[9, 10, 11, 12]
|
||||
```
|
||||
Пример 2
|
||||
```py
|
||||
>>> sps3=[['Иванов И.',1],['Петров П.',2],['Сидоров С.',3]]
|
||||
>>> fp3=open('zapis4.txt','w')
|
||||
>>> for i in range(len(sps3)):
|
||||
... stroka4=sps3[i][0]+' '+str(sps3[i][1])
|
||||
... fp3.write(stroka4)
|
||||
...
|
||||
11
|
||||
11
|
||||
12
|
||||
>>> fp3.close()
|
||||
```
|
||||
Открыли файл и увидели
|
||||
```py
|
||||
Иванов И. 1Петров П. 2Сидоров.
|
||||
```
|
||||
Легко заметить, что информация записана в файл не очень удачно.Тогда попробум сделать так:
|
||||
```py
|
||||
>>> gh=open('zapis5.txt','w')
|
||||
>>> for r in sps3:
|
||||
... gh.write(r[0]+' '+str(r[1])+'\n')
|
||||
...
|
||||
12
|
||||
12
|
||||
13
|
||||
>>> gh.close()
|
||||
```
|
||||
Открыли файл и увидели
|
||||
```py
|
||||
Иванов И. 1
|
||||
Петров П. 2
|
||||
Сидоров С. 3
|
||||
```
|
||||
можно было записать цикл как
|
||||
```py
|
||||
for r in sps3: gh.write(r[0]+' '+str(r[1])+'\n')
|
||||
```
|
||||
4.6 Первый способ чтения информации из текстового файла.
|
||||
```py
|
||||
>>> sps1=[]
|
||||
>>> fp=open('zapis3.txt')
|
||||
>>> for stroka in fp:
|
||||
... stroka=stroka.rstrip('\n')
|
||||
... stroka=stroka.replace('[','')
|
||||
... stroka=stroka.replace(']','')
|
||||
... sps1=sps1+stroka.split(',') # на этот моменте целые числа превращаются в строки
|
||||
...
|
||||
>>> fp.close()
|
||||
>>> sps1
|
||||
['1', ' 2', ' 3', ' 4', '5', ' 6', ' 7', ' 8', '9', ' 10', ' 11', ' 12']
|
||||
```
|
||||
Обратите внимание, что в функции открытия файла использован только один аргумент, остальные – со значениями «по умолчанию».
|
||||
Здесь, перед занесением строки в список с помощью метода rstrip, из неё удаляется сим-вол конца строки, а с помощью метода replace – скобки.
|
||||
Видно, что полученный список отличается от исходного sps, в первую очередь, типом данных.
|
||||
К тому же, в sps1 убрались не все пробелы.
|
||||
Преобразовать sps1 в sps можно, например, так:
|
||||
```py
|
||||
>>> sps2 = [int(i.strip()) for i in sps1]
|
||||
>>> sps2
|
||||
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
||||
```
|
||||
Это list comprehension, который у кажлого элемента sps1 убирает лишние пробелы с обеих
|
||||
сторон (в этом отличие rstrip от strip). Затем полученная строка конвертируется в число.
|
||||
## Пункт 4.7. Чтение информации из файла с помощью метода read.
|
||||
Метод read, как и write, относится к объекту – файловой переменной. В качестве аргумен-та этого метода может задаваться целое число – количество символов или, если открыт бинарный файл, - количество байт, которое должно быть прочитано, соответственно, из текстового или би-нарного файла, начиная с текущего положения маркера. Если указанное число превышает коли-чество оставшихся символов (байт) в файле, то считываются все оставшиеся символы (байты). Если это число не указано, то считываются вся информация от маркера до конца файла. Метод возвращает строку с символами или совокупность байт, прочитанных из файла. Например,
|
||||
```py
|
||||
>>> fp=open('zapis3.txt')
|
||||
>>> stroka1=fp.read(12) # Чтение первых 12 файлов, курсор остановится на 13-ом (/n)
|
||||
>>> stroka2=fp.read() # Чтение всех оставшихся файлов вплоть до EOF
|
||||
>>> fp.close()
|
||||
>>> stroka1
|
||||
'[1, 2, 3, 4]'
|
||||
>>> stroka2
|
||||
'\n[5, 6, 7, 8]\n[9, 10, 11, 12]\n'
|
||||
```
|
||||
## Пункт 4.8. Чтение информации с помощью readline и readlines.
|
||||
|
||||
Метод readline() считывает одну строку из файла за один вызов. Он читает символы до тех пор,
|
||||
пока не встретит символ новой строки (\n; включается в строку) или конец файла (EOF).
|
||||
Если файл содержит только одну строку или указатель чтения находится в конце файла, то при
|
||||
вызове readline() будет возвращена пустая строка.
|
||||
|
||||
Метод readlines() считывает все строки файла и возвращает их в виде списка, где каждая
|
||||
строка — это отдельный элемент списка. Каждая строка в списке будет содержать символ новой
|
||||
строки \n, если он есть в файле.
|
||||
```py
|
||||
>>> file = open("zapis5.txt")
|
||||
>>> file.readline()
|
||||
'Иванов И. 1\n'
|
||||
>>> file.seek(0) # Вовзращение указателя обратно в начало, чтобы нагляднее выполнить
|
||||
readlines
|
||||
0
|
||||
>>> file.readlines()
|
||||
['Иванов И. 1\n', 'Петров П. 2\n', 'Сидоров С. 3\n']
|
||||
```
|
||||
## Пункт 4.9. Ввод-вывод объектов с использованием функций из модуля pickle.
|
||||
В модуле pickle содержатся функции для работы с бинарными файлами, в которые могут после-довательно записываться или считываться целиком один или несколько объектов из оперативной памяти. Рассмотрите этот способ работы с файлами на следующем примере:
|
||||
```py
|
||||
>>> import pickle
|
||||
>>> mnoz1={'pen','book','pen','iPhone','table','book'} #Объект типа «множество»
|
||||
>>> fp=open('zapis6.mnz','wb') # Бинарный файл - на запись
|
||||
>>> pickle.dump(mnoz1,fp) #dump - метод записи объекта в файл
|
||||
>>> fp.close()
|
||||
```
|
||||
Откроем получившийся файл в текстовом редакторе, увидим подобную строку.
|
||||
```py
|
||||
Ђ•# Џ”(ЊiPhone”Њbook”Њtable”Њpen”ђ.
|
||||
```
|
||||
Так происходит, потому что байты в этом файле не предназначены для текстового представления.
|
||||
Они могут содержать символы, которые не могут быть корректно интерпретированы в рамках
|
||||
любой текстовой кодировки. Но в некоторых байтах содержатся символы, которые попадают в
|
||||
диапазон, поддерживаемый текстовым редактором и конкретной кодировкой (в моем случае ANSI),
|
||||
поэтому правильно дешифрованные буквы все же есть.
|
||||
|
||||
|
||||
Десериализуем множество обратно:
|
||||
```py
|
||||
>>> fp = open('zapis6.mnz','rb')
|
||||
>>> mnoz2 = pickle.load(fp)
|
||||
>>> fp.close()
|
||||
>>> mnoz2
|
||||
{'book', 'iPhone', 'table', 'pen'}
|
||||
>>> mnoz1
|
||||
{'book', 'iPhone', 'table', 'pen'}
|
||||
>>> mnoz1 == mnoz2
|
||||
True
|
||||
```
|
||||
mnoz1 не совпадает с тем, что было задано, потому что это множество. Оно исключает
|
||||
повторяющиеся элементы, оставляя только один, а еще не содержит конкретный порядок элементов.
|
||||
Но два множества равны, если у них равны все элементы и их одинаковое количество, вне
|
||||
зависимости от порядка, так что сравнение возвращает True.
|
||||
```py
|
||||
>>> fp = open('zapis7.2ob','wb')
|
||||
>>> pickle.dump(mnoz1,fp)
|
||||
>>> pickle.dump(sps3,fp)
|
||||
>>> fp.close()
|
||||
>>> fp = open('zapis7.2ob','rb')
|
||||
>>> obj1 = pickle.load(fp)
|
||||
>>> obj2 = pickle.load(fp)
|
||||
>>> fp.close()
|
||||
>>> obj1
|
||||
{'book', 'iPhone', 'table', 'pen'}
|
||||
>>> obj2
|
||||
[['Иванов И.', 1], ['Петров П.', 2], ['Сидоров С.', 3]]
|
||||
>>> mnoz1 == obj1
|
||||
True
|
||||
>>> obj2 == sps3
|
||||
True
|
||||
```
|
||||
# Пункт 5. Перенаправление потоков ввода и вывода данных.
|
||||
|
||||
Поток в python и других ЯП - это абстракция, которая позволяет регулировать источники
|
||||
ввода информации и то, куда её выводить. Всего их по умолчанию три (еще можнно создать
|
||||
пользовательские):
|
||||
sys.stdin — поток ввода (обычно клавиатура)
|
||||
sys.stdout — поток вывода
|
||||
sys.stderr — поток ошибок (оба обычно экран)
|
||||
|
||||
Для работы с потоками импортируем модуль sys:
|
||||
```py
|
||||
>>> import sys
|
||||
```
|
||||
Сохраним адрес в памяти текущего потока вывода:
|
||||
```py
|
||||
>>> vr_out = sys.stdout
|
||||
>>> vr_out
|
||||
<idlelib.run.StdOutputFile object at 0x0000018C2F7961C0>
|
||||
```
|
||||
Откроем (созадем) файл на запись:
|
||||
```py
|
||||
>>> fc = open('Stroka.txt','w')
|
||||
```
|
||||
Теперь зададим в качестве потока вывода этот файл:
|
||||
```py
|
||||
>>> sys.stdout = fc
|
||||
>>> print('запись строки в файл')
|
||||
```
|
||||
Видно, что в консоли не появилось строки. Вернем поток по умолчанию обратно:
|
||||
```py
|
||||
>>> sys.stdout = vr_out
|
||||
>>> print('запись строки на экран')
|
||||
запись строки на экран
|
||||
>>> fc.close()
|
||||
```
|
||||
В файле Stroka.txt находится: запись строки в файл
|
||||
|
||||
Можно перенаправить и поток ввода тоже. Например, на файл:
|
||||
```py
|
||||
>>> tmp_in = sys.stdin
|
||||
>>> fd = open("Stroka.txt", "r")
|
||||
>>> sys.stdin = fd
|
||||
>>> sys.stdin
|
||||
<_io.TextIOWrapper name='Stroka.txt' mode='r' encoding='cp1251'>
|
||||
>>> while True:
|
||||
try: # Конструкция try-except предназначена для отладки исключений
|
||||
# То есть если возвращается ошибка, можно ее перехватить и
|
||||
# указать, что делать в таком случае
|
||||
line = input()
|
||||
print(line)
|
||||
except EOFError:
|
||||
break
|
||||
запись строки в файл
|
||||
>>> fd.close()
|
||||
>>> sys.stdin = tmp_in
|
||||
```
|
||||
62
TEMA6/task.md
Обычный файл
@@ -0,0 +1,62 @@
|
||||
• Создаётся объект-кортеж со 125 целыми случайными числами из диапазона от 6 до 56,
|
||||
представленными в виде символьных строк.
|
||||
```py
|
||||
>>> nums = tuple(str(random.randint(6, 56)) for _ in range(125))
|
||||
>>> nums
|
||||
('41', '37', '13', '26', '9', '33', '55', '50', '51', '44', '38', '17', '18', '18', '36',
|
||||
'23', '43', '38', '41', '42', '53', '16', '41', '34', '38', '48', '37', '17', '36', '48',
|
||||
'31', '34', '51', '18', '12', '37', '42', '50', '47', '26', '27', '30', '26', '11', '19',
|
||||
'56', '15', '7', '6', '45', '22', '37', '36', '54', '31', '35', '46', '54', '31', '13',
|
||||
...'41', '9', '9', '22')
|
||||
```
|
||||
Примечание: если итератор не надо использовать в теле цикла, принято просто обозначать его _
|
||||
|
||||
• Создаётся объект-список с вашей фамилией и 4 фамилиями ваших одноклассников.
|
||||
```py
|
||||
>>> group = ["Tsvetkova", "Konovalova", "Kiselyov", "Kirsanov", "Romanov"]
|
||||
```
|
||||
• Записывается кортеж в бинарный файл.
|
||||
```py
|
||||
>>> fl = open("okz.okz", "wb")
|
||||
>>> pickle.dump(nums, fl)
|
||||
```
|
||||
• Записывается в этот же файл список и закрывается файл.
|
||||
```py
|
||||
>>> pickle.dump(group, fl)
|
||||
>>> fl.close()
|
||||
```
|
||||
• Открывается этот файл для чтения и считывает из него данные в 2 новых объекта.
|
||||
```py
|
||||
>>> fl = open("okz.okz", "rb")
|
||||
>>> nums1 = pickle.load(fl)
|
||||
>>> nums1
|
||||
('41', '37', ... '41', '9', '9', '22')
|
||||
>>> group1 = pickle.load(fl)
|
||||
>>> group1
|
||||
['Tsvetkova', 'Konovalova', 'Kiselyov', 'Kirsanov', 'Romanov']
|
||||
```
|
||||
Примечание: при чтении с помощью pickle.load() тоже есть указатель, который останавливается
|
||||
при достижении /n, так что можно просто вызвать ее два раза, чтобы записать эти два объекта.
|
||||
Если вызвать ее третий раз, будет EOFError.
|
||||
|
||||
• Проверяется на совпадение новых объектов с исходными и выводится соответствующее сообщение.
|
||||
```py
|
||||
>>> print("Файлы nums совпадают!") if nums == nums1 else print("Файлы nums не совпадают :(")
|
||||
Файлы nums совпадают!
|
||||
>>> print("Файлы group совпадают!") if group == group1 else print("Файлы group не совпадают :(")
|
||||
Файлы group совпадают!
|
||||
```
|
||||
• Разделяется кортеж на совокупности по 5 чисел в каждой и
|
||||
они записываются в виде отдельных списков со своими именами. (Динамические имена, согласно
|
||||
примечанию на git uit)
|
||||
```py
|
||||
>>> for i in range(125//5):
|
||||
exec('list' + str(i) + '=' + str(list(nums1[i:i+5])))
|
||||
```
|
||||
Можно вызвать конкретные списки для проверки:
|
||||
```py
|
||||
>>> list1
|
||||
['37', '13', '26', '9', '33']
|
||||
>>> list6
|
||||
['55', '50', '51', '44', '38']
|
||||
```
|
||||
23
TEMA7/1111.md
Обычный файл
@@ -0,0 +1,23 @@
|
||||
16. Разработайте функцию с 2 аргументами, которая для заданного словаря (аргумент функции) с любыми ключами и с числовыми значениями создаёт новый словарь с теми же ключами и со значениями, равными синусам от значений из входного словаря с заданным именами. Проверьте функцию на примере двух разных входных словарей.
|
||||
```py
|
||||
>>> import math
|
||||
>>> def f(a):
|
||||
... result = {}
|
||||
... for k, v in a.items(): # Перебираем все пары ключ-значение из входного словаря
|
||||
... result[k] = math.sin(v)
|
||||
... return result
|
||||
...
|
||||
>>> def test():
|
||||
... print("Тест 1", f({'a': 0, 'b': 1.57, 'c': 3.14}))
|
||||
...
|
||||
>>> def test2():
|
||||
... print("Тест 2", f({'x': 0.5, 'y': 1.0, 'z': 2.0}))
|
||||
...
|
||||
|
||||
>>> test
|
||||
<function test at 0x0000016467AAAAC0>
|
||||
>>> test()
|
||||
Тест 1 {'a': 0.0, 'b': 0.9999996829318346, 'c': 0.0015926529164868282}
|
||||
>>> test2()
|
||||
Тест 2 {'x': 0.479425538604203, 'y': 0.8414709848078965, 'z': 0.9092974268256817}
|
||||
```
|
||||
739
TEMA7/7.md
Обычный файл
@@ -0,0 +1,739 @@
|
||||
# Пункт 2. Создание пользовательской функции.
|
||||
|
||||
Общий вид:
|
||||
```py
|
||||
def <Имя функции>([<Список аргументов >]):
|
||||
[<отступы> """<Комментарий по назначению функции>"""]
|
||||
<отступы> <Блок инструкций – тело функции>
|
||||
[<отступы> return <Значение или вычисляемое выражение>]
|
||||
```
|
||||
Функция считается оконченной, если в очередной строке нет отступов или их число меньше, чем
|
||||
в отступах в функции. Если при выполнении функции будет выполнена инструкция return, то
|
||||
выполнение функции прекращается с возвратом значения, следующего за этой инструкцией.
|
||||
В Python, если функция не содержит оператора return, она автоматически возвращает значение
|
||||
None.
|
||||
|
||||
## Пункт 2.1. Функция без аргументов.
|
||||
```py
|
||||
>>> def uspeh():
|
||||
"""Подтверждение успеха операции"""
|
||||
print('Выполнено успешно!')
|
||||
>>> uspeh()
|
||||
Выполнено успешно!
|
||||
```
|
||||
Функция - класс function:
|
||||
```py
|
||||
>>> type(uspeh)
|
||||
<class 'function'>
|
||||
```
|
||||
Видно, что такой объект появился в рабочем пространстве:
|
||||
```py
|
||||
>>> dir()
|
||||
['__annotations__', '__builtins__',
|
||||
'__doc__', '__loader__', '__name__', '__package__', '__spec__', 'os', 'uspeh']
|
||||
```
|
||||
```py
|
||||
>>> help(uspeh)
|
||||
Help on function uspeh in module __main__:
|
||||
uspeh()
|
||||
Подтверждение успеха операции
|
||||
```
|
||||
Видно, что help вернуло имя функции и то описание, которое было указано в тройных кавычках
|
||||
при её определении.
|
||||
|
||||
## Пункт 2.2. Функция с аргументами.
|
||||
```py
|
||||
>>> def sravnenie(a, b):
|
||||
"""Сравнение a и b"""
|
||||
if a > b:
|
||||
print(a, ' больше ', b)
|
||||
elif a < b:
|
||||
print(a, ' меньше ', b)
|
||||
else:
|
||||
print(a, ' равно ',b)
|
||||
|
||||
```
|
||||
```py
|
||||
>>> n, m = 16, 5; sravnenie(n,m)
|
||||
16 больше 5
|
||||
```
|
||||
Так как при описании функции мы не конкретизировали, какой тип данных хотим получить, то
|
||||
python сможет принять любые данные, которые можно сравнить. Если что-то нельзя сравнить,
|
||||
вернется TypeError
|
||||
```py
|
||||
>>> sravnenie(2+3j > 1+2j)
|
||||
File "<stdin>", line 1, in <module>
|
||||
TypeError: '>' not supported between instances of 'complex' and 'complex'
|
||||
>>> sravnenie(2+3j == 2+3j)
|
||||
True
|
||||
>>>sravnenie("abbb", "baaaaa") # abbb меньше baaaa (т.к. 'a' < 'b')
|
||||
>>>sravnenie("abbb", "abbbbb") # abbb меньше abbbbb (короткая строка меньше)
|
||||
>>>sravnenie("10", "2") # 10 меньше 2 (т.к. '1' < '2')
|
||||
>>>sravnenie([1, 2, 3], [1, 2, 4]) # [1, 2, 3] меньше [1, 2, 4] (т.к. 3 < 4)
|
||||
>>>sravnenie([1, 2], [1, 2, 0]) # [1, 2] меньше [1, 2, 0] (короткий список меньше)
|
||||
|
||||
```
|
||||
## Пункт 2.3. Функция с return.
|
||||
```py
|
||||
>>> def logistfun(b, a):
|
||||
"""Вычисление логистической функции"""
|
||||
import math
|
||||
return a / (1 + math.exp(-b))
|
||||
```
|
||||
```py
|
||||
>>> v=1
|
||||
>>> w = 0.7
|
||||
>>> z = logistfun(w, v)
|
||||
>>> z
|
||||
0.6681877721681662
|
||||
```
|
||||
## 2.4. Сложение для разных типов аргументов
|
||||
```py
|
||||
>>> def slozh(a1,a2,a3,a4):
|
||||
... """ Сложение значений четырех аргументов"""
|
||||
... return a1+a2+a3+a4
|
||||
...
|
||||
```
|
||||
```py
|
||||
>>> 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]
|
||||
|
||||
>>> slozh((1, 2), (3, 4), (-5, 0), (-7, -3)) #Для кортежей
|
||||
(1, 2, 3, 4, -5, 0, -7, -3)
|
||||
|
||||
|
||||
>>> slozh({1,1,1,1}, {2}, {"аааа", True, None}, {6, 6, "a"}) #Для множеств
|
||||
...
|
||||
TypeError: unsupported operand type(s) for +: 'set' and 'set'
|
||||
```
|
||||
Как видно, операция сложения для множеств не применима. Если нужно объединить два множества,
|
||||
для этого есть специальная операция set union вида set1 | set2 | set3
|
||||
```py
|
||||
>>> dict1 = {'a': 1}; dict2 = {'b': 2}; dict3 = {'c': 3}; dict4 = {'d': 4} #Для словарей
|
||||
...
|
||||
TypeError: unsupported operand type(s) for +: 'dict' and 'dict'
|
||||
```
|
||||
Словари тоже нельзя сложить плюсом. Для объединения словарей есть оператор распаковывания
|
||||
**dict1.
|
||||
|
||||
```py
|
||||
>>> slozh(1, "а", 2, "б") #Число и строка
|
||||
...
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
```
|
||||
С коллекциями без явного преобразования тоже не сработает.
|
||||
```py
|
||||
>>> slozh(1, True, 2, False) #Число и логический тип
|
||||
4
|
||||
>>> slozh(1, 3.44, 2.0, 7) #Целое число и число с плавающей точкой
|
||||
13.44
|
||||
```
|
||||
## Пункт 2.5. Функция, реализующая модель некоторого устройства,
|
||||
на вход которого в текущий момент поступает сигнал х, на выходе получается сигнал y:
|
||||
```py
|
||||
>>> def inerz(x,T,ypred):
|
||||
""" Модель устройства с памятью:
|
||||
x - текущее значение вх.сигнала,
|
||||
T - постоянная времени,
|
||||
ypred - предыдущее значение выхода устройства"""
|
||||
y = (x + T * ypred) / (T + 1)
|
||||
return y
|
||||
```
|
||||
Создаем список с измерениями значений входного сигнала – в виде «ступеньки»:
|
||||
```py
|
||||
>>> sps = [0] + [1] * 100
|
||||
>>> spsy = []
|
||||
>>> TT = 20
|
||||
>>> yy = 0
|
||||
>>> for xx in sps:
|
||||
yy = inerz(xx,TT,yy)
|
||||
spsy.append(yy)
|
||||
```
|
||||
```py
|
||||
>>> import pylab as plt
|
||||
>>> plt.plot(spsy, label = "Выходной сигнал")
|
||||
[<matplotlib.lines.Line2D object at 0x00000241DC815370>]
|
||||
>>> plt.show()
|
||||
```
|
||||
График сохранен в файле с именем Figure_1.
|
||||
|
||||
|
||||
# Пункт 3. Функции как объекты.
|
||||
|
||||
## Пункт 3.1. Получение списка атрибутов объекта-функции.
|
||||
```py
|
||||
>>> 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__
|
||||
' Модель устройства с памятью:\nx- текущее значение вх.сигнала,\n\tT -постоянная времени,\n\typred - предыдущее значение выхода устройства'
|
||||
>>> help(inerz)
|
||||
Help on function inerz in module __main__:
|
||||
```
|
||||
Если нет, то inerz.__doc__ будет иметь значение None.
|
||||
|
||||
Примеры других атрибутов функций:
|
||||
```py
|
||||
>>> def f(a : int, b : int, c = 10):
|
||||
return
|
||||
|
||||
>>> f.__annotations__
|
||||
{'a': <class 'int'>, 'b': <class 'int'>} # Возвращает типы аргументов, если они заданы
|
||||
|
||||
>>> f.__defaults__ # Возвращает значения по умолчанию, если они заданы
|
||||
(10,)
|
||||
>>> f.__name__ # Возвращает имя функции (для функций, определенных внутри других, возвращает
|
||||
полный путь
|
||||
'f'
|
||||
```
|
||||
## Пункт 3.2. Сохранение ссылки на объект-функцию в другой переменной.
|
||||
```py
|
||||
>> fnkt = sravnenie
|
||||
>>> v = 16
|
||||
>>> fnkt(v, 23)
|
||||
16 меньше 23
|
||||
```
|
||||
Здесь происходит присвоение функции sravnenie переменной fnkt. Функции можно передавать в
|
||||
переменные, как и любые другие объекты. После этого переменная fnkt ссылается на ту же самую
|
||||
функцию, что и sravnenie.
|
||||
|
||||
## Пункт 3.3. Возможность альтернативного определения функции в программе.
|
||||
```py
|
||||
>>> typ_fun=8
|
||||
>>> if typ_fun==1:
|
||||
... def func():
|
||||
... print('Функция 1')
|
||||
... else:
|
||||
... def func():
|
||||
... print('Функция 2')
|
||||
...
|
||||
>>> func()
|
||||
Функция 2
|
||||
```
|
||||
|
||||
Программа выводит сообщение "Функция 2", потому что переменная typ_fun не равна 1, и
|
||||
выполняется блок else, в котором функция func определена как выводящая, собственно,
|
||||
"Функция 2".
|
||||
|
||||
# Пункт 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)
|
||||
-2.3318122278318336
|
||||
```
|
||||
Python передаёт ссылку на объект функции logistfun в переменную fff. Внутри
|
||||
функции выполняется операция: a + fff(c, b), что эквивалентно -3 + logistfun(0.7, 1)
|
||||
|
||||
## Пункт 4.2. Обязательные и необязательные аргументы.
|
||||
```py
|
||||
>>> 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. Возможность обращения к функции с произвольным расположением аргументов.
|
||||
```py
|
||||
>>> logistfun(b = 0.5, a = 0.8)
|
||||
0.34498724056380625
|
||||
```
|
||||
Но при этом нельзя сделать так:
|
||||
```py
|
||||
>>> logistfun(b = 2, 0.7)
|
||||
SyntaxError: positional argument follows keyword argument
|
||||
```
|
||||
Python ожидает, что все позиционные аргументы будут переданы первыми, а затем уже
|
||||
могут следовать именованные аргументы.
|
||||
|
||||
## Пункт 4.4. Пример со значениями аргументов функции, содержащимися в списке или кортеже.
|
||||
```py
|
||||
>>> b1234 = [b1, b2, b3, b4]
|
||||
>>> b1234
|
||||
[[1, 2], [-1, -2], [0, 2], [-1, -1]]
|
||||
>>> qq = slozh(*b1234)
|
||||
>>> qq
|
||||
[1, 2, -1, -2, 0, 2, -1, -1]
|
||||
```
|
||||
Со звёздочкой коллекции передаются как набор аргументов функции, Она также называется
|
||||
"оператор распаковки". Это было бы эквивалентно записи slozh(b1,b2,b3,b4)
|
||||
|
||||
## Пункт 4.5. Пример со значениями аргументов функции, содержащимися в словаре
|
||||
```py
|
||||
>>> dic4 = {"a1": 1, "a2": 2, "a3": 3, "a4": 4}
|
||||
>>> qqq = slozh(**dic4)
|
||||
>>> qqq
|
||||
10
|
||||
```
|
||||
В данном случае распаковка произошла так, что ключи на входе функции восприниимаются как
|
||||
значения позиционных переменных, а значения, соответственно, как значения.
|
||||
|
||||
Примечание: Если поставить только одну звездочку, python попытается интерпретировать
|
||||
ключи, а не значения словаря как позиционные аргументы. Получается так:
|
||||
```py
|
||||
>>> slozh(*dic4)
|
||||
'a1a2a3a4'
|
||||
```
|
||||
## Пункт 4.6. Смешанные ссылки
|
||||
```py
|
||||
>>> e1 = (-1, 6); dd2 = {'a3': 3, 'a4': 9}
|
||||
>>> qqqq = slozh(*e1,**dd2)
|
||||
>>> qqqq
|
||||
17
|
||||
```
|
||||
То есть (-1) + 6 + 3 + 9 = 17
|
||||
|
||||
## Пункт 4.7. Переменное число аргументов у функции.
|
||||
```py
|
||||
>>> 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. Комбинация аргументов
|
||||
```py
|
||||
>>> 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 * 9 + 2 = -7.
|
||||
|
||||
Если захочется НЕ передавать b, придется переопределить функцию так, чтобы
|
||||
именованный параметр b был в конце, а позиционный кортеж - перед ним. Например,
|
||||
так:
|
||||
```py
|
||||
>>> def func4(a, *kort7, b = 7):
|
||||
smm = 0
|
||||
for elt in kort7:
|
||||
smm += elt
|
||||
return a * smm + b
|
||||
|
||||
>>> func4(5, *[1, 2, 3])
|
||||
37
|
||||
```
|
||||
Примечание:
|
||||
|
||||
В общем виде *args и **kwargs - способы передать не уточненное заранее число
|
||||
элементов, причем:
|
||||
|
||||
*args — переменное количество позиционных аргументов. Переданные с одной
|
||||
звездочкой аргументы собираются в кортеж.
|
||||
|
||||
**kwargs — переменное количество именованных аргументов. Все переданные аргументы,
|
||||
которые указываются по имени, собираются в словарь.
|
||||
|
||||
Как и всегда, *args всегда должно идти перед **kwargs.
|
||||
|
||||
## Пункт 4.9. Изменение значений объектов, используемых в качестве аргументов функции.
|
||||
```py
|
||||
>>> a = 90
|
||||
>>> def func3(b):
|
||||
b = 5*b+67
|
||||
|
||||
|
||||
>>> func3(a)
|
||||
>>> a
|
||||
90
|
||||
```
|
||||
Поскольку функция ничего не возвращает (то есть, формально, является процедурой), то вычисленное
|
||||
значение b = 5*b+67 существует только локально внутри нее и не выносится в глобальную область видимости
|
||||
Для наглядности:
|
||||
```py
|
||||
>>> def func3(b):
|
||||
b = 5*b+67
|
||||
print(b)
|
||||
|
||||
|
||||
>>> func3(a)
|
||||
517
|
||||
>>> a
|
||||
90
|
||||
```
|
||||
```py
|
||||
|
||||
>>> sps1=[1,2,3,4]
|
||||
>>> def func2(sps):
|
||||
sps[1] = 99
|
||||
|
||||
|
||||
>>> func2(sps1)
|
||||
>>> print(sps1)
|
||||
[1, 99, 3, 4]
|
||||
```
|
||||
В отличие от предыдущего примера с переменной численного типа, список передается по ссылке, а не по
|
||||
значению, поэтому изменяется именно тот объект, который был передан.
|
||||
Для наглядности:
|
||||
```py
|
||||
>>> def func3(b):
|
||||
b = 5*b+67
|
||||
print(id(b))
|
||||
|
||||
>>> func3(a)
|
||||
2763070067568
|
||||
>>> id(a)
|
||||
2763028911248 # Разные адреса
|
||||
|
||||
>>> def func3(b):
|
||||
b = 5*b+67
|
||||
print(id(b))
|
||||
|
||||
>>> func3(a)
|
||||
2763070067568
|
||||
>>> id(a)
|
||||
2763028911248 # Одинаковые адреса
|
||||
```
|
||||
```py
|
||||
>>> kort = (1,2,3,4)
|
||||
>>> func2(kort)
|
||||
Traceback (most recent call last):
|
||||
File "<pyshell#41>", line 1, in <module>
|
||||
func2(kort)
|
||||
File "<pyshell#40>", line 2, in func2
|
||||
sps[1] = 99
|
||||
TypeError: 'tuple' object does not support item assignment
|
||||
```
|
||||
Кортеж - неизменяемая коллекция, так что переназначение значения в таком виде, как здесь, не работает.
|
||||
# Пункт 5. Специальные типы пользовательских функций
|
||||
|
||||
## Пункт 5.1. Анонимные функции (лямбда-функции).
|
||||
```py
|
||||
>>> anfun1 = lambda: 1.5 + math.log10(17.23)
|
||||
>>> type(anfun1)
|
||||
<class 'function'>
|
||||
|
||||
>>> 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
|
||||
```
|
||||
Вызов лямбда-функции создает объект класса "функция", который потом можно положить в другую переменную
|
||||
и далее вызывать. Но это делать необязательно: если она используется один раз, можно вызвать ее сразу,
|
||||
например:
|
||||
```py
|
||||
>>> r = (lambda a, b: a**2 + b)(5, 2) # Это результат функции, а не объект класса "функция"
|
||||
>>> r
|
||||
27
|
||||
```
|
||||
Внутри лямбда-функции не могут использоваться многострочные выражения, например:
|
||||
```py
|
||||
>>> r1 = lambda: (for i in range(5): print(i))
|
||||
SyntaxError: invalid syntax
|
||||
```
|
||||
Но при этом:
|
||||
```py
|
||||
>>> r1 = lambda: (print(i) for i in range(5))
|
||||
|
||||
```
|
||||
Аналогично нельзя использовать if-else, но можно использовать тернарный оператор.
|
||||
|
||||
## Пункт 5.2. Функции-генераторы
|
||||
|
||||
Иногда в циклах на каждой итерации нужно получать одно из значений. Для этого есть оператор yield.
|
||||
Это похоже на return, но в отличие от return не останавливает полностью выполнение программы.
|
||||
Когда выполнение генератора возобновляется после yield, оно продолжается с того места, где было
|
||||
приостановлено, до следующего оператора yield (или до конца функции).
|
||||
Вместе с yield, можно использовать next(). Например:
|
||||
```py
|
||||
>>> def test():
|
||||
for i in range(3):
|
||||
yield i
|
||||
|
||||
|
||||
>>> l = test()
|
||||
>>> l
|
||||
<generator object test at 0x0000028353CCFF90>
|
||||
>>> next(l)
|
||||
0
|
||||
>>> next(l)
|
||||
1
|
||||
```
|
||||
Аналогично, можно использовать и метод __next__
|
||||
```py
|
||||
>>> print(l.__next__())
|
||||
2
|
||||
```
|
||||
Другой пример:
|
||||
```py
|
||||
>>> alp=func5(7,3)
|
||||
>>> print(alp.__next__())
|
||||
1
|
||||
>>> print(alp.__next__())
|
||||
5
|
||||
>>> print(alp.__next__())
|
||||
4
|
||||
...
|
||||
```
|
||||
__next__ помогает вывести значение, которое yield передает на каждй итерации цикла. Если функция
|
||||
отработала последнюю итерацию, но мы все попытаемся сделать вызов, вернется ошибка:
|
||||
```py
|
||||
>>> print(alp.__next__())
|
||||
Traceback (most recent call last):
|
||||
File "<pyshell#96>", line 1, in <module>
|
||||
print(alp.__next__())
|
||||
StopIteration
|
||||
```
|
||||
# Пункт 6. Локализация объектов в функциях.
|
||||
|
||||
Все объекты - переменные, коллекции, функции и т.д. - могут быть определены глобально или локально.
|
||||
Глобально - значит вне всяких функций.Локальные переменные определены внутри функции, и если хочется
|
||||
использовать такую переменную в другой функции, то нужно обрабатывать доступ к ним из других функций.
|
||||
|
||||
## Пункт 6.1. Примеры
|
||||
```py
|
||||
>>> glb = 10
|
||||
>>> def func7(arg):
|
||||
loc1 = 15
|
||||
glb = 8
|
||||
return loc1*arg
|
||||
|
||||
>>> res = func7(glb)
|
||||
>>> res
|
||||
150
|
||||
```
|
||||
Проверим:
|
||||
```py
|
||||
>>> glb
|
||||
10
|
||||
```
|
||||
|
||||
Посмотрим подробнее, что происходит внутри функции:
|
||||
```py
|
||||
>>> def func7(arg):
|
||||
loc1=15
|
||||
glb=8
|
||||
print(glb, arg)
|
||||
return loc1*arg
|
||||
|
||||
>>> res=func7(glb)
|
||||
8 10
|
||||
```
|
||||
Видно, что внутри объект с именем glb принял значение 8, но глобальная переменная при этом после выполнения
|
||||
функции значения не поменяла. Это происходит потому, что технически, локальный glb и глобальный glb -
|
||||
это два разных объекта. В этом можно убедиться:
|
||||
```py
|
||||
>>> res=func7(glb) #При определенении func7 добавлена строка print(id(glb))
|
||||
2763028720144
|
||||
8 10
|
||||
>>> id(glb)
|
||||
276302872020
|
||||
```
|
||||
|
||||
Пример 2.
|
||||
```py
|
||||
>>> def func8(arg):
|
||||
loc1=15
|
||||
print(glb)
|
||||
glb=8
|
||||
return loc1*arg
|
||||
|
||||
>>> res=func8(glb)
|
||||
Traceback (most recent call last):
|
||||
File "<pyshell#119>", line 1, in <module>
|
||||
res=func8(glb)
|
||||
File "<pyshell#118>", line 3, in func8
|
||||
print(glb)
|
||||
UnboundLocalError: local variable 'glb' referenced before assignment
|
||||
```
|
||||
Ошибка возникает, потому что когда python видит внутри функции переменную, он по умолчанию считает ее
|
||||
локальной. И получается, что вызов локальной переменной glb происходит раньше объявления локальной
|
||||
переменной glb, на что нам и указывает ошибка. Можно исправить эту проблему, переопределив лоаклизацию
|
||||
glb внутри func8():
|
||||
```py
|
||||
>>> glb=11
|
||||
>>> def func7(arg):
|
||||
loc1=15
|
||||
global glb
|
||||
print(glb)
|
||||
glb=8
|
||||
return loc1*arg
|
||||
|
||||
>>> res=func7(glb)
|
||||
11
|
||||
>>> glb
|
||||
8
|
||||
```
|
||||
Здесь мы явно указали, что в функции имеем в виду глобальную переменную, так что она изменилась.
|
||||
|
||||
## Пункт 6.2. locals() и globals()
|
||||
|
||||
Эти функции возвращают словари, ключами в которых будут имена объектов, являющихся, соответственно,
|
||||
локальными или глобальными на уровне вызова этих функций.
|
||||
```py
|
||||
>>> globals().keys()
|
||||
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__',
|
||||
'__builtins__', '__file__', 'math', 'random', 'pickle', 'task', 't', 'number', 'a',
|
||||
'func3', 'sps1', 'func2', 'kort', 'anfun1', 'anfun2', 'anfun3',
|
||||
'func5', 'mm', 'r', 'r1', 'test', 'l', 'alp', 'glb', 'func7', 'res', 'func8'])
|
||||
>>> locals().keys()
|
||||
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__',
|
||||
'__builtins__', '__file__', 'math', 'random', 'pickle', 'task', 't', 'number', 'a',
|
||||
'func3', 'sps1', 'func2', 'kort', 'anfun1', 'anfun2', 'anfun3', 'func5', 'mm', 'r',
|
||||
'r1', 'test', 'l', 'alp', 'glb', 'func7', 'res', 'func8'])
|
||||
```
|
||||
Сейчас различий нет, потому что эти методы возвращают объекты на уровне вызова этих функций, но мы
|
||||
вызвали обе самом внешнем уровне, не внутри какой-либо функции, а в самом рабочем пространстве, где
|
||||
локальная и глобальная области видимости совпадают.
|
||||
```py
|
||||
>>> glb = 10
|
||||
>>> def func8(arg):
|
||||
loc1=15
|
||||
glb=8
|
||||
print(globals().keys()) #Перечень глобальных объектов «изнутри» функции
|
||||
print(locals()) #Перечень локальных объектов «изнутри» функции (для наглядности отобразим
|
||||
и значения тоже)
|
||||
return loc1*arg
|
||||
|
||||
>>> hh=func8(glb)
|
||||
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__',
|
||||
'__builtins__', '__file__', 'math', 'random', 'pickle', 'task', 't', 'number', 'a',
|
||||
'func3', 'sps1', 'func2', 'kort', 'anfun1', 'anfun2', 'anfun3', 'func5', 'mm', 'r',
|
||||
'r1', 'test', 'l', 'alp', 'glb', 'func7', 'res', 'func8', 'hh']) # Тут глобальное glb
|
||||
{'arg': 10, 'loc1': 15, 'glb': 8} # Это локальное glb
|
||||
>>> glb # Снова глобальное glb
|
||||
10
|
||||
```
|
||||
## Пункт 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)
|
||||
glob_func9_1: dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__',
|
||||
'__annotations__', '__builtins__', '__file__', 'math', 'random', 'pickle',
|
||||
'task', 't', 'number', 'a', 'func3', 'sps1', 'func2', 'kort', 'anfun1',
|
||||
'anfun2', 'anfun3', 'func5', 'mm', 'r', 'r1', 'test', 'l', 'alp', 'glb',
|
||||
'func7', 'res', 'func8', 'hh', 'func9', 'loc1'])
|
||||
|
||||
locl_func9_1: dict_keys(['arg1', 'loc1', 'glb1']) # Содержит только объекты, определенные внутри func9_1,
|
||||
а также объект, переданный как аргумент функции
|
||||
|
||||
loc_func9: dict_keys(['arg2', 'arg3', 'func9_1', 'loc1', 'glb']) # Содержит все то же, что и locl_func9_1,
|
||||
но еще и arg3, переданный func9,
|
||||
и саму func9_1
|
||||
|
||||
glob_func9: dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__'
|
||||
'__builtins__', '__file__', 'math', 'random', 'pickle', 'task', 't', 'number',
|
||||
'a', 'func3', 'sps1', 'func2', 'kort', 'anfun1', 'anfun2', 'anfun3', 'func5',
|
||||
'mm', 'r', 'r1', 'test', 'l', 'alp', 'glb', 'func7', 'res', 'func8', 'hh',
|
||||
'func9', 'loc1']) # Такой же, как glob_func9_1
|
||||
```
|
||||
## Пункт 6.4. Моделирование САУ
|
||||
```py
|
||||
>>> 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])
|
||||
>>> 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,
|
||||
...
|
||||
1.1010469343064857e-13,
|
||||
-8.856348540728095e-13, -1.8813744015762676e-12, 7.608648580119871e-13, -2.3487468949147107e-13, -1.
|
||||
2306142369949293e-12, -2.226353784498387e-12, 4.1588547508986746e-13, -5.798540724135906e-13,
|
||||
-1.5755936199170489e-12]
|
||||
|
||||
>>> 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)
|
||||
y = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.0183086292055208, 0, 26.39885775889784,
|
||||
-36.65029553691161, -34.19982663883278, 196.29963397615063, -151.6919482160481,
|
||||
-388.32493988337274, 1057.8073200868555, -308.3186572590445,
|
||||
...
|
||||
2.37392249152569e+226, -2.801972415904499e+226, -3.2288710633399875e+226,
|
||||
1.321721142591339e+227, -9.144734174579399e+226]
|
||||
|
||||
```
|
||||
Двоичные данные
TEMA7/Figure_1.png
Обычный файл
|
После Ширина: | Высота: | Размер: 15 KiB |
89
TEMA7/test.md
Обычный файл
@@ -0,0 +1,89 @@
|
||||
|
||||
Разработайте и проверьте функцию, реализующую для момента времени t расчет выхода y(t) для
|
||||
устройства задержки: на вход поступает сигнал, а на выходе повторяется этот сигнал с задержкой на
|
||||
заданное время Т.
|
||||
```py
|
||||
def delays (signal, T):
|
||||
for i in range(len(signal)):
|
||||
signal[i] += T
|
||||
return signal
|
||||
```
|
||||
Входной сигнал:
|
||||
```py
|
||||
>>> y = [random.gauss(3, 1.5) for _ in range(40)]
|
||||
>>> y
|
||||
[0.9991072002742722, 1.5968849542569137, 2.3438553070732215, 3.5914160170650784, 4.037092622456526,
|
||||
2.918114740779675, 4.802139541704564, 3.2313443629034646, 2.329031244833026, 4.450860002446187,
|
||||
1.4135232524868848, 5.914364290743276, 3.7898798373923634, 2.364244259128151, 4.9786840892253235,
|
||||
1.4351490690602144, 2.351122955511408, 1.8798309616294469, 0.7931480954519166, 3.811575392065204,
|
||||
2.524732026173494, 2.8373060222940696, 4.497504412830464, 3.406940931674363, 3.876506913067825,
|
||||
1.7529616032820314, 2.6542411737897087, 1.948604542902865, 6.138099312505814, 1.4111492356181103,
|
||||
3.736820673744037, 4.509373750771566, 1.7486314440126465, 4.70122140759552,
|
||||
-0.6513915222680815, 0.171219291885647, 2.2079783562880486, 4.390489704586708, 0.9670198540727273,
|
||||
1.6420724788248429]
|
||||
|
||||
>>> yd = delays(y, 4)
|
||||
>>> yd
|
||||
[4.999107200274272, 5.596884954256914, 6.3438553070732215, 7.591416017065079, 8.037092622456527,
|
||||
6.918114740779675, 8.802139541704564, 7.231344362903465, 6.3290312448330255, 8.450860002446188,
|
||||
5.413523252486884, 9.914364290743276, 7.7898798373923634, 6.364244259128151, 8.978684089225323,
|
||||
5.435149069060214, 6.351122955511408, 5.879830961629446, 4.793148095451917, 7.811575392065204,
|
||||
6.524732026173494, 6.83730602229407, 8.497504412830464, 7.406940931674363, 7.876506913067825,
|
||||
5.752961603282031, 6.654241173789709, 5.948604542902865, 10.138099312505814, 5.41114923561811,
|
||||
7.736820673744036, 8.509373750771566, 5.748631444012647, 8.70122140759552,
|
||||
3.3486084777319185, 4.171219291885647, 6.207978356288049, 8.390489704586708, 4.967019854072728, 5.642072478824843]
|
||||
```
|
||||
Разработайте и проверьте функцию, реализующую расчет гистограммы по выборке случайной величины с каким-то
|
||||
распределением. Гистограмма при выводе на экран представляется в виде таблицы: границы интервала, число элементов
|
||||
выборки в интервале. Аргументы функции: выборка, число интервалов разбиения диапазона изменения
|
||||
случайной величины. Возвращаемый результат функции: список с числами элементов выборки в интервалах разбиения.
|
||||
```py
|
||||
import numpy as np
|
||||
import random
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
def histo(data, num):
|
||||
minval, maxval = min(data), max(data)
|
||||
parts = np.linspace(minval, maxval, num + 1)
|
||||
rows = [0] * num
|
||||
for now in data:
|
||||
for i in range(num):
|
||||
if parts[i] <= now < parts[i + 1]:
|
||||
rows[i] += 1
|
||||
break
|
||||
if now == maxval:
|
||||
rows[-1] += 1
|
||||
|
||||
plt.hist(data, bins=parts)
|
||||
plt.xlabel('Значения выборки')
|
||||
plt.ylabel('Число элементов')
|
||||
plt.title('Гистограмма выборки')
|
||||
plt.show()
|
||||
|
||||
return rows
|
||||
|
||||
sample = [random.gauss(random.random(), random.random()) for _ in range(random.randint(10,200))]
|
||||
intervals = int(input("Введите количество интервалов разбиения: "))
|
||||
output = histo(sample, intervals)
|
||||
|
||||
======================= RESTART: D:/STUDY/POAS/Тема7/hist.py ======================
|
||||
Введите количество интервалов разбиения: 12
|
||||
[1, 0, 3, 4, 11, 21, 43, 57, 22, 6, 2, 3]
|
||||
|
||||
```
|
||||
Разработайте и проверьте анонимную функцию, вычисляющую значение оценки отклика Y линейной регрессии при значении переменной Х
|
||||
Y=b1+b2*X
|
||||
и имеющую аргументы b1, b2 и X.
|
||||
```py
|
||||
linreg = lambda b1, b2, x: b1 + b2 * x
|
||||
b1 = float(input("Введите коэффициент b1 линейной регрессии: "))
|
||||
b2 = float(input("Введите коэффициент b2 линейной регрессии: "))
|
||||
x_val = float(input("Введите значение x: "))
|
||||
print(linreg(b1, b2, x_val))
|
||||
|
||||
|
||||
Введите коэффициент b1 линейной регрессии: 2
|
||||
Введите коэффициент b2 линейной регрессии: 3
|
||||
Введите значение x: 5
|
||||
17.0
|
||||
```
|
||||
42
TEMA8/16.md
Обычный файл
@@ -0,0 +1,42 @@
|
||||
Разработайте функцию с 2 аргументами, которая для заданного словаря (аргумент функции) с любыми ключами и с числовыми значениями создаёт новый словарь с теми же ключами и со значениями, равными синусам от значений из входного словаря с заданным именами. Проверьте функцию на примере двух разных входных словарей.
|
||||
Через модуль:
|
||||
Модуль1
|
||||
```py
|
||||
import math
|
||||
|
||||
def f(a):
|
||||
"""Функция f."""
|
||||
result = {}
|
||||
for k, v in a.items(): # Перебираем все пары ключ-значение
|
||||
result[k] = math.sin(v)
|
||||
return result
|
||||
|
||||
def test():
|
||||
"""Первая тестовая функция."""
|
||||
print("Тест 1", f({'a': 0, 'b': 1.57, 'c': 3.14}))
|
||||
|
||||
if __name__ == "__main__":
|
||||
test()
|
||||
print("mode1.py работает корректно")
|
||||
```
|
||||
Модуль2:
|
||||
```py
|
||||
from mode1 import f
|
||||
|
||||
def test2():
|
||||
"""Вторая тестовая функция."""
|
||||
print("Тест 2", f({'x': 0.5, 'y': 1.0, 'z': 2.0}))
|
||||
|
||||
if __name__ == "__main__":
|
||||
test2()
|
||||
print("mode2.py работает корректно")
|
||||
```
|
||||
```py
|
||||
>>> os.chdir('C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA8')
|
||||
>>> import mode1
|
||||
>>> import mode2
|
||||
>>> mode1.test()
|
||||
Тест 1 {'a': 0.0, 'b': 0.9999996829318346, 'c': 0.0015926529164868282}
|
||||
>>> mode2.test2()
|
||||
Тест 2 {'x': 0.479425538604203, 'y': 0.8414709848078965, 'z': 0.9092974268256817}
|
||||
```
|
||||
111
TEMA8/1819.md
Обычный файл
@@ -0,0 +1,111 @@
|
||||
16. Разработайте функцию с 2 аргументами, которая для заданного словаря (аргумент функции) с любыми ключами и с числовыми значениями создаёт новый словарь с теми же ключами и со значениями, равными синусам от значений из входного словаря, и записывает новый словарь в бинарный файл с заданным именем (аргумент функции). Проверьте функцию на примере двух разных входных словарей.
|
||||
|
||||
Модуль 1
|
||||
```py
|
||||
import math
|
||||
import pickle
|
||||
|
||||
def slov_sin(input_dict, filename):
|
||||
new_dict = {key: math.sin(value) for key, value in input_dict.items()}
|
||||
with open(filename, 'wb') as f:
|
||||
pickle.dump(new_dict, f)
|
||||
print(f"Файл записан: {filename}")
|
||||
return new_dict
|
||||
|
||||
def read_slov(filename):
|
||||
try:
|
||||
with open(filename, 'rb') as f:
|
||||
loaded_dict = pickle.load(f)
|
||||
print(f"Файл прочитан: {filename}")
|
||||
return loaded_dict
|
||||
|
||||
|
||||
def test1():
|
||||
dict1 = {'a': 0, 'b': math.pi / 2, 'c': math.pi, 'd': 3 * math.pi / 2}
|
||||
file1 = 'sin_values_1.bin'
|
||||
|
||||
saved = slov_sin(dict1, file1)
|
||||
loaded = read_slov(file1)
|
||||
|
||||
print(f"Исходный: {dict1}")
|
||||
print(f"Загруженный: {loaded}")
|
||||
|
||||
if saved == loaded:
|
||||
print("OK")
|
||||
else:
|
||||
print("ERROR")
|
||||
|
||||
return loaded
|
||||
|
||||
def test2():
|
||||
dict2 = {'x': 1.0, 'y': 2.0, 'z': -0.5}
|
||||
file2 = 'sin_values_2.bin'
|
||||
|
||||
saved = slov_sin(dict2, file2)
|
||||
loaded = read_slov(file2)
|
||||
|
||||
print(f"Исходный: {dict2}")
|
||||
print(f"Загруженный: {loaded}")
|
||||
|
||||
if saved == loaded:
|
||||
print("OK")
|
||||
else:
|
||||
print("ERROR")
|
||||
|
||||
return loaded
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Тесты запущены")
|
||||
test1()
|
||||
test2()
|
||||
print("\n" + "="*60)
|
||||
print("АВТОТЕСТЫ ЗАВЕРШЕНЫ")
|
||||
print("="*60)
|
||||
```
|
||||
Модуль 2
|
||||
```py
|
||||
import slov_module
|
||||
|
||||
def run_tests():
|
||||
"""Запустить все тесты"""
|
||||
print("Тест 1:")
|
||||
slov_module.test1()
|
||||
|
||||
print("\nТест 2:")
|
||||
slov_module.test2()
|
||||
|
||||
print("\nТест 3 (свой):")
|
||||
d = {'x': 0.5, 'y': 1.0, 'z': 2.0}
|
||||
f = 'my_test.bin'
|
||||
|
||||
s = slov_module.slov_sin(d, f)
|
||||
print(f"Исходный: {d}")
|
||||
print(f"Синусы: {s}")
|
||||
|
||||
l = slov_module.read_slov(f)
|
||||
print(f"Из файла: {l}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_tests()
|
||||
|
||||
```
|
||||
|
||||
```py
|
||||
|
||||
>>> import slov_module
|
||||
>>> import test_module
|
||||
>>> slov_module.test1()
|
||||
Файл записан: sin_values_1.bin
|
||||
Файл прочитан: sin_values_1.bin
|
||||
Исходный: {'a': 0, 'b': 1.5707963267948966, 'c': 3.141592653589793, 'd': 4.71238898038469}
|
||||
Загруженный: {'a': 0.0, 'b': 1.0, 'c': 1.2246467991473532e-16, 'd': -1.0}
|
||||
OK
|
||||
{'a': 0.0, 'b': 1.0, 'c': 1.2246467991473532e-16, 'd': -1.0}
|
||||
>>> slov_module.test2()
|
||||
Файл записан: sin_values_2.bin
|
||||
Файл прочитан: sin_values_2.bin
|
||||
Исходный: {'x': 1.0, 'y': 2.0, 'z': -0.5}
|
||||
Загруженный: {'x': 0.8414709848078965, 'y': 0.9092974268256817, 'z': -0.479425538604203}
|
||||
OK
|
||||
{'x': 0.8414709848078965, 'y': 0.9092974268256817, 'z': -0.479425538604203}
|
||||
```
|
||||
362
TEMA8/8.md
Обычный файл
@@ -0,0 +1,362 @@
|
||||
|
||||
|
||||
# 1. Запуск интерактивной оболочки IDLE
|
||||
```py
|
||||
>>> import os,sys,importlib #Импорт трёх важных вспомогательных модулей
|
||||
>>> os.chdir('C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA8')
|
||||
>>> os.getcwd() #Контролируем корректность установки текущего каталога
|
||||
'C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA8'
|
||||
```
|
||||
# 2. Создание и использование модулей в среде Python
|
||||
Большие программы делятся на части-модули, записываемые в отдельные файлы. Это делается для удобства отладки, обеспечения возможности коллективной разработки, создания возможности повторного использования программ. Модулем в среде Python называется любая часть программного кода на этом языке, записанная в отдельном файле.
|
||||
|
||||
## 2.1 Запуск модуля на выполнение путём его импорта
|
||||
После импорта модуль становится объектом в пространстве имен той части программы, где осуществлен импорт. Модуль получает имя или псевдоним, заданные в инструкции импорта, а также набор атрибутов. При этом появляется возможность использования всех приемов, применяемых при работе с модулями. Создадим и откроем в текущем каталоге файл с именем Mod1.py, который будет содержать следующее:
|
||||
```py
|
||||
perm1=input('Mod1:Введите значение = ')
|
||||
print('Mod1:Значение perm1=',perm1)
|
||||
```
|
||||
Пока введённый или изменённый текст в окне редактора с текстом модуля не сохранён в файле, в заголовке перед именем файла будет стоять символ "*".
|
||||
```py
|
||||
>>> import Mod1 # Запуск модуля
|
||||
Mod1:Введите значение = 5
|
||||
Mod1:Значение perm1= 5
|
||||
>>> type(Mod1) # Модуль имеет класс объекта типа модуль
|
||||
<class 'module'>
|
||||
>>> dir(Mod1)
|
||||
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'perm1']
|
||||
>>> Mod1.perm1 # Получим доступ к значению объекта, созданного в модуле
|
||||
'5'
|
||||
```
|
||||
При импорте модуля управление передаётся от модуля __main__ к модулю Mod1, который ищется в рабочем каталоге. Если бы данного модуля там не было, то при импорте пришлось бы ещё указать каталог, где он находится.
|
||||
|
||||
При повторном импорте модуля, запуска программы не происходит. Чтобы это исправить, применим функцию reload из модуля importlib:
|
||||
```py
|
||||
>>> importlib.reload(Mod1)
|
||||
Mod1:Введите значение = 3
|
||||
Mod1:Значение perm1= 3
|
||||
<module 'Mod1' from 'C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA8'>
|
||||
>>> Mod1.perm1
|
||||
'3'
|
||||
```
|
||||
## 2.2 Импортированные модули заносятся в словарь - значение атрибута sys.modules
|
||||
```py
|
||||
>>> print(sorted(sys.modules.keys()))
|
||||
['Mod1', '__future__', '__main__', '_abc', '_ast', '_bisect', '_bz2', '_codecs', '_collections', '_collections_abc', '_colorize', '_compat_pickle', '_compression', '_datetime', '_frozen_importlib', '_frozen_importlib_external', '_functools', '_heapq', '_imp', '_io', '_lzma', '_opcode', '_opcode_metadata', '_operator', '_pickle', '_pyrepl', '_pyrepl.pager', '_queue', '_random', '_signal', '_sitebuiltins', '_socket', '_sre', '_stat', '_string', '_struct', '_sysconfig', '_thread', '_tkinter', '_tokenize', '_typing', '_warnings', '_weakref', '_weakrefset', '_winapi', '_wmi', 'abc', 'ast', 'bdb', 'binascii', 'bisect', 'builtins', 'bz2', 'codecs', 'collections', 'collections.abc', 'configparser', 'contextlib', 'copyreg', 'datetime', 'dis', 'encodings', 'encodings.aliases', 'encodings.cp1251', 'encodings.utf_8', 'enum', 'errno', 'fnmatch', 'functools', 'genericpath', 'heapq', 'idlelib', 'idlelib.autocomplete', 'idlelib.autocomplete_w', 'idlelib.calltip', 'idlelib.calltip_w', 'idlelib.config', 'idlelib.debugger', 'idlelib.debugger_r', 'idlelib.debugobj', 'idlelib.debugobj_r', 'idlelib.hyperparser', 'idlelib.iomenu', 'idlelib.macosx', 'idlelib.multicall', 'idlelib.pyparse', 'idlelib.rpc', 'idlelib.run', 'idlelib.scrolledlist', 'idlelib.stackviewer', 'idlelib.tooltip', 'idlelib.tree', 'idlelib.util', 'idlelib.window', 'idlelib.zoomheight', 'importlib', 'importlib._abc', 'importlib._bootstrap', 'importlib._bootstrap_external', 'importlib.machinery', 'importlib.util', 'inspect', 'io', 'ipaddress', 'itertools', 'keyword', 'linecache', 'lzma', 'marshal', 'math', 'nt', 'ntpath', 'opcode', 'operator', 'os', 'os.path', 'pickle', 'pkgutil', 'platform', 'plistlib', 'posixpath', 'pydoc', 'pyexpat', 'pyexpat.errors', 'pyexpat.model', 'queue', 'random', 're', 're._casefix', 're._compiler', 're._constants', 're._parser', 'reprlib', 'select', 'selectors', 'shlex', 'shutil', 'site', 'socket', 'socketserver', 'stat', 'string', 'struct', 'sys', 'sysconfig', 'tempfile', 'textwrap', 'threading', 'time', 'tkinter', 'tkinter.constants', 'token', 'tokenize', 'traceback', 'types', 'typing', 'urllib', 'urllib.parse', 'warnings', 'weakref', 'winreg', 'xml', 'xml.parsers', 'xml.parsers.expat', 'xml.parsers.expat.errors', 'xml.parsers.expat.model', 'zipimport', 'zlib']
|
||||
```py
|
||||
Для повторного импорта модуля и выполнения программы, удалим модуль из этого словаря. Затем снова повторим импорт и убедимся в выполнении программы.
|
||||
```py
|
||||
>>> sys.modules.pop('Mod1')
|
||||
<module 'Mod1' from 'C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA8'>
|
||||
>>> print(sorted(sys.modules.keys()))
|
||||
['__future__', '__main__', '_abc', '_ast', '_bisect', '_bz2', '_codecs', '_collections', '_collections_abc', '_colorize', '_compat_pickle', '_compression', '_datetime', '_frozen_importlib', '_frozen_importlib_external', '_functools', '_heapq', '_imp', '_io', '_lzma', '_opcode', '_opcode_metadata', '_operator', '_pickle', '_pyrepl', '_pyrepl.pager', '_queue', '_random', '_signal', '_sitebuiltins', '_socket', '_sre', '_stat', '_string', '_struct', '_sysconfig', '_thread', '_tkinter', '_tokenize', '_typing', '_warnings', '_weakref', '_weakrefset', '_winapi', '_wmi', 'abc', 'ast', 'bdb', 'binascii', 'bisect', 'builtins', 'bz2', 'codecs', 'collections', 'collections.abc', 'configparser', 'contextlib', 'copyreg', 'datetime', 'dis', 'encodings', 'encodings.aliases', 'encodings.cp1251', 'encodings.utf_8', 'enum', 'errno', 'fnmatch', 'functools', 'genericpath', 'heapq', 'idlelib', 'idlelib.autocomplete', 'idlelib.autocomplete_w', 'idlelib.calltip', 'idlelib.calltip_w', 'idlelib.config', 'idlelib.debugger', 'idlelib.debugger_r', 'idlelib.debugobj', 'idlelib.debugobj_r', 'idlelib.hyperparser', 'idlelib.iomenu', 'idlelib.macosx', 'idlelib.multicall', 'idlelib.pyparse', 'idlelib.rpc', 'idlelib.run', 'idlelib.scrolledlist', 'idlelib.stackviewer', 'idlelib.tooltip', 'idlelib.tree', 'idlelib.util', 'idlelib.window', 'idlelib.zoomheight', 'importlib', 'importlib._abc', 'importlib._bootstrap', 'importlib._bootstrap_external', 'importlib.machinery', 'importlib.util', 'inspect', 'io', 'ipaddress', 'itertools', 'keyword', 'linecache', 'lzma', 'marshal', 'math', 'nt', 'ntpath', 'opcode', 'operator', 'os', 'os.path', 'pickle', 'pkgutil', 'platform', 'plistlib', 'posixpath', 'pydoc', 'pyexpat', 'pyexpat.errors', 'pyexpat.model', 'queue', 'random', 're', 're._casefix', 're._compiler', 're._constants', 're._parser', 'reprlib', 'select', 'selectors', 'shlex', 'shutil', 'site', 'socket', 'socketserver', 'stat', 'string', 'struct', 'sys', 'sysconfig', 'tempfile', 'textwrap', 'threading', 'time', 'tkinter', 'tkinter.constants', 'token', 'tokenize', 'traceback', 'types', 'typing', 'urllib', 'urllib.parse', 'warnings', 'weakref', 'winreg', 'xml', 'xml.parsers', 'xml.parsers.expat', 'xml.parsers.expat.errors', 'xml.parsers.expat.model', 'zipimport', 'zlib']
|
||||
>>> import Mod1
|
||||
Mod1:Введите значение = 5
|
||||
Mod1:Значение perm1= 5
|
||||
>>> sys.modules.pop('Mod1')
|
||||
<module 'Mod1' from 'C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA8'>
|
||||
```
|
||||
Отличие importlib.reload() от sys.modules.pop() заключается в том, что importlib.reload() перезагружает модуль, выполняя его код заново, но не удаляет модуль из словаря. Он имеет тот же адрес в памяти и все зависимости от него остаются в силе. sys.modules.pop() убирает модуль из словаря, при повторном импорте он уже будет иметь другой адрес.
|
||||
|
||||
## 2.3 Запуск модуля на выполнение с помощью функции exec()
|
||||
Здесь модуль не требуется импортировать. Функция exec действует так, как будто на месте обращения к ней в программу вставлен код из объекта-аргумента функции. Но объект-модуль при этом не создается. Созданные при выполнении модуля объекты становятся объектами главной программы!
|
||||
```py
|
||||
>>> exec(open('Mod1.py').read())
|
||||
Mod1:Введите значение = 5
|
||||
Mod1:Значение perm1= 5
|
||||
# Здесь наблюдается проблема с кодировкой символов, файл был сохранён в одной кодировке, а Python хочет его прочитать в другой. Поэтому укажем явно кодировку
|
||||
>>> exec(open('Mod1.py', encoding='utf-8').read())
|
||||
Mod1:Введите значение = 5
|
||||
Mod1:Значение perm1= 5
|
||||
>>> exec(open('Mod1.py', encoding='utf-8').read())
|
||||
Mod1:Введите значение = 1
|
||||
Mod1:Значение perm1= 1
|
||||
>>> exec(open('Mod1.py', encoding='utf-8').read())
|
||||
Mod1:Введите значение = 9
|
||||
Mod1:Значение perm1= 9
|
||||
>>> perm1
|
||||
'9'
|
||||
```
|
||||
## 2.4 Использование инструкции from ... import ...
|
||||
В одном модуле может содержаться несколько функций или пользовательских объектов. Тогда можно осуществлять импорт модуля не целиком, а только часть содержащихся в нем объектов.
|
||||
|
||||
Пример 1:
|
||||
```py
|
||||
>>> from Mod1 import perm1
|
||||
Mod1:Введите значение = 5
|
||||
Mod1:Значение perm1= 5
|
||||
>>> print(sorted(sys.modules.keys()))
|
||||
['Mod1', '__future__', '__main__', '_abc', '_ast', '_bisect', '_bz2', '_codecs', '_collections', '_collections_abc', '_colorize', '_compat_pickle', '_compression', '_datetime', '_frozen_importlib', '_frozen_importlib_external', '_functools', '_heapq', '_imp', '_io', '_lzma', '_opcode', '_opcode_metadata', '_operator', '_pickle', '_pyrepl', '_pyrepl.pager', '_queue', '_random', '_signal', '_sitebuiltins', '_socket', '_sre', '_stat', '_string', '_struct', '_sysconfig', '_thread', '_tkinter', '_tokenize', '_typing', '_warnings', '_weakref', '_weakrefset', '_winapi', '_wmi', 'abc', 'ast', 'bdb', 'binascii', 'bisect', 'builtins', 'bz2', 'codecs', 'collections', 'collections.abc', 'configparser', 'contextlib', 'copyreg', 'datetime', 'dis', 'encodings', 'encodings.aliases', 'encodings.cp1251', 'encodings.utf_8', 'enum', 'errno', 'fnmatch', 'functools', 'genericpath', 'heapq', 'idlelib', 'idlelib.autocomplete', 'idlelib.autocomplete_w', 'idlelib.calltip', 'idlelib.calltip_w', 'idlelib.config', 'idlelib.debugger', 'idlelib.debugger_r', 'idlelib.debugobj', 'idlelib.debugobj_r', 'idlelib.hyperparser', 'idlelib.iomenu', 'idlelib.macosx', 'idlelib.multicall', 'idlelib.pyparse', 'idlelib.rpc', 'idlelib.run', 'idlelib.scrolledlist', 'idlelib.stackviewer', 'idlelib.tooltip', 'idlelib.tree', 'idlelib.util', 'idlelib.window', 'idlelib.zoomheight', 'importlib', 'importlib._abc', 'importlib._bootstrap', 'importlib._bootstrap_external', 'importlib.machinery', 'importlib.util', 'inspect', 'io', 'ipaddress', 'itertools', 'keyword', 'linecache', 'lzma', 'marshal', 'math', 'nt', 'ntpath', 'opcode', 'operator', 'os', 'os.path', 'pickle', 'pkgutil', 'platform', 'plistlib', 'posixpath', 'pydoc', 'pyexpat', 'pyexpat.errors', 'pyexpat.model', 'queue', 'random', 're', 're._casefix', 're._compiler', 're._constants', 're._parser', 'reprlib', 'select', 'selectors', 'shlex', 'shutil', 'site', 'socket', 'socketserver', 'stat', 'string', 'struct', 'sys', 'sysconfig', 'tempfile', 'textwrap', 'threading', 'time', 'tkinter', 'tkinter.constants', 'token', 'tokenize', 'traceback', 'types', 'typing', 'urllib', 'urllib.parse', 'warnings', 'weakref', 'winreg', 'xml', 'xml.parsers', 'xml.parsers.expat', 'xml.parsers.expat.errors', 'xml.parsers.expat.model', 'zipimport', 'zlib']
|
||||
>>> perm1
|
||||
'5'
|
||||
>>> from Mod1 import perm1
|
||||
>>> from Mod1 import perm1
|
||||
```
|
||||
Объект Mod1 появился в памяти, программа на выполнение вызвалась, аналогично использованию import. При последующем повторении команды ничего не происходит. Python хранит загруженные модули в sys.modules, при первом импорте выполняется весь код модуля, при повторном импорте Python просто берёт модуль из кэша.
|
||||
|
||||
Пример2: С помощью текстового редактора создадим ещё один модуль Mod2, содержащий две функции:
|
||||
```py
|
||||
def alpha():
|
||||
print('****ALPHA****')
|
||||
t=input('Значение t=')
|
||||
return t
|
||||
|
||||
def beta(q):
|
||||
import math
|
||||
expi=q*math.pi
|
||||
return math.exp(expi)
|
||||
```
|
||||
Импортируем из этого модуля только функцию beta:
|
||||
```py
|
||||
>>> from Mod2 import beta
|
||||
>>> g=beta(2)
|
||||
****BETA****
|
||||
>>> g
|
||||
535.4916555247646
|
||||
>>> print(sorted(sys.modules.keys()))
|
||||
['Mod2', '__future__', '__main__', '_abc', '_ast', '_bisect', '_bz2', '_codecs', '_collections', '_collections_abc', '_colorize', '_compat_pickle', '_compression', '_datetime', '_frozen_importlib', '_frozen_importlib_external', '_functools', '_heapq', '_imp', '_io', '_lzma', '_opcode', '_opcode_metadata', '_operator', '_pickle', '_pyrepl', '_pyrepl.pager', '_queue', '_random', '_signal', '_sitebuiltins', '_socket', '_sre', '_stat', '_string', '_struct', '_sysconfig', '_thread', '_tkinter', '_tokenize', '_typing', '_warnings', '_weakref', '_weakrefset', '_winapi', '_wmi', 'abc', 'ast', 'bdb', 'binascii', 'bisect', 'builtins', 'bz2', 'codecs', 'collections', 'collections.abc', 'configparser', 'contextlib', 'copyreg', 'datetime', 'dis', 'encodings', 'encodings.aliases', 'encodings.cp1251', 'encodings.utf_8', 'enum', 'errno', 'fnmatch', 'functools', 'genericpath', 'heapq', 'idlelib', 'idlelib.autocomplete', 'idlelib.autocomplete_w', 'idlelib.calltip', 'idlelib.calltip_w', 'idlelib.config', 'idlelib.debugger', 'idlelib.debugger_r', 'idlelib.debugobj', 'idlelib.debugobj_r', 'idlelib.hyperparser', 'idlelib.iomenu', 'idlelib.macosx', 'idlelib.multicall', 'idlelib.pyparse', 'idlelib.rpc', 'idlelib.run', 'idlelib.scrolledlist', 'idlelib.stackviewer', 'idlelib.tooltip', 'idlelib.tree', 'idlelib.util', 'idlelib.window', 'idlelib.zoomheight', 'importlib', 'importlib._abc', 'importlib._bootstrap', 'importlib._bootstrap_external', 'importlib.machinery', 'importlib.util', 'inspect', 'io', 'ipaddress', 'itertools', 'keyword', 'linecache', 'lzma', 'marshal', 'math', 'nt', 'ntpath', 'opcode', 'operator', 'os', 'os.path', 'pickle', 'pkgutil', 'platform', 'plistlib', 'posixpath', 'pydoc', 'pyexpat', 'pyexpat.errors', 'pyexpat.model', 'queue', 'random', 're', 're._casefix', 're._compiler', 're._constants', 're._parser', 'reprlib', 'select', 'selectors', 'shlex', 'shutil', 'site', 'socket', 'socketserver', 'stat', 'string', 'struct', 'sys', 'sysconfig', 'tempfile', 'textwrap', 'threading', 'time', 'tkinter', 'tkinter.constants', 'token', 'tokenize', 'traceback', 'types', 'typing', 'urllib', 'urllib.parse', 'warnings', 'weakref', 'winreg', 'xml', 'xml.parsers', 'xml.parsers.expat', 'xml.parsers.expat.errors', 'xml.parsers.expat.model', 'zipimport', 'zlib']
|
||||
>>> alpha()
|
||||
Traceback (most recent call last):
|
||||
File "<pyshell#6>", line 1, in <module>
|
||||
alpha()
|
||||
NameError: name 'alpha' is not defined
|
||||
```
|
||||
Модуль Mod2 появился в списке. Функция alpha не была импортирована, поэтому и вышла ошибка. Теперь импортируем только функцию alpha, используя для неё псевдоним al:
|
||||
```py
|
||||
>>> from Mod2 import alpha as al
|
||||
>>> al()
|
||||
****ALPHA****
|
||||
Значение t=5
|
||||
'5'
|
||||
>>> del al,beta # Удаление импортированных объектов
|
||||
>>> from Mod2 import alpha as al, beta as bt # Импорт двух функций одной инструкцией
|
||||
>>> sys.modules.pop('Mod1') # Удаление импортированных объектов
|
||||
<module 'Mod1' from 'C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA8'>
|
||||
>>> sys.modules.pop('Mod2')
|
||||
<module 'Mod2' from 'C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA8'>
|
||||
>>> from Mod2 import * # Импорт всего содержимого модуля
|
||||
>>> tt=alpha()
|
||||
****ALPHA****
|
||||
Значение t=0.12
|
||||
>>> uu=beta(float(tt))
|
||||
****BETA****
|
||||
>>> uu
|
||||
1.4578913609506803
|
||||
```
|
||||
# 3. Создание многомодульных программ
|
||||
|
||||
## 3.1 Пример простой многомодульной программы
|
||||
Создадим модуль Mod0 со следующим содержанием:
|
||||
```py
|
||||
#Модуль Mod0
|
||||
import Mod1
|
||||
print('perm1=',Mod1.perm1)
|
||||
from Mod2 import alpha as al
|
||||
tt=al()
|
||||
print('tt=',tt)
|
||||
from Mod2 import beta
|
||||
qq=beta(float(tt))
|
||||
print('qq=',qq)
|
||||
```
|
||||
Данный модуль содержит программу, вызывающую на выполнение ранее созданные модули Mod1, Mod2. Теперь программа будет состоять из 5 частей: главная программа, которой является командная строка IDLE и из которой будет вызываться модуль Mod0, и 3 модуля, вызываемых из модуля Mod0.
|
||||
```py
|
||||
>>> import Mod0
|
||||
Mod1:Введите значение = 3
|
||||
Mod1:Значение perm1= 3
|
||||
perm1= 3
|
||||
****ALPHA****
|
||||
Значение t=10
|
||||
tt= 10
|
||||
****BETA****
|
||||
qq= 44031505860631.98
|
||||
>>> Mod0.tt;Mod0.qq;Mod0.Mod1.perm1
|
||||
'10'
|
||||
44031505860631.98
|
||||
'3'
|
||||
```
|
||||
Переменная perm1 находится в пространстве имен модуля Mod1, а не модуля Mod0. Поэтому пришлось указывать не только имя модуля Mod0, но и имя модуля Mod1, в котором локализован объект.
|
||||
|
||||
## 3.2 Пример
|
||||
Создадим модуль MM1, включив в него разработанные при выполнении предыдущей темы функции, реализующие усилитель, реальный двигатель, тахогенератор и нелинейное звено типа «зона нечувствительности». Затем создадим модуль ММ2, включив в него инструкции, обеспечивающие ввод параметров задачи, формирование входного сигнала, импорт модуля ММ1 и реализацию модели при расчете выходного сигнала. Модуль MM1:
|
||||
```py
|
||||
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
|
||||
```
|
||||
Модуль MM2:
|
||||
```py
|
||||
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))
|
||||
|
||||
import MM1 as mod
|
||||
yi1=0;yin1=0;yi2=0
|
||||
vyhod=[]
|
||||
for xt in vhod:
|
||||
xt1=xt-yi2 #отрицательная обратная связь
|
||||
[yi1,yin1]=mod.realdvig(xt1,k1,T,yi1,yin1)
|
||||
yi2=mod.tahogen(yin1,k2,yi2)
|
||||
yt=mod.nechus(yin1,Xm)
|
||||
vyhod.append(yt)
|
||||
```
|
||||
Теперь создадим главную программу - модуль MM0, которая запускает на выполнение модуль MM2 и выводит полученный выходной сигнал:
|
||||
```py
|
||||
import MM2
|
||||
print('y=',MM2.vyhod)
|
||||
```
|
||||
Запустим модуль MM0:
|
||||
```py
|
||||
>>> import MM0
|
||||
k1,T,k2,Xm,A,F,N=8,5,3,10,2,0.5,1000
|
||||
y=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.0183086292055208, 0, 26.39885775889784, -36.65029553691161, -34.19982663883278, 196.29963397615063, -151.6919482160481, -388.32493988337274, 1057.8073200868555, -308.3186572590445, -2798.051869998873, 5004.749701095182, 1362.331454336744, ...]
|
||||
```
|
||||
## 3.3 Области действия объектов в модулях
|
||||
В ранее созданных модулях вводятся и используются следующие объекты: Mod1: perm1 Mod2: функции alpha, beta; переменные t, expi Mod0: переменные tt,qq
|
||||
|
||||
Исходя из примеров, приведенных ниже, можно сказать, что объекты входящие в один модуль будут локализованы в этом модуле и доступны в нем. К переменным из другого модуля, даже импортированного в главный (выполняемый) модуль, прямого доступа не будет.
|
||||
|
||||
## 3.3.1 Добавление в функцию alpha обращение к функции beta и, наоборот, из beta – к alpha. Изменим содержание файла Mod2.py:
|
||||
```py
|
||||
def alpha():
|
||||
print('****ALPHA****')
|
||||
t=input('Значение t=')
|
||||
beta(int(t))
|
||||
return t
|
||||
|
||||
def beta(q):
|
||||
import math
|
||||
expi=q*math.pi
|
||||
return math.exp(expi)
|
||||
```
|
||||
Запустим программу:
|
||||
```py
|
||||
>>> from Mod2 import *
|
||||
>>> alpha()
|
||||
****ALPHA****
|
||||
Значение t=5
|
||||
153552935.39544657
|
||||
'5'
|
||||
```
|
||||
Теперь добавим в функцию beta вызов функции alpha():
|
||||
```py
|
||||
def alpha():
|
||||
print('****ALPHA****')
|
||||
t=input('Значение t=')
|
||||
return t
|
||||
|
||||
def beta(q):
|
||||
import math
|
||||
expi=q*math.pi
|
||||
alpha()
|
||||
return math.exp(expi)
|
||||
```
|
||||
Протестируем выполнение:
|
||||
```py
|
||||
>>> beta(6)
|
||||
****ALPHA****
|
||||
Значение t=5
|
||||
153552935.39544657
|
||||
```
|
||||
## 3.3.2 Отобразим на экране в модуле Mod0 значения объектов t и expi
|
||||
Изменим содержание Mod0:
|
||||
```py
|
||||
#Модуль Mod0
|
||||
import Mod1
|
||||
print('perm1=',Mod1.perm1)
|
||||
from Mod2 import alpha as al
|
||||
tt=al()
|
||||
print('tt=',tt)
|
||||
from Mod2 import beta
|
||||
qq=beta(float(tt))
|
||||
print('qq=',qq)
|
||||
print(t, expi)
|
||||
```
|
||||
Запустим на выполнение:
|
||||
```py
|
||||
>>> import Mod0
|
||||
perm1= 5
|
||||
****ALPHA****
|
||||
Значение t=10
|
||||
tt= 10
|
||||
qq= 44031505860631.98
|
||||
Traceback (most recent call last):
|
||||
File "<pyshell#16>", line 1, in <module>
|
||||
import Mod0
|
||||
File 'C:\Users\Admin\Documents\Tsvetkova\python-labs\TEMA8'\Mod0.py", line 10, in <module>
|
||||
print(t, expi)
|
||||
NameError: name 't' is not defined. Did you mean: 'tt'?
|
||||
```
|
||||
Выходит ошибка, потому что переменные t и expi определены в разных областях видимости и не доступны в модуле Mod0. В модуле Mod2: t - это локальная переменная функции alpha(), expi - это локальная переменная функции beta(). В модуле Mod0: мы пытаемся обратиться к переменным t и expi, которые никогда не были объявлены в этом модуле.
|
||||
|
||||
## 3.3.3 Увеличение в модуле Mod0 в 3 раза значение объекта perm1 и отобразить его после этого на экране.
|
||||
Изменим содержание Mod0:
|
||||
```py
|
||||
#Модуль Mod0
|
||||
import Mod1
|
||||
print('perm1=',Mod1.perm1)
|
||||
Mod1.perm1 = str(int(Mod1.perm1)*3)
|
||||
print('Увеличение perm1 в 3 раза:', Mod1.perm1)
|
||||
from Mod2 import alpha as al
|
||||
tt=al()
|
||||
print('tt=',tt)
|
||||
from Mod2 import beta
|
||||
qq=beta(float(tt))
|
||||
print('qq=',qq)
|
||||
```
|
||||
Тестирование программы:
|
||||
```py
|
||||
>>> import Mod0
|
||||
perm1= 30
|
||||
Увеличение perm1 в 3 раза: 90
|
||||
****ALPHA****
|
||||
Значение t=10
|
||||
tt= 10
|
||||
qq= 44031505860631.98
|
||||
```
|
||||
## 3.3.4 В командной строке необходимо увеличить в 2 раза значения объектов perm1, tt, qq
|
||||
```py
|
||||
>>> import Mod0
|
||||
perm1= 5
|
||||
****ALPHA****
|
||||
Значение t=10
|
||||
tt= 10
|
||||
qq= 44031505860631.98
|
||||
>>> Mod0.Mod1.perm1=str(int(Mod0.Mod1.perm1)*2)
|
||||
>>> Mod0.Mod1.perm1
|
||||
'10'
|
||||
>>> Mod0.tt=str(int(Mod0.tt)*2)
|
||||
>>> Mod0.tt
|
||||
'20'
|
||||
>>> Mod0.qq=Mod0.qq*2
|
||||
>>> Mod0.qq
|
||||
88063011721263.95
|
||||
```
|
||||
# 4. Завершение сеанса работы с IDLE
|
||||
2
TEMA8/MM0.py
Обычный файл
@@ -0,0 +1,2 @@
|
||||
import MM2
|
||||
print('y=',MM2.vyhod)
|
||||
22
TEMA8/MM1.py
Обычный файл
@@ -0,0 +1,22 @@
|
||||
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
|
||||
23
TEMA8/MM2.py
Обычный файл
@@ -0,0 +1,23 @@
|
||||
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))
|
||||
|
||||
import MM1 as mod
|
||||
yi1=0;yin1=0;yi2=0
|
||||
vyhod=[]
|
||||
for xt in vhod:
|
||||
xt1=xt-yi2 #отрицательная обратная связь
|
||||
[yi1,yin1]=mod.realdvig(xt1,k1,T,yi1,yin1)
|
||||
yi2=mod.tahogen(yin1,k2,yi2)
|
||||
yt=mod.nechus(yin1,Xm)
|
||||
vyhod.append(yt)
|
||||
@@ -4,8 +4,7 @@ def alpha():
|
||||
return t
|
||||
|
||||
def beta(q):
|
||||
print('****BETA****')
|
||||
import math
|
||||
expi=q*math.pi
|
||||
return math.exp(expi)
|
||||
|
||||
alpha()
|
||||
return math.exp(expi)
|
||||
7
TEMA8/Modul1.py
Обычный файл
@@ -0,0 +1,7 @@
|
||||
def read (file):
|
||||
""""Чтение данных из файла"""
|
||||
nums = []
|
||||
with open(file, 'r') as file: # Открытие файла для чтения
|
||||
for line in file:
|
||||
nums.extend(map(float, line.split())) # Добавление всех элементов в список
|
||||
return nums
|
||||
16
TEMA8/Modul2.py
Обычный файл
@@ -0,0 +1,16 @@
|
||||
def correlation(list1, list2):
|
||||
"""Расчёт коэффициента корреляции"""
|
||||
n = min(len(list1), len(list2)) # Общая длина
|
||||
list1 = list1[:n]
|
||||
list2 = list2[:n]
|
||||
mean1 = sum(list1) / n
|
||||
mean2 = sum(list2) / n
|
||||
chislitel = sum((list1[i] - mean1) * (list2[i] - mean2) for i in range(n))
|
||||
#Числитель формулы корреляции
|
||||
znamenatel1 = sum((x - mean1) ** 2 for x in list1)
|
||||
znamenatel2 = sum((y - mean2) ** 2 for y in list2)
|
||||
|
||||
if znamenatel1 == 0 or znamenatel2 == 0:
|
||||
return 0
|
||||
|
||||
return chislitel/(znamenatel1 * znamenatel2) ** 0.5
|
||||
8
TEMA8/Modul3.py
Обычный файл
@@ -0,0 +1,8 @@
|
||||
import Modul1
|
||||
import Modul2
|
||||
file1 = input("Введите имя первого файла: ")
|
||||
file2 = input("Введите имя второго файла: ")
|
||||
list1 = Modul1.read(file1)
|
||||
list2 = Modul1.read(file2)
|
||||
corr = Modul2.correlation(list1, list2)
|
||||
print("Коэффициент корреляции:", corr)
|
||||
4
TEMA8/data1.txt
Обычный файл
@@ -0,0 +1,4 @@
|
||||
1 2 3
|
||||
4 5
|
||||
6 7 8
|
||||
9
|
||||
3
TEMA8/data2.txt
Обычный файл
@@ -0,0 +1,3 @@
|
||||
2 4 6
|
||||
8
|
||||
10 11
|
||||
71
TEMA8/task.md
Обычный файл
@@ -0,0 +1,71 @@
|
||||
# Общее контрольное задание по теме 8
|
||||
|
||||
|
||||
# Задание:
|
||||
1. Разработать программу, состоящую из трех модулей:
|
||||
Модуль 1 содержит функцию считывания числового списка из текстового файла с заданным именем (аргумент функции – имя файла). Элементы в файле могут располагаться по несколько на строке с разделением пробелом. Числа элементов в строках могут быть разными. Полученный список должен возвращаться в вызывающую программу.
|
||||
|
||||
Модуль 2 содержит функцию расчета коэффициента корреляции по двум числовым спискам (аргументы функции – имена двух списков). Числа элементов в списках могут различаться. Значение коэффициента должно возвращаться в вызывающую программу.
|
||||
|
||||
Модуль 3 запрашивает у пользователя и вводит имена двух файлов с исходными данными, дважды вызывает функцию из модуля 1 и считывает два списка из двух текстовых файлов. Затем вызывает функцию расчета коэффициента корреляции с помощью функции из модуля 2 и отображает рассчитанное значение на экране с округлением до трех цифр после точки.
|
||||
|
||||
Подготовить два текстовых файла с числовыми данными и проверить по ним работу программы.
|
||||
|
||||
|
||||
# Решение
|
||||
|
||||
## 1. Модуль 1 - Чтение данных из файла
|
||||
```py
|
||||
def read (file):
|
||||
""""Чтение данных из файла"""
|
||||
nums = []
|
||||
with open(file, 'r') as file: # Открытие файла для чтения
|
||||
for line in file:
|
||||
nums.extend(map(float, line.split())) # Добавление всех элементов в список
|
||||
return nums
|
||||
```
|
||||
|
||||
## 2. Модуль 2 - Расчёт коэффициента корреляции
|
||||
```py
|
||||
def correlation(list1, list2):
|
||||
"""Расчёт коэффициента корреляции"""
|
||||
n = min(len(list1), len(list2)) # Общая длина
|
||||
list1 = list1[:n]
|
||||
list2 = list2[:n]
|
||||
mean1 = sum(list1) / n
|
||||
mean2 = sum(list2) / n
|
||||
chislitel = sum((list1[i] - mean1) * (list2[i] - mean2) for i in range(n))
|
||||
#Числитель формулы корреляции
|
||||
znamenatel1 = sum((x - mean1) ** 2 for x in list1) # Знаменатель формулы корреляции
|
||||
znamenatel2 = sum((y - mean2) ** 2 for y in list2)
|
||||
|
||||
if znamenatel1 == 0 or znamenatel2 == 0: # Проверка деления на 0
|
||||
return 0
|
||||
|
||||
return chislitel/(znamenatel1 * znamenatel2) ** 0.5
|
||||
```
|
||||
|
||||
## 3. Модуль 3 - Запрос у пользователя и ввод имён файлов с исходными данными
|
||||
```py
|
||||
import Modul1
|
||||
import Modul2
|
||||
file1 = input("Введите имя первого файла: ")
|
||||
file2 = input("Введите имя второго файла: ")
|
||||
list1 = Modul1.read(file1)
|
||||
list2 = Modul1.read(file2)
|
||||
corr = Modul2.correlation(list1, list2)
|
||||
print("Коэффициент корреляции:", corr)
|
||||
```
|
||||
|
||||
Были подготовлены два файла с данными data1.txt и data2.txt
|
||||
|
||||
## 4. Тестирование
|
||||
```py
|
||||
>>> import Modul3
|
||||
Введите имя первого файла: data1.txt
|
||||
Введите имя второго файла: data2.txt
|
||||
Коэффициент корреляции: 0.9960784162656539
|
||||
```
|
||||
|
||||
|
||||
|
||||
323
TEMA9/9.md
Обычный файл
@@ -0,0 +1,323 @@
|
||||
|
||||
|
||||
# 2 Создание классов и их наследников
|
||||
## 2.1 Создание автономного класса
|
||||
```py
|
||||
>>> class Class1: #Объявление класса
|
||||
... def zad_zn(self,znach): #Метод 1 класса1 – задание значения data
|
||||
... self.data=znach # self - ссылка на экземпляр класса
|
||||
... def otobrazh(self): # Метод 2 класса1
|
||||
... print(self.data)#Отображение данных экземпляра класса
|
||||
...
|
||||
```py
|
||||
Создали 2 экземпляра этого класса
|
||||
```py
|
||||
>>> z1=Class1()
|
||||
>>> z2=Class1()
|
||||
```
|
||||
С помощью первого метода задали разные значения атрибута у двух экземпляров
|
||||
```py
|
||||
>>> z1.zad_zn('экз.класса 1')
|
||||
>>> z2.zad_zn(-632.453)
|
||||
```
|
||||
Для контроля отобразили его значения с помощью второго метода
|
||||
```py
|
||||
>>> z1.otobrazh()
|
||||
экз.класса 1
|
||||
>>> z2.otobrazh()
|
||||
-632.453
|
||||
```
|
||||
Изменили значение атрибута у первого экземпляра и отобразили его
|
||||
```py
|
||||
>>> z1.data='Новое значение атрибута у экз.1'
|
||||
>>> z1.otobrazh()
|
||||
Новое значение атрибута у экз.1
|
||||
```
|
||||
## 2.2 Создание класса-наследника
|
||||
В объявлении класса после его имени в скобках перечисляются его «родительские классы»
|
||||
```py
|
||||
>>> class Class2(Class1): #Class2 - наследник класса Class1
|
||||
... def otobrazh(self): # Метод класса Class2 – переопределяет метод родителя
|
||||
... print('значение=',self.data)#Отображение данных экземпляра
|
||||
...
|
||||
```
|
||||
Создали экземпляр второго класса
|
||||
```py
|
||||
>>> z3=Class2()
|
||||
>>> dir(z3)
|
||||
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__static_attributes__', '__str__', '__subclasshook__', '__weakref__', 'otobrazh', 'zad_zn']
|
||||
```
|
||||
Задали у него значение данного data (унаследовано от Class1)
|
||||
```py
|
||||
>>> z3.zad_zn('Совсем новое')
|
||||
>>> z3.otobrazh()
|
||||
значение= Совсем новое
|
||||
>>> z1.otobrazh()
|
||||
Новое значение атрибута у экз.1
|
||||
>>> del z1,z2,z3
|
||||
```
|
||||
3 Использование классов, содержащихся в модулях
|
||||
|
||||
Содержимое Mod3
|
||||
```py
|
||||
class Class1: #Объявление класса Class1 в модуле
|
||||
def zad_zn(self,znach): # 1 Метод класса
|
||||
self.data=znach # self - ссылка на экземпляр класса Class1
|
||||
def otobrazh(self): # 2 Метод класса
|
||||
print(self.data)#Отображение данных экземпляра
|
||||
class Class2(Class1): #Class2 - наследник класса Class1
|
||||
def otobrazh(self): # Метод класса Class2
|
||||
print('значение=',self.data)#Отображение данных экземпляра
|
||||
def otobrazh(objekt): #Объявление самостоятельной функции
|
||||
print('значение объекта=',objekt)
|
||||
```
|
||||
Импортировали первый класс из модуля
|
||||
```py
|
||||
>>> from Mod3 import Class1 #Частичный импорт содержимого модуля
|
||||
>>> z4=Class1()
|
||||
>>> z4.otobrazh()
|
||||
Traceback (most recent call last):
|
||||
File "<pyshell#20>", line 1, in <module>
|
||||
z4.otobrazh()
|
||||
File "C:\Users\uprkt\Desktop\ПО\python-labs\TEMA9\Mod3.py", line 5, in otobrazh
|
||||
print(self.data)#Отображение данных экземпляра
|
||||
AttributeError: 'Class1' object has no attribute 'data'
|
||||
```
|
||||
Ошибка возникает потому, что атрибут data еще не был создан для объекта z4.
|
||||
```py
|
||||
>>> from Mod3 import Class1
|
||||
>>> z4=Class1()
|
||||
>>> z4.data='значение данного data у экз.4'
|
||||
>>> z4.otobrazh()
|
||||
значение данного data у экз.4
|
||||
```
|
||||
Удалим экземпляр z4 и импортируем модуль
|
||||
```py
|
||||
>>> del z4
|
||||
>>> import Mod3
|
||||
```
|
||||
Создали экземпляр класса теперь инструкцией
|
||||
```py
|
||||
>>> z4=Mod3.Class2()
|
||||
>>> z4.zad_zn('Класс из модуля')
|
||||
>>> z4.otobrazh()
|
||||
значение= Класс из модуля
|
||||
>>> Mod3.otobrazh('Объект')
|
||||
значение объекта= Объект
|
||||
```
|
||||
Вызывается самостоятельная функция из модуля, а не метод класса
|
||||
|
||||
## 4 Использование специальных методов
|
||||
Имена специальных методов предваряются одним или двумя подчерками и имеют вид: __<имя специального метода>__
|
||||
Для примера создали класс, содержащий два специальных метода
|
||||
```py
|
||||
>>> class Class3(Class2): #Наследник класса Class2, а через него – и класса Class1
|
||||
... def __init__(self,znach): #Конструктор-вызывается при создании нового экземпляра класса
|
||||
... self.data=znach
|
||||
... def __add__(self,drug_zn): #Вызывается, когда экземпляр участвует в операции «+»
|
||||
... return Class3(self.data+drug_zn)
|
||||
... def zad_dr_zn(self,povtor): #А это - обычный метод
|
||||
... self.data*=povtor
|
||||
...
|
||||
```
|
||||
Метод __add__ - это один из методов, осуществляющих так называемую «перегрузку» операторов.
|
||||
Для иллюстрации работы этих методов создали экземпляр класса Class3 и отобразили его
|
||||
```py
|
||||
>>> z5=Class3('abc')
|
||||
>>> z5.otobrazh()
|
||||
значение= abc
|
||||
```
|
||||
А теперь выполнили операцию «+» (должен сработать специальный метод __add__)
|
||||
```py
|
||||
>>> z6=z5+'def'
|
||||
>>> z6.otobrazh()
|
||||
значение= abcdef
|
||||
```
|
||||
Обратились к обычному методу класса:
|
||||
```py
|
||||
>>> z6.zad_dr_zn(3)
|
||||
>>> z6.otobrazh()
|
||||
значение= abcdefabcdefabcdef
|
||||
```
|
||||
5 Присоединение атрибутов к классу
|
||||
```py
|
||||
>>> dir(Class3)
|
||||
['__add__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__static_attributes__', '__str__', '__subclasshook__', '__weakref__', 'otobrazh', 'zad_dr_zn', 'zad_zn']
|
||||
```
|
||||
Создали новый атрибут
|
||||
```py
|
||||
>>> Class3.fio='Иванов И.И.'
|
||||
>>> dir(Class3)
|
||||
['__add__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__static_attributes__', '__str__', '__subclasshook__', '__weakref__', 'fio', 'otobrazh', 'zad_dr_zn', 'zad_zn']
|
||||
```
|
||||
Создали экземпляр
|
||||
```py
|
||||
>>> z7=Class3(123)
|
||||
>>> dir(z7)==dir(Class3)
|
||||
False
|
||||
>>> z7.fio
|
||||
'Иванов И.И.'
|
||||
```
|
||||
Обновили новый атрибут у созданного экземпляра
|
||||
```py
|
||||
>>> z7.rozden='1987'
|
||||
>>> dir(z7)
|
||||
['__add__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__static_attributes__', '__str__', '__subclasshook__', '__weakref__', 'data', 'fio', 'otobrazh', 'rozden', 'zad_dr_zn', 'zad_zn']
|
||||
>>> dir(Class3)
|
||||
['__add__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__static_attributes__', '__str__', '__subclasshook__', '__weakref__', 'fio', 'otobrazh', 'zad_dr_zn', 'zad_zn']
|
||||
```
|
||||
## 6 Выявление родительских классов
|
||||
Такое выявление делается с помощью специального атрибута __bases__, например, вывели родительский класс для созданного класса Class3
|
||||
```py
|
||||
>>> Class3.__bases__
|
||||
(<class '__main__.Class2'>,)
|
||||
>>> Class2.__bases__
|
||||
(<class '__main__.Class1'>,)
|
||||
>>> Class1.__bases__
|
||||
(<class 'object'>,)
|
||||
```
|
||||
Для получения всей цепочки наследования использовали атрибут __mro__:
|
||||
```py
|
||||
>>> Class3.__mro__
|
||||
(<class '__main__.Class3'>, <class '__main__.Class2'>, <class '__main__.Class1'>, <class 'object'>)
|
||||
```
|
||||
Получили всю цепочку наследования для встроенного класса ошибок «деление на ноль»:
|
||||
```py
|
||||
>>> ZeroDivisionError.__mro__
|
||||
(<class 'ZeroDivisionError'>, <class 'ArithmeticError'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>)
|
||||
```
|
||||
## 7 Создание свойства класса
|
||||
Свойство (property) класса – это особый атрибут класса, с которым можно производить операции чтения или задания его значения, а также удаление значения этого атрибута.
|
||||
Создали новый класс с определенным в нем свойством
|
||||
```py
|
||||
>>> class Class4:
|
||||
... def __init__(sam,znach):
|
||||
... sam.__prm=znach
|
||||
... def chten(sam):
|
||||
... return sam.__prm
|
||||
... def zapis(sam,znch):
|
||||
... sam.__prm=znch
|
||||
... def stiran(sam):
|
||||
... del sam.__prm
|
||||
... svojstvo=property(chten,zapis,stiran)
|
||||
...
|
||||
```
|
||||
Обратили внимание на то, что здесь имеется 3 метода: chten, zapis, stiran, которые обслуживают созданное свойство, реализуя операции, соответственно, чтения, записи или удаления значений свойства. Теперь попробобавали некоторые операции с этим свойством
|
||||
```py
|
||||
>>> exempl=Class4(12)
|
||||
>>> exempl.svojstvo
|
||||
12
|
||||
>>> exempl.svojstvo=45
|
||||
>>> print(exempl.svojstvo)
|
||||
45
|
||||
>>> del exempl.svojstvo
|
||||
```
|
||||
После этого попробовали еще раз отобразить значение свойства
|
||||
```py
|
||||
>>> exempl.svojstvo
|
||||
Traceback (most recent call last):
|
||||
File "<pyshell#61>", line 1, in <module>
|
||||
exempl.svojstvo
|
||||
File "<pyshell#55>", line 5, in chten
|
||||
return sam.__prm
|
||||
AttributeError: 'Class4' object has no attribute '_Class4__prm'
|
||||
```
|
||||
Свойство было удалено. exempl.svojstvo → вызывает chten(). chten() пытается вернуть sam.__prm. Python ищет _Class4__prm (после преобразования). Атрибут удален → AttributeError
|
||||
## 8 Пример представления в виде класса модели системы автоматического регулирования (САР)
|
||||
```py
|
||||
class SAU:
|
||||
def __init__(self,zn_param):
|
||||
self.param=zn_param
|
||||
self.ypr=[0,0]
|
||||
|
||||
def zdn_zn(self,upr):
|
||||
self.x=upr
|
||||
|
||||
def model(self):
|
||||
def inerz(x,T,yy):
|
||||
return (x+T*yy)/(T+1)
|
||||
|
||||
y0=self.x-self.ypr[1]*self.param[3] #Обр.связь с усилителем 2
|
||||
y1=self.param[0]*y0 #Усилитель1
|
||||
y2=inerz(y1,self.param[1],self.ypr[0]) #Инерционное звено1
|
||||
y3=inerz(y2,self.param[2],self.ypr[1]) #Инерционное звено2
|
||||
self.ypr[0]=y2
|
||||
self.ypr[1]=y3
|
||||
|
||||
def otobraz(self):
|
||||
print('y=',self.ypr[1])
|
||||
```
|
||||
Проверка работы:
|
||||
```py
|
||||
prm=[2.5,4,1.3,0.8] #Параметры модели: коэф.усиления, 2 пост.времени, обратная связь
|
||||
from SAU import *
|
||||
xx=[0]+[1]*20 #Входной сигнал – «ступенька»
|
||||
SAUe=SAU(prm) # Создаём экземпляр класса
|
||||
yt=[]
|
||||
for xt in xx: # Прохождение входного сигнала
|
||||
SAUe.zdn_zn(xt)
|
||||
... SAUe.model()
|
||||
... SAUe.otobraz()
|
||||
... yt.append(SAUe.ypr[1])
|
||||
...
|
||||
y= 0.0
|
||||
y= 0.2173913043478261
|
||||
y= 0.4763705103969754
|
||||
y= 0.686594887811293
|
||||
y= 0.8199324616478645
|
||||
y= 0.8837201137353929
|
||||
y= 0.8994188484874774
|
||||
y= 0.8892777072047301
|
||||
y= 0.870097963179993
|
||||
y= 0.8518346102696789
|
||||
y= 0.8387499784485772
|
||||
y= 0.8314204114211459
|
||||
y= 0.8286051955249649
|
||||
y= 0.8285656555914835
|
||||
y= 0.8297915186846528
|
||||
y= 0.8312697736438287
|
||||
y= 0.8324765218921963
|
||||
y= 0.8332456979978418
|
||||
y= 0.8336163607592184
|
||||
y= 0.8337101315489143
|
||||
y= 0.833654237067147
|
||||
>>> import pylab
|
||||
>>> pylab.plot(yt)
|
||||
[<matplotlib.lines.Line2D object at 0x0000028C363DA710>]
|
||||
>>> pylab.show()
|
||||
>>> prm=[5.5,2,6.3,0.9]
|
||||
>>> SAUe=SAU(prm)
|
||||
>>> yt=[]
|
||||
>>> for xt in xx: # Прохождение входного сигнала
|
||||
... SAUe.zdn_zn(xt)
|
||||
... SAUe.model()
|
||||
... SAUe.otobraz()
|
||||
... yt.append(SAUe.ypr[1])
|
||||
...
|
||||
y= 0.0
|
||||
y= 0.2511415525114155
|
||||
y= 0.5785429828402243
|
||||
y= 0.8608684291527201
|
||||
y= 1.0405548889736682
|
||||
y= 1.1123698572088563
|
||||
y= 1.1026104028422206
|
||||
y= 1.0485692602883017
|
||||
y= 0.9837333929415083
|
||||
y= 0.9303020862487426
|
||||
y= 0.8979490324812144
|
||||
y= 0.8865131776531742
|
||||
y= 0.8902188772938274
|
||||
y= 0.9016293565437798
|
||||
y= 0.9143726153161045
|
||||
y= 0.9244204691700071
|
||||
y= 0.9301876457452414
|
||||
y= 0.931925085592902
|
||||
y= 0.9308720026158589
|
||||
y= 0.9284995249411967
|
||||
y= 0.9260125207356777
|
||||
>>> pylab.plot(yt)
|
||||
[<matplotlib.lines.Line2D object at 0x0000028C385FB110>]
|
||||
>>> pylab.show()
|
||||
lin1
|
||||
```
|
||||

|
||||
Двоичные данные
TEMA9/Figure_1.png
Обычный файл
|
После Ширина: | Высота: | Размер: 15 KiB |
10
TEMA9/Mod3.py
Обычный файл
@@ -0,0 +1,10 @@
|
||||
class Class1: #Объявление класса Class1 в модуле
|
||||
def zad_zn(self,znach): # 1 Метод класса
|
||||
self.data=znach # self - ссылка на экземпляр класса Class1
|
||||
def otobrazh(self): # 2 Метод класса
|
||||
print(self.data)#Отображение данных экземпляра
|
||||
class Class2(Class1): #Class2 - наследник класса Class1
|
||||
def otobrazh(self): # Метод класса Class2
|
||||
print('значение=',self.data)#Отображение данных экземпляра
|
||||
def otobrazh(objekt): #Объявление самостоятельной функции
|
||||
print('значение объекта=',objekt)
|
||||
Двоичные данные
TEMA9/Ris1.png
Обычный файл
|
После Ширина: | Высота: | Размер: 14 KiB |
21
TEMA9/SAU.py
Обычный файл
@@ -0,0 +1,21 @@
|
||||
class SAU:
|
||||
def __init__(self,zn_param):
|
||||
self.param=zn_param
|
||||
self.ypr=[0,0]
|
||||
|
||||
def zdn_zn(self,upr):
|
||||
self.x=upr
|
||||
|
||||
def model(self):
|
||||
def inerz(x,T,yy):
|
||||
return (x+T*yy)/(T+1)
|
||||
|
||||
y0=self.x-self.ypr[1]*self.param[3] #Обр.связь с усилителем 2
|
||||
y1=self.param[0]*y0 #Усилитель1
|
||||
y2=inerz(y1,self.param[1],self.ypr[0]) #Инерционное звено1
|
||||
y3=inerz(y2,self.param[2],self.ypr[1]) #Инерционное звено2
|
||||
self.ypr[0]=y2
|
||||
self.ypr[1]=y3
|
||||
|
||||
def otobraz(self):
|
||||
print('y=',self.ypr[1])
|
||||
65
TEMA9/task.md
Обычный файл
@@ -0,0 +1,65 @@
|
||||
|
||||
Создать и записать в модуль класс, содержащий следующие компоненты:
|
||||
конструктор, задающий четырем атрибутам (fio, otdel, dolzhnost, oklad), представляющим фамилии сотрудников, название отделов, названия должностей сотрудников и размеры их окладов, некоторые начальные значения;
|
||||
метод для обеспечения операции повышения оклада сотрудника на заданное значение;
|
||||
метод для обеспечения перевода сотрудника из одного отдела в другой;
|
||||
метод для изменения должности сотрудника;
|
||||
свойство, содержащее перечень (список) поощрений сотрудника.
|
||||
Создать 2 экземпляра класса, задать им некоторые значения атрибутов и свойства. Отобразить эти значения. Попробовать с этими экземплярами операции перевода из отдела в отдел, изменения должности и оклада, объявления благодарности.
|
||||
|
||||
Решение
|
||||
```py
|
||||
>>> class Employee:
|
||||
... def __init__(self, fio="", otdel="", dolzhnost="", oklad=0):
|
||||
... self.fio = fio
|
||||
... self.otdel = otdel
|
||||
... self.dolzhnost = dolzhnost
|
||||
... self.oklad = oklad
|
||||
... self._pooshchreniya = [] # исправлено на единое имя
|
||||
...
|
||||
... def povyshenie_oklad(self, summa):
|
||||
... if summa > 0:
|
||||
... self.oklad += summa
|
||||
... return self.oklad
|
||||
... else:
|
||||
... print("Сумма для повышения оклада должна быть больше нуля.")
|
||||
...
|
||||
... def perevod(self, new_otdel):
|
||||
... self.otdel = new_otdel
|
||||
... return self.otdel
|
||||
...
|
||||
... def cmena_dolzhnosty(self, new_dolzhnost):
|
||||
... self.dolzhnost = new_dolzhnost
|
||||
... return self.dolzhnost
|
||||
...
|
||||
... @property
|
||||
... def pooshchrenia(self):
|
||||
... return self._pooshchreniya # исправлено на единое имя
|
||||
...
|
||||
... def add_pooshchrenie(self, pooshchrenie):
|
||||
... self._pooshchreniya.append(pooshchrenie) # исправлено на единое имя
|
||||
... print(f"Сотрудник {self.fio} теперь имеет поощрение: {pooshchrenie}")
|
||||
...
|
||||
...
|
||||
>>> emp_1=Employee ("Толчеев В.О.", "Кафедра Управления и информационных технологий", "Профессор", 150000)
|
||||
>>> emp_2=Employee ("Бобряков А.В.", "Кафедра Управления и информационных технологий", "Заведующий кафедрой", 1000000)
|
||||
>>> print(f"{emp_1.fio}, {emp_1.otdel}, {emp_1.dolzhnost}, оклад: {emp_1.oklad}")
|
||||
Толчеев В.О., Кафедра Управления и информационных технологий, Профессор, оклад: 150000
|
||||
>>> print(f"{emp_2.fio}, {emp_2.otdel}, {emp_2.dolzhnost}, оклад: {emp_2.oklad}")
|
||||
Бобряков А.В., Кафедра Управления и информационных технологий, Заведующий кафедрой, оклад: 1000000
|
||||
>>> emp_2.perevod("МТУСИ")
|
||||
'МТУСИ'
|
||||
>>> emp_2.povyshenie_oklad(10000)
|
||||
1010000
|
||||
>>> emp_1.cmena_dolzhnosty("Заведующий кафедрой")
|
||||
'Заведующий кафедрой'
|
||||
>>> emp_2.add_pooshchrenie("Выслуга лет")
|
||||
Сотрудник Бобряков А.В. теперь имеет поощрение: Выслуга лет
|
||||
>>> emp_1.add_pooshchrenie("Лучший проект")
|
||||
Сотрудник Толчеев В.О. теперь имеет поощрение: Лучший проект
|
||||
>>> print(f"Поощрения {emp_1.fio}: {emp_1.pooshchrenia}")
|
||||
Поощрения Толчеев В.О.: ['Лучший проект']
|
||||
>>> print(f"Поощрения {emp_2.fio}: {emp_2.pooshchrenia}")
|
||||
Поощрения Бобряков А.В.: ['Выслуга лет']
|
||||
|
||||
```
|
||||
151
TEMA9/zadanie1.md
Обычный файл
@@ -0,0 +1,151 @@
|
||||
M3_1
|
||||
1)Создайте модуль М1, содержащий две функции:
|
||||
|
||||
функция 1: аргумент - список или кортеж с выборкой; функция должна произвести расчет по выборке оценки её дисперсии DX, а также наименьшего и наибольшего значений и вернуть эти значения в вызывающую программу в виде списка;
|
||||
|
||||
функция 2: аргументы - два списка или кортежа с выборками X и Y; функция должна произвести с помощью функции 1 расчет статистик по выборкам и рассчитать статистику Фишера:
|
||||
|
||||
F=DX/DY
|
||||
|
||||
2)Создайте еще один модуль М2, в котором должны выполняться следующие операции:
|
||||
|
||||
запрашивается имя бинарного файла с выборками X и Y, проверяется его наличие и при отсутствии - повторяется запрос;
|
||||
|
||||
выборки считываются из файлов;
|
||||
|
||||
с помощью функции 1 по выборкам рассчитываются их статистики,
|
||||
|
||||
с помощью функции 2 рассчитывается значение статистики Фишера,
|
||||
|
||||
если числа элементов в выборках одинаково, графически отображается поле рассеивания для Х и Y;
|
||||
|
||||
результаты расчета с соответствующими заголовками выводятся в текстовый файл.
|
||||
|
||||
3)Создайте модуль М0 - главную программу, которая вызывает М2 и отображает результаты расчета на экране.
|
||||
|
||||
4)Создайте 2 бинарных файла: с выборками одинакового размера и с выборками разного размера. Проверьте программу с использованием этих файлов.
|
||||
|
||||
Модуль 1
|
||||
```py
|
||||
import math
|
||||
def disp(s): # функция рассчета дисперсии
|
||||
if len(s) == 0:
|
||||
return [0, 0, 0]
|
||||
sr = sum(s) / len(s)
|
||||
v = sum((x - sr) ** 2 for x in s) / len(s) # среднее квадратов отклонений от среднего
|
||||
m_n = min(s)
|
||||
m_x = max(s)
|
||||
|
||||
return [v, m_n, m_x]
|
||||
|
||||
def fisher_stat(sample_x, sample_y): # статистика фишера
|
||||
stats_x = disp(sample_x)
|
||||
stats_y = disp(sample_y)
|
||||
|
||||
dx = stats_x[0] # дисп х
|
||||
dy = stats_y[0] # дисп у
|
||||
|
||||
if dy == 0:
|
||||
return 0, stats_x, stats_y
|
||||
else:
|
||||
f = dx / dy
|
||||
return f, stats_x, stats_y
|
||||
```
|
||||
Модуль 2
|
||||
```py
|
||||
import pickle
|
||||
import matplotlib.pyplot as plt
|
||||
import M1
|
||||
|
||||
def load_samples(filename): #Загружаем выборки х и у
|
||||
|
||||
while True:
|
||||
try:
|
||||
with open(filename, 'rb') as f:
|
||||
data = pickle.load(f)
|
||||
x = data['X']
|
||||
y = data['Y']
|
||||
print(f"Файл {filename} успешно загружен!")
|
||||
return x, y
|
||||
except FileNotFoundError:
|
||||
print(f"Файл {filename} не найден!")
|
||||
filename = input("Введите имя файла снова: ")
|
||||
except Exception as e:
|
||||
print(f"Ошибка чтения файла: {e}")
|
||||
filename = input("Введите имя файла снова: ")
|
||||
|
||||
def analysis():
|
||||
x, y = load_samples(input("Введите имя бинарного файла: "))
|
||||
f, stats_x, stats_y = M1.fisher_stat(x, y)
|
||||
|
||||
print("\nРЕЗУЛЬТАТЫ РАСЧЕТА:")
|
||||
print(f"Размер выборки X: {len(x)}, Y: {len(y)}")
|
||||
print(f"X: Дисперсия={stats_x[0]:.4f}, мин={stats_x[1]:.4f}, макс={stats_x[2]:.4f}")
|
||||
print(f"Y: Дисперсия={stats_y[0]:.4f}, мин={stats_y[1]:.4f}, макс={stats_y[2]:.4f}")
|
||||
print(f"Статистика Фишера F = {f:.4f}")
|
||||
|
||||
|
||||
if len(x) == len(y): # График размеры одинаковые
|
||||
plt.figure(figsize=(8, 6))
|
||||
plt.scatter(x, y, alpha=0.7, color='blue')
|
||||
plt.xlabel('X')
|
||||
plt.ylabel('Y')
|
||||
plt.title('Поле рассеивания X-Y')
|
||||
plt.grid(True)
|
||||
plt.show()
|
||||
|
||||
# Сохраняем в текстовый файл
|
||||
with open('results.txt', 'w') as f: # Сохраняем в файл
|
||||
f.write("РЕЗУЛЬТАТЫ СТАТИСТИЧЕСКОГО АНАЛИЗА\n")
|
||||
f.write(f"Размер выборки X: {len(x)}\n")
|
||||
f.write(f"Размер выборки Y: {len(y)}\n\n")
|
||||
f.write(f"СТАТИСТИКИ ПО X:\n")
|
||||
f.write(f" Дисперсия DX = {stats_x[0]:.6f}\n")
|
||||
f.write(f" Минимум = {stats_x[1]:.6f}\n")
|
||||
f.write(f" Максимум = {stats_x[2]:.6f}\n")
|
||||
f.write(f"СТАТИСТИКИ ПО Y:\n")
|
||||
f.write(f" Дисперсия DY = {stats_y[0]:.6f}\n")
|
||||
f.write(f" Минимум = {stats_y[1]:.6f}\n")
|
||||
f.write(f" Максимум = {stats_y[2]:.6f}\n")
|
||||
f.write(f"СТАТИСТИКА ФИШЕРА:\n")
|
||||
f.write(f" F = DX/DY = {f:.6f}\n")
|
||||
|
||||
print("Результаты сохранены в файл results.txt")
|
||||
return f, stats_x, stats_y
|
||||
|
||||
if __name__ == "__main__":
|
||||
analysis()
|
||||
```
|
||||
Модуль 0
|
||||
```py
|
||||
import M2
|
||||
|
||||
def main():
|
||||
|
||||
print("СТАТИСТИЧЕСКИЙ АНАЛИЗ")
|
||||
results = M2.analysis() # Запускаем анализ
|
||||
print("АНАЛИЗ ЗАВЕРШЕН!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
|
||||
```py
|
||||
>>> import os
|
||||
>>> os.chdir('C:\\Users\\Admin\\Documents\\Tsvetkova\\python-labs\\TEMA9')
|
||||
>>> import M1
|
||||
>>> import M2
|
||||
>>> import M0
|
||||
>>> M0.main()
|
||||
СТАТИСТИЧЕСКИЙ АНАЛИЗ
|
||||
Введите имя бинарного файла: same_size.bin
|
||||
Файл same_size.bin успешно загружен!
|
||||
|
||||
РЕЗУЛЬТАТЫ РАСЧЕТА:
|
||||
Размер выборки X: 20, Y: 20
|
||||
X: Дисперсия=4.7969, мин=1.4282, макс=9.9043
|
||||
Y: Дисперсия=3.2402, мин=2.1279, макс=7.5406
|
||||
Статистика Фишера F = 1.4804
|
||||
```
|
||||

|
||||