Pogojni stavki

Sledijo zapiski predavanj prof. Demšarja. Najnovejšo verzijo zapiskov dobite na spletni učilnici.

Začnimo s preprostim programom za izračun indeksa telesne teže.

teza = float(input("Teža: "))
visina = float(input("Telesna višina: "))
bmi = teza / visina ** 2
print("Indeks vaše telesne teže je", bmi)

Želimo si, da bi program povedal še, ali je uporabnik slučajno preobilen. Prvi, seveda napačni poskus, bi bil takšen.

teza = float(input("Teža: "))
visina = float(input("Telesna višina: "))
bmi = teza / visina ** 2
print("Indeks vaše telesne teže je", bmi)
print("Potrebno bo shujšati!")

Program v tej obliki bi, v širši rabi, povzročal anoreksijo, saj vse po vrsti pošilja na hujšanje. Zadnjo vrstico, izpis poziva k hujšanju, mora izvesti le, če je bmi večji od 25 (ta meja namreč velja za mejo debelosti, oziroma, politično korektno, prekomerne telesne teže).

To storimo tako, da pred vrstico dodamo pogoj. Ta se glasi "če bmi > 25", le v angleščini.

teza = float(input("Teža: "))
visina = float(input("Telesna višina: "))
bmi = teza / visina ** 2
print("Indeks vaše telesne teže je", bmi)
if bmi > 25:
    print("Potrebno bo shujšati!")

Ne spreglejmo dveh pomembnih reči. Prva: na konec pogoja smo postavili dvopičje. To ne služi le za okras: dvopičja ne smemo izpustiti. Python na tem mestu zahteva dvopičje.

Druga: za if-om sem vrstico nekoliko zamaknil. Obilajno je zamik štiri presledke. Ni obvezno, a če boste uporabljali štiri presledke, boste pisali enako kodo kot drugi. In nikoli nikoli ne uporabljajte tabulatorjev, ti naredijo zmedo!

Zamaknjenih vrstic bi lahko bilo še več. Vse se izvedejo le, če je pogoj izpolnjen.

teza = float(input("Teža: "))
visina = float(input("Telesna višina: "))
bmi = teza / visina ** 2
print("Indeks vaše telesne teže je", bmi)
if bmi > 25:
    print("Potrebno bo shujšati!")
    print("Da, gospod ali gospa, preveč vas je skupaj.")
print("Pregled je končan, oglasite se spet čez dva tedna.")

Tako kot smo zastavili zdaj, se printa, ki sta zamaknjena, izvedeta le, če je oseba preobilna. Zadnji print ni več znotraj pogoja, zato se izvede v vsakem primeru, za suhe in debele.

Program bi bil še bolj simpatičen, če bi tiste, ki niso predebeli, pohvalil.

teza = float(input("Teža: "))
visina = float(input("Telesna višina: "))
bmi = teza / visina ** 2
print("Indeks vaše telesne teže je", bmi)
if bmi > 25:
    print("Potrebno bo shujšati!")
    print("Da, gospod ali gospa, preveč vas je skupaj.")
else:
    print("Odlično, le še naprej jejte toliko kot doslej!")
print("Pregled je končan, oglasite se spet čez dva tedna.")

Pogojnemu stavku lahko sledi še else, ki vsebuje tisto, kar naj se zgodi, če pogoj ni izpolnjen.

Znotraj pogojnih stavkov seveda lahko pišemo tudi druge reči, ne le printov. Takole: uporabniki programa se bodo pogosto zmotili in namesto višine v metrih vpisali višino v centimetrih, zato jih bo program obtožil težke anoreksije. To lahko popravimo preprosto tako, da program še pred računanjem BMI preveri, ali je višina slučajno večja od, recimo, treh metrov. V tem primeru sklepa, da je uporabnik podal višino v centimetrih, zato številko, ki jo je vpisal uporabnik, deli s 100.

Začetek programa tako postane takšen.

teza = float(input("Teža: "))
visina = float(input("Telesna višina: "))
if visina > 3:
    visina = visina / 100
bmi = teza / visina ** 2

Še ena estetska zadeva: za dvopičjem vedno pojdite v novo vrsto. Kot boste zvedavi kmalu odkrili, Python sicer dovoli, da napišete tudi

if bmi > 25: print ("Potrebno bo shujšati")
vendar to vodi v nepregledne programe. To se ne dela.

Tule pa je še nekaj primerov napačno zamikanih programov.

if bmi > 25:
    print("Potrebno bo shujšati!")
  print("Da, gospod ali gospa, preveč vas je skupaj.")
else:
    print("Odlično, le še naprej jejte toliko kot doslej!")
print("Pregled je končan, oglasite se spet čez dva tedna.")

Tretja vrstica mora imeti enak zamik kot druga, sicer Python ne more vedeti, ali je še znotraj pogoja ali ne.

if bmi > 25:
    print("Potrebno bo shujšati!")
      print("Da, gospod ali gospa, preveč vas je skupaj.")
else:
    print("Odlično, le še naprej jejte toliko kot doslej!")
print("Pregled je končan, oglasite se spet čez dva tedna.")

Ne, tudi v to smer ne smemo. Tu se Python vpraša, zakaj je tretja vrstica zamaknjena še bolj kot druga - smo pozabili še kakšen pogoj ali kaj?

if bmi > 25:
print("Potrebno bo shujšati!")
print("Da, gospod ali gospa, preveč vas je skupaj.")

Blok za stavkom if mora biti zamaknjen.

if bmi > 25:
    print("Potrebno bo shujšati!")
    print("Da, gospod ali gospa, preveč vas je skupaj.")
  else:
    print("Odlično, le še naprej jejte toliko kot doslej!")
print("Pregled je končan, oglasite se spet čez dva tedna.")

if in else morata biti poravnana. Kmalu bomo videli programe z več ifi in elsei; zamiki bodo potrebni, da bomo vedeli, kateri else sodi h kateremu if.

Če poskušamo zagnati kateregakoli od naštetih programov, bo Python javil sintaktično napako. Za razliko od običajnih napak, ki jih boste delali, in ko bodo programi naredili vsaj nekaj malega in potem crknili, ta ne bo niti trznil, temveč kar takoj javil napako. Spodnji program pa je sintaktično pravilen. Python ga lahko izvede. Najbrž pa to ni to, kar smo hoteli, saj se zadnji print izvede le, če pogoj ni izpolnjen.

if bmi > 25:
    print("Potrebno bo shujšati!")
  print("Da, gospod ali gospa, preveč vas je skupaj.")
else:
    print("Odlično, le še naprej jejte toliko kot doslej!")
    print("Pregled je končan, oglasite se spet čez dva tedna.")

Gnezdeni pogoji

Do sem vse lepo in prav, vendar: kaj bomo z anoreksičnimi? Program bi jim mirno svetoval, naj še naprej jedo toliko kot doslej (torej: premalo). Ne: pri takšnih, ki imajo BMI manjši od 18.5, moramo zastokati, naj vendar že začnejo jesti.

teza = float(input("Teža: "))
visina = float(input("Telesna višina: "))
bmi = teza / visina ** 2
print("Indeks vaše telesne teže je", bmi)
if bmi > 25:
    print("Potrebno bo shujšati!")
    print("Da, gospod ali gospa, preveč vas je skupaj.")
else:
    if bmi < 18.5:
        print("Trlica!")
        print("Zunaj so avtomati s sendviči in čokolado. Med pavzo si le postrezite!")
    else:
        print("Odlično, le še naprej jejte toliko kot doslej!")
print("Pregled je končan, oglasite se spet čez dva tedna.")

Vidimo? Znotraj ifa ali elsea smemo ugnezditi nov pogoj. Zamikamo ga lepo naprej.

Da bodo reči še nekoliko daljše (a poučnejše), dodajmo še en print.

teza = float(input("Teža: "))
visina = float(input("Telesna višina: "))
bmi = teza / visina ** 2
print("Indeks vaše telesne teže je", bmi)
if bmi > 25:
    print("Potrebno bo shujšati!")
    print("Da, gospod ali gospa, preveč vas je skupaj.")
else:
    print("Predebeli ravno niste.")
    if bmi < 18.5:
        print("Trlica!")
        print("Zunaj so avtomati s sendviči in čokolado. Med pavzo si le postrezite!")
    else:
        print("Odlično, le še naprej jejte toliko kot doslej!")
print("Pregled je končan, oglasite se spet čez dva tedna.")

Zdaj program vsem, ki niso predebeli, napiše dobro novico, da niso predebeli. Šele nato se loti preverjanja, da niso slučajno presuhi.

Tule mimogrede (prvič - a še velikokrat bomo) posvarimo pred ponavljanjem kode. Gornji program bi lahko napisali tudi tako:

teza = float(input("Teža: "))
visina = float(input("Telesna višina: "))
bmi = teza / visina ** 2
print("Indeks vaše telesne teže je", bmi)
if bmi > 25:
    print("Potrebno bo shujšati!")
    print("Da, gospod ali gospa, preveč vas je skupaj.")
else:
    if bmi < 18.5:
        print("Predebeli ravno niste.")
        print("Trlica!")
        print("Zunaj so avtomati s sendviči in čokolado. Med pavzo si le postrezite!")
    else:
        print("Predebeli ravno niste.")
        print("Odlično, le še naprej jejte toliko kot doslej!")
print("Pregled je končan, oglasite se spet čez dva tedna.")

Ali celo tako.

teza = float(input("Teža: "))
visina = float(input("Telesna višina: "))
bmi = teza / visina ** 2
print("Indeks vaše telesne teže je", bmi)
if bmi > 25:
    print("Potrebno bo shujšati!")
    print("Da, gospod ali gospa, preveč vas je skupaj.")
    print("Pregled je končan, oglasite se spet čez dva tedna.")
else:
    if bmi < 18.5:
        print("Predebeli ravno niste.")
        print("Trlica!")
        print("Zunaj so avtomati s sendviči in čokolado. Med pavzo si le postrezite!")
        print("Pregled je končan, oglasite se spet čez dva tedna.")
    else:
        print("Predebeli ravno niste.")
        print("Odlično, le še naprej jejte toliko kot doslej!")
        print("Pregled je končan, oglasite se spet čez dva tedna.")

To ni dobra ideja, ker je program daljši, manj pregleden, težje mu je slediti, težje ga je spreminjati... Vedno se izogibajte ponavljanju. Več o tem pa čez dva ali tri tedne.

Sicerče

Da se ne izgubimo, spet malo skrajšajmo program.

teza = float(input("Teža: "))
visina = float(input("Telesna višina: "))
bmi = teza / visina ** 2
print("Indeks vaše telesne teže je", bmi)
if bmi > 25:
    print("Potrebno bo shujšati!")
else:
    if bmi < 18.5:
        print("Trlica!")
    else:
        print("Odlično, le še naprej jejte toliko kot doslej!")

Pogojni stavki se nam lahko hitro zagnezdijo precej globoko in vrstice zbežijo nekam daleč proti desni. (Da ne govorimo o tem, da pogojni stavki niso niti približno edina reč, za katero bomo morali zamikati vrstice.) Ker so situacija, kakršna je zgornja, kar pogoste, imajo nekateri programski jeziki - in Python je med njimi - poleg if in else še elseif oziroma elif. (Še ena rezervirana beseda!) V Pythonu se uporablja slednja različica, elif. V gornjem programu ga uporabimo takole:

teza = float(input("Teža: "))
visina = float(input("Telesna višina: "))
bmi = teza / visina ** 2
print("Indeks vaše telesne teže je", bmi)
if bmi > 25:
    print("Potrebno bo shujšati!")
elif bmi < 18.5:
    print("Trlica!")
else:
    print("Odlično, le še naprej jejte toliko kot doslej!")

Program se zdaj prebere še lepše kot prej: če je BMI prevelik, pozovemo k hujšanju, sicerče je premajhen, ozmerjamo dotično najstnico s trlico, sicer pa izrečemo pohvalo.

Po izkušnjah je elif za študente huda, nenavadna skušnjava: nekateri ga pogosto uporabljajo namesto elsea. Recimo, da bi hoteli sprogramirati skrajšano pesimistično različico, po kateri so vsi, ki niso debeluhi, trlice. Radi bi torej tole:

if bmi > 25:
    print("Potrebno bo shujšati!")
else:
    print("Trlica!")

Mnogi bi (iz meni neznanega razloga) naredili takole:

if bmi > 25:
    print("Potrebno bo shujšati!")
elif bmi < 25:
    print("Trlica!")

Python ni pozabil ifa in bo tudi, če napišemo le else, čisto dobro vedel, kakšen je pogoj zanj. Drugi pogoj je nepotreben; če bmi ni večji od 25, je pač očitno manjši.

Torej: ne zamenjujte else brez potrebe z elif.

Mimogrede, program ne izpiše ničesar za tiste, ki imajo BMI natančno 25. Drugi pogoj, če ga res hočemo imeti, bi se moral vprašati, ali je bmi manjši ali enak 25.