9. Metodika pre učiteľa - Náhoda


Úlohy na zopakovanie podprogramov:

  1. Riešenie:

    def ciara():
        print('+--+--+--+--+--+--+')
    
    def palicky():
        print('|  |  |  |  |  |  |')
    
    ciara()
    palicky()
    ciara()
    palicky()
    ciara()
    

  1. Riešenie:

    def ciara():
        print('+--+--+--+--+--+--+')
    
    def palicky():
        print('|  |  |  |  |  |  |')
    
    def stvorcekovy_papier():
        ciara()
        palicky()
        ciara()
        palicky()
        ciara()
        palicky()
        ciara()
        palicky()
        ciara()
    
    stvorcekovy_papier()
    

Cieľom je učiť náhodné čísla – žiakov necháme experimentovať s generátorom náhodných čísel:

  1. Komentár:

    Vidíme, že činnosť generátora sa najlepšie prejaví, ak ho vyvoláme viackrát.

    V metodike programovania sa môže postupovať tak, že:

    • buď najskôr učíme žiakov cyklus a potom podprogramy,

    • alebo najskôr podprogramy a potom cyklus.

    V jazyky Python je problém: ak najskôr učíme cyklus, môžeme žiakom zadávať iba také úlohy, ktorých riešenia majú v tele cyklu iba príkazy print, priradenia alebo kreslenie grafiky na tú istú pozíciu. Táto množina úloh je malá, vedie k náročným, skôr matematickým problémom, ktoré môžu byť pre začiatočníkov veľmi náročné. Keby sme ešte cyklus skombinovali aj s náhodnosťou, úlohy by sa ťažko vysvetľovali, prípadne by sa riešenia zle krokovali.

    Ak začneme s podprogramami ako prvými, môžeme žiakov prirodzene motivovať tak, že skupinu príkazov zabalíme a pomenujeme. Potom podprogram stačí raz alebo niekoľko krát vyvolať aj bez použitia cyklu. Tento metodický postup sa nám zdá výrazne jednoduchší a vedie aj k prehľadnejším riešeniam, zápisom.

    Zápis import random má podobný význam ako už známy import tkinter: nášmu programu sprístupní externú knižnicu nových príkazov (podprogramov). Knižnica tkinter obsahuje kompletnú grafiku a my sme ju využívali v zápise ˙˙tkinter.Canvas()˙˙. Knižnica random obsahuje viac užitočných funkcií, ktoré generujú náhodné čísla, my z nich zatiaľ využijeme len funkciu random.randint(od, do), ktorá náhodne vyberie hodnotu z daného intervalu celých čísel <od, do>.


Cieľom nasledujúcej ukážky je naučiť žiakov používať premenné na zapamätanie náhodne vygenerovanej hodnoty:

  1. Komentár:

    Premenná n je tzv. globálna premenná.


Ďalej chceme zabaliť hádzanie kockou do podprogramu, aby sa hody kockou dali jednoducho viackrát zopakovať. Z pohľadu žiaka je v nasledujúcej ukážke nové: použite premennej v podprograme (t.j. lokálna premenná n), použitie náhodných čísel v podprograme.

  1. Riešenie – iba bez použitia cyklu (t.j. copy-paste):

    import random
    
    def hod_kockou():
        n = random.randint(1, 6)
        print('Na kocke padla', n)
    
    hod_kockou()
    hod_kockou()
    hod_kockou()
    hod_kockou()
    hod_kockou()
    hod_kockou()
    hod_kockou()
    hod_kockou()
    hod_kockou()
    hod_kockou()
    

    Pojmy lokálna a globálna premenná zatiaľ netreba učiť. Plánujeme riešiť iba také úlohy, v ktorých by sa nemali vyskytnúť konflikty s premennými.

    Z pohľadu Pythonu lokálna premenná existuje len počas behu podprogramu, t.j. vznikne až po zavolaní podprogramu. Po skončení behu podprogramu táto premenná viac neexistuje (sa automaticky zruší). Globálne premenné existujú od ich vzniku (priradením mimo podprogramu), ale na rozdiel od lokálnych premenných nemôžeme im meniť hodnotu v podprograme.

    Toto žiakom vysvetľovať nemusíme, ale je to dobre vedieť, ak bude treba riešiť nejaký problém.


Nasledujú úlohy, v ktorých žiaci lepšie spoznávajú generátor náhodných čísel. Pri všetkých riešeniach predpokladáme, že ich pre otestovanie zavolajú viackrát.

  1. Riešenie – iba upravený podprogram hod_kockou:

    def hod_kockou():
        n = random.randint(1, 20)
        print('Na kocke padla', n)
    

  1. (*) Riešenie – iba upravený podprogram hod_kockou:

    def hod_kockou():
        n = random.randint(0, 1)
        print('Na kocke padla', n)
    

  1. (*) Riešenie – iba upravený podprogram hod_kockou:

    def hod_kockou():
        n = random.randint(1, 6) * 2
        print('Na kocke padla', n)
    

  1. (*) Riešenie – iba upravený podprogram hod_kockou:

    def hod_kockou():
        n = random.randint(1, 6) * 2 - 1
        print('Na kocke padla', n)
    

  1. (*) Riešenie – iba upravený podprogram hod_kockou:

    def hod_kockou():
        n = random.randint(1, 6) ** 2
        print('Na kocke padla', n)
    

    Ak budú mať žiaci problémy, treba s nimi diskutovať a učiť ich takéto výrazy zostavovať.


  1. Riešenie:

    def predpoved():
        print('Dnes bude', random.randint(-15, 35), 'stupňov.')
    
    predpoved()
    

  1. Riešenie:

    import random
    
    a = random.randint(0, 9)
    b = random.randint(0, 9)
    c = random.randint(0, 9)
    d = random.randint(0, 9)
    print('Tvoj nový PIN je', a, b, c, d)
    

  1. Riešenie:

    import random
    
    den = random.randint(1, 30)
    mesiac = random.randint(1, 12)
    rok = random.randint(2018, 2099)
    print('Koniec sveta bude', den, '.', mesiac, '.', rok)
    

    Alebo bez premenných:

    import random
    
    print('Koniec sveta bude',
          random.randint(1, 30), '.',
          random.randint(1, 12), '.',
          random.randint(2018, 2099))
    

    Takýto výpis sa niektorým žiakom nemusí páčiť, keď vypisované bodky vo vygenerovanom dátume sú od čísel oddelené medzerami. Pokročilejšie formátovanie výstupov je náročnejšia téma a je mimo tohto kurzu. Len pre zaujímavosť uvádzame rôzne riešenia zápisu riadku s príkazom print:

    print('Koniec sveta bude', den, '.', mesiac, '.', rok)
    

    Tieto zápisy dajú rovnaký výsledok:

    print(f'Koniec sveta bude {den}.{mesiac}.{rok}')
    print('Koniec sveta bude {}.{}.{}'.format(den, mesiac, rok))
    print('Koniec sveta bude', str(den) + '.' + str(mesiac) + '.' + str(rok))
    print('Koniec sveta bude ', den, '.', mesiac, '.', rok, sep='')
    

    Neodporúčame to učiť žiakov pri ich momentálnych programátorských skúsenostiach.


V nasledujúcich úlohách sa kombinuje kreslenie a náhodné čísla:

  1. Riešenie – iba volania:

    nahodny_stvorcek()
    nahodny_stvorcek()
    nahodny_stvorcek()
    nahodny_stvorcek()
    nahodny_stvorcek()
    

  1. Riešenie – iba upravený podprogram nahodny_stvorcek:

    def nahodny_stvorcek():
        x = random.randint(10, 300)
        y = random.randint(10, 200)
        a = random.randint(10, 100)
        canvas.create_rectangle(x, y, x + a, y + a, fill='orange')
    

    Premenné x, y, a sú lokálne premenné. Premenná canvas je globálna premenná.


  1. Riešenie:

    import tkinter
    import random
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    def nahodny_stvorcek():
        x = random.randint(10, 300)
        y = random.randint(10, 200)
        a = random.randint(10, 100)
        canvas.create_rectangle(x, y, x + a, y + a, fill='orange')
    
    def nahodny_obdlznik():
        x = random.randint(10, 300)
        y = random.randint(10, 200)
        a = random.randint(10, 100)
        b = random.randint(10, 100)
        canvas.create_rectangle(x, y, x + a, y + b, fill='lime green')
    
    nahodny_stvorcek()
    nahodny_obdlznik()
    nahodny_stvorcek()
    nahodny_obdlznik()
    nahodny_stvorcek()
    nahodny_obdlznik()
    nahodny_stvorcek()
    nahodny_obdlznik()
    nahodny_stvorcek()
    nahodny_obdlznik()
    

    Podprogram nahodny_obdlznik zrejme vznikne ako kópia podprogramu nahodny_stvorcek, ktorú premenujeme a pridáme do neho lokálnu premennú b pre výsku obdĺžnika. Farbu si zvoľte podľa vlastného výberu.


  1. Riešenie:

    import tkinter
    import random
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    x = random.randint(50, 250)
    y = random.randint(50, 150)
    canvas.create_rectangle(10, 10, 10 + x, 10 + y, fill='darkgreen')
    canvas.create_rectangle(10 + x, 10, 310, 10 + y, fill='yellow')
    canvas.create_rectangle(10, 10 + y, 10 + x, 210, fill='orange')
    canvas.create_rectangle(10 + x, 10 + y, 310, 210, fill='navy')
    

    Vonkajšie vrcholy obdĺžnika si zvoľte ľubovoľne. V našom riešení má ľavý horný roh súradnice (10, 10) a keďže jeho rozmery majú byť 300x200, tak protiľahlý vrchol (pravý dolný) má súradnice (310, 210). Vnútorný náhodne zvolený bod sme vygenerovali tak, aby bol od okrajov obdĺžnika vzdialený aspoň 50, tada každá zo štyroch oblastí bude minimálne veľká 50x50.


Zhrnutie

ciele lekcie

  • zoznámiť sa s ideou generátora náhodných čísel z nejakého rozsahu (intervalu)

  • naučiť sa používať lokálne premenné v podprogramoch (intuitívne bez nutnosti vysvetľovania)

  • naučiť sa, že vygenerovanú hodnotu treba niekedy uložiť do premennej (na jej viacnásobné použitie)

zručnosti

  • zápis import random na úplnom začiatku programu

syntaktické pravidlá

  • príkaz import pre začlenenie knižnice random

  • spôsob zápisu volania generátora náhodných čísel (random.randint(1, 6))