16. Parametre podprogramov

Viac parametrov

Pri vytváraní podprogramu môžeme využiť aj viac ako jeden parameter. Vtedy ich v hlavičke podprogramu navzájom oddelíme čiarkami. Zapíšeme:

def meno_príkazu(parameter1, parameter2, ...):
    príkaz
    príkaz
    ...

Ako to funguje, ukážeme na príklade. Napíšeme podprogram, ktorý pre dané (x, y) nakreslí modrý kruh s daným stredom a polomerom 20:

import tkinter

platno = tkinter.Canvas(bg='white')
platno.pack()

def modry_kruh(x, y):
    platno.create_oval(x - 20, y - 20, x + 20, y + 20, fill='blue')

Podprogram modry_kruh má dva parametre x a y, a preto, keď ho chceme zavolať, musíme určiť hodnoty oboch parametrov. Zrejme pri volaní podprogramu sa prvá hodnota priradí do prvého parametra x a druhá hodnota do druhého y. Napr.

modry_kruh(150, 50)
modry_kruh(150, 200)
modry_kruh(50, 120)
modry_kruh(250, 120)

Nakreslí:

_images/16_01.png

Nič nám nebráni v tom, aby sme tento podprogram ešte trochu vylepšili. Napíšeme podprogram kruh, ktorý bude mať okrem x a y ešte dva ďalšie parametre r a farba:

def kruh(x, y, r, farba):
    platno.create_oval(x - r, y - r, x + r, y + r, fill=farba)

Z mien parametrov sa dá pochopiť, že podprogram bude kresliť kruh so stredom (x, y), s polomerom r a s farbou výplne farba. Takáto logika parametrov je pri programovaní bežná, len si bude treba dávať trochu väčší pozor na poradie parametrov pri volaní podprogramu.

Vďaka tomuto jednoduchému podprogramu môžeme takto elegantne zapísať program, ktorý nakreslí do jedného radu niekoľko zväčšujúcich sa kruhov:

x = 15
r = 10
for i in range(8):
    kruh(x, 120, r, 'brown')
    x = x + r + r + 5
    r = r + 5

a takto to vyzerá po spustení:

_images/16_02.png

Keďže v premennej x je x-ová súradnica stredu práve kresleného kruhu, preto po nakreslení kruhu najprv toto x zväčšíme o r (dostali sme sa na pravý okraj kružnice) a keďže nasledovný kruh bude mať polomer r zväčšený o 5, tak aj x zväačšíme o r+5 - teraz je x nastavené presne na stred nasledovného už väčšieho kruhu.

Teraz, keď už máme podprogram kruh, môžeme nakresliť snehuliaka, ktorý sa bude skladať z troch na sebe postavených kruhov. Napíšeme nový podprogram, ktorý bude mať iba dva parametre x a y a na ich základe nakreslí tri kruhy takto: prvý najväčší bude mať svoj stred v (x, y) a polomer 30, druhý s polomerom 20 bude umiestnený na ňom, teda jeho y-ová súradnica bude menšia nielen o polomer väčšieho 30 ale aj jeho polomer teda 20. Najmenší kruh s polomerom 10 bude mať ešte zmenšenú y-ovú súradnicu oproti druhému o svoj aj jeho polomer. Zapíšme tento nový podprogram:

def snehuliak(x, y):
    kruh(x, y, 30, 'light gray')
    kruh(x, y-30-20, 20, 'light gray')
    kruh(x, y-30-20-20-10, 10, 'light gray')

Farbu kruhov sme zvolili svetlošedú, aby boli lepšie viditeľné na bielom podklade. Napr. volania:

snehuliak(100, 200)
snehuliak(150, 110)
snehuliak(230, 160)
snehuliak(300, 130)

Nakreslia:

_images/16_03.png

Je dobré si uvedomiť, ako vlastne fungujú vzájomné volania podprogramov:

  • náš program štyrikrát zavolal podprogram snehuliak - zakaždým s inými parametrami

  • v podprograme snehuliak sa trikrát zavolal podprogram kruh - zakaždým s niekorými inými parametrami

  • v podprograme kruh sa raz zavolal príkaz create_oval, ktorý je v skutočnosti tiež podprogram, lenže tento už dávnejšie naprogramoval niekto iný a je súčasťou modulu tkinter

Čo všetko sa v skutočnosti udeje, keď sa na nejakom mieste zavolá nejaký podprogram?

  1. Python si musí zapamätať presné miesto, kam sa bude treba po vykonaní podprogramu vrátiť

    • napr. pri volaní snehuliak(100, 200) sa zapamätá, že potom bude nasledovať vykonávanie 2. riadku programu

  2. Pre každý z parametrov v hlavičke podprogramu sa vytvoria dočasné premenné a priradia sa im hodnoty skutočných parametrov

    • napr. pri volaní snehuliak(100, 200) sa v tomto podprograme vyrobia dve dočasné premenné x a y a priradia sa im hodnoty 100 a 200

  3. Postupne sa vykonajú všetky príkazy v tele podprogramu

    • pre podprogram snehuliak sú to tri volania kruh

  4. Keď sa sončí vykonávanie všetkých príkazov z tela podprogramu, zrušia sa všetky dočasné premenné, teda x a y

  5. Ďalší výpočet pokračuje na zapamätanom riadku z prvého bodu postupu

Asi ste si všimli, že oba podprogramy snehuliak aj kruh majú parametre x a y. Každý z týchto podprogramov má ale svoju vlastnú verziu týchto premenných. Python bez problémov zvláda veľa verzií tých istých premenných, ktoré ale existujú len počas behu nejakého podprogramu.

Úlohy

  1. Napíšte podprogram kvet, ktorý bude mať 3 parametre x, y a farba. Podprogram nakreslí takúto kvetinku: najprv štyri lupene (zafarbené kruhy, ktoré sa dotýkajú bodu (x, y)) a potom do stredu (x, y) žltý kruh. Všetky tieto kruhy majú polomer 15. Napr.

    _images/16_04.png

    Na kreslenie kruhov použite procedúru kruh.

  1. Napíšte podprogram pyramida s tromi parametrami: vyska, x, y. Podprogram nakreslí pyramídu, ktorá je zložená s vyska obdĺžnikov, pričom najmenší má rozmer 10x10, každý ďalší má šírky o 20 väčšiu, teda postupne 30x10, 50x10, … Parametre x a y určujú stred najmenšieho obdĺžnika. Napr.

    _images/16_05.png

    Na tomto obrázku sú nakreslené tri pyramídy, ktoré boli vytvorené volaním podprogramu pyramida s rôznymi parametrami.

  1. Napíšte tri podprogramy: panel(x, y), rad(n, x, y) a panelak(m, n, x, y). Podprogram panel nakreslí šedý štvorec 40x40 s modrým oknom 20x20 uprostred. (x, y) je ľavý horný vrchol tohto štvorca. Podprogram rad nakreslí rad panelov, t.j. n-krát zavolá podprogram panel. (x, y) je ľavý horný vrchol prvého panelu v rade. Podprogram panelak zavolá m-krát podprogram rad, aby sa postavil panelák zložený z m radov po n panelov. Na nasledovnom obrázku vidíte jeden panel, jeden rad aj panelak so 4 radmi po 3 panely v každom:

    _images/16_06.png

Zhrnutie

čo sme sa naučili:

  • podprogramy môžu mať 0, 1, 2, alebo aj viac parametrov - definujú sa v hlavičke podprogramu def

  • pri volaní podprogramov musíme do zátvoriek uviesť presne toľko hodnôt, koľko parametrov sa tu očakáva

  • Python potom tieto hodnoty parametrov dosadí do dočasných premenných, ktoré sa po skončení vykonávania tela podprogramu zrušia