python

Funksionet

Funksionet dhe krijimi i tyre

Në fjalorin e gjuhës së sotme shqipe jepet kuptimi i fjalës funksion duke specifikuar fushën e përdorimit. Në fjalitë e më poshtme, të shkëputura nga fjalori, jepen disa shembuj të përdorimit të kesaj fjale:

zyrt. Funksion drejtues. Është ngarkuar me një funksion të rëndësishëm. Funksionet e shtetit.
fiziol: fuksionet e zemrës.
mat: Funksion algjebrik. Teoria e funksioneve.
gjuh: funksion morfologjik. Funksioni i fonemës.

Siç e shohim edhe nga fjalitë, fjala funksion ka përdorim të gjerë si në fushën zyrtare, fiziologjike, matematikore apo gjuhësore. Fjala funksion mund të përkufizohet si punë, detyrë, qëllim apo veprimtari.

Në programim mund të themi se funksionet janë miniprograme të cilat kryejne detyra të caktuara.

Deri tani ne jemi ndeshur me funksionin print(). Ky funksion, ashtu si çdo funksion, përbëhet nga një emër dhe quhet print si dhe kryen një detyrë, pikërisht na shfaq në ekran atë që ne i themi, duke e cilesuar brenda kllapave ().

Gjuhët e programimit mundësojne jo vetëm përdorimin e funksioneve të gatshme, por edhe krijimin e tyre. Sintaksa është kjo:

def emri():
    blloku i komandave

def është një fjalë kyçe e pythonit, të cilen e kemi përmendur në Tabelën 1. Fjala def i tregon pythonit që po krijojmë një funksion. Le të krijojme një funksion

>>> def gjej_zanoret():
        if (germa == 'a'
            or germa == 'e'
            or germa == 'i'
            or germa == 'o'
            or germa == 'u'
            or germa == 'y'):
            # i kombinojme kushtet ne nje te vetem meqe
            # rezultati eshte i njejte per cdo zanore
            print 'zanore'
        else:
            print 'bashketingellore'
>>> germa ='b'
>>> gjej_zanoret()
bashketingellore

Funksioni gjej_zanoret, kërkon për llojet e gërmave zanore apo bashkëtingëllore. Për të kryer detyrën e tij, funksioni ka nevojë të therritet dhe kjo gjë bëhet e mundur ne rreshtin 14 duke shkruar emrin e tij bashkë me kllapat.

Parametrat dhe argumentet

Deri tani nuk kemi shpjeguar ende rolin e kllapave që ndodhen pas emrit të funksionit. Le të studiojmë shembullin e mëposhtëm.

>>> def shuma(numri1, numri2):
    shuma = numri1 + numri2
    print 'Shuma e', numri1, 'dhe', numri2, 'eshte', shuma

Tek kllapat brenda funksionit shuma, kemi shkruar dy ndryshore të ndara me presje njera nga tjetra. Këto ndryshore quhen parametra. Pra kemi krijuar një funksion me emrin shuma që merr dy parametra. Funksioni shuma mbledh vlerat e dy ndryshoreve dhe me ane të funksionit të gatshëm print jep rezultatin.

Siç i hedhim vlera ndryshoreve me operatorin = (operatori i hedhjes së vlerës), parametrave u hedhim vlerën me thirrjen e funksioneve. Kur therrasim funksionin vlerat që marrin parametrat quhen argumenta.

>>> shuma(2,3)
Shuma e 2 dhe 3 eshte 5

Me sipër kemi thirrur funksionin shuma duke i kaluar dy argumentat 2 dhe 3.

Funksionet që kthejnë vlerë

Funksionet që nuk kthejnë vlerë janë ato funksione që nuk na japin si rezultat një vlerë. Shembull:

>>> def printo_emrin(emri):
        print emri
>>> printo_emrin('python')
python

Funksioni i mësipërm nuk kthen vlerë, por zbaton komandat e tij duke shfaqur në ekran fjalën python. Në python fjala kyçe return përdoret për të kthyer një vlerë. Vlera e kthyer nga funksioni mund të përdoret më pas si çdo shprehje tjetër. Shembull:

>>> def shuma(numri1, numri2):
        return numri1 + numri2
>>> print "Shuma e numrave 2, 3 dhe 4 eshte:", shuma(2,3) + 4
Shuma e numrave 2, 3 dhe 4 eshte: 9

Gjatë studimit të funksioneve duhet të kemi parasysh disa parime të programimit të mirë:

Në shembullin e më poshtëm do të shohim zbatimin e këtyre parimeve. Ripërdorimi i kodit thjeshton shumë punën, sidomos nëse jemi duke punuar me programe të mëdha.

Shembull: Të krijojmë një program që numëron sa zanore dhe bashkëtingëllore ka një fjalë apo fjali. Qëllimi i këtij shembulli është të shpjegojë përdorimin e funksioneve ne python. Konsiderimi i gërmave dyshe të gjuhës shqipe si një bashkëtingëllore e vetme do ta komplikonte kodin që do të shkruajmë në mënyrë të panevojshme. Për këtë arsye shkronjat si psh "th" do të konsiderohen si dy bashkëtingëlloret "t" dhe "h".

Në fillim do të krijojmë një funksion të thjeshtë që ka për detyrë vetëm të dallojë nëse një gërmë është zanore apo jo

def zanore_apo_jo(germa):	
    if (germa == 'a'
        or germa == 'e'
        or germa == 'i'
        or germa == 'o'
        or germa == 'u'
        or germa == 'y'):
        # nese eshte zanore kthejme True
        return True
    else:
        return False

Funksioni zanore_apo_jo ka një parametër. Ky funksion kontrollon gërmën nëse është zanore apo jo dhe kthen True ose False përkatësisht.

Tani mund të shkruajmë një funksion që numëron zanoret në një fjalë të dhënë.

>>> def numero_zanoret(fjala):
        nr_zanoreve = 0
        for i in fjala:
            rezultati = zanore_apo_jo(i)
            if rezultati == True:
                nr_zanoreve += 1
        return nr_zanoreve
>>> numero_zanoret('python')
2

Funksioni i mësipërm që ka një parametër fillon me krijimin e një ndryshoreje që numëron zanoret dhe fillimisht ka vlerën zero. Cikli for shëtit nëpër çdo gërmë të parametrit fjala dhe thërret funksionin që krijuam më sipër. Në çdo përsëritje të ciklit ne i kalojmë si argument funksionit zanore_apo_jo një gërmë të parametrit të funksionit numero_zanoret ( parametri fjala). Tani zbatohen komandat e funksionit zanore_apo_jo. Pas perfundimit, programi kthehet serish aty ku kishte lënë zbatimet e komandave dhe vlerën e kthyer ne ja hedhim ndryshores rezultati. Nëse gërma sipas funksionit zanore_apo_jo është zanore e rrisim me një vlerën e ndryshores ku po numërojmë zanoret.

Operatori += është shkurtimi i : x = x + 1 që do të thotë vlerës së ndryshores x jepi vlerën që ndodhet në të djathtë të operatorit të hedhjes së vlerës duke ruajtur vlerën që ka dhe duke e shtuar me një sa herë që është e nevojshme të zbatohet kjo komandë.

Për të numëruar bashkëtingëlloret, në vazhdim të parimit të ripërdorimit të kodit e kemi shumë të lehtë të shkruajmë një funksion tjetër:

>>> def numero_bashketingelloret(fjala):
        nr_zanoreve = numero_zanoret(fjala)
        nr_bashketingelloreve = len(fjala) - nr_zanoreve
        return nr_bashketingelloreve
>>> numero_bashketingelloret('python')
4

Këtu kemi përdorur një funksion të gatshëm të pythonit që numëron gjatësinë e vargut të karaktereve len(). Ky funksion është përdorur për të gjetur numrin e bashkëtingëlloreve që ndodhen në një fjalë. Kështu nga numri i gërmave që ka fjala zbresim numrin e zanoreve, të cilin e gjejmë shumë lehtë tashmë me funksionin që shkruam më parë, dhe marrim numrin e bashkëtingëlloreve.

Le t'i kombinojmë funksionet që kemi shkruar për të përfunduar këtë shembull:

>>> def analizo_tekstin(teksti):
    print numero_zanoret(teksti), 'zanore dhe', numero_bashketingelloret(teksti), 'bashketingellore'
>>> analizo_tekstin('python')
2 zanore dhe 4 bashketingellore

Po të provoni të shkruani emrin tuaj dhe mbiemrin, ose te kaloni një fjali çfarëdo si argument për parametrin fjala, do të shikoni se hapesira do të merret si bashketingellore. Duke qenë se kodin e kemi organizuar ne funksione te veçanta për çdo detyrë, e kemi shumë të lehtë ta gjejmë se cila pjesë e kodit duhet ndryshuar për të korigjuar këtë gabim. Konkretisht llogaritja e hapësirës si bashkëtingëllore ndodh te funksioni që numëron bashkëtingëlloret, prandaj ky funksion është e vetmja pjesë që duhet ndryshuar nga i gjithë programi:

>>> def numero_bashketingelloret(fjala):
        nr_zanoreve = numero_zanoret(fjala)
        nr_bashketingelloreve = len(fjala) - nr_zanoreve
        nr_hapesirave = fjala.count(' ')
        return nr_bashketingelloreve - nr_hapesirave

Nga selektimi duket qarte kodi që kemi shtuar. Pra zgjidhja e problemit ishte zbritja e numrit të hapësirave nga numri i bashkëtingëlloreve. Për të gjetur numrin e hapësirave të një fjale nuk kemi nevojë të shkruajmë një funksion tjetër psh. "gjej_hapesirat" pasi mund të përdorim një funksion të gatshëm të python të quajtur count. Ky funksion ka një parametër që na lejon të specifikojmë një karakter, dhe na kthen si rezultat një numër që tregon se sa herë gjendet ky karakter tek fjala. Për funksionet e gatshme te vargjeve të karaktereve do të flasim më gjatë në një kapitull të veçantë.

>>> analizo_tekstin('monty pythons flying circus')
8 zanore dhe 16 bashketingellore

Në fund të këtij shembulli besoj janë të qarta avantazhet e ripërdorimit të kodit. Një gjë e tillë shmang gabimet si dhe e bën më te lehtë për të shkruar dhe më pas lexuar kodin.

Gjithashtu në këtë shembull zbatuam edhe parimin e dytë: përgjithësimin e kodit. Ne e bëmë funksionin final sa më të pergjithshëm duke shqyrtuar hapesirat që mund të kishte një fjalë, duke marrë parasysh që përdoruesi i këtij funksioni mund të dojë të shkruajë edhe fjali jo vetëm fjalë.

Parimi i tretë gjeti zbatim tek përdorimi i funksioneve të gatshëm len() dhe count(). Ne nuk u interesuam fare për të parë se si janë shkruar këto funksione te gatshme nga krijuesit e gjuhës, ne mjaftohemi me përdorimin e tyre për të realizuar detyrën që na duhej.

Në vazhdim do të shohim edhe zbatime të tjera të këtyre parimeve. Nëse krijojmë programe të ndryshme do të na duhet të krijojmë funksione specifike që do të na duhet t'i përdorim gjatë pjesëve të ndryshme të kodit. Për të arritur ketu duhet të krijojme funksione të mira. Që do të thotë: të këtë emër të mirë dhe komente të mira. E rëndësishme është vendosja e emrave me kuptim si dhe komente që u thjeshtojnë punë programuesve që punojnë në ekipe apo edhe vetë kur duam t'i kthehemi për ndryshime pjesëve të ndryshme të kodit. Komentet e mira bëjnë që të shmangim lodhjen për të kuptuar rreshtat e kodit që kemi shkruar dikur.

Funksionet e Bulit (Predikatet)

Funksionet e bulit në gjuhën e matematikës njihen si predikate. Këto funksione japin si rezultat dy vlera: e vërtetë e gabuar, 1 ose 0 etj.

Në shembullin që dhamë më lart ne morem si rezultat dy vlera: True dhe False.

def zanore_apo_jo(germa):	
    if (germa == 'a'
        or germa == 'e'
        or germa == 'i'
        or germa == 'o'
        or germa == 'u'
        or germa == 'y'):
        # nese eshte zanore kthejme True
        return True
    else:
        return False

Zakonisht këto funksione përdoren për t'i sherbyer pjesëve të tjera të kodit. Kështu funksionin e më sipërm ne e përdorëm në një tjetër funksion në këtë mënyrë:

rezultati = zanore_apo_jo(i)
if rezultati == True

Duke qenë se struktura e kontrollit if pranon çdo shprehje që mund të përkthehet në fund në True ose False, dhe duke qenë se funksionet predikate kthejnë njërën prej këtyre dy vlerave, funksionin mund ta kishim përdorur edhe në këtë mënyrë:

if zanore_apo_jo(i):

Funksionet rekursive

Pamë deri tani funksione që thërrasin brenda kodit të tyre funksione të tjerë. Funksionet rekursive janë funksionet që thërrasin veten. Ajo që duhet pasur parasysh kur krijojmë funksione rekursive është që të mos hyjme në cikle të pafundme; kjo mund të eleminohet duke përdorur strukturën if else. Pjse e If nuk do të përmbajë thirrje rekursive dhe bën të mundur mbylljen e funksionit, ndërsa else përmban rekursion. Për ta bërë më të qarte le të shohim shembullin e gjetjes së pjesëtuesit më të madh të përbashket të dy numrave:

>>> def pmp(a,b):
        if b==0:
            return a
        else:
            return pmp(b,a%b)
>>> pmp(20,14)
2

Funksioni i mësipërm pmp merr dy parametra. Fillimisht kërkon nëse b është i barabartë me zero dhe nëse plotësohet ky kusht na jep si rezultat vlerën e a-së. Nëse kushti nuk plotësohet atëherë funksioni thërret veten me parametra në këtë rast: b dhe mbetjen e pjesëtimit të a me b.

Shembulli është bazuar në algoritmin e euklidit për gjetjen e pmp-së i cili ndjek këtë logjikë:

Nqs a plotëpjesëtohet me b atëherë pmp(a,b)=b

Nqs a = b * h + m, ku h dhe m janë numra të plotë, atëherë pmp(a, b) = pmp(b, m).

(20,14)
20=1*14+6
14=2*6+2
6=3*2+0

Për ta pasur më të qarte le të shfaqim në ekran vlerat që merr funksioni sa herë që therret veten:

>>> def pmp(a,b):
        if b==0:
            return a
        else:
            print a,b
            return pmp(b,a%b)
>>> pmp(20,14)
20 14
14 6
6 2
2

Fillimisht vlerat janë 20 dhe 14. Më pas zbatohet thirrja e funksionit tek else dhe i kalohen argumentat b në vend të a-së që në këtë rast është 14 dhe në vend të b-së mbetja e a-së me b-në që është 6.

Tani funksioni fillon me argumentat 14 dhe 6. Kontrollohet nëse vlera e b-së është zero, përndryshe kalohet tek else, i cili thërret sërish veten me 6 dhe 2 si argumenta.

Sërish fillojmë nga e para me argumentat 2 dhe zero. Në këtë moment zbatohet kushti i if pasi vlera e b-së është zero. Dhe marrim si rezultat vlerën e a-së që është pmp.