diff --git a/TEMA5/Figure_1.png b/TEMA5/Figure_1.png new file mode 100644 index 0000000..52d76d5 Binary files /dev/null and b/TEMA5/Figure_1.png differ diff --git a/TEMA5/Figure_2.png b/TEMA5/Figure_2.png new file mode 100644 index 0000000..f935d4c Binary files /dev/null and b/TEMA5/Figure_2.png differ diff --git a/TEMA5/report.md b/TEMA5/report.md new file mode 100644 index 0000000..ca01a4f --- /dev/null +++ b/TEMA5/report.md @@ -0,0 +1,445 @@ +# Тема 5. Блоки инструкций, управляющие инструкции +Выполнил: Тимошенко А.А. +Проверил: Козлюк Д. А. + +## Пункт 1. +``` +>>> import os +>>> os.chdir("C:/Users/mapon/OneDrive/Рабочий стол/ПО АС/ТЕМА5") +``` +## Пункт 2. Ветвление по условию (if) + +Общий вид выглядит так: + +if <условие>: +<отступы> <Блок инструкций, выполняемый, если условие истинно> + [elif <условие2>: +<отступы><Блок инструкций2, выполняемый, если условие2 истинно> +] +[else: +< отступы><Блок инструкций3, выполняемый, если условие ложно> +] + +Причем elif и else вместе или по отдельности могут отсуствовать. + +Пример: +``` +>>> porog = 6 +>>> rashod1 = 8 +>>> rashod2 = 5 +>>> if rashod1 >= porog: + dohod = 12 # Это выполняется, если rashod1 >= porog +elif rashod2 == porog: + dohod = 0 # Это выполняется, если первое условие ложно, но rashod2 == porog +else: + dohod = -8 # Это выполняется, если ни первое, ни второе условие не были истинными + +>>> dohod +12 +``` +Оператор rashod1 >= porog (например, в числах, 8 >= 5) возвращает логическое значение True, +поэтому будет выполняться блок инструкций, соответствующий этому условию. Важно понимать, +что в конструкции if-elif-else всегда выполняется только одна ветвь. Даже если условие +в elif также истинно, оно не будет проверено и, соответственно, не выполнится, если до +этого уже выполнился блок if. Это связано с тем, что после выполнения любого блока +инструкции (будь то if, elif или else) остальные части конструкции игнорируются. + +Перезададим некоторые значения и выполним другую управляющую инструкцию: +``` +>>> rashod2 = 4 +>>> porog = 4 +>>> if rashod1 >= 3 and rashod2 == 4: #Верно + dohod = rashod1 + if rashod2 == porog or rashod1 < rashod2: #Тоже верно + dohod = porog + +>>> dohod +4 +``` +В данном случае выполняются оба if, потому что один находится в блоке инструкций другого +вложенное условие). Вложенное условие будет проверяться в любом случае, если выполнилось +внешнее. +``` +>>> if porog == 3: #Неверно + dohod = 1 +elif porog == 4: #Верно + dohod = 2 +elif porog == 5: #Игнорируется + dohod = 3 +else: #Игнорируется + dohod = 0 + +>>> dohod +2 +``` +Еще одна форма записи условных управляющих инструкций - тернарный оператор (от лат. "тройной"): + +<Объект> = <значение 1> if <условие> else <значение 2> +``` +>>> dohod = 2 if porog >= 4 else 0 +>>> dohod +2 +``` +Если в блоке инструкций всего одна строка, можно записать всё в одну строку: +``` +>>> porog = 2 +>>> if porog >= 5 : rashod1 = 6; rashod2 = 0 + +>>> rashod1 +8 +>>> rashod2 +4 +``` +Поскольку сейчас значение porog было задано таким, чтобы не удовлетворять условию, то +эта строка полностью не была выполнена и не повлияла на значения переменных. Но в другом +случае: +``` +>>> porog = 7 +>>> if porog >= 5 : rashod1 = 6; rashod2 = 0 + +>>> rashod1 +6 +>>> rashod2 +0 +``` +Выполняется условие и выполняются инструкции. + +## Пункт 3. Цикл по перечислению (for) + +for <Объект-переменная цикла> in <объект>: +<отступы> <Блок инструкций 1 – тело цикла> +[else: +<отступы> <Блок инструкций 2 – если в цикле не сработал break>] + +В качестве объекта сойдёт любая коллекция или, например, диапазон range. Если сообщить +словарь, то будут перебираться его ключи. Если сообщить множество, перебор будет осуществлен, +но порядок будет неочевидным. + + +### Пункт 3.1. Простой цикл. +``` +>>> temperatura = 5 +>>> for i in range(3,18,3): + temperatura += i + +>>> temperatura +50 +``` + +### Пункт 3.2. Более сложный цикл. +``` +>>> 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 (это можно понять не только по +смыслу, но и по табуляции) + +Рассмотрим другой вариант: +``` +>>> 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, и список, изменяющийся внутри цикла - это объекты, +имеющие разные адреса. Это можно проверить: +``` +>>> id(sps) +1684034116672 +>>> id(sps[:]) +1684069134400 +``` +Следовательно, else не успеет сработать, потому что итерируемый в управляющей инструкции +объект окажется короче и завершит цикл раньше: + +### Пункт 3.3 +``` +>>> 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) +``` +Программа ничего не вывела. Посмотрим, почему именно: +``` +>>> ss +501 +>>> sps5 +[25, 66, 4, 30, 8, 97, 87, 11, 51, 57, 65] +``` +После того, как прошло одиннадцать итераций, сумма элементов списка уже была больше 500, поэтому +цикл закончился из-за if, а не из-за окончания диапазона range(10). + +Попробуем обнулить список и выполнить ту же программу еще раз: +``` +>>> sps5 = [] +>>> for i in range(10): + sps5.append(rn.randint(1,100)) + ss = sum(sps5) + if ss > 500: break +else: + print(ss) + +436 +``` +В этот раз программа вывела ответ самостоятельно, потому что сработал else, потому что +за все десять итераций цикла так и не успел выполниться break по условию if. + +Примечание: + Рассмотрим строку >>> import random as rn + Если мы попробуем вызвать функцию из этого модуля по ее исходному названию, ничего не + выйдет: +``` +>>> random.randint(4,7) +Traceback (most recent call last): + File "", line 1, in + random.randint(4,7) +NameError: name 'random' is not defined +``` +Так происходит потому, что на этапе преобразования программы в байт-код python связывает +модуль random, найденный где-то в каталогах, принадлежащих python, с именем rs. Модуль +random становится объектом в пространстве имен, создаётся ссылка на объект модуля random +и ему присваивается имя rn. Но имя random ему НЕ присваивается, поэтому обратиться к +методам и атрибутам по имени random нельзя. + + +### Пункт 3.4. Пример с символьной строкой +``` +>>> stroka = 'Это – автоматизированная система' +>>> stroka1 = "" +>>> for ss in stroka: + stroka1 += " " + ss + + +>>> stroka1 +' Э т о – а в т о м а т и з и р о в а н н а я с и с т е м а' +``` +Переменная ss проходит по всему строковому объекту, на каждой итерации принимая значение +одного знака. Этот знак с предшествующим пробелом дописывается в конец другой, изначально +пустой строки. Цикл закончится, когда закончится исходная строка. + +### Пункт 3.5. Запись цикла в строке +``` +>>> 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] +``` +Такая конструкция называется list comprehention (генератор списков). В общем +виде она выглядит так: + +<итоговый список> = [<выражение> for <элемент> in <исходный объект> if <условие>] + +Эту синусоиду можно отобразить на графике: +``` +>>> import pylab +>>> pylab.plot(sps2, label='Синусоидальный сигнал', color = 'green') +[] +>>> pylab.show() +``` +Полученный график корректен и и сохранен в файле Figure_1 + + +## Пункт 4. Цикл "пока истинно условие" (while) + +Общий вид: +``` +while <Условие>: +<отступы><Блок инструкций 1 – тело цикла> +[else: +<отступы><Блок инструкций 2 – если в цикле не сработал break>] + +break и else работают аналогично предыдущему случаю. +``` +### Пункт 4.1. Цикл со счетчиком +``` +>>> rashod = 300 +>>> while rashod: + print("Расход =",rashod) + rashod -= 50 + +Расход = 300 +Расход = 250 +Расход = 200 +Расход = 150 +Расход = 100 +Расход = 50 +``` +Как именно произошло завершение цикла? Нужно вспомнить, что все числа, кроме нуля, при +конвертации в логический тип данных имеют логическое значение True: +``` +>>> bool(50) +True +``` +И только нуль имеет значение False: +``` +>>> bool(0) +False +``` +Сравниваемая в управляющей инструкции переменная уменьшается в самом цикле, поэтому, когда +строка со сравнением обнаружит 0, то воспримет это как False, и действия по выводу +и уменьшению числа выполняться больше не будут. + +### Пункт 4.2. Пример с символьной строкой +``` +>>> import math +>>> stroka='Расчет процесса в объекте регулирования' +>>> i=0 +>>> sps2=[] +>>> while i>> pylab.show() +``` +График сохранен под именем Figure_2. + + +### Пункт 4.3. Определение, является ли число простым (делится только на самого себя или 1). +``` +>>> 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. +``` +>>> 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. + +Она используется, когда надо при определенном условии не завершить весь цикл, а завершить +только текущую итерацию. + +Пример (вывести только положительные числа): +``` +>>> nums = [rn.randint(-30, 30) for x in range(15)] +>>> nums +[-11, -1, 25, -11, 12, 24, -28, -16, -2, 15, -25, -2, -15, 9, -4] + +>>> for now in nums: + if now < 0: continue + print(now, " > 0") +else: print("все числа обработаны") + +25 > 0 +12 > 0 +24 > 0 +15 > 0 +9 > 0 +все числа обработаны +```