Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # 01 => Sta je proceduralno programiranje?
- #
- # Omogucava da kod koji resava jedan manji problem pozivamo
- # vise puta. Logika samog koda u okviru funkcija predstavljena je kao
- # blok u okviru koje se implementira odredjena funkcionalnost u cilju
- # postizanja ponovnog iskoriscenja koda, modularnosti, preglednosti,
- # lakseg upravljanja kodom, lakseg odrzavanja itd.
- #
- # 02 => Deklaracija metoda
- #
- # Metode se u Pythonu deklarisu na sledeci nacin (ovim redosledom) pri
- # cemu se mora voditi racuna o identaciji:
- #
- # 1: DEF
- # 2: FUNCNAME
- # 3: PROTOTYPE (OPTIONAL)
- # 4: DOUBLEDOT
- # 5: BLOCK
- def helloworld():
- pass # do nothing =}
- # Prva izjava u okviru funkcijskog bloka je obicno dokumentacija
- def helloworld():
- '''this is just a demonstration of python doc inside function'''
- pass
- # Metod .__doc__ omogucava stampanje ove vrednosti
- print(myMethod.__doc__)
- # Pored __doc__ Python sadrzi veliki broj ovih specijalnih metoda
- # preko kojih mozemo da saznamo odredjene detalje vezane za same
- # metode.
- # Nakon dokumentacije (koja obicno predstavlja prvu liniju koda) pocinjemo
- # sa pisanjem logike programa. Taj blok koda se moze/ne mora zavrsiti
- # sa return izjavom koja vraca odredjeni rezultat.
- def sortMe(listToSort):
- '''izmisljen blok koda ;-)'''
- sortedList = []
- # ...
- # ...
- # ...
- return sortedList
- # 02 => Prosledjivanje parametara
- #
- # Interesantna stvar kod Pajtona jeste nacin na koji se mogu proslediti,
- # odnosno obraditi parametri jedne metode. Postoje 4 vrste paramametara:
- #
- # => Required Args (tacno odredjen format prema poziciji)
- # => Keyword Args (setovanje vrednosti parametara na osnovu keywordsa)
- # => Default Args (default vrednost ukoliko param. ne bude prosledjen)
- # => Variable-length Args (argumenti promenljive duzine)
- # REQUIRED ARGUMENTS
- #
- # Argumenti koji su definisani u tacno odredjenom formatu u smislu
- # da svaki naveden parametar ima svoju zahtevanu poziciju. Na osnovu
- # poziva funkcije odnosno prosledjivanja njenih parametara program
- # tacno zna koju vrednost vezuje za koji argument.
- def authenticate(userName, password):
- print("userName: " + userName)
- print("password:", password)
- pass
- authenticate("miksi", 123); # works!
- authenticate("miksi"); # missing 1 arg
- # KEYWORD ARGUMENTS
- #
- # Argumenti koji uticu na redosled dodeljivanja vrednosti prototipu.
- # Koriscenjem ove vrste argumenata se moze zaobici prethodni problem
- # sekvencijalnog dodeljivanja vrednosti.
- def alphabet(a, b, c):
- print("A is:", a)
- print("B is:", b)
- print("C is:", c)
- alphabet(1, 2, 3) # a=1, b=2, c=3
- alphabet(c = 1, b = 2, a = 3) # a=3, b=2, c=1
- alphabet(b = 1, a = 2, c = 3) # a=2, b=1, c=3
- # DEFAULT ARGUMENTS
- #
- # Argumenti koji omogucavaju zamenjivanje vrednosti argumentima ukoliko
- # neka vrednost nije provided u pozivu funkcije. Primer:
- def alphabet(a = None, b = None, c = None):
- print("A:", a)
- print("B:", b)
- print("C:", c)
- alphabet(1, 2, 3) # a=1, b=2, c=3
- alphabet(2, 3) # a=2, b=3, c=None
- alphabet(1, 3) # a=1, b=3, c=None
- alphabet(a=1, c=3) # a=1, b=None, c=3
- alphabet(a = 10, b = 15) # a=10, b=15, c=None
- # VARIABLE-LENGTH ARGUMENTS
- #
- # U nekom trenutku mogu se javiti metode koje primaju odredjeni broj
- # parametara ali i one za koje se ne zna tacan broj jer je on nepredvidljiv.
- def alphabet(a, b, c): # 3 params max
- print("a", a)
- print("b", b)
- print("c", c)
- alphabet(1,2,3, 4) # 4 params provided = error
- # Var length primer gde *additional zapravo predstavlja tupple
- def alphabet(a, b, c, *additional):
- print("a", a)
- print("b", b)
- print("c", c)
- for arg in additional:
- print("result(s): ", arg)
- alphabet(1,2,3)
- alphabet(1,2,3, 4) # additonal args = 4
- alphabet(1,2,3, 4,5,6) # additional args = 4,5,6
- # Sta je Tupple? Sta ce se desiti ako probamo da appendujemo jos
- # jedan element u okviru additionalargs tuppla?
- ...
- additional.append(9) # throws an error, cause its a tupple!
- for arg in additional:
- print("result(s): ", arg)
- ...
- # 03 => Python-like prosledjivanje vrednosti preko referenci
- #
- # Interesantna je razlika izmedju nacina na koji Perl, odnosno
- # Python upravljaju prenosom podataka.
- #
- # Perl potprogram (prenos po vrednosti => lista se razlikuje):
- use strict;
- use warnings;
- use v5.10.1;
- sub test {
- my(@list) = @_;
- push(@list, 55);
- say "@list inside" # RES => 1, 2, 3, 55
- }
- my @list = (1,2,3);
- test(@list);
- say "@list outside" # RES => 1, 2, 3
- # Python metod (prenos po ref. => lista uvek ostaje ista):
- def test(listy):
- listy.append(15)
- print("Inside: ", listy) # RES => 1, 2, 3, 15
- listy = [1,2,3]
- test(listy)
- print("Outside: ", listy) # RES => 1, 2, 3, 15
- # PERL VS. PYTHON
- #
- # U prethodnom primeru prikazano je da Python podrazumevano koristi
- # reference za slanje parametara dok kod Perla to moramo da naglasimo
- # da bi on shvatio Ε‘ta je potrebno uraditi.
- #
- # PERL FIX?
- sub test {
- my($list) = @_;
- push(@$list, 55);
- say "@$list inside" # RES => 1, 2, 3, 55
- }
- my @list = (1,2,3);
- test(\@list);
- say "@list outside" # RES => 1, 2, 3, 55
- # REDEFINISANJE VREDNOSTI REFERENCE
- listy = [1,2,3]
- def test(listy):
- # promenom originalne liste
- # na lokalnom nivou rezultuje..
- listy = [3,2,1] # new reference creation
- print("inside", listy) # RET => 3, 2, 1
- test(listy)
- print("outside", listy) # RET => 1, 2, 3
- # 06 => Annonymous functions
- #
- # metode u pajtonu u single-line maniru
- def single(x): print(x**2);
- single();
- # Anonimne funkcije nisu vezane za ime (kao sto smo navikli, npr. authenticate())
- # vec se vezuju za odredjenu promenljivu.
- #
- # Anonimne funkcije u trenutku izvrsavanja koriste tzv. LAMBDA construct
- # koji predstavlja powerful koncept Python programskog jezika.
- #
- # Pattern:
- # nameOfAnonimousFunction = lambdaConstruct arg1, arg2, argN: code:
- multiply = lambda x: x**2
- print(multiply(2)) # RES => 4
- # Primer sa vise argumenata
- sum = lambda a, b, c: a + b - c
- print(sum(10,10,19))
- # Prethodne 2 funkcije rade istu stvar samo sto je ovo anonimna
- # dakle vezana je za promenljivu. Vidimo da u anonimnoj nema
- # return izjave sto znaci da automatski uvek vraca rezultat.
- # Anonimne funkcije u okviru funkcija :=)
- def setExponent(exp):
- return lambda num: num ** exp
- num1 = setExponent(2)
- num2 = setExponent(4)
- num3 = setExponent(5)
- print(num1(2)) # 2 ^ 2 = 4
- print(num2(4)) # 4 ^ 4 = 256
- print(num3(5)) # Calc Error :D
- # 04 => Globalne, lokalne promenljive
- luckyNumbers = [1, 2, 3]
- def blockA():
- local_a = 77
- luckyNumbers.append(local_a)
- def blockB():
- local_b = 88
- luckyNumbers.append(local_b)
- def blockC():
- local_c = 99
- luckyNumbers.append(local_c)
- blockA()
- blockB()
- blockC()
- print(luckyNumbers)
- # print(local_a) => throws an error
- # 08 => Exceptions
- #
- # Najjednostavniji primer kada se ovo desava jeste deljenje sa nulom:
- def divide(a, b):
- return a/b
- print(divide(2,5))
- # print(divide(2,0)) ZeroDivisionError: division by zero
- # Sta je exception?
- #
- # to je dogadjaj koji nastaje u vremenu izvrsavanja programa a koji
- # utice na to da se normalan tok izvrsavanja programa poremeti zbog
- # nemogucnosti interpretera da se izbori sa delom koda u okviru koga
- # se javila greska.
- #
- # Sta uraditi povodom toga?
- #
- # Ono sto se moze uraditi povodom toga jeste da se u trenutku pojavljivanja
- # exceptiona on uhvati i obradi na neki nacin tako da program ipak
- # nastavi sa radom iako je doslo do greske u radu.
- # Syntax
- try:
- # kriticna linija koda
- except ExceptionI:
- # ako je ExceptionI bacen izvrsi ovaj blok
- except ExceptionII:
- # ako je ExceptionII bacen izvrsi ovaj blok
- else:
- # ukoliko ne dodje ni do kakvog exceptiona, izvrsi ovaj blok
- # Prethodni primer ilustruje try i except blokove kojim se manipulise
- # nad izuzecima u programu.
- #
- # ExceptionI, ExceptionII su podklase glavne Exception klase i oni ce
- # biti pozvani u trenutku kada se desi greska koja odgovara njihovim
- # osobinama.
- try:
- # res = 2/1
- # res = 2/0 => throw exception "oops, something happend"
- except: # podrazumevani exception
- print("oops, something happend")
- else:
- print("Cool, there are no exceptions!")
- # Kao u prethodnom priemru (Exception I, II) mi mozemo navesti neke
- # od exceptiona za koje smatramo da se mogu dogoditi nad odredjenim
- # delom koda.
- x, y = 5, 0
- try:
- z = x/y
- except ZeroDivisionError:
- print("divided by zero")
- else:
- print("Cool, there are no exceptions!")
- # ili
- x, y = 5, 0
- try:
- z = x/int("y")
- except ZeroDivisionError:
- print("divided by zero")
- except ValueError:
- print("expected int but parsed string")
- else:
- print("Cool, there are no exceptions!")
- # Recimo da je potrebno onemoguciti korisnika da prekoci korak
- # upisivanja neke int vrednosti. U tom slucaju, exception
- # ce biti bacen svaki put kada korisnik ne unese ocekivanu
- # vrednost (tip int)
- while True:
- try:
- x = int(input("Please enter number:"))
- break
- except ValueError:
- print("Oops, Not a valid number!")
- # mozemo vise exceptiona da definesmo u jednoj liniji
- except(Exception, IOError, ...):
- # Pregled
- #
- # TRY - kriticna linija koda
- # EXCEPT - izvrsava se ukoliko dodje do izuzetka
- # ELSE - izvrsava se ukoliko ne dodje do bacanja izuzetka
- # FINALLY - izvrsava se svakako bez obzira na bilo kakav dogadjaj
- try:
- res = 2/1
- except:
- print("error")
- else:
- print("cool, no exceptions no problems!")
- finally:
- print("im gonna print this anyway..")
- # Jedan lep primer bacanja exceptiona u trenutku kada dodje do
- # pokusaja upisivanja u fajl za koji nemate dozvolu upisivanja
- # (read only file).
- try:
- fh = open("filename", "w")
- try:
- fh.write("This is my test file for exception handling!!")
- finally:
- print "Going to close the file"
- fh.close()
- except IOError:
- print "Error: can\'t find file or read data"
- # GET ERROR MESSAGE
- #
- # Neke klase izuzetaka pruzaju detaljnije informacije o prouzrokovanoj
- # gresci kroz vid argumenata.
- try:
- fh = open("filename", "w")
- try:
- fh.write("Helloworld.")
- finally:
- print("File written. Closing..")
- fh.close()
- except IOError as arg:
- print("~Error:" + arg)
- # Raising an Exception
- myNumbers = [1,2,4]
- def badLuckNum():
- for num in myNumbers:
- if num == 4:
- raise Exception("Num captured as 4")
- print(num)
- # Hvatanje exceptiona?
- try:
- badLuckNum()
- except:
- print("something went wrong..")
- # 09 => Recursive
- #
- # Sama ideja rekurzije je pomalo zbunjujuca.
- #
- # Rekurzija je metod resavanja odredjenog problema tako sto se on deli
- # na vise manjih, jednostavnijih za resavanje, do trenutka kada se ne
- # dobije dovoljno mali (potproblem) koji se moze resiti na jednostavan
- # nacin.
- #
- # Ovo se ostvaruje kroz vid sekvencijalnih poziva metode koja poziva
- # samu sebe. Dakle, ideja rekurzije jeste da metod poziva samog sebe.
- #
- # Razmotrimo sledeci primer gde metod say pokusava da pozove samog
- # sebe:
- def say():
- print("Ok, I am in method 'say' now")
- say() # call say again
- say() # call say, at the end: maximum recursion depth exceeded
- # Zbog cega je doslo do greske?
- #
- # Kako bismo napravili efektivnu rekurzivnu funkciju, u okviru nje mora
- # postojati nesto sto se naziva "base case" ili "ending point". To u
- # najjednostavnijem prevodu znaci da mora da postoji nesto sto ce prekinuti
- # izvrsavanje funkcije u trenutku kada to bude bilo potrebno. U suprotnom,
- # program ce uci u beskonacnu petlju i izvrsavace se dok racunar ne "padne".
- #
- # Najjednostavniji primer je rekurzivna funkcija koja racuna faktorijal
- # nekog broja.
- #
- # Racunanje faktorijala:
- #
- # 5! = 5 * 4 * 3 * 2 * 1 # ili 5 * 4!
- # 4! = 4 * 3 * 2 *1 # ili 4 * 3!
- # 3! = 3 * 2 * 1 # ...
- # 2! = 2 * 1 # ...
- # 1! = 1 # ...
- def makeFaktorialOf(num):
- # base case
- if num == 1:
- return 1
- else:
- return num * makeFaktorialOf(num-1)
- print(makeFaktorialOf(5)) # => 120
- # 5 * makeFaktorialOf(4) => 4*3*2*1
- # 4 * makeFaktorialOf(3) => 3*2*1
- # 3 * makeFaktorialOf(2) => 2*1
- # 2 * makeFaktorialOf(1) => 1
- # Postoji izuzetno veliki broj problema koji se moze prikladno resiti
- # rekurzijom i to je razlog zbog koje se ona koristi.
- # Primer sumiranja elemenata liste na nerekurzivan nacin:
- def sumNumbers(numList):
- summ = 0
- for num in numList:
- summ = summ + num
- return summ
- print(sumNumbers([1,3,5,7,9]))
- # Za rekurzivnu metodu potrebno je:
- #
- # 1) Podeliti problem na manje delove. Recimo:
- # 1, 3, 5, 7, 9
- #
- # 2) Sabirati poslednje 2 cifre (7 i 9 u ovom slucaju) u cilju
- # dobijanja sume.
- #
- # 3) Pozvati funkciju koja ce ponovo sabrati poslednje 2 cifre
- # i prethodno izracunatu sumu.
- #
- # 4) Izvrsiti izracunavanje dokle god ima elemenata u listi.
- # (1 + (3 + (5 + (7 + 9))))
- # Najdublji problem je 7+9 koji se moze resiti bez prolaska kroz petlje.
- # To znaci da se moze iskoristiti sledeca sekvenca izraza kako bi se
- # dospelo do rekurzivnog resenja za ovaj problem:
- total = (1 + (3 + (5 + (7 + (9))))
- total = (1 + (3 + (5 + 16)))
- total = (1 + (3 + 21))
- total = (1 + 24)
- total = 25
- # Vise rekurzivan primer prethodne sumNumbers metode gde je:
- #
- # numList[0] - uvek prvi element liste
- # numList[1:] - od drugog elementa pa do kraja liste
- #
- # def: suma = firstElem(List) + suma(OstaliIzListe)
- def sumNumbers(numList):
- if len(numList) == 1:
- return numList[0]
- else:
- return numList[0] + sumNumbers(numList[1:])
- print(sumNumbers([1,3,5,7,9])) # 25
- # print to see whass going on:
- def sumNumbers(numList):
- if len(numList) == 1:
- return numList[0]
- else:
- print(numList[0] , " + " , numList[1:])
- return numList[0] + sumNumbers(numList[1:])
- print(sumNumbers([1,3,5,7,9]))
- # serija rekurzivnih poziva bi izgledala:
- sum(1,3,5,7,9) = 1 + # plus lista ispod
- sum(3,5,7,9) = 3 + # plus lista ispod
- sum(5,7,9) = 5 + # plus lista ispod
- sum(7,9) = 7 + # plus lista ispod
- sum(9) = 9
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement