10: Funkcijų kūrimas

Šioje pamokoje išmoksime vieną svarbiausių programavimo idėjų -- funkcijų kūrimą! Naudodami funkcijas galime programas padaryti trumpesnėmis, geriau-organizuotomis, lengviau skaitomomomis ir panaudojamomis. Tolimesnėse pamokose apžvelgsime kitus naudingus Pitono elementus, tokius kaip rekursiją (recursion).

Kaip apibrėžti funkciją?

Pradėsime nuo pavyzdžio. Ar atsimenate funkciją abs? Ji priima vieną argumentą - skaičių x, ir grąžina jo modulį - teigiamą reikšmę (x kai x ≥ 0, ir -x kai x < 0). Python’e šią funkciją galima sukurti (apibrėžti) taip:

def abs(x):     # def - sutrumpintas angl. „define“ - apibrėžti.; pavadinimas „abs“ ir argumentas, pavadinimu „x“.
  if x >= 0:    # funkcijos veiksmai -- atitrauktame bloke
    return x
  else:
    return -x   # funkcijos veiksmų pabaiga
(Spustelkite čia, kad išbandytum šį kodą konsolėje.)

 

Dvi funkcijos aprašymo dalys

Pirmoje eilutėje nurodomas funkcijos pavadinimas ir skliaustuose -- argumentai (parametrai) :

def «pavadinimas»(«argumentai»):

Pavyzdyje, abs yra vardas, o argumentas -- x. Argumentų gali būti ir daugiau, pvz  def skaiciuok(x, y, z), o gali ir visai nebūti - tiesiog tušti skliaustai def darykkazka(). Argumentai - tai iškvietimo metu funkcijos gaunami duomenys (įvestis).Kitose eilutėse, atitraukus nuo krašto, surašomi funkcijos veiksmai. Kai funkcija yra iškviečiama programoje, Pitonas tiesiog vykdo joje nurodytus veiksmus (su gautais argumentais). Komanda

return «rezultatas»

baigia funkcijos vykdymą ir grąžina funkcijos rezultatą (išvestį) ten, iš kur funkcija buvo kviesta. Kaip matote „abs“ apraše, return veiksmai gali būti keliose vietose, bet tik vienas būna įvykdytas (priklausomai nuo aplinkybių). Jei nėra return komandos, funkcija, baigusi savo veiksmus, grąžina specialią reikšmę None.

 

Pavyzdys: funkcijos kūrimas ir kvietimas

Šioje programoje yra aprašoma funkcija ir keletas veiksmų, naudojančių tą funkciją. Ar galite atspėti ką atspausdins ši programa?

Matome, kad funkcijos pavadinimas yra „square“, jai reika pateikti vieną argumentą (x), o funkcijos veiksmuose tėra viena eilutė return x*x. Po funkcijos yra dvi komandos, kurios ją iškviečia iš viso 3 kartus.Vykdydami veiksmų sekimą, atkreipkite dėmesį, kad iškvietus funkciją, jai yra išskiriama atskira darbinė sritis (angl. "frame"). Pasibaigus funkcijai, ši sritis vėl panaikinama (atlaisvinama kompiuterio atmintis).Pasiaiškinkime, kaip pažingsiniui atliekama programa.

  1. Kai iškviečiama pirmoji komanda  square(10),
    • Pitonas priskiria duomenis (10) argumentui (x). Programa vykdo return x*x, žinodama, kad x reikšmė yra 10. Todėl funkcijos reikšmė gaunasi 100.  Ji ir atspausdinama.
  2. Kai iškviečiama antroji komanda  square(square(2)),
    • Vidinė dalis (square(2)) yra atliekama pirmiau: x reikšmė būna  2, o funkcijos rezultatas -- 4.
    • Po to jau galima įstatyti reikšmę ir skaičiuoti likusią išraišką - dar kartą kelti kvadratu -- square(4). Tai grąžina 16, ir ši reikšmė atspausdinama.

Svarbu neužmirši, kad funkcija yra vykdoma, tik ją iškvietus - neužtenka vien aprašymo.  Tuo pačiu, iškviesti funkciją galima tik po jos aprašo (ne prieš jį). Žvilgtelkite pavyzdį:

Pasirinkimo užduotis:
Ką atspausdins ši programa?

def f():          # funkcija su 0 argumentų
   print("in f")
print("not in f")
f()               # čia iškviečiame „f“
Teisingai! Funkcija f yra apibrėžta, tačiau jos veiksmai dar nėra atliekami. Apibrėžę funkciją mes atspausdiname not in f. Tada funkcija kartu su visais joje esamais veiksmai, yra atliekama in f.

Pitone funkcijas galima aprašyti bet kurioje vietoje, bet patartina jas išvardinti programos pradžioje, kad nesimaišytų su pagrindinio algoritmo kodu.

4 dažniausios klaidos

1. Dažnai, aprašant funkciją, pamiršima panaudoti return komanda.

Pavyzdys
Pirma klaida: pamirštas  return
Jeigu funkcijoje nėra return, ji grąžina None reikšmę.
Kartais return nėra būtinas. Pavyzdžiui, funkcijose, kurios skirtos rezultato atspausdinimui:
Pavyzdys: Rezultatas spausdinamas, o ne grąžinamas

 

2. Antra dažna klaida yra susijusi su atitraukimu - IndentationError.

Pavyzdys
Antra klaida: pamiršome atitraukti

 

3. Kaip jau matėme antrojoje pamokoje, argumentų skaičiaus neatitikimas taip pat iššaukia klaidą.

Pavyzdys
Trečia klaida: kvietimas su per daug argumentų.

 

4. Galų gale, gali pasitaikyti rašybos klaidos. Tai gali atsitikti dviejose vietose, aprašant arba kviečiant funkciją. Tokiais atvejais bus pranešimas, kad funkcija nėra apibrėžta.

Pavyzdys
Ketvirta klaida: klaidingas pavadinimas

Pabandykite patys

Programavimo pratimas: Kubizmas
Aprašykite funkciją cube(n), kuri gauna vieną skaičių n ir grąžina jo kubą n × n × n.
Žemiau įveskite testavimo veiksmus, pvz., print(myfunction("testiniai duomenys")).

 

Du ar daugiau argumentų

Aukščiau esanti funkcija naudoja tik vieną argumentą, tačiau jų gali būti bet kiek. Pavyzdžiui, jau esame kvietę input(), kuriai nereikalingas nei vienas argumentas.Pavyzdžiui, funkcijai trikampio plotui skaičiuoti reikalingi du argumentai: trikampio pagrindo ilgis ir aukštinė.

area = base × height / 2
plotas = pagrindas × aukštinė / 2

Čia reikės 2 argumentų:  def «funkcijos_vardas»(«argumentas1», «argumentas2»).


 

Paskutiniame pratime paskaičiuosime stačiakampio perimetrą (visų kraštinių sumą). Pagal dešinėje esantį brėžinuką, tiktų formulė:

\textrm{perimetras = (height + width) * 2 }



Programavimo pratimas: Stačiakampio perimetras
Apibrėžkite funkciją rectanglePerimeter(width, height), kuri suskaičiuos stačiakampio perimetrą.
Žemiau įveskite testavimo veiksmus, pvz., print(myfunction("testiniai duomenys")).

 

Funkcijos, kviečiančios funkcijas

Funkcijos yra gerai suprojektuotų didelių programų „plytos“. Funkcijos leidžia pakartoti veiksmus, jų neaprašant daug kartų, o tik pakartotinai iškviečiant funkciją.  Beje, funkcijose galime naudoti kitas funkcijas.Programavimo pratikoje yra rekomenduojama laikytis „DRY KISS“ principų -- jie reiškia:

  • „Don't Repeat Yourself“  (neaprašinėti kelis kartus to paties)
  • „Keep It Simple Stupid“  (organizuoti programą taip, kad joje būtų kuo lengviau susigaudyti (net ir kvailiams) )

Funkcijos padeda įgyvendinti abu šiuos principus :).

Ar galite atspėti ką daro ši programa? Prisiminkime, ko mokėmės 4-oje pamokoje, daugindami tekstą iš skaičiaus -- gauname teksto pakartojimą. Pavyzdžiui, "tar"*2 tampa "tartar".
Galite patraukti vertikalią pilką liniją į šoną, kad matytume daugiau kodo.Vykdant veiksmų sekimą, galite pastebėti, kaip funkcija „inner“ iškviečiama iš  funkcijos „outer“. 8-tame vykdymo žingsnyje matome, kad yra 3 darbinės sritys ("frames"): globali, „outer“, ir ką tik atsiradusi „inner“. Funkcija „outer“ laukia, kol „inner“ baigsis, ir tada toliau tęsiama. Pabandykite atidžiai „pražingsniuoti“per visą programą ir sekti funkcijų darbines sritis.