Сравнить коммиты

...

34 Коммитов

Автор SHA1 Сообщение Дата
e1d0599622 zadanie 2025-12-08 16:55:43 +03:00
e67b412977 ris 2025-12-08 16:30:07 +03:00
69a9d61875 zadanie1 2025-12-08 16:27:43 +03:00
7c1552aa67 zadanie 2025-12-08 15:24:08 +03:00
b3bd732ba8 zadanie 2025-12-08 15:11:01 +03:00
6053fbe787 16 2025-12-08 14:28:39 +03:00
bdeb1c27f1 9 2025-12-07 22:52:02 +03:00
f6ed84af3d task 2025-12-07 22:47:22 +03:00
d8f5f5b631 txt 2025-12-07 22:46:08 +03:00
b643e0a0b2 modul 2025-12-07 22:45:00 +03:00
f1e43207fc mod 2025-12-07 22:42:24 +03:00
c5bca092a1 task 2025-12-07 22:37:24 +03:00
0bb5224e01 Mod3.py 2025-12-07 22:23:33 +03:00
4bfdf950b8 9 2025-12-07 22:12:21 +03:00
d5e5e9b5d3 8.md 2025-12-07 15:56:56 +03:00
3920c08f52 16 2025-11-24 14:24:51 +03:00
6de200f325 test 2025-11-24 11:56:10 +03:00
ce72d1f7b1 Figurem1 2025-11-24 11:55:41 +03:00
4363aa2fa2 Lab7 2025-11-23 23:35:28 +03:00
fd2984bcdf Lab7 2025-11-23 23:31:18 +03:00
6160c052b9 7 2025-11-10 15:13:49 +03:00
cae5dea1a4 7 2025-11-10 15:10:41 +03:00
ae4e396508 laba6 2025-11-08 11:51:44 +03:00
a621ace813 lab6 2025-11-08 11:48:53 +03:00
f307214522 task 2025-11-08 11:23:57 +03:00
b74c73fe72 17 2025-10-27 14:23:19 +03:00
1e1fd17e90 Lab5 2025-10-27 12:24:27 +03:00
e827cd0d89 Figure_2 2025-10-26 23:54:19 +03:00
4e69415fd4 Figure_1 2025-10-26 23:54:02 +03:00
e9950f74f7 task 2025-10-26 23:53:09 +03:00
13cc4d3748 Lab5 2025-10-26 23:52:22 +03:00
a915bf70e4 Ris4 2025-10-13 15:58:21 +03:00
03d8d26d94 Ris3 2025-10-13 15:57:57 +03:00
5c03990cec Ris2 2025-10-13 15:57:33 +03:00
36 изменённых файлов: 3566 добавлений и 3 удалений

Двоичные данные
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
![](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)
График прикреплен файлом 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
```
![](Ris1.png)

Двоичные данные
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
```
![](Figure_1.png)