Med nalogami iz prejšnje "lekcije" je bila ena na temo računanja poprečne teže treh oseb, Ane, Berte in Cilke. Če vzamemo, da imamo šest oseb in če izpustimo vnašanje podatkov, bi lahko bil program tak.

anze = 74 benjamin = 82 cilka = 58 dani = 66 eva = 61 franc = 84 print("Poprečna teža znaša", (anze + benjamin + cilka + dani + eva + franc) / 6.0)

To ni posebej praktično. Če bi morali namesto tega poiskati najtežjo osebo, bi bil program že naravnost odvraten.

najlazji = anze if benjamin < najlazji: najlazji = benjamin if cilka < najlazji: najlazji = cilka if dani < najlazji: najlazji = dani if eva < najlazji: najlazji = eva if franc < najlazji: najlazji = franc print("Najlazji student(-ka) ima", najlazji, "kilogramov.")

Če bi imeli teže stotih ljudi ... ne, tako ne gre.

Povejmo po domače: pripraviti bi morali seznam tež vseh študentov in seštevati stvari s seznama, iskati največjo stvar na seznamu... in tako naprej. V resnici pravzaprav niti nismo povedali po "kar tako, po domače", tudi v resnici naredimo natančno to.

Seznami

Seznam tež zapišemo takole:

teze = [74, 82, 58, 66, 61, 84]

Seznam (angl. list) v resnici nekoliko spominja na niz: niz je zaporedje znakov, ki ga zapišemo tako, da ga zapremo v narekovaje. Seznam je zaporedje česarkoli, recimo števil, lahko pa tudi česa drugega. Števila ali kaj drugega naštejemo, vmes pišemo vejice in vse skupaj zapremo v oglate oklepaje ([ in ]). Za primer sestavimo še seznam imen študentov

imena = ["Anže", "Benjamin", "Cilka", "Dani", "Eva", "Franc"]

in seznam, ki bo povedal, ali gre za študenta ali študentko

studentka = [False, False, True, False, True, False]

S seznami se da delati ogromno reči. Nek drug pomemben jezik, Lisp, tako temelji na seznamih, da je po njih dobil celo ime (list processor). Tu jih bomo spoznali samo v povezavi z zanko for.

Zanka for

Python ima dve vrsti zank: zanki while dela družbo for. Medtem ko while nekaj počne, dokler velja določen pogoj, je for veliko preprostejša.

Zastavimo si preprosto (in ne čisto smiselno) nalogo: izpišimo teže in kvadrate tež vseh študentov na seznamu. Se pravi (po slovensko)

za vsako težo s seznama teže stori tole: izpiši težo in težo na kvadrat

V Pythonu pa prav tako, samo brez sklonov:

for teza in teze: print(teza, teza ** 2)

V zanki for se skriva prirejanje. Zanka najprej priredi spremenljivki teza prvi element seznama teze. Nato se izvrši vsa koda bloka znotraj bloka for - tako, kot se je dogajalo v zanki while. V naslednji rundi priredi spremenljivki teza drugi element in spet izvede kodo znotraj bloka, ... ter tako naprej do konca seznama.

Zdaj pa izpišimo vse teže, ki so večje od 70.

for teza in teze: if teza > 70: print(teza)

Napišimo program, ki pove, kako težak je najlažji študent.

najlazji = 1000 for teza in teze: if teza < najlazji: najlazji = teza print(najlazji)

Je potrebno prevesti v slovenščino? Pa dajmo.

za začetek naj bo najlažja teža 1000 (gotovo bomo kasneje našli koga lažjega) za vsako težo iz seznama tež: če je teža manjša od najmanjše doslej: najlažja je ta teža izpiši najmanjšo težo

Deluje ta program samo na seznamih števil? Ali pa bi znal poiskati tudi najmanjši niz? Kako pravzaprav primerjamo nize? Nize primerja, seveda, po abecedi. In, da, program deluje tudi na nizih, vrne "najmanjši" niz - prvi niz po abecedi.

Mimogrede, Python ima že vdelano funkcijo min, ki vrne najmanjši element seznama.

Kako bi izračunali vsoto elementov seznama?

s = 0 for teza in teze: s += teza

Pa poprečno vrednost? Za to moramo poznati dolžino seznama. Pove nam jo funkcija len (okrajšava za length, če ji kot argument podamo nek seznam).

s = 0 for teza in teze: s += teza s /= len(teze)

Samo... malo previdni moramo biti. Seznam bi lahko bil tudi prazen. Dogovorimo se, da bo poprečna vrednost v tem primeru 0. Pravilno delujoč program bi bil takšen.

s = 0 for teza in teze: s += teza if len(teze) > 0: s /= len(teze)

Štetje

Če hočemo šteti od 10 do 20, to naredimo - še znamo? - z zanko while.

i = 10 while i <= 20: print(i) i = i + 1

Tole je malček nerodno. Štetje je tako pogosta reč, da bi bilo koristno, če bi obstajala zanj bližnjica. In seveda obstaja. Funkcija range(10, 20) sestavi seznam števil od 10 do 19. Hmnja, ja. Spodnja meja je vključena, zgornja ne. Če hočemo od 10 do 20, moramo uporabiti range(10, 21). (Čemu služi ta nekonsistentnost? V resnici je zelo uporabna. To je ena boljših stvari v Pythonu. Razlaga, zakaj je to tako super, pa bi spet presegala čas našega druženja.)

Če bi torej hoteli izpisati števila od 10 do 20, bi to z zanko for naredil takole:

for i in range(10, 21): print(i)

Po slovensko: za vsako število i od 10 do 21 naredi tole: izpiši ga.

Ker pogosto štejemo od 0, imamo za to bližnjico. Namesto, recimo, range(0, 8) pišemo kar range(8). Tako bo

for i in range(8): print(i)

izpisal števila od 0 do 7. Torej 8 števil. Velikokrat štejemo tudi le zato, da nekaj ponovimo toliko in tolikokrat. Samega "števca", i, niti ne potrebujemo. Tako bi, recimo

for i in range(8): print("Ana")

osemkrat napisal Ana.

Iskanje po seznamih

Za konec tega bežnega srečanja z zankami, spoznajmo nekaj, kar brucom programiranja pogosto dela težave - gre pa za lep primer tega, kako mora vrteti svoje misli programer.

Lihi - sodi

Kako bi ugotovili, ali vsebuje seznam kako sodo število? Tako kot prej si bomo izmislili seznam nekih števil (in program preskušali tako, da ga bomo spreminjali).

s = [6, 8, 42, 5, 12, 13] imamo_sodo = False for teza in teze: if teza % 2 == 0: imamo_sodo = True if imamo_sodo: print("Seznam vsebuje sodo število") else: print("Seznam ne vsebuje sodega števila")

V začetku si rečemo, da nimamo nobenega sodega števila. Nato gremo prek vseh števil in čim naletimo na kakega sodega, zabeležimo, da smo, aleluja, našli sodo število.

Ne naredite klasične napake. Tole je narobe:

s = [6, 8, 42, 5, 12, 13] imamo_sodo = False for teza in teze: if teza % 2 == 0: imamo_sodo = True else: imamo_sodo = False if imamo_sodo: print("Seznam vsebuje sodo število") else: print("Seznam ne vsebuje sodega števila")

Ta program se bo ob vsakem lihem številu delal, da doslej ni bilo še nobenega sodega - zaradi imamo_sodo = False bo pozabil, da je kdajkoli videl kako sodo število. V gornjem seznamu bo, recimo, pregledal vsa števila, končal bo s 13 in si ob tem rekel imamo_sodo = False. Rezultat bo tako napačen.

Kako pa ugotovimo, ali ima seznam sama soda števila?

sama_soda = True for teza in teze: if teza % 2 != 0: sama_soda = False if sama_soda: print("Seznam vsebuje sodo število") else: print("Seznam ne vsebuje sodega števila")

Spet bomo naredili podobno napako kot prej, če bomo pisali

s = [1, 3, 5, 7, 9, 42] sama_soda = True for teza in teze: if teza % 2 != 0: sama_soda = False else: sama_soda = True if sama_soda: print("Seznam vsebuje sodo število") else: print("Seznam ne vsebuje sodega števila")

Program že takoj, ko vidi 1, ugotovi, da niso vsa števila v seznamu soda, in postavi sama_soda = False. Vendar melje seznam naprej in ob vsakem koraku znova nastavlja sama_soda. Ko pride do 42, postavi sama_soda na True. To pa je ravno zadnje število; sama_soda ostane True... pa smo tam.

Mimogrede, rezultat tega programa je znan že, čim naletimo na prvo liho število. Torej bi bilo čisto vseeno, če računalnik v tistem trenutku neha pregledovanje. To mu v resnici lahko naročimo.

sama_soda = True for teza in teze: if teza % 2 != 0: sama_soda = False break if sama_soda: print("Seznam vsebuje sodo število") else: print("Seznam ne vsebuje sodega števila")

Ukaz break pomeni, da želimo prekiniti zanko. Program skoči "ven" iz zanke in nadaljuje z izvajanjem ukazov, ki sledijo zanki.

Praštevila

Napisati želimo program, ki pove, ali je dano število praštevilo. Tole je zelo podobno programu, ki išče sama soda števila. Drugačen je le pogoj: namesto, da bi preverjali, ali je število deljiNaredili bi lahko takole:

n = int(input("Vpiši število")) je_prastevilo = True for i in range(2, n): if n % i == 0: je_prastevilo = False break if je_prastevilo: print(n, " je praštevilo.") else: print(n, " ni praštevilo.")

V začetku predpostavimo, da je število praštevilo (je_prastevilo = True). Nato gremo prek števil od 2 do n (for i in range(2, n)); če naletimo na delitelj števila, ki ga je vpisal uporabnik, (if n % i == 0) si zapomnimo, da to število ni praštevilo (je_prastevilo = False) in končamo zanko (break).

Povemo lahko celo, kateri je najmanjši delitelj tega števila.

n = int(input("Vpiši število")) for i in range(2, n): if n % i == 0: break if i == n - 1: print(n, "je praštevilo") else: print(n, "ni praštevilo, njegov najmanjši delitelj je", i)

Ko smo zanko prekinili, je i ostal, kakršen je bil. Če je na koncu enak n-1, vemo, da se je zanka iztekla do konca, število n-1 pa navadno ni delitelj n-ja ... razen, če je n enak 2. No, v tem primeru je stvar še hujša: če je n enak 2, se zanka ne izvede in i sploh ni definiran. Naš program za 2 sploh ne deluje. Popravite ga sami. ;)

Last modified: Sunday, 25 October 2015, 6:43 PM