Friday, May 1, 2020

Prvi razred - lekcija 4 naredba grananja

Наредбе гранања

У животу често неке ствари радимо само ако је неки услов испуњен. На пример, ако пада киша, тада ћемо понети кишобран. Ако је наша висина већа од 140 cm, тада ће нас пустити да се спуштамо низ водени тобоган у аква-парку. И у програмирању се одређене наредбе извршавају само ако неки услов испуњен. Да би се описало условно извршавање неких наредби користи се наредба if коју смо већ сретали у програмима са Карелом и корњачом и која у језику Python има следећи облик:
1
if uslov:           # ако је услов испуњен:
2
    naredba_1       #     изврши наредбу 1
3
    ...             #     ...
4
    naredba_k       #     изврши наредбу k
5
(if_синтакса)
Реч if на енглеском језику значи ако.
Подсетимо се да се након услова обавезно мора навести двотачка (карактер :) и да се наредбе које се извршавају условно морају мало увући (обично се то уради тако што се испред сваке наредбе откуцају три размака).
Често се јавља и потреба да се у зависности од тога да ли је услов испуњен изврши једна или друга група наредби. На пример, ако је корисник унео исправну лозинку треба му пожелети добродошлицу на сајт, а у супротном му треба јавити да унета лозинка није исправна. Такав облик организације извршавања програма се постиже наредбом if-else који у језику Python има следећи облик:
1
if uslov:        # ако је услов испуњен:
2
    naredba_1    #   изврши наредбу 1
3
    ...          #   ...
4
    naredba_m    #   изврши наребу m
5
else:            # у супротном:
6
    naredba_1    #   изврши наредбу 1
7
    ...          #   ...
8
    naredba_n    #   изврши наредбу n
9
(if_else_синтакса)
Реч else на енглеском језику значи u suprotnom.
Приметимо да је двотачку потребно навести и иза else, као и да су оба блока наредби увучена.
Наредбом if-else ток програма се раздваја на две могућности (могу се извршити наредбе испод if или испод else), па се каже да се ток програма на том месту грана, а наредба if-else назива се наредба гранања.

Поређење (релацијски оператори)

Најједноставнији облик услова је поређење неких величина. Рачунар уме да пореди величине (бројеве, али и ниске). За то се користе оператори слични онима које сте већ видели у математици:
  • a < b проверава да ли је a мање од b
  • a > b проверава да ли је a веће од b
  • a >= b проверава да ли је a веће или једнако b
  • a <= b проверава да ли је a мање или једнако b
  • a == b проверава да ли је a једнако b
  • a != b проверава да ли је a различито од b
Резултат примене ових операција је тачно или нетачно (кажемо да је резултат логичка тј. истинитосна вредност).
Илуструјмо сада примену гранања и поређења кроз неколико једноставних програма.

Млади програмери

Напишимо програм који корисницима млађим од 15 година шаље посебну похвалу јер су кренули да програмирају веома рано.
1
godine = int(input("Koliko imate godina: "))
2
if godine < 15:
3
    print("Tako ste mladi, a već programirate! Svaka čast!")
4
(млади_програмери)

Покушај сада да измениш претходни програм тако што ћеш онима који имају 15 или више године рећи да никада није касно да крену са учењем програмирања.
1
godine = int(input("Koliko imate godina: "))
2
if True:   # popravi ovaj uslov
3
    print("Nikada nije kasno da se krene sa učenjem programiranja!")
4
(старији_програмери)

Тобоган

Напиши програм који на основу висине детета одређује да ли дете сме да иде на тобоган.
Наредни програм садржи пар грешкица. Исправи их.
1
visina = int(input("Unesi svoju visinu: "))
2
if visina >= 140
3
print("Možeš na tobogan")
4
(тобоган)
И наредни програм садржи пар грешака. Пробај да их исрпавиш.
1
visina = int(input("Unesi svoju visinu: "))
2
if visina >= 140:
3
print("Možeš na tobogan")
4
else
5
    print("Još ne možeš na tobogan")
6
print("Moraš još malo da porasteš")
7
(тобоган_1)

Цвилидрета

Поређење се може вршити и над нискама. На пример, могуће је проверити да ли је унета ниска једнака некој траженој. Погледајмо наредни задатак.

У бајци браће Грим, патуљак се звао Цвилидрета и девојка је требало да погоди његово име. Ако принцеза промаши, потребно је исписати јој поруку да, нажалост, није погодила.
../_images/cvilidreta.jpg
1
ime = input("Kako se zove patuljak: ")
2
if True:   # ispravi ovaj uslov
3
    print("Nažalost nisi pogodila :(")
4
(цвилидрета)

Ред речи у речнику

Ниске се могу поредити и по абецедном или азбучном реду, како су ваша имена сложена у школском дневнику или како су речи сложене у речнику. Такво поређење се назива лексикографско. За то се користе исти оператори који се користе и за бројеве. На пример, важи да је "Ana" < "Biljana" јер је слово A испред слова B у абецеди. Слично, важи да је "Ana" > "Aleksandar", јер су им прва два слова једнака, па се онда прелази на гледање другог слова, а на том месту се десило да је слово n у абецеди иза слова l. На крају, важи и да је "Ana" < "Anastasija", јер када се не нађе на различито слово, тада се краћа реч ставља пре друге. Напоменимо да овакво поређење савршено ради за слова енглеског алфабета, али да су за слова наше латинице или ћирилице понекад потребна нека додатна подешавања. Обрати пажњу и на то да се приликом поређења прави разлика између великих и малих слова (сва велика слова иду пре свих малих слова).
Q-8: Означи изразе који имају вредност True тј. тачно.





Пошто се ниске могу поредити, на њих се могу примењивати и функције попут min (она одређује мању од две речи) и max (она одређује већу од две речи).

Ко иде пре у дневнику

Напиши програм који за унета два презимена ђака одређује ко од њих иде пре, а ко иде после у дневнику.
Наредна два програма представљају различита решења овог задатка, али и један и други садрже грешке које треба да исправиш.
1
ucenik1 = input("Unesi prezime prvog ucenika (koristi samo engleske karaktere):")
2
ucenik2 = input("Unesi prezime drugog ucenika (koristi samo engleske karaktere):")
3
if ucenik1 < ucenik2:
4
    print(ucenik1, "ide pre", ucenik2)
5
else:
6
    print(ucenik1, "ide pre", ucenik2)
7
(лексикографски1)
1
ucenik1 = input("Unesi prezime prvog ucenika (koristi samo engleske karaktere):")
2
ucenik2 = input("Unesi prezime drugog ucenika (koristi samo engleske karaktere):")
3
print(min(ucenik1, ucenik2), "ide pre", min(ucenik1, ucenik2))
4
(лексикографски2)

Парност броја

Напиши програм који испитује да ли је унети број паран или непаран.
Проверу да ли је један број дељив другим можемо извршити тако што израчунамо остатак при дељењу и упоредимо га са нулом. Подсетимо се, о целобројном дељењу је већ било речи у глави о дељењу и тада смо рекли да се остатак може израчунати коришћењем оператора %.
1
broj = 17
2
if broj % 2 == 0:
3
    print("Broj je paran")
4
else:
5
    print("Broj je neparan")
6
(паран_непаран)

Логичке вредности

Променљива може да садржи и истинитосне вредности (кажемо и логичке вредности или исказне вредности) тачно тј. True и нетачно тј. False (обрати пажњу на велико почетно слово). Променљиве чије су вредности истинитосне се кажу да су логичке или буловске (тј. да су типа bool - у част великог математичара Џорџа Була који је први увео математички рачун над истинитосним вредностима).
1
pada_kisa = True
2
if pada_kisa:
3
    print("Ponesi kišobran")
4
else:
5
    print("Ne moraš da nosiš kišobran")
6
(киша)
Ако у претходном програму у првом реду уместо вредности True поставиш вредност False, добићеш другачију поруку након покретања програма.
Истинитосна вредност може бити додељена и као резултат неког поређења (релације). На пример.
1
x = int(input("Unesi broj:"))
2
pozitivan = x > 0     # tačno ako je x > 0, tj. netačno, u suprotnom
3
if pozitivan:
4
    print("Uneti broj je pozitivan")
5
(позитиван)
Дужи начин да се променљивој додели истинитосна вредност је да се употреби гранање и константе True и False.
1
x = int(input("Unesi broj:"))
2
3
if x > 0:
4
    pozitivan = True
5
else:
6
    pozitivan = False
7
8
if pozitivan:
9
    print("Uneti broj je pozitivan")
10
(позитиван1)
Наравно, када год можемо користићемо краћи и једноставнији начин. Још једно место где ћемо често користити истинитосне вредности су функције које нешто испитују и враћају тачно или нетачно. На пример, можемо дефинисати функцију која проверава да ли је број позитиван.
1
def pozitivan(x):
2
    return x > 0
3
4
x = int(input("Unesi broj:"))
5
if pozitivan(x):
6
    print("Uneti broj je pozitivan")
7
(позитиван_функција)
Дужи начин да се ова функција дефинише је уз употребу гранања.
1
def pozitivan(x):
2
    if x > 0:
3
        return True
4
    else:
5
        return False
6
7
x = int(input("Unesi broj:"))
8
if pozitivan(x):
9
    print("Uneti broj je pozitivan")
10
(позитиван_функција_1)

Комбиновање више логичких услова (логички оператори)

Једноставнији услови се могу комбиновати. На пример, учитељица жели да поклони књигу свим оним ученицима који нису правили проблеме у владању током године и који су били одлични ђаци или су учествовали у украшавању учионице. Једноставније услове комбинујемо обично речима иили и не. Приметимо да је претходна реченица облика не услов1 и (услов2 или услов3), где је услов1 услов да је ученик правио проблеме, услов2 да је био одличан ђак, а услов3 да је учествовао у украшавању учионице.
  • Да би услов облика услов1 и услов2 био испуњен морају бити испуњена оба услова услов1 и услов2. На пример, да би реченица грмило је и севало била тачна, потребно је да је грмило и да је севало. Приметимо да реч и на неки начин одговара пресеку скупова о којем сте сигурно пуно учили из математике. Реч и се у језику Python записује помоћу речи and.
  • Да би услов облика услов1 или услов2 био испуњен довољно је да је један од услова услов1 и услов2 буде испуњен. На пример, реченица „ићи ћу за викенд у позориште или у биоскоп” је тачна ако одеш само у позориште, само у биоскоп, али и ако одеш и у позориште и у биоскоп (постоји посебан облик „или-или” који забрањује да су оба услова испуњена, али њега нећемо детаљније разматрати). Реч или се у језику Python записује помоћу речи or.
  • Да би услов облика не услов био испуњен услов услов не сме бити испуњен. На пример, реченица „Данас не пада киша” је тачна само ако реченица „Данас пада киша” није тачна. Реч не се у језику Python записује помоћу речи not.
Веома често је потребно проверити да ли се број налази у неком интервалу (на пример, време је најпријатније ако је температура између 20 и 25 степени, тј. ако припада интервалу [20,25]). То се ради тако што се провери да је вредност већа од доње границе интервала и да је мања од горње границе интервала.
Често је нејасно да ли се границе интервала припадају интервалу или не. На пример, када кажемо између 20 и 25 степени, није јасно да ли ту подразумевамо и 20 и 25 степени, или не. Да би се разјаснило да ли крај припада интервалу користе се различите врсте заграда. Мале заграде (заграде ()) означавају отворене интервале којима крајеви не припадају, док средње заграде (заграде []) означавају завтворене интервале који садрже и своје крајеве. На пример, интервал [20,25] садржи и вредности 20 и 25, интервал (20,25) их не садржи, док интервал [20,25) садржи вредност 20, али не и 25. Са оваквим полуотвореним интервалима смо се већ срели код индексирања ниски и листа (подсетимо се, str[a:b] издваја све карактере из ниске са позиција из интервала [a,b), тј. карактере који почињу на позицији a, а завршавају се на позицији стриктно испред b).

Индекс телесне масе

Индекс телесне масе човека (енгл. body mass index, bmi) се дефинише као количник његове масе у килограмима и квадрата његове висине у метрима. Нормалним се сматра индекс телесне масе из (затвореног) интервала од 18,5kgm2 до 25 25kgm2. Да ли човек који је висок 180 центиметара и тежак 79 килограма нормалне дебљине?
1
masa = 79
2
visina = 180 / 100
3
bmi = masa / (visina * visina)
4
if 18.5 <= bmi and bmi <= 25:
5
    print("indeks telesne mase je u preporučenim granicama")
6
else:
7
    print("Masa treba da bude od", 18.5*visina*visina, "do", 25*visina*visina, "kg")
8
(bmi)

Кућни ред

Кућни ред забрањује прављење буке пре 6 часова и између 13 и 17 часова, и након 22 часа. Напиши програм који радницима говори да ли у неком датом тренутку могу да изводе бучније радове.
../_images/kucni-red.jpg
Сматраћемо да су ови интервали полуотворени тј. да је дозвољено правити буку у интервалу [6,13) и [17,22) и у програму ћемо проверити да ли време припада неком од тих интервала.
1
sati = 15
2
minuta = 23
3
if (sati >= 6 and sati < 13) or (sati >= 17 and sati < 22):
4
    print("Možete da izvodite bučnije radove")
5
else:
6
    print("Ne bi trebalo da izvodite bučnije radove")
7
(кућни_ред_1)
или
1
if not (sati < 6 or (13 <= sati and sati < 17) or sati >= 22):
2
    print("Možete da izvodite bučnije radove")
3
else:
4
    print("Ne bi trebalo da izvodite bučnije radove")
5
(кућни_ред_2)

Преступна година

Година је преступна ако је дељива са 4 и није дељива са 100 или је дељива са 400. Напиши функцију која проверава да ли је година преступна.
../_images/prestupna.jpg
Овако уведен систем преступних година уводи тачно 97 преступних година на сваких 400 година. Тиме је време једне године тачно (97 × 366 + 303 × 365) / 400 = 365,2425 дана, што је прилично добра процена вредности 365,242374, коју астрономи обично узимају за трајање године.
Подсетимо се, проверу да ли је број дељив другим бројем можеш извршити тако што израчунаш остатак при дељењу (коришћењем оператора %) и провериш да ли је он једнак нули. На пример, проверу да ли је година дељива са 4 можеш извршити изразом godina % 4 == 0.
1
def prestupna(godina):
2
    return True
3
(преступна_година)

Предност у превозу

Предност у превозу имају труднице, деца млађа од 7 година и старији од 65 година. Допуни програм који испитује да ли особа има предност (параметар godine садржи број година, а параметар trudnica има вредност true ако је особа трудница, односно false у супротном).
1
def prednost(godine, trudnica)
2
    return True
3
(предност_у_превозу)

Конструкција elif

Прикажимо употребу конструкције elif кроз следећи задатак.

Агрегатно стање воде

Напиши програм који за дату температуру воде (у степеним Целзијуса) одређује њено агрегатно стање (сматраћемо да је вода у чврстом стању ако јој је температура строго мања од 0, да је у течном ако јој је температура између 0 и 100 степени, укључујући и те границе и да је у гасовитом стању ако јој је температура строго већа од 100 степени).
../_images/stanje-vode.png
На основу услова задатка може се формирати програм у којем се помоћу три провере услова независно проверава припадност температуре једном од три интервала (,0](0,100) и [100,).
1
temperatura = 15
2
3
if temperatura < 0:
4
    stanje = "čvrsto"
5
if temperatura >= 0 and temperatura <= 100:
6
    stanje = "tečno"
7
if temperatura > 100:
8
    stanje = "gasovito"
9
(агрегатно_стање_1)
Међутим, решење се може креирати и ако размишљамо на следећи начин (тако да логички услови буду међусобно зависни):
  • ако температура мања од 0C - агрегатно стање је чврсто;
  • у противном (температура је већа или једнака 0C): ако је температура мања или једнака 100C (припада другом интервалу) - агрегатно стање je течно;
  • у противном (температура је већа 100C) агрегатно стање је гасовито.
Такво постпуно проверавање услова се остварује помоћу конструкције elif.
1
temperatura = 15
2
3
if temperatura < 0:
4
    stanje = "čvrsto"
5
elif temperatura <= 100:
6
    stanje = "tečno"
7
else:
8
    stanje = "gasovito"
9
10
print(stanje)
11
(агрегатно_стање_2)
У општем случају, општи облик ове конструкције је следећи:
1
if uslov_1:
2
    naredbe
3
elif uslov_2:
4
    naredbe
5
...
6
elif uslov_k:
7
    naredbe
8
else:
9
    naredbe
10
(elif)
Прва група наредби се извршава ако је први услов испуњен, друга ако први није испуњен а други јесте, трећа ако прва два услова нису испуњена, а трећи јесте и тако даље, све до последње групе наредби која се извршава ако ниједан од наведених услова није испуњен. Приметимо да се увек извршава тачно један блок наредби у наведеном коду.
Приметимо да је срж следећег задатка била у томе да се одреди којем од неколико надовезаних интервала припада дата вредност (то су били интервали (,0)[0,100] и (100,+)). Задаци тог облика су чести и када је таквих интервала мало, обично се решавају конструкцијом elif. И следећи задатак је тог типа.

Број потеза краља

Позиције на шаховској табли се обележавају, на пример, са a3b5h1 и слично. Прво се наводи словна ознака колоне (од a до h), а затим бројевна ознака врсте (од 1 до 8). Ако је дата позиција краља на шаховској табли на којој нема других фигура осим тог краља, напиши програм који одређује број потеза које тај краљ може да направи (краљ се у шаху може померити на било које њему суседно поље).
Постоје три различите врсте поља. Поља у угловима табле (поља a1a8h1 и h8) су таква да краљ може да се помери на само три околне позиције. Поља која су на ивицама (у колонама a или h тј. у врстама 1 или 8), али нису у угловима су таква да краљ може да се помери на пет околних позиција. Са осталих поља краљ може да се помери на осам суседних позиција.
1
kralj = input("Unesi poziciju kralja:")
2
kolona = kralj[0]
3
vrsta  = kralj[1]
4
kolona_na_ivici = kolona == "a" or kolona == "h"
5
vrsta_na_ivici  = vrsta == "1" or vrsta == "8"
6
if True:  # ispravi ovaj red
7
    broj_poteza = 3
8
elif True:  # ispravi ovaj red
9
    broj_poteza = 5
10
else:
11
    broj_poteza = 0   # ispravi ovaj red
12
print(broj_poteza)
13
(краљ_број_потеза)

Домаћи задатак

Ево и неколико задатака које можеш урадити за домаћи.

Килобајт

Напиши програм који проверава да ли је корисник научио колико бајтова постоји у једном килобајту.
../_images/bits_bytes.jpg
1
odgovor = int(input("Koliko bajtova ima u jednom kilobajtu"))
2
if True:  # popravi ovaj uslov
3
    print("Bravo")
4
else:
5
    print("Odgovor nije tačan")
6
(бајтова_у_килобајту)
Q-9: Који од наредних услова треба употребити у претходном програму?





Жупан или краљ

Стефан Немањић је био Велики жупан од 1196 до 1217, а краљ од 1217 до 1228. Да ли је дуже владао као краљ или Велики жупан?
../_images/stefan_nemanjic.jpg
1
zupan = 0   # ispravi ovaj red
2
kralj = 0   # ispravi ovaj red
3
if zupan < kralj:
4
print("Дуже је био краљ.")     # ispravi ovaj red
5
else:
6
print("Дуже је био жупан.")    # ispravi ovaj red
7
(жупан_краљ)

Оцена на факултету

На факултету се оцена одређује на основу броја поена на следећи начин. За 50 поена и мање добија се оцена 5, за поене од 51 до 60 добија се оцена 6, од 61 до 70 оцена 7, од 71 до 80 оцена 8, од 81 до 90 оцена 9 и за поене од 91 до 100 добија се оцена 10. Напиши програм који за дати број поена одређује оцену.
../_images/indeks.jpg
1
poeni = int(input("Unesi broj poena:"))
2
3
if poeni < 51:
4
    ocena = 5
5
elif True:      # ispravi ovaj red
6
    ocena = 6
7
elif True:      # ispravi ovaj red
8
    ocena = 7
9
elif poeni < 81:
10
    ocena = 0   # ispravi ovaj red
11
elif True:      # ispravi ovaj red
12
    ocena = 9
13
else:
14
    ocena = 0    # ispravi ovaj red
15
16
print(ocena)
17
(оцена_на_основу_поена)
Рецимо и да смо овај задатак могли решити уз помоћ мало математике, без гранања.
1
poeni = int(input("Unesi broj poena:"))
2
ocena = (poeni - 1) // 10 + 1
3
print(ocena)
4
(оцена_на_основу_поена_без_гранања)

Потези фигура у шаху

Краљ у шаху може да се помера само једно поље (на било које од могућих 8 суседних поља). Топ у шаху може да се помера вертикално или хоризонтално, било који број поља. Ловац у шаху може да се помера дијагонално, било који број поља. Краљица може да се помера хоризонтално, вертикално или дијагонално, било који број поља. Коњ се помера тако што иде два поља вертикално и једно поље хоризонтално или два поља хоризонтално и једно поље вертикално. Са сваку од описаних шаховских фигура дефиниши функцију која за дата два поља на шаховској табли (одређена својим координатама) одређује да ли фигура на празној табли може да стигне са првог на друго поље.
../_images/sahovske_figure.jpg
Први услов је да полазно поље мора бити различито од долазног. Ако су дата поља са координатама (x1, y1) и (x2, y2), овај се услов просто може проверити помоћу (x1, y1) != (x2, y2). Други начин не користи парове и захтева да је бар једна од две координате различита тј. да важи x1 != x2 or y1 != y2.
Већина провера се може засновати на анализи хоризонталног и вертикалног растојања између два поља. Када смо разматрали апсолутну вредност рекли смо да се растојање између два броја може једноставно израчунати као апсолутна вредност њихове разлике. Тако, , хоризонтално растојање можемо одредити помоћу abs(x1 - x2), док вертикално растојање можемо одредити помоћу abs(y1 - y2).
  • Краљ се може померити ако је веће од ова два растојања једнако тачно 1 (тада је растојање по једној координати 1, а по другој 0 или 1, што је тачно услов померања краља).
  • Топ се може померити ако полазно и долазно поље имају исту координату x или исту координату y (обе координате не смеју бити једнаке јер би тада полазно и долазно поље било исто).
  • Ловац се може померити ако два поља леже на истој дијагонали. Овај се критеријум може проверити тако што се утврди да је хоризонтално растојање између два поља једнако њиховом вертикалном растојању (у сваком дијагоналном кораку се та растојања умањују за 1, све док се не стигне до долазног поља када оба та растојања истовремено постају нула, што значи да су у почетку морала бити једнака).
  • Проверу за краљицу можеш извршити тако што ћеш искомбиновати две већ направљене провере (ону за топа и ловца).
  • На крају, проверу за коња можеш извршити тако што ћеш проверити да ли је хоризонтално растојање једнако 2, а вертикално 1 или је хоризонтално растојање једнако 1, а вертикално 2.
Имајући претходну анализу у виду, покушај да дефинишеш функције које проверавају доступност поља. Када покренеш програм видећеш све потезе које свака од фигура може да направи са датог поља, на основу чега ћеш видети да ли је твоје решење исправно.
1
def kralj(x1, y1, x2, y2):
2
    return False
3
4
def top(x1, y1, x2, y2):
5
    return False
6
7
def lovac(x1, y1, x2, y2):
8
    return False
9
10
def kraljica(x1, y1, x2, y2):
11
    return False
12
13
def konj(x1, y1, x2, y2):
14
    return False
15
16
polje = (3, 5)
17
(шаховске_фигуре)
 

No comments:

Post a Comment

Prvi Razred                                               Drugi razred