You are on page 1of 46

Python

Intermediate skripta
Uvod u srednji stupanj Python-a

Josip Katalinić

Zagreb, 2016.
Sadržaj
1. Dokumenti................................................................................................................................................. 3
1.1. Zapisivanje podataka u dokument...................................................................................................... 4
1.2. Čitanje podataka iz datoteke .............................................................................................................. 4
1.3. Čitanje linije po liniju ........................................................................................................................ 5
1.4. Konkatenacija nove linije stringu ...................................................................................................... 5
1.5. Čitanje stringa i micanje nove linije s kraja ....................................................................................... 6
1.6. Dodavanje podataka u postojeći dokument ....................................................................................... 6
1.7. Čitanje i zapisivanje numeričkih vrijednosti ...................................................................................... 7
1.8. Korištenje petlje za obadu datoteke ................................................................................................... 8
1.9. Čitanje dokumenta sa petljom i detektiranje kraja dokumenta .......................................................... 8
1.10. Korištenje for petlje za čitanje linija ................................................................................................ 9
2. Iznimke ..................................................................................................................................................... 9
2.1. TypeError iznimka ........................................................................................................................... 10
2.2. IOError iznimka ............................................................................................................................... 10
3. Liste ........................................................................................................................................................ 12
3.1. Uvod u liste ...................................................................................................................................... 12
3.2. Operator ponavljanja ........................................................................................................................ 12
3.3. Iteracija preko liste sa for petljom.................................................................................................... 13
3.4. Indeksiranje liste .............................................................................................................................. 13
3.5. Len funkcija ..................................................................................................................................... 13
3.6 Liste su promjenjive .......................................................................................................................... 14
3.7. Konkatenacija lista ........................................................................................................................... 14
3.8. List slicing........................................................................................................................................ 15
3.9. Pronalaženje elemenata u listi sa in operatorom .............................................................................. 15
3.10. Metode liste.................................................................................................................................... 16
4. Rječnici ................................................................................................................................................... 18
4.1. Kreiranje rječnika i operacije na rječnicima .................................................................................... 18
4.2. Miješanje tipova podataka u rječniku .............................................................................................. 19
4.3. Korištenje for petlje za iteraciju kroz rječnik................................................................................... 20
4.4. Metode rječnika ............................................................................................................................... 21
5. Klase i Objektno orijentirano programiranje .......................................................................................... 23
5.1 Klase ................................................................................................................................................. 23

1
Python_102
5.2 Definicija klase ................................................................................................................................. 23
5.3. Instance ............................................................................................................................................ 24
5.4. Pristup vrijednosti putem self .......................................................................................................... 25
5.5 __init__ ............................................................................................................................................. 27
5.6 Skrivanje atributa .............................................................................................................................. 28
5.7. Nasljeđivanje.................................................................................................................................... 29
6. Skupovi (sets).......................................................................................................................................... 30
6.1 Kreacija seta i operacije na setovima ................................................................................................ 30
7. Rekurzija ................................................................................................................................................. 35
7.1 Rješavanje problema uz pomoć rekurzije ......................................................................................... 36
8. Izgrađivanje programa kroz klase ........................................................................................................... 38
8.1 Postavljanje objekata kao argumenta ................................................................................................ 39
9. Serijalizacija Objekta .............................................................................................................................. 40
9.1. Deserijalizacija objekta .................................................................................................................... 41
10. Operator overloading ............................................................................................................................ 42
10.1. __sub__ .......................................................................................................................................... 42
10.2. __add__ .......................................................................................................................................... 43
10.3. __mul__ ......................................................................................................................................... 44
10.4. __div__ .......................................................................................................................................... 45

2
Python_102
1. Dokumenti
Kada program treba spremiti podatke za kasniju uporabu, zapisujemo podatke u dokument.

Generalno postoje dva tipa dokumenata: tekstualni i binarni.

Baviti ćemo se tekstualnim tipom dokumenata, u Python-u postoje dva načina pristupa spremljenim
podatcima unutar dokumenta:

a) sekvencijalni pristup dokumentu – gdje pristupamo podatcima od početka dokumenta, sve do kraja
dokumenta (ako želimo pristupiti podatku koji je na kraju dokumenta, moramo proći cijeli dokument)

b) direktni pristup dokumentu – gdje pristupamo podatcima tako da direktno odlazimo do željenog
podatka, bez potrebe za prolaženjem podataka koji su prije željenog podatka

Za usporedbu sekvencijalni pristup možemo promatrati kao kazetu koju premotavamo, gdje moramo
proći sve pjesme da bi došli do željene pjesme, dok direktni pristup bi odgovarao CD-u, gdje možemo
pristupiti bilo kojoj pjesmi bez potrebe prolaska pjesama koje su bile prije.

Tri koraka korištenja dokumenta:

1.) Otvaranje dokumenta

2.) Obrada podataka

3.) Zatvaranje dokumenta

Generalni format otvaranja dokumenta:

Dokument = open(naziv_dokumenta, mod)

Postoje 3 moda:

''r'' – otvara se dokument samo za čitanje, dokument se ne može izmijeniti, odnosno ne možemo
zapisati ništa u njega

''w'' – otvaramo dokument za zapisivanje, ako dokument već postoji izbrisati će se njegov sadržaj, ako ne
postoji kreiraj ga

''a'' – otvaramo dokument za zapisivanje, svi podatci zapisani u dokument će biti dodani na kraj
dokumenta, ako dokument ne postoji kreiraj ga

Da bi Python mogao raditi sa dokumentima na disku kompjutera, program mora kreirati tip podataka file
koji se asocirao sa dokumentom, tip podataka file možemo referencirati varijablom čime efektivno
referenciramo dokument.

3
Python_102
Npr. ukoliko kreiramo dokument vjezba.txt u istom folderu gdje nam je kreiran i .py program, možemo
ga otvoriti tako što koristimo:

vjezba_file = open('vjezba.txt', 'r')

print type(vjezba_file)

>> <type 'file'>

Također ukoliko .txt dokument nije u istom folderu gdje je kreiran .py program, možemo specificirati
putanju, npr. ukoliko se .txt nalazi na desktopu, a .py se nalazi na nekom drugom mjestu, putanju ćemo
pisati npr. :

vjezba_file = open(r'C:\Users\Korisnik\Desktop\vjezba', 'r')

print type(vjezba_file)

>> <type 'file'>

1.1. Zapisivanje podataka u dokument


Na varijablu koja referencira file tip podataka, pozivamo funkcije sa notacijom točke, koje se nazivaju
metodama, metoda write nam omogućuje zapisivanje podataka u dokument.

vjezba_file = open('naziv.txt', "w")

ime = "Pero"

vjezba_file.write("Peric\n")

vjezba_file.write(ime)

print type(vjezba_file)

vjezba_file.close()

1.2. Čitanje podataka iz datoteke


Uz pomoć metode read možemo pročitati podatke iz dokemenata

def main():

test_dok = open('naziv.txt', 'r')

procitano = test_dok.read()

test_dok.close()

print procitano

main()

4
Python_102
>> Pero

Peric

1.3. Čitanje linije po liniju


Uz pomoć metode readline možemo pročitati liniju iz dokumenta, linija u Pythonu je skup skringova koji
završavaju sa \n. Metoda readline vraća takav skup stringova zajedno sa \n.

def main():

test_dok = open('naziv.txt', 'r')

procitano1 = test_dok.readline()

procitano2 = test_dok.readline()

test_dok.close()

print procitano1

print procitano2

main()

>> Pero

Peric

1.4. Konkatenacija nove linije stringu


Često je potrebno kontaktenirati \n prije zapisivanja podatka

def main():

print "Unesi imena dvojice prijatelja"

prijatelj1 = raw_input("Prijatelj #1: ")

prijatelj2 = raw_input("Prijatelj #2: ")

prijatelji_dok = open('prijatelji.txt', 'w')

5
Python_102
prijatelji_dok.write(prijatelj1+"\n")

prijatelji_dok.write(prijatelj2+"\n")

prijatelji_dok.close()

print "Imena prijatelja su spremljena u prijatelji.txt"

main()

1.5. Čitanje stringa i micanje nove linije s kraja


Metoda rstrip, miče specificirane znakove sa kraja stringa, zove se tako jer miče s desne strane (r=right)

def main():

prijatelji_dok = open('prijatelji.txt', 'r')

linija1 = prijatelji_dok.readline()

linija2 = prijatelji_dok.readline()

prijatelji_dok.close()

print linija1.rstrip("\n")

print linija2.rstrip("\n")

main()

>> Pero

Mato

1.6. Dodavanje podataka u postojeći dokument


Postiže se append modom 'a', koji radi sljedeće:

- ako dokument postoji neće biti izbrisan, ako dokument ne postoji biti će kreiran

6
Python_102
- kada podatak zapisujemo u dokument, zapisat će se na kraju sadržaja dokumenta

def main():

prijatelji_dok = open('prijatelji.txt', 'a')

prijatelji_dok.write("Josip\n")

prijatelji_dok.write("Ivan\n")

prijatelji_dok.close()

main()

1.7. Čitanje i zapisivanje numeričkih vrijednosti


Stringovi se izravno zapisuju sa write metodom, dok se brojevi(int/float) se moraju cast u stringove prije
nego što mogu biti zapisani, tako npr. varijablu broj koja sadrži vrijednost int 99, možemo cast pomoću
str(broj) čime dobivamo string ''99''

def main():

dok = open('brojevi.txt', 'w')

br_1 = input("Unesi broj #1: ")

br_2 = input("Unesi broj #2: ")

dok.write(str(br_1) + "\n")

dok.write(str(br_2) + "\n")

dok.close()

print "Brojevi su zapisani u brojevi.txt"

7
Python_102
main()

1.8. Korištenje petlje za obadu datoteke


Datoteke obično sadrže veliku količinu podataka, te programi obično koriste petlju da bi obradili podatke
u datoteci.

def main():

br_dana = int(input("Koiko dana za redom imas rasprodaju: "))

br_dok = open("prodaja.txt", "w")

for broj in range(1, br_dana+1):

prodaja = float(input("Unesi prodaju za dan #"+\

str(broj)+": "))

br_dok.write(str(prodaja)+"\n")

br_dok.close()

print "Vrijednosti su sacuvane u prodaja.txt"

main()

1.9. Čitanje dokumenta sa petljom i detektiranje kraja dokumenta


Često program mora pročitati sadržaj dokumenta, a da prilikom toga ne zna broj predmeta koji su
pohranjeni u dokumentu. U Pythonu readline metoda vraća prazni string, ako pokuša pročitati izvan
kraja dokumenta.

def main():

prod_dok = open("prodaja.txt", "r")

linija = prod_dok.readline()

8
Python_102
while linija != "":

kolicina = float(linija)

print format(kolicina, ".2f")

linija = prod_dok.readline()

prod_dok.close()

main()

1.10. Korištenje for petlje za čitanje linija


Python omogućuje pisanje for petlje koja automatski čita liniju u dokumentu, bez testiranja nekog
posebnog uvjeta koji bi signalizirao kraj dokumenta.

def main():

prod_dok = open("prodaja.txt", "r")

for linija in prod_dok:

kolicina = float(linija)

print format(kolicina, ".2f")

prod_dok.close()

main()

2. Iznimke
Iznimka je error koji se događa dok je program pokrenut, te uzrokuje naglo zaustavljanje programa.
Možemo koristiti try/excet izjavu za rukovanje iznimkama.

Generalni format ty/except izjave:

try:

izjava Try blok može potencijalno izazvati iznimku

9
Python_102
izjava

except NazivIznimke:

izjava

izjava Except blok prihvaća definiranu iznimku, te nastavlja sa izvršavanjem bloka

2.1. TypeError iznimka


Jedan od čestih error-a je taj kada pokušamo konkatenirati string sa numeričkom vrijednosti:

ime = ''Pero''

godine = 25

print ime + godine

>> TypeError: cannot concatenate 'str' and 'int' objects

No sada možemo upozoriti korisnika kroz except navođenjem naziva iznimke, da konkatenacija mora sa
tipovima podataka string.

ime = "Pero"

godine = 25

try:

print ime + godine

except TypeError:

print "Konkatenacija je jedino moguća sa tipovima podataka string"

2.2. IOError iznimka

Ukoliko bi unijeli naziv dokumenta koji ne postoji dobili bi smo IOError.

def main():

naziv_dok = raw_input("Unesi naziv dokumenta: ")

10
Python_102
dok = open(naziv_dok, "r")

sadrzaj = dok.read()

print sadrzaj

dok.close()

main()

Već smo spomenuli, ukoliko bi unijeli naziv dokumenta koji ne postoji dobili bi IOError, no sada ga
možemo uhvatiti unutar except izjave, te ispisati da navedeni dokument ne postoji.

def main():

naziv_dok = raw_input("Unesi naziv dokumenta: ")

try:

dok = open(naziv_dok, "r")

sadrzaj = dok.read()

print sadrzaj

dok.close()

except IOError:

print "Dokument pod nazivom", naziv_dok, "ne postoji."

main()

11
Python_102
3. Liste
Sekvenca – drži višestruki broj podataka, poredanih jedan za drugim, na sekvencama se mogu provoditi
specifične operacije s kojima možemo ispitati i manipulirati svaki podatak.

Najpoznatija sekvenca je lista – promjenjiva sekvenca (program može mijenjati sadržaj)

Lista može sadržavati sekvence različitih tipova podataka.

3.1. Uvod u liste


Lista je tip podatka koji sadrži višestruki broj podataka, svaki podatak koji je pohranjen u listi se naziva
element.

Primjer liste sa 4 elementa tipa integer, koju smo pridružili varijabli godine:

godine = [25, 48, 39, 16]

Ukoliko lista sadrži samo jedan tip podataka, naziva se lista stringova, int-ova itd.

Budući da lista ima svojstvo prihvaćanja različitih tipova podatka, možemo napisati sljedeće:

godine = [''dvadeset i pet godina“, 48, 39.2, 16]

print godine

>> ['dvadeset i pet godina', 48, 39.2, 16]

Uz pomoć range funkcije možemo kreirati listu integera

brojevi = range(1,4+1)

print brojevi

> >[1, 2, 3, 4]

3.2. Operator ponavljanja


* - simbol koji označava množenje, no kada se lista nalazi s lijeve strane, te int sa desne strane, onda
znak množenja postaje operator ponavljanja, generalni format:

lista * n

brojevi [0] * 5

print brojevi

>>[0, 0, 0, 0, 0]

brojevi = [1, 2, 3] * 3

print brojevi

12
Python_102
>>[1, 2, 3, 1, 2, 3, 1, 2, 3]

3.3. Iteracija preko liste sa for petljom


def main():

brojevi = [1, 2, 3]

for i in brojevi:

print i

main()

>>1

3.4. Indeksiranje liste


Elementima liste također možemo pristupiti putem indeksa, svaki element u listi ima svoj indeks koji
specificira njegovu poziciju u listi, indeksi počinju od 0, tako da je prvi element 0, drugi 1 itd.

brojevi = [1, 2, 3]

print brojevi[0], brojevi[1], brojevi[2]

>>1 2 3

IndexError iznimka je pozvana ukoliko pozovemo nepostojeći indeks unutar liste

brojevi = [1, 2, 3]

print brojevi[3]

>>IndexError: list indeks out of range

3.5. Len funkcija


Python ima ugrađenu funkciju len koja vraća družinu sekvence poput liste

brojevi = [1, 2, 3]

len(brojevi)

>>3

- len funkcija se može koristiti da bi se zaustavila IndexError iznimka prilikom iteracije liste sa petljom.

13
Python_102
def main():

brojevi = [1, 2, 3]

index = 0

while index < len(brojevi):

print brojevi[index]

index+=1

main()

>> 1

3.6 Liste su promjenjive


Liste su promjenjive što znači da se njihovi elementi mogu izmjeniti

brojevi = [1, 2, 3]

brojevi[0] = 10

print brojevi

>> [10, 2, 3]

3.7. Konkatenacija lista


Konkatenacija znači povezivanje dviju stvari zajedno, te se koristi u kontekstu povezivanja stringova, no
možemo koristiti operator + da bi konkatenirali dvije liste.

lista1 = [1,2,3]

lista2 = [4,5,6]

lista3 = lista1+lista2

print lista3

>>[1, 2, 3, 4, 5, 6]

muska_imena = ["Pero", "Mato"]

zenska_imena = ["Marija", "Dora"]

sva_imena = muska_imena + zenska_imena

print sva_imena

14
Python_102
>>['Pero', 'Mato', 'Marija', 'Dora']

3.8. List slicing


Pomoću slicinga odabiremo dio elemenata iz sekvence, da bi primijenili slice na listu pišemo sljedeći
format:

naziv_liste[pocetak:kraj]

dani = ["Pon", "Uto", "Sri", "Cet", "Pet", "Sub", "Ned"]

vikendi = dani[5:7]

print vikendi

>>['Sub', 'Ned']

print dani[:]

>>['Pon', 'Uto', 'Sri', 'Cet', 'Pet', 'Sub', 'Ned']

print dani[:2]

>>['Pon', 'Uto']

print dani[2:]

>>['Sri', 'Cet', 'Pet', 'Sub', 'Ned']

print dani[1:8:2]

>>['Uto', 'Cet', 'Sub']

print dani[-1]

>>''Ned''

print dani[-2:]

>>['Sub', 'Ned']

print dani[:-2]

>>['Pon', 'Uto', 'Sri', 'Cet', 'Pet']

3.9. Pronalaženje elemenata u listi sa in operatorom


Ukoliko element postoji unutar liste in operator će vratiti True vrijedost.

dani = ["Pon", "Uto", "Sri", "Cet", "Pet", "Sub", "Ned"]

15
Python_102
print "Pon" in dani

print "Utorak" in dani

>>True

False

3.10. Metode liste


a) append(predmet) – najčešće korištena metoda, suži za dodavanje predmeta listi, predmet je poslan
kao argument te je dodan na kraj liste

brojevi = [1,2]

brojevi.append(3)

print brojevi

>>[1, 2, 3]

brojevi = [1,2]

brojevi.append("tri")

print brojevi

[1, 2, 'tri']

b) index(predmet) – vraća indeks prvog elementa čija je vrijednost jednaka predmetu

brojevi = [1,2]

print brojevi.index(1)

>>0

brojevi = [1,2]

print brojevi.index(2)

>>'0

c) insert(index, predmet) – insert stavlja određeni predmet na specificirani indeks, kada je predmet
stavljen u listu lista je proširena

brojevi = [1,2]

brojevi.insert(2,3)

print brojevi indeks

>> [1, 2, 3]

16
Python_102
brojevi = [1,2]

brojevi.insert(0,"jedan")

print brojevi

>> ['jedan', 1, 2]

d) sort() – sortira predmete u listi od najmanje do najveće vrijednosti

brojevi = [2,1]

brojevi.sort()

print brojevi

>> [1, 2]

imena = ["Mato", "Ana"]

imena.sort()

print imena

>> ['Ana', 'Mato']

e) remove(predmet) – uklanja prvo pojavljivanje predmeta iz liste, ValueError iznimka se poziva ukoliko
predmet nije nađen u listi

imena = ["Mato", "Ana"]

imena.remove("Ana")

print imena

>> ['Mato']

imena = ["Mato", "Ana"]

imena.remove("Ivo")

print imena

>> ValueError: list.remove(x): x not in list

17
Python_102
4. Rječnici
U Pythonu rječnik je objekt koji sprema kolekciju elemenata, svaki element koji je spremljen u rječniku
ima dva dijela, ključ i vrijednost, te se nazivaju ključ-vrijednost par.

4.1. Kreiranje rječnika i operacije na rječnicima


Rječnik se kreira u sljedećem formatu:

rječnik = {ključ:vrijednost}

S time da ključ mora biti jednostavan tip podatka (string, float, int, boolean).

telefonski_imenik = {"Pero":"019435", "Mato":"012432", "Ivo":"28636"}

Operacije na rječnicima

a) Vraćanje vrijednosti ključa se izvršava uz pomoć specificiranja ključa u formatu:

rječnik[ključ]

Tako npr. ukoliko želimo dobiti vrijednost telefonskog broja od Pere koristimo:

print telefonski_imenik["Pero"]

>>>019435

b) Koristeći in, kao i not in operator možemo testirati nalaze li se određene vrijednosti u rječniku.

telefonski_imenik = {"Pero":"019435", "Mato":"012432", "Ivo":"28636"}

if "Pero" in telefonski_imenik:

print telefonski_imenik["Pero"]

if "Marija" not in telefonski_imenik:

print "Marija nije u telefonskom imeniku"

c) Dodavanje elemenata u rječnik

Format dodavanja elemenata u rječnik je:

rječnik[ključ] = vrijednost

Tako da možemo dodati novi element u rječnik čiji ključ je ''Ivo'', te vrijednost ''012523''

telefonski_imenik = {"Pero":"019435", "Mato":"012432"}

18
Python_102
telefonski_imenik["Ivo"] = "012523"

print telefonski_imenik

>>>{"Pero":"019435", "Mato":"012432", "Ivo":"012523"}

d) Brisanje elemenata

Možemo izbrisati ključ-vrijednost par iz rječnika sa del izjavom, generalni format je:

del naziv_rječnika[ključ]

telefonski_imenik = {"Pero":"019435", "Mato":"012432"}

del telefonski_imenik["Pero"]

print telefonski_imenik

>>>{'Mato': '012432'}

if "Ivo" in telefonski_imenik:

del telefonski_imenik["Ivo"]

e) Dobivanje broja elemenata u rječniku

Uz pomoć len funkcije možemo dobiti broj elemenata u listi:

telefonski_imenik = {"Pero":"019435", "Mato":"012432"}

print len(telefonski_imenik)

>> 2

f) Kreiranje praznog rječnika

Prazni rječnik se kreira praznim vitičastim zagradama

telefonski_imenik = {}

telefonski_imenik[''Pero''] = ''019435''

4.2. Miješanje tipova podataka u rječniku


Dok ključevi moraju biti jedan od 4 jednostavna tipa podatka (string, float, int, boolean), njihove
vrijednosti mogu biti razni tipovi podatka.

19
Python_102
telefonski_imenik = {"Pero":3, 3.2:320, "Ivo":[25,1990,185]}

print telefonski_imenik["Ivo"]

>>> [25,1990,185]

print len(telefonski_imenik["Ivo"])

>>>3

zaposlenik = {"naziv":"Pero Peric", "oib":20363234, "placa":8900.00}

print zaposlenik["oib"]

>>>20363234

4.3. Korištenje for petlje za iteraciju kroz rječnik


Generalni format for petlje za iteraciju kroz sve ključeve u rječniku:

for kljuc in rjecnik:

izjava

izjava

telefonski_imenik = {"Pero":"019435", "Mato":"012432", "Ivo":"012523"}

for korisnik in telefonski_imenik:

print korisnik

>>>

Mato

Ivo

Pero

Ukoliko želimo prikazati ključeve i vrijednosti koristimo:

telefonski_imenik = {"Pero":"019435", "Mato":"012432", "Ivo":"012523"}

20
Python_102
for korisnik in telefonski_imenik:

print korisnik, telefonski_imenik[korisnik]

>>>

Mato 012432

Ivo 012523

Pero 019435

4.4. Metode rječnika


a) Clear metoda

Clear metoda briše sve elemente u rječniku ostavljajući rječnik praznim, generalni format je:

rječnik.clear()

telefonski_imenik = {"Pero":"019435", "Mato":"012432", "Ivo":"012523"}

telefonski_imenik.clear()

print telefonski_imenik

>>>{}

b) Get metoda

Get metoda se koristi kao alternativa [] operatoru za dobivanje vrijednosti na temelju ključa, s tim
ukoliko se ne nađe specificirani ključ, metoda ne izaziva iznimku već se ispisuje drugi argument metode,
generalni format

rječnik.get(ključ, ispis)

telefonski_imenik = {"Pero":"019435", "Mato":"012432", "Ivo":"012523"}

print telefonski_imenik.get("Pero", "Pero nije nadjen")

print telefonski_imenik.get("Luka", "Luka nije nadjen")

>>>

21
Python_102
019435

Luka nije nadjen

c) keys metoda

Keys metoda vraća sve ključeve rječnika u formatu liste

telefonski_imenik = {"Pero":"019435", "Mato":"012432", "Ivo":"012523"}

print telefonski_imenik.keys()

>>>

['Mato', 'Ivo', 'Pero']

d) pop metoda

Pop metoda vraća vrijednosti asocirane sa specifičnim ključevima i briše ključ-vrijednost par iz rječnika,
ako ključ nije nađen metoda ispisuje drugi argument, generalni format:

rječnik.pop(ključ, ispis)

telefonski_imenik = {"Pero":"019435", "Mato":"012432", "Ivo":"012523"}

izbrisani_pero = telefonski_imenik.pop("Pero", "Pero nije nadjen")

print telefonski_imenik

print izbrisani_pero

>>>

{'Mato': '012432', 'Ivo': '012523'}

019435

e) values metoda

Values metoda vraća sve vrijednosti u formatu liste

telefonski_imenik = {"Pero":"019435", "Mato":"012432", "Ivo":"012523"}

print telefonski_imenik.values()

>>>

['012432', '012523', '019435']

22
Python_102
5. Klase i Objektno orijentirano programiranje
Proceduralno programiranje je metoda pisanja softvera koja se bazira oko funkcija koje obavljaju
određeni zadatak npr. dobivanje inputa od korisnika, čitanje i zapisivanje u dokument, ispisivanje inputa
itd…

Proceduralno programiranje može dovesti do određenih problema, uzmimo za primjer rad na velikom
programu koji ima korisnike u bazi podataka, program je dizajniran da ima tri varijable ime, adresu i
telefonski broj. Naš posao bi bio napraviti funkcije koje pristupaju tim trima varijablama, te ovisno o
ulozi funkcije rade drugačije zadatke. Ovdje možemo uočiti jedan problem, ukoliko odlučimo da program
više neće imati tri varijable, već da će se podatci spremati unutar liste, morali bi izmijeniti svaku funkciju
gdje se pojavljuju varijable, da bi ih spremili unutar liste.

Dok se proceduralno programiranje centrira oko kreiranja procedura(funkcija), objektno orijentirano


programiranje (OOP) se centrira oko kreiranja objekata.

Objekt je softverski entitet koji sadrži podatke i procedure.

Podatak u objektu je poznat kao data atribut koji označava ništa druge nego varijable koji referenciraju
vrijednosti.

Procedure koji objekt izvršava zovu se metode, dok metode možemo gledati kao funkcije objekta koje
izvršavaju operacije na data atributima.

5.1 Klase
Programer odlučuje koji su mu atributi potrebi, kao i metode za specifičan objekt, te onda kreira klasu.

Klasu možemo promatrati kao nacrt kroz koji su objekti kreirani, kada koristimo takav jedan „nacrt“ da bi
izgradi objekt (npr. kuću), kažemo da izgrađujemo instancu kuće koja je opisana nacrtom.

Još jedan od primjera bi mogao poslužiti za opis razlike klase i objekta je kalup za kolače i sami kolač.
Kalup za kolače nije sami kolač, no opisuje kolač, također kalup za kolače može kreirati više instanci
kolača uz pomoć istog kalupa.

5.2 Definicija klase


Da bi kreirali klasu, pišemo definiciju klase, definicija klase je skup izjava koji definiraju metode i atribute
klase.

Generalni format definicije klase:

class NazivKlase:

atributi

metode

23
Python_102
Na primjer kreirajmo klasu Ime koja sadrži atribut naziv čija je vrijednost ''Pero'', te za zatim ispisuje

class Ime:

naziv = ''Pero''

print naziv

Ime()

>>Pero

U gornjem primjeru vidimo kreiranu klasu Ime, koja u svojoj definiciji sadrži atribut naziv koji je zatim
ispisan.

Nakon što je klasa Ime kreirana i definirana, pozivamo ju poput funkcije sa dvostrukim zagradama

Ime()

Čime dobivamo ispis atributa naziv ''Pero''

Kreirajmo klasu Voce koja sadrži metodu Naziv, te zatim ispisuje naziv voća

class Voce:

def Naziv(self, naziv_voca):

print naziv_voca

Voce().Naziv("Banana")

U ovom primjeru vidimo metodu Naziv koja sadrži 2 parametra, jedan obavezni self, i jedan proizvoljni
naziv_voca, nakon poziva klase Voce() sa notacijom točke smo pozvali metodu Naziv i predali joj
argument ''Banana'' koji je potom ispisan.

5.3. Instance
Instanca je individualni objekt određene klase.

Generali format kreiranja instance:

naziv_instance = naziv_klase()

24
Python_102
Uzmimo prijašnji primjer sa voćem i kreirajmo 2 instance, instancu banana i instancu mango.

class Voce:

def Naziv(self, naziv_voca):

print naziv_voca

banana = Voce()

mango = Voce()

banana.Naziv("Banana")

mango.Naziv("Mango")

Ovdje vidimo kreirane 2 instance, banana i mango. Nakon što su kreirane instance, preko njih možemo
pozvati metode koje sadrži klasa iz koje su instance kreirane. U našem primjeru na instanci banana
pozivamo metodu Naziv kojoj kao argument dajemo string ''Banana'', dok na instanci mango pozivamo
također metodu Naziv kojoj kao argument dajemo string ''Mango''

5.4. Pristup vrijednosti putem self


Self nam omogućava pristup vrijednostima klase, imajući ponašanje poput globalne varijable. Kroz 2
načina možemo pridružiti vrijednosti self-a:

a) Kao proizvoljno definirana self varijabla u tijelu metode, kojoj pridružujemo vrijednost parametra

Generalni format:

class Klasa:

def Metoda(self, parametar)

self.moja_varijabla = parametar

Kreirajmo klasu Ime koja ima dvije metode, Naziv i Ispis, te definirajmo proizvoljnu self varijablu ime,
kojoj će biti pridružena vrijednost parametra naziv unutar tijela metode Naziv. Zatim kroz metodu Ispis
koja sadrži obavezni parametar self, ispišimo našu ''globalnu'' varijablu self.ime

class Ime:

def Naziv(self, naziv):

self.ime = naziv

25
Python_102
def Ispis(self):

print self.ime

pero = Ime()

pero.Naziv("Pero")

pero.Ispis()

*U mnogim primjerima se često koristi isti naziv za self varijablu, kao i za parametar koji se pridružuje
self varijabli, tako umjesto self.ime = naziv, piše se self.naziv = naziv.

b) Kao proizvoljno definirana varijabla klase, kojoj možemo pristupiti putem self varijable, s time da self
varijabla ne može biti proizvoljna nego mora imati isto ime kao i varijabla klase na koju se poziva.

Generalni format:

class Klasa:

ime = "Pero" #varijabla klase ime

def Metoda(self):

self.ime = ''Mato'' #pristupili smo varijabli klase ime, te joj promijenili vrijednost u ''Mato''

Kreirajmo klasu Ime koja ima varijablu klase nadimak čija je vrijednost string ''Perica'', vrijednost
nadimak izmijenimo u tijelu metode Naziv u ''Perko'', te zatim ispišimo novu vrijednost varijable
nadimak

class Ime:

nadimak = "Perica"

def Naziv(self):

self.nadimak = "Perko"

print self.nadimak

pero = Ime()

pero.Naziv()

26
Python_102
5.5 __init__
__init__ (dva underscore s obje strane) označava inicijalizaciju, odnosno metoda sa nazivom __init__ će
biti automatski pozvan prilikom kreiranja instance klase, kao i prilikom poziva klase

class Hrana:

def __init__(self):

print "init je pozvan"

def Burek(self):

print "Burek"

burek = Hrana()

burek.Burek()

>>init je pozvan

>>Burek

Prilikom kreiranja instance hrana __init__ je pozvan te ispisuje ''init je pozvan''

__init__ nam također može poslužiti za promjenu vrijednosti varijabli klase

class Hrana:

prilog = "Vrhnje"

def __init__(self):

self.prilog = "Jogurt"

print "Nova vrijednost priloga"

def Burek(self):

print "Burek i", self.prilog

burek = Hrana()

burek.Burek()

27
Python_102
U ovom programu smo promijenili vrijednost varijable klase prilog koja ima string vrijednost ''Vrhnje'',
kroz __init__ u ''Jogurt''

5.6 Skrivanje atributa


Uzmimo primjer gdje vanjski kod (kod izvan klase) može pristupiti vrijednostima atributa (u našem
slučaju varijabla klase), te ih izmijeniti.

class Hrana:

prilog = "Vrhnje"

def Burek(self):

print self.prilog

burek = Hrana()

burek.prilog = "Jogurt"

burek.Burek()

>>Jogurt

U ovom programu smo promijenili vrijednost varijable klase u Jogurt, kroz instancu burek.

Ukoliko želimo učiniti atribute privatnim, na način da im te može pristupiti vanjski kod te izmijeniti
njihovu vrijednost to činimo dvostrukim underscore __

class Hrana:

__prilog = "Vrhnje"

def Burek(self):

print self.__prilog

burek = Hrana()

burek.prilog = "Jogurt"

burek.Burek()

>>Vrhnje

28
Python_102
5.7. Nasljeđivanje
Nasljeđivanje omogućuje proširivanje funkcionalnosti klase kroz prethodno kreirane klase.

Nasljeđivanje možemo promatrati kao odnosi, tako na primjer:

Njemački ovčar je pas, auto je vozilo, cvijet je biljka, trokut je oblik, nogometaš je sportaš…

Nasljeđivanje uključuje parent klasu i child klasu


a) parent klasa je generalna klasa
b) child klasa je specijalizirana klasa

Pod klasu možemo smatrati kao proširenom verzijom parent klase, child klasa nasljeđuje atribute i
metode iz parent klasa bez da ih moramo ponovno pisati.

Također novi atributi i metode mogu biti dodani u child klasu, te je to ono što ju čini specijaliziranom
verzijom child klase.

Generalni format:

class Child(Parent_klasa)

Tako na primjer možemo kreirati parent klasa Slatko koja ima metodu Secer koja ispisuje ''Secer'', te
child klasa Cokolada koja nasljeđuje atribute i metode iz parent klase Slatko.

class Slatko:

sastojak = "Kakao"

def Secer(self):

print "Secer", self.sastojak

class Cokolada(Slatko):

def Milka(self):

print "Milka"

29
Python_102
svizac = Cokolada()

svizac.Secer()

svizac.Milka()

Nakon što smo kreirali instancu na child klasi koja je naslijedila atribute i metode parent klase, možemo
pozvati sve metode parent klase.

6. Skupovi (sets)
Skup(set) sadrži kolekciju unikatnih vrijednosti, te ga shvaćamo poput matematičkih skupova.

6.1 Kreacija seta i operacije na setovima


Prazni set se kreira tako što varijabli predamo funkciju set bez argumenata

brojevi = set()

Set se kreira tako što kao argument funkciji set predamo listu sa različitim elementima:

brojevi = set([1,2,3])

print brojevi

>>set([1, 2, 3])

a) Dobivanje broja elemenata

Dobivanje broja elemenata u setu postižemo len funkcijom.

brojevi = set([1,2,3])

print len(brojevi)

>>>3

b) Dodavanje i brisanje elemenata

Za dodavanje elemenata u listu koristimo add metodu, gdje kao argument dajemo željenu vrijednost,
ukoliko dodamo vrijednost koja već postoji, ta vrijednost neće biti dodana u set.

brojevi = set()

30
Python_102
brojevi.add(1)

brojevi.add(2)

brojevi.add(2) # vrijednost 2 već postoji, tako da neće biti dodana u set

brojevi.add(3)

print brojevi

>>> set([1, 2, 3])

Ukoliko želimo dodati grupu elemenata koristimo update metodu, gdje kao argument možemo staviti
(listu, string ili pak drugi set)

brojevi1 = set([1,2,3])

brojevi2 = set([4,5,6])

brojevi2.update([7,8,9])

brojevi1.update(brojevi2)

print brojevi1

print brojevi2

>>>

set([1, 2, 3, 4, 5, 6, 7, 8, 9])

set([4, 5, 6, 7, 8, 9])

Ukoliko želimo izbrisati element seta koristimo remove ili discard metodu, ove dvije metode se razlikuju
u tome kako se ponašaju kada specifičan element nije pronađen u setu, budući da remove poziva
KeyError iznimku, dok discard ne poziva iznimku.

brojevi = set([1,2,3])

brojevi.remove(1)

brojevi.discard(2)

print brojevi

>>> set([3])

#Pozivanje KeyError iznimke

brojevi = set([1,2,3])

brojevi.remove(4)

>>>

31
Python_102
KeyError: 4

# Discard ne poziva KeyError iznimku

brojevi = set([1,2,3])

brojevi.discard(4)

c) Korištenje for petlje za iteraciju kroz set

Za iteraciju kroz sve elemente u setu koristimo generalni format:

for element in set:

izjava

izjava

brojevi = set([1,2,3])

for element in brojevi:

print element

>>>

d) Korištenje in i noti n operatora za testiranje vrijednosti u setu

Možemo koristiti in operator da bi utvrdili postoji li vrijednost u setu

brojevi = set([1,2,3])

if 2 in brojevi:

print "Broj 2 je u setu"

>>>

Broj 2 je u setu

Također možemo koristiti not in operator da bi utvrdili ne postoji li određena vrijednost u setu.

brojevi = set([1,2,3])

32
Python_102
if 4 not in brojevi:

print "Broj 4 nije u setu"

>>>

Broj 4 nije u setu

e) Pronalaženje unije setova

Unija dva seta je unija koja sadrže elemente iz oba seta, generalni format je:

set1.unija(set2)

brojevi1 = set([1,2,3,4])

brojevi2 = set([2,3,4,5])

unija = brojevi1.union(brojevi2)

print unija

>>>

set([1, 2, 3, 4, 5])

f) Pronalaženje presjeka setova

Presjek dva seta je set koji sadrži samo elemente koji su u oba seta, generalni format je:

set1.intersection(set2)

brojevi1 = set([1,2,3,4])

brojevi2 = set([2,3,4,5])

presjek = brojevi1.intersection(brojevi2)

print presjek

>>>

set([2, 3, 4])

g) Pronalaženje razlike između setova

33
Python_102
Razlika seta1 i seta2 su elementi koji se pojavljuju u setu1, ali se ne pojavljuju u setu2, generalni format
je:

set1.difference(set2)

brojevi1 = set([1,2,3,4])

brojevi2 = set([2,3,4,5])

razlika = brojevi1.difference(brojevi2)

print razlika

>>>

set([1])

h) Pronalaženje simetričke razlike setova

Simetrička razlika se odnosi na elemente koji su u jednom setu, ali ne u oba, generalni format je:

set1.symetric_difference(set2)

brojevi1 = set([1,2,3,4])

brojevi2 = set([2,3,4,5])

sim_razlika = brojevi1.symmetric_difference(brojevi2)

print sim_razlika

>>>

set([1, 5])

i) Pronalaženje podseta i superseta

Ukoliko set2 sadrži sve elemente seta1, onda se kaže da je set2 podskup seta1, generalni format je:

set2.issubset(set1) # funkcija issubset vraća boolean (True/False) vrijednost

brojevi1 = set([1,2,3,4])

34
Python_102
brojevi2 = set([2,3,4])

print brojevi2.issubset(brojevi1)

>>>

True

Ukoliko set1 sadrži sve elemente seta2, onda se kaže da je set1 nadskup seta2, generalni format je:

set1.issuperset(set2) # funkcija issubset vraća boolean (True/False) vrijednost

brojevi1 = set([1,2,3,4])

brojevi2 = set([2,3,4])

print brojevi1.issuperset(brojevi2)

>>>

True

7. Rekurzija
Rekurzivna funkcija je funkcija koja poziva sebe.

Primjer takve funkcije bi bio:

def main():

poruka()

def poruka():

print "Ovo je rekurzivna funkcija"

poruka()

main()

Ukoliko želimo kontrolirati broj rekurzija to činimo uz pomoć argumenta:

def main():

poruka(5)

def poruka(ponavljanja):

35
Python_102
if ponavljanja > 0:

print "Ovo je rekurzivna funkcija"

poruka(ponavljanja -1)

main()

7.1 Rješavanje problema uz pomoć rekurzije


Problemi se uz pomoć rekurzije mogu riješiti tako što se razbijaju na manje dijelove koji su identični u
strukturi generalnog problema.

Npr. računanje faktorijela:

def main():

broj = int(input('Unesi ne negativni integer: '))

fact = faktorijal(broj)

print('Faktorijal', broj, 'je', fact)

def faktorijal(unos):

if unos == 0:

return 1

else:

return unos * faktorijal(unos - 1)

main()

Primjer zbrajanja elemenata liste sa rekurzijom:

def main():

brojevi = [1, 2, 3, 4, 5, 6, 7, 8, 9]

suma = range_sum(brojevi, 2, 5)

print('Suma elementa 2 do 5 je', suma)

def range_sum(brojevna_lista, pocetak, kraj):

if pocetak > kraj:

36
Python_102
return 0

else:

return brojevna_lista[pocetak] + range_sum(brojevna_lista, pocetak + 1, kraj)

main()

Primjer Fibonacci niza:

If n = 0 onda Fib(n) = 0

If n = 1 onda Fib(n) = 1

If n = 1 onda Fib(n) = Fib(n= 1) + Fib(n = 2)

Rekurzivna funkcija bi nam izgledala:

def fib(n):

if n == 0:

return 0

elif n == 1:

return 1

else:

return fib(n - 1) + fib(n - 2)

Dok bi cijeli program izgledao:

def main():

print('Prvih 10 brojeva u')

print('Fibonacci nizu su:')

for broj in range(1, 11):

print(fib(broj))

37
Python_102
def fib(n):

if n == 0:

return 0

elif n == 1:

return 1

else:

return fib(n - 1) + fib(n - 2)

main()

8. Izgrađivanje programa kroz klase


Prilikom izgrađivanja programa kroz klase pratimo strukturu kroz 3 koraka

1. Naziv klase

2. Atributi (varijable kojima su pridruženi podatci)

3. Metode

Programi koji koriste klase često koriste get/set metode, koji omogućuju dodatnu fleksibilnost
manipulacije podataka.

Get metoda omogućuje postavljanje, dok set metoda omogućuje pristup podatcima.

Primjer get/set metode unutar klase automobil.

#automobil.py

class Automobil:
def __init__(self, proizvodjac, model):
self.__proizvodjac = proizvodjac
self.__model = model

38
Python_102
def set_proizvodjac(self, proizvodjac):
self.__proizvodjac = proizvodjac
def set_model(self, model):
self.__model = model
def get_proizvodjac(self):
return self.__proizvodjac
def get_model(self):
return self.__model

volvo = Automobil("Volvo", "S60")


bmw = Automobil("BMW", "318")

volvo.set_model("S90")
bmw.set_proizvodjac("Bayerische Motoren Werke")

print volvo.get_proizvodjac()
print bmw.get_model()

U ovom primjeru kreirana je set/get metoda koje pridružuju/vraćaju vrijednost parametra na self
varijablu.

Kreiramo instancu volvo putem Automobil klase, dajemo 2 argumenta koja su definirana unutar __init__
funkcije (proizvodjac, model).

Nakon što je instanca kreirana ona sadrži set i get metode, te proizvoljno možemo mijenjati/pozivati
proizvodjaca i model.

8.1 Postavljanje objekata kao argumenta


Česti slučaj je postavljanje objekta kao argumenta vanjskog koda (kod izvan klase), to postižemo pomoću
return unutar metode klase koja vraća vrijednost tipa podatka self varijable.

Za primjer kreirajmo 2 .py dokumenta grad.py i poziv.py

39
Python_102
#grad.py

class Grad:

def __init__(self,naziv):

self.__naziv = naziv

def get_naziv(self):

return self.__naziv

#poziv.py

import grad

zg = grad.Grad("ZG")

def vanjski_kod(grad):

print grad + " naziv grad"

vanjski_kod(zg.get_naziv())

Ovdje vidimo primjer gdje smo unutar poziv.py pozvali dokument grad (import grad), te kreirali instancu
zg = grad.Grad(''ZG''), nakon toga smo kreirali funkciju vanjski_kod, koja prima 1 parametar, te ga
ispisuje konkatenirajući vrijednost parametra grad + '' naziv grad''.

Nakon toga smo pozvali funkciju dajući za argument, metodu get_naziv instance zg), koja je u našem
slučaju string vrijednosti ''ZG'', budući da get_naziv vraća self varijablu koja je postavljena u __init__
''ZG'' prilikom kreiranja instance zg.

9. Serijalizacija Objekta
Serijalizacija objekta je proces pretvaranja objekta u bajtove koji mogu biti spremljeni za kasnije
korištenje. U Pythonu, proces serijalizacije se naziva pickling.

40
Python_102
Python standardna knjižnica pruža modul koji se zove pickle, te nam omogućuje različite funkcije za
serijalizaciju/pickling objekta.

Nakon što smo napravili import pickle modula, radimo sljedeće korake za serijalizaciju objekta:

1. Otvaramo dokument za binarno zapisivanje

spremljeni_dokument = open('podatak.dat', 'wb')

2. Pozivamo na pickle modulu dump metodu, koja nam omogućuje serijalizaciju objekta i zapisivanje u
specifični dokument

pickle.dump(objekt, spremljeni_dokument)

3. Nakon što smo serijalizirali sve objekta koje želimo, zatvaramo datoteku

spremljeni_dokument.close()

Cijeli algoritam:

import pickle

imena = ["Pero", "Ivo", "Mato"]

pohrana = open('imenik.dat', 'wb')

pickle.dump(imena, pohrana)

pohrana.close()

9.1. Deserijalizacija objekta


Nakon što smo serijalizirali objekt za kasnije korištenje u datoteku imenik.dat, možemo ga otvoriti,
odnosno deserijalizirati za korištenje.

Generali format deserijalizacije:

1. Otvorimo dokument za binarno čitanje

pohrana = open('imenik.dat', 'rb')

41
Python_102
2. Zovemo funkciju load modula pickle, da bi otvorili objekt iz dokumenta

ucitano = pickle.load(pohrana)

3. Nakon što je objekt deserijaliziran (učitan), zatvaramo dokument

pohrana.close()

Cijeli algoritam:

import pickle

pohrana = open('imenik.dat', 'rb')

ucitano = pickle.load(pohrana)

pohrana.close()

print type(ucitano)

10. Operator overloading


Omogućava automatsko pokretanje funkcija, kada su određeni operatori pozvani na instanci objekta.

10.1. __sub__
Uzmimo za primjer operator overloading za oduzimanje __sub__:

class Broj:

def __init__(self, broj):

self.broj = broj

def __sub__(self, broj2):

return Broj(self.broj+broj2+2) #unutar return traži se naziv klase

x = Broj(5)

a=x-2

42
Python_102
print a.broj

>>>9

Ovdje vidimo zanimljiv primjer gdje ukoliko na instanci pozovemo operator oduzimanja

a=x -2

Pozivamo __sub__ operator overloading metodu, koja su svojem tijelu ima sintakstu

return NazivKlase(atributi)

Upravo ovdje kreiramo naše custom ponašanje ukoliko se na instanci pozove operator oduzimanja,
poštujući gore navedenu sintaksu možemo stavljati opcionalne parametre, te ponašanja koja nama
odgovaraju. Poput konkatenacije, zbrajanja, oduzimanja, množenja, dijeljenja, potenciranja…

Jedno od naših custom ponašanja je to da smo broju 5, koji je postavljen na self varijablu broj kroz
inicijalizaciju

x = Broj(5)

Dodali unutar tijela funkcije broj2, koji odgovara broju 2 prilikom poziva operatora oduzimanja

a=x–2

Te mu zatim dodali broj 2

return Broj(self.broj+broj2+2)

S čime na kraju pozivanjem self varijable broj dobivamo 5 + 2 + 2 = 9.

10.2. __add__
Primjer operatora overloading za zbrajanju __add__:

class Broj:

43
Python_102
def __init__(self, broj):

self.broj = broj

def __add__(self, broj2):

return Broj("Ovo je broj "+str(self.broj))

x = Broj(5)

a=x+2

print a.broj

>>> Ovo je broj 5

Ovdje imamo isti slučaj kao i sa prethodnim operatorom -, samo što je u našem slučaju operator
overloading pozvan na operatoru zbrajanja. Također sintaksa je poštivana, te je u tijelu __add__ funkcije
vraćena konkatenacije ''Ovo je broj '' + str(self.broj) gdje smo u potpunosti ignorirali parametar (broj2)
__add__ funkcije čime dobivamo nakon poziva operatora + na instanci klase vrijednost a.broj ''Ovo je
broj 5''.

10.3. __mul__
Primjer operatora overloading za množenje __mul__:

class Broj:

def __init__(self, broj):

self.broj = broj

def __mul__(self, broj2):

return Broj("Mnozenje")

x = Broj(5)

a=x*2

print a.broj

44
Python_102
>>>Mnozenje

10.4. __div__
Primjer operatora overloading za dijeljenje __div__:

class Broj:

def __init__(self, broj):

self.broj = broj

def __div__(self, broj2):

return Broj(self.broj-broj2)

x = Broj(5)

a=x/2

print a.broj

>>>3

45
Python_102

You might also like