15. Parameter podprogramu

Už od 7. témy Vytvárame podprogramy sme zostavovali veľa rôznych podprogramov, napr.

  • zavolanie stvorec_nahodne() na náhodnú pozíciu nakreslí zafarbený štvorček veľkosti 50x50

  • zavolanie karticka_nahodne() opäť na náhodnú pozíciu vykreslí bledomodrú kartičku s textom Python

  • zavolanie hlava(), telo(), ruky(), nohy() nakreslia na konštantnú pozíciu časti robota

Všetky tieto naše nové príkazy, teda podprogramy, fungujú úplne nezávisle. Ak by sme im chceli hocičo zmeniť, museli by sme buď preprogramovať podprogram, alebo vyrobiť z neho kópiu a v nej urobiť opravu.

Ukážeme to na príklade. Použijeme opäť podprogram stvorec_nahodne:

import tkinter
import random

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

def stvorec_nahodne():
    x = random.randint(10, 310)
    y = random.randint(10, 200)
    platno.create_rectangle(x, y, x+50, y+50, fill='indian red')

Tento podprogram vždy na náhodné pozície nakreslí červený štvorec veľkosti 50x50. Ak by sme ale potrebovali nakresliť aj štvorec napr. veľkosti 10x10, alebo nebodaj zelený, museli by sme vyrobiť kópiu tohto podprogramu (s novým menom) a v nej by sme urobili opravy, napr. takto:

def stvorec_nahodne2():
    x = random.randint(10, 310)
    y = random.randint(10, 200)
    platno.create_rectangle(x, y, x+10, y+10, fill='pale green')

Prípadne by sme pre každú predpokladanú veľkosť vytvorili nový podprogram s novým menom, prípadne s novou farbou.

Ale aj na toto existuje vo všetkých programovacích jazykoch mechanizmus, pomocou ktorého vieme riešiť takéto situácie bez toho, aby sme vyrábali kópie podprogramov s malými zmenami oproti pôvodným verziám.

Podprogram s parametrom

Pomocou parametra vieme do podprogramu pri jeho zavolaní priniesť z vonku nejakú informáciu, napr. veľkosť štvorčeka, počet kružníc, farba štvorčeka, text na kartičke a pod. To znamená, že podprogram musíme na toto pripraviť špeciálnym spôsobom, aby vedel s touto informáciou spávne pracovať.

Pri definovaní podprogramu môžeme zapísať:

def meno_príkazu(parameter):
    príkaz
    príkaz
    ...

V zátvorkách hlavičky podprogramu môžeme uviesť meno parametra, s ktorým bude vedieť tento podprogram pracovať. Je vhodné tu zvoliť také meno, aby už z neho bolo jasné s akou informáciu bude podprogram pracovať. Napr. keď zapíšeme:

def stvorec_nahodne(velkost):
    ...

už z hlavičky podprogramu tušíme, že podprogram bude kresliť štvorec danej veľkosti. Ak by sme videli hlavičku podprogramu:

def karticka_nahodne(vypisovany_text):
    ...

budeme predpokladať, že text, ktorý je parametrom bude vypísaný aj na kartičke.

Takže v tele podprogramu (odsunutý blok príkazov) by sa mal príslušný parameter použiť. Z pohľadu podprogramu je meno parametra obyčajnou premennou a preto s ňou podprogram môže normálne pracovať, napr.

def stvorec_nahodne(velkost):
    x = random.randint(10, 360-velkost)
    y = random.randint(10, 250-velkost)
    platno.create_rectangle(x, y, x+velkost, y+velkost, fill='indian red')

Vidíte, že v tele podprogramu sa pracuje s premennou velkost ako s obyčajnou premennou, ktorá je zatiaľ „neznáma“. Pri volaní podprogramu teraz namiesto stvorec_nahodne() musíme do týchto okrúhlych zátvoriek zapísať aj hodnotu parametra. Táto hodnota sa pri zavolaní podprogramu priradí do parametra velkost a tým sa bude dať korektne vykonať telo podprogramu.

Ak by sme teraz zapísali:

>>> stvorec_nahodne()
...
TypeError: stvorec_nahodne() missing 1 required positional argument: 'velkost'

Python nám touto správou oznamuje, že podprogram stvorec_nahodne očakával, že zadáme hodnotu parametra velkost. Hodnotu parametra (tzv. skutočný parameter) zadávame pri volaní podprogramu v okrúhlych zátvorkách. Napr. takéto volanie:

>>> stvorec_nahodne(10)

už funguje správne: hodnota 10 sa priradí do parametra velkost a potom sa normálne vykoná telo podprogramu už s touto priradenou hodnotou. Podprogram teda na náhodnú pozíciu nakreslí červený štvorček 10x10. Môžeme to vidieť. aj keď to zavoláme vo for-cykle:

for i in range(10):
    stvorec_nahodne(100)

dostaneme:

_images/15_01.png

Teraz ukážeme niekoľko príkladov podprogramov s parametrami.

Podprogram mocniny vypíše n riadkov, pričom v každom bude jeho poradové číslo (číslujeme od 0) a tiež druhá a tretia mocnina tohto čísla. Zrejme parametrom procedúry bude n a samotný podprogram bude vo for-cykle vypisovať tri čísla: premennú cyklu a jej druhú a tretiu mocninu:

def mocniny(n):
    for i in range(n):
        print(i, i**2, i**3)

Otestujeme:

>>> mocniny(10)
0 0 0
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729

Ďalší podprogram vypis bude mať parameter, ktorým nastavíme, aký text sa má vypísať, že ho máme radi:

def vypis(co):
    for i in range(5):
        print('*** mam rad', co, '***')

Otestujeme:

>>> vypis(37)
*** mam rad 37 ***
*** mam rad 37 ***
*** mam rad 37 ***
*** mam rad 37 ***
*** mam rad 37 ***
>>> vypis('matfyz')
*** mam rad matfyz ***
*** mam rad matfyz ***
*** mam rad matfyz ***
*** mam rad matfyz ***
*** mam rad matfyz ***

Vidíme, že hodnotou parametra nemusí byť len číslo, ale aj znakový reťazec.

Ďalší podprogram vypis_python na náhodnú pozíciu grafickej plochy vypíše slovo 'Python'. Parametrom podprogramu bude farba tohto textu:

import tkinter
import random

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

def vypis_python(farba):
    x = random.randint(50, 350)
    y = random.randint(50, 250)
    platno.create_text(x, y, text='Python', fill=farba, font='times 30')

vypis_python('red')
vypis_python('green')
vypis_python('blue')
vypis_python('gray')

Tento program na náhodné pozície vypíše slovo 'Python' rôznymi farbami:

_images/15_02.png

Úlohy

  1. Napíšte podprogram sucet s jedným parametrom n, ktorý spočíta súčet prvých n nepárnych čísel. Napr. pre n=4 treba spočítať 1+3+5+7. Procedúra vypíše tento súčet, napr.

    >>> sucet(4)
    vysledok = 16
    

    V procedúre využite for-cyklus, v ktorom bude mať range krok 2.

  1. Napíšte podprogram panelak s jedným parametrom pocet, ktorý zo štvorcov veľkosti 40x40 nakreslí panelák so zadaným počtom poschodí. Každé poschodie paneláku by mohlo mať nakreslené aj jedno okno. Napr.

    >>> panelak(5)
    

    nakreslí takýto obrázok:

    _images/15_03.png

  1. Napíšte podprogram farebny_stvorec s jedným parametrom farba, ktorý na náhodnú pozíciu nakreslí štvorec veľkosti 20x20 s danou farbou. Napr. nasledovný kód nakreslí takýto obrázok:

    for i in range(100):
        farebny_stvorec('red')
        farebny_stvorec('blue')
        farebny_stvorec('yellow')
    
    _images/15_04.png

Zhrnutie

čo sme sa naučili:

  • podprogramy môžu mať 0 alebo jeden parameter - 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