Funkcije

9 Funkcije 

U dosadašnjem toku našeg tutorijala, mi smo dosta često koristili mnoge funkcije koje su dostupne u samom Python jeziku, na primer, koristili smo funkcije len(), range(), print(), input().... Kao što sam ti bio napomenuo, funkcije su neki objekti koji za nas rade nešto. Na primer, rekao sam ti da je funkcija print() ugrađeni štampač, u koji mi stavimo nešto što želimo, i on nam to – odštampa na ekranu! Ali, šta  se krije iza ovog koncepta? Šta je taj „štampač“? Iznenadićeš se koliko su stvari – jednostavne.
Funkcije nisu ništa drugo, nego neki prethodno definisani delovi programa koji se mogu koristiti više puta u toku pisanja programa. One su, u neku ruku samo ime koje dajemo (ili je neko drugi već dao) nekom bloku komandi koji sam po sebi vrši neku, tačno određenu funkciju, što nam omogućava da pokrećemo taj blok komandi koristeći njeno ime, bilo gde u programu i koliko god puta želimo. Ovo se naziva: pozivanje funkcije, i mi smo u toku ovog našeg kratkog puta kroz programiranje to radili dosta puta, i kao što si video, nije strašno uopšte, ali, ako te je ipak strah, da ponovimo malko:
>>> print('print() je najobičnija funkcija.') 
print() je najobičnija funkcija. 
>>> input('A ni input() nije daleko.') 
A ni input() nije daleko. 
'' 
Vidiš, pozivanje funkcija je mačiji kašalj (ako mačka prethodno nije sažvakala neku koščatu životinju, pa joj se zaglavilo neko rebarce u grlo...).
Problem: Ma čekaj... Ali ja nigde ne vidim niti jedan blok naredbi koji predstavlja print(), niti koji predstavlja funkciju input(), ili bilo koju drugu....
Odgovor: Neka te to ne buni.... To su takozvane ugrađene funkcije, i one su ti dostupne od istog trenutka kada si instalirao Python na računar. Kreatori Pythona su baš super ljudi kada nam nešto daju za džabe, a mi sa tim možemo da radimo šta nam je milo, zar ne?
Koncept funkcija je jedan od najvažnijih kamenja u temelju prilikom izgradnje bilo kog važnog softvera (i, pri tom, važan je i u bilo kom programskom jeziku), i zbog toga ću ti pokazati mnogo različitih aspekata funkcija u ovom delu tutorijala.
Ali da krenemo dalje. Do sada smo samo pozivali funkcije, ali šta se iza tog poziva krije? Ako imamo šporet u koji stavljamo neko testo da se ispeče, kako je taj šporet sastavljen? Ili, ako nam taj šporet nije pri ruci – negde smo na izletu, da li mi možda možemo i umemo da – naložimo vatru i sami ispečemo to testo? Odgovor je jednostavan – ukoliko imamo sve što nam je potrebno (šibice, drva, neki pleh na kom želimo da pečemo, i naravno testo, ali pre svega toga, dobru volju koju nećemo izgubiti pokušavajući da nađemo sve prethodno navedeno) možemo peći – šporet nam ne treba! Ali kako naložiti vatru? Kako konstruisati skalameriju? Ma za nas to nije bitno! Nama je važnija stvar – kako definisati funkciju, tj kako dati instrukcije za sklapanje skalamerije, a kasnije nek se Python muči i peče!
Pa da objasnimo to malo.
Funkciju definišemo pomoću ključne reči def. Posle reči def pišemo identifikaciono ime koje želimo da damo funkciji (sva pravila za imena promenljivih važe i u ovom slučaju), iza imena koje smo joj dali slede zagrade (kasnije ćeš shvatiti čemu služe), a na kraju, iza zagrada stoji dvotačka, koja, kao što si već verovatno zapamtio, govori Pythonu da se tu završava logička linija ispod koje sledi neki blok naredbi koji predstavlja funkciju (a ovaj blok se naziva telo funkcije). U suštini to izgleda ovako:
def ime_funkcije():
    telo_funkcije
Sledeći primer će ti pokazati koliko je sve to jednostavno. Za početak ti predstavljam jednu od naj(bes)korisnijih i naj(lenjih)vrednijih funkcija prilikom programiranja.
Šta trućaš ti to? Jel nešto beskorisno ili korisno? Pa nemože nešto da bude vredno i lenjo? Gde to ima?
Zavisi kako gledaš na svet, ako si tako isključiv, džaba ti sve... Moraš promeniti poglede da bi imao perspektivu za realnu sliku sveta... Naravno, ako si slikar (ili programer, ili jednostavno voliš da razmišljaš, ili...) pa ti je ta realna slika sveta potrebna. Gledaj sad:
>>> def lenjitis(): 
...     pass 
... 
>>> lenjitis() 
>>> lenjitis() 
>>> lenjitis() 
>>> 
Ili, ako ti ovo nije jasno:
>>> def pozdrav(): 
...     print('Pozdrav Veliki Care!') 
... 
>>> lenjitis() 
>>> pozdrav() 
Pozdrav Veliki Care! 
>>> pozdrav() 
Pozdrav Veliki Care! 
>>> lenjitis() 
>>> pozdrav() 
Pozdrav Veliki Care! 
>>> 
U drugom slučaju sam definisao funkciju sa imenom pozdrav, na način koji sam objasnio ranije. Ovako definisanoj funkciji ne možemo da „pošaljemo“ nešto:
>>> pozdrav('care') 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
TypeError: pozdrav() takes no arguments (1 given) 
>>> 
Ako „pošaljemo“ nešto u funkciju – dobijamo izveštaj o greški. To je zato što nismo definisali parametre, malo kasnije ću ti pričati o tome. 
Primeti da možeš da pozoveš funkciju koliko god želiš puta, što u suštini znači da ne moraš uvek nanovo da kucaš deo koda koji je telo funkcije. I to je cela svrha postojanja funkcija! Lenjost! Jednom napišeš – uvek te služi (naravno, ukoliko je u skripti, budući da sam ja radio u interaktivnom promptu, čim izađem iz njega, sve je zaboravljeno).
Ali šta je sa onom najkorisnijom i najbeskorisnijom funkcijom? Tamo mi ništa nije jasno....
Ah... Oprosti... Namerno zaboravih na nju....
Vidimo da smo je definisali na sasvim uobičajen način, dajući joj ime lenjitis. Šta tu ima čudno?
pass
Komanda pass? Pa šta misliš, prema nazivu funkcije, šta komanda pass radi? Ne radi ništa! Pod milim bogom, ona je najlenja komanda na koju ćeš naleteti u Pythonu.
Pa šta će nam onda? Čemu služi nešto što ne radi – ništa?
Nemoj se iznenaditi, ali može služiti svačemu.... Na primer, želiš da pustiš pesmu, ali je muzički kanal zauzet, da ne bi puštao u isto vreme i pravio džumbus, možda je bolja solucija da – ne pustiš tu novu pesmu u tom trenutku? Ili, ako ti je zauztost memorije 99%, bolje je ne opteretiti je sa još nečim, tj, pametnije je ne uraditi ništa! Ali, hajde, sve su to specifični slučajevi sa kojima se možda (ali možda) nećeš nikada ni susretati. Prava tajna i prava upotreba ove komande je baš u funkcijama (i nešto kasnije u klasama).
Da bi ti objasnio čemu ovakva „konstrukcija“ zapravo služi, treba mi tvoja pomoć. Zamisli da pišeš neki veliki program – kako ispeći testo na izletu bez šporeta. Ti kao programer, u startu ne znaš kako ispeći, ali znaš da treba da dobiješ – hleb (ili krofne... a možda ako baš voliš ekstremne sportove – palačinke na roštilju). Zatim kreće razmišljanje, pa dođeš do nekakvog zaključka, koje upisuješ u skriptu (ja ću u interaktivni prompt, da se ne mučim):
>>> def skupljaj_sirovine(): 
...     pass 
... 
>>> def nađi_mesto(): 
...     pass 
... 
>>> def zapali_vatru(): 
...     pass 
... 
>>> def postavi_pleh(): 
...     pass 
... 
>>> def umesi_testo(): 
...     pass 
... 
>>> def peci_testo(): 
...     pass 
... 
>>> def jedi_hleb(): 
...     pass 
... 
>>> 
Pa čekaj... Nit sam šta uradio, nit sam šta dobio....
Sa ovakvom konstrukcijom ti ne da si nešto uradio, već si mnogo i dobio! Stvorio si skelet programa, na koji ćeš, kasnijim izučavanjem ili razmišljanjem „lepiti“ potrebne korake, i tako, jednu po jednu eliminisati pass komande, i na njihovo mesto stavljati druge komande koje služe svrsi u tim funkcijama. Neki iskusan programer koji bude čitao tvoj program, i bude naleteo na pass će shvatiti da funkcija treba da se dorađuje, ali će shvatiti TVOJ način razmišljanja i TVOJ pristup rešavanju problema, pa će se prebaciti u „tvoj film“ da ti pomogne, ali, sasvim sigurno, i nešto novo da nauči od tebe.
Kao što vidiš, i stvari koje izgledaju kao bespotrebne i beskorisne, korišćenjem na mudar način postaju moćan alat za rešavanje problema!
Za čas samo baci ponovo pogled na prethodni primer.... Razmisli sad... umesi_testo() ne mora da se primenjje samo na ovom izletu, zar ne? Može i u kuhinji, u pekari.... zapali_vatru() - pa potrebno je to znanje skoro uvek! O tome ti pričam. Suština funkcija nije samo da se lakše i brže reši neki problem, ne, njihov značaj je veći u baš suprotnom smeru – suština funkcija je da se one mogu primeniti na što više problema, bez da se menjaju! Tako na primer, odeš i kupiš burek, da bi ga pojeo, ne moraš da „izmišljaš“ nešto – samo primeniš funkciju koju si ovde definisao – jedi_hleb() jer nema nikakve razlike u „žvakanju“! Iznenađujuće će ti biti saznanje, da jedan problem, koji si možda rešavao u nekom programu za dijagnostiku automobila, ima dodirne tačke sa problemom u nekom programu koji spaja parove koji su samci na osnovu njihovih zajedničkih interesovanja. Jednostavno – primeniš istu funkciju u oba slučaja.
I za kraj ovog uvoda, mali zadatak za razmišljanje. Svo vreme sam ti govorio da su i funkcije neki (zasebni) objekti u tvom programu. Šta misliš, gledajući u grešku koju je izbacio jedan od primera, kako ti „objekti“ komuniciraju sa samim tvojim programom? Evo na šta mislim:
>>> i = 2 
>>> def prikaz(): 
...     print(i) 
... 
>>> def saberi(): 
...     i += i 
...     print(i) 
... 
>>> prikaz() 
2 
>>> saberi() 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
  File "<stdin>", line 2, in saberi 
UnboundLocalError: local variable 'i' referenced before assignment 
>>> 
Šta bi? Nemoj previše lupati glavu, kazaću ti kasnije, ali želim da uporediš ovo i način na koji si do sada komunicirao sa funkcijama print() ili input() - vidiš li na šta mislim?

8.6 Rezime Indeks 9.1 Argumenti i
parametri funkcija

Primjedbe

Popularno ovog meseca

Gde pronaći novosti sa facebook stranica nakon velike promene koja ga je zadesila?

Dva načina da vratite svoj Windows 10 na fabričke vrednosti

Kako preuzeti video koji je neko postavio na facebook-u bez upotrebe dodatnih programa?

Više neće biti moguć besplatan prelazak na Windows 10

Prijateljski meč ŠK "Titel" - ŠK "Bukovac"

Tu je novi Qt creator 4.4.0!

Kako manipulisati Windows licencom pomoću slmgr komande?

Fake poet

Da li je poželjno biti anoniman na internetu (ili se predstavljati punim imenom i prezimenom)?

Organizacija foldera i fajlova u Linux fajl sistemu