FilippovDY (FilippovDY) 4 дней назад
Родитель c4c8ff836c
Сommit 874fe4901c

@ -0,0 +1,428 @@
# Отчёт по теме 5: "Блоки инструкций, управляющие инструкции"
Филиппов Даниил Юрьевич, А-01-23
# 1. Запуск интерактивной оболочки IDLE
```py
>>> import os
>>> os.chdir('C:\\Users\\danii\\Desktop\\FilippovDY\\python-labs\\TEMA5')
```
Управляющие инструкции, как и в других языках программирования, используются в Python для разветвления линий потока. Их применение имеет как сходство, так и заметные отличия по сравнению с другими языками программирования. В программах на Python они применяются по следующей общей схеме:
<Управляющая инструкция>:
<отступы><Блок инструкций>
Здесь управляющая инструкция начинается зарезервированными словами, такими как if, while, for… и дополняется логическим выражением, со значением True или False.
Блок инструкций – это совокупность инструкций на языке Python, возможно, включающая вложенные управляющие инструкции. Относительно управляющей инструкции блок инструкций сдвигается влево с использованием одинаковых отступов, задаваемых либо некоторым числом пробелов, либо одной или несколькими табуляциями. Величина отступа задаётся в настройках среды (Indentation Width). По умолчанию – это 4 пробела или 1 табуляция.
# 2. Ветвление по условию – управляющая инструкция if.
Общее правило написания:
if <условие>:
<отступы><Блок инструкций, выполняемый, если условие истинно>
[elif <условие2>:
<отступы><Блок инструкций2, выполняемый, если условие2 истинно>
]
[else:
< отступы><Блок инструкций3, выполняемый, если условие ложно>
]
Условие задается в виде логического выражения, которое может принимать значение True или False. Блок инструкций может располагаться на нескольких строках. Отступы во всех строках блока должны быть одинаковыми по отношению к первому символу управляющей инструкции. Если имеется вложенная управляющая инструкция, то она вводится с таким же отступом, а все строки ее блоков – отступают по отношению к ее первому символу. Признак конца блока – отсутствие отступов в очередной строке или ввод пустой строки.
Если в Блоке инструкций только одна инструкция, её можно записывать без отступов сразу за знаком «:».
```py
>>> porog=50
>>> rashod1=200
>>> rashod2=30
>>> if rashod1>=porog:
... dohod=12
... elif rashod2==porog:
... dohod=0
... else:
... dohod=-8 # Это выполняется, если ни первое, ни второе условия не были истинными
...
...
>>> dohod
12
```
В конструкции if-elif-else всегда выполняется только одна ветвь. Даже если условие
в elif также истинно, оно не будет проверено и, соответственно, не выполнится, если до
этого уже выполнился блок if. Это связано с тем, что после выполнения любого блока
инструкции (будь то if, elif или else) остальные части конструкции игнорируются.
```py
>>> rashod2=4
>>> porog=4
>>> rashod1=8
>>> if porog==3:
... dohod=1
... elif porog==4:
... dohod=2 # Верно
... elif porog==5:
... dohod=3 # Игнорируется
... else:
... dohod=0 # Игнорируется
...
...
>>> dohod
2
```
Условные инструкции могут записываться также в одну строку в операторе присваивания по следующей схеме:
<Объект>=<значение 1> if <условие> else <значение 2>
или ещё:
if <условие>: <инструкция1>[;<инструкция2>….]
```py
>>> dohod=2 if porog>=4 else 0
>>> dohod
2
>>> if porog>=5 : rashod1=6; rashod2=0 #
...
>>> rashod1 # Условие не выполнено, значения прежние
8
>>> rashod2
4
```
# 3. Цикл по перечислению – управляющая инструкция for.
Общее правило написания:
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
```
Также можно увидеть, какое значение имеет переменная i на каждой итерации:
```py
>>> for i in range(3,18,3):
... i
... temperatura+=i
...
...
3
6
9
12
15
```
## 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, и объект, изменяющийся
внутри цикла. Если список изменяется во время цикла, это влияет на последующие итерации.
(При этом 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, и список, изменяющийся внутри цикла - это объекты, имеющие разные адреса. Цикл итерируется по копии, но изменяет оригинальный список sps. Итерации происходят только 4 раза (по 4 элементам в копии), независимо от того, как растет оригинальный список.
## 3.3 Пример
Создание списка с 10 целыми случайными числами из диапазона от 1 до 100. При этом, если сумма чисел не превышает 500, эта сумма должна быть отображена на экране.
```py
>>> import random as rn
>>> sps5=[]
>>> for i in range(10):
... sps5.append(rn.randint(1,100))
... ss=sum(sps5)
... if ss>500: break
... else:
... print(ss)
...
...
321
```
Программа вывела ответ, потому что сработал else, и за все десять итераций цикла так и не успел выполниться break по условию if. Блок else выполняется только если цикл завершился нормально (не был прерван break). Если срабатывает break, блок else пропускается.
Попробуем обнулить список и запустить программу ещё раз:
```py
>>> for i in range(10):
... sps5.append(rn.randint(1,100))
... ss=sum(sps5)
... if ss>500: break
... else: print(ss)
...
>>> ss
521
>>> sps5
[97, 78, 21, 54, 32, 74, 62, 60, 10, 33]
```
После того, как прошло девять итераций, сумма элементов списка уже была больше 500, поэтому
цикл закончился из-за if, а не из-за окончания диапазона range(10).
## 3.4 Пример с символьной строкой
```py
>>> stroka='Это – автоматизированная система'
>>> stroka1=""
>>> for ss in stroka:
... stroka1+=" "+ss
...
...
>>> 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]
>>> import pylab
>>> pylab.plot(sps2, label='Синусоидальный сигнал', color = 'green')
[<matplotlib.lines.Line2D object at 0x00000244DD254A50>]
>>> pylab.show()
```
Здесь используется конструкция list comprehention (генератор списков). В общем
виде она выглядит так:
<итоговый список> = [<выражение> for <элемент> in <исходный объект> if <условие>]
Полученный график сохранен в файле Figure_1
![Синусоида] (Figure_1.png)
# 4. Цикл «пока истинно условие» – управляющая инструкция while.
Общее правило написания:
while <Условие>:
<отступы><Блок инструкций 1 – тело цикла>
[else:
<отступы><Блок инструкций 2 – если в цикле не сработал break>]
Здесь <Условие> - некоторое логическое выражение. Если на очередном витке цикла оно принимает значение True (или не равно 0), то выполняется Блок инструкций 1. При этом, если в этом блоке присутствует инструкция break и она будет выполнена, то цикл завершается, иначе – переходит к новому витку цикла. В блоке инструкций 1 могут быть изменены значения объектов, входящих в Условие и его значение тоже может измениться. Если же его значением останется True, то вновь выполняется Блок инструкций 1 и т.д. Если в цикле присутствует Блок инструкций 2, то он будет выполнен, если завершение цикла произошло не по инструкции break, а по значению False (или значению =0) условия.
## 4.1 Цикл со счетчиком.
```py
>>> rashod=300
>>> while rashod:
... print("Расход=",rashod)
... rashod-=50
...
...
Расход= 300
Расход= 250
Расход= 200
Расход= 150
Расход= 100
Расход= 50
```
Мы не видим в выводе: когда rashod = 0, потому что цикл уже завершился. Все числа, кроме нуля, при конвертации в логический тип данных имеют логическое значение True и только ноль имеет значение 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 меньше.
```py
>>> pylab.plot(sps2, label='Сигнал выхода', color='black')
[<matplotlib.lines.Line2D object at 0x00000244DD305BD0>]
>>> pylab.title("Сигнал на выходе инерционного звена")
Text(0.5, 1.0, 'Сигнал на выходе инерционного звена')
>>> pylab.show()
```
График сохранен под именем Figure_2.
![График] (Figure_2.png)
## 4.3 Определение, является ли число простым (делится только на самого себя или 1)
```py
>>> chislo=267 #Проверяемое число
>>> kandidat = chislo // 2 # Для значений chislo > 1
>>> while kandidat > 1:
... if chislo%kandidat == 0: # Остаток от деления
... print(chislo, ' имеет множитель ', kandidat)
... break # else выполняться не будет
... kandidat -= 1
... else: # При завершении цикла без break
... print(chislo, ' является простым!')
...
267 имеет множитель 89
```
Программа работает так: переменная kandidat отвечает за потенциальный делитель заданного
числа. Изначально мы задаем половину от заданного числа, потому что у числа не может быть
делителя большего, чем половина от него. Далее мы последовательно уменьшаем потенциальный
множитель, каждый раз проверяя, получилось ли поделить без остатка. Если получилось, то
число непростое, и цикл можно прекращать досрочно.
Дополним программу так, чтобы она проверяла все числа от 250 до 300.
```py
>>> chislo = [x for x in range (250, 301)]
>>> for a in chislo:
... kandidat = a // 2
... while kandidat > 1:
... if a % kandidat == 0:
... print(a, ' имеет множитель ', kandidat)
... break
... kandidat -= 1
... else: print(a, " является простым!")
...
...
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
>>> for i in range(1, 11):
... if i % 2 == 0: # Если число четное
... continue # Пропускаем оставшуюся часть цикла
... print(i)
...
...
1
3
5
7
9
```
# 5. Завершение сеанса работы с IDLE
Загрузка…
Отмена
Сохранить