8. Náhoda

Aby sme mohli ešte lepšie ilustrovať vytváranie nových príkazov pre kreslenie do grafickej plochy, zavedieme najprv pojem náhodné čísla.

Náhodné čísla

Programátori veľmi často potrebujú, aby im počítač vygeneroval nejaké náhodné číslo. Počítač vtedy nejako simuluje náhodnosť, teda „sa tvári“, že si vymyslí číslo z nejakého intervalu. Keby sme potrebovali napr. interval od 1 do 6, počítač by dokázal donekonečna vymýšľať postupnosť takýchto čísel, akokeby hádzal hracou kockou, na stranách ktorej sú čísla od 1 do 6. Generovať takúto náhodnú postupnosť je z matematického hľadiska veľmi zaujímavé, my ale budeme predpokladať, že to počítač zvláda dobre a nikdy nebudeme vedieť predpokladať, aké číslo padne nabudúce.

Náhodný generátor programátori využívajú nielen v počítačových hrách (aby sa nepriateľ správal nepredvídateľne), ale aj na simuláciu rôznych procesov (mapr. hádzanie hracou kockou) a často aj na ladenie našich programov (počítač napr. náhodne určí, kde sa nakreslí nejaký útvar).

Naučme sa teraz používať náhodný generátor v Pythone. Tak, ako sme pri grafickje ploche zapísali import tkinter (označuje, že chceme pracovať s grafikou), aj pri práci s náhodným generátorom musíme najprv uviesť:

import random

Týmto príkazom Python vie, že budeme pracovať s náhodnými číslami, teda dostávame k dispozícii niekoľko funkcií, ktoré dokážu generovať takéto čísla. My sa zoznámime jednou z nich random.randint, hoci v dokumentácii sa dajú nájsť aj ďalšie 1. Funkcia random.randint je taký podprogram, ktorý nič nevypisuje, nevykresľuje, ale vždy keď ho zavoláme, vráti nejaké náhodné číslo. Interval, z ktorého sa náhodne toto číslo vyberie, sa určuje parametrami:

random.randint(od, do)

Každé zavolanie tejto funkcie vráti náhodnú hodnotu z intervalu oddo. Môžeme to otestovať v interaktívnom režime:

>>> import random
>>> random.randint(1, 6)
3
>>> random.randint(1, 6)
1
>>> random.randint(1, 6)
6
>>> random.randint(1, 6)
1
>>> random.randint(1, 6)
1

Každým ďalším zavolaním tejto funkcie dostaneme nejakú náhodnú hodnotu. Samozrejme, že sa tieto hodnoty môžu opakovať rovnako, ako by sa mohli opakovať, keby sme hádzali hracou kockou (s číslami od 0 do 5).

Napíšme teraz program, ktorý hodí dvomi kockami (dvakrát zavolá funkciu random.randint), potom tieto dve hodnoty vypíše aj s ich súčtom:

# program s nahodnymi cislami

import random

def hadz_dvomi_kockami():
    prva = random.randint(1, 6)
    druha = random.randint(1, 6)
    print('hodil si', prva, 'a', druha, 'a ich sucet je', prva + druha)

hadz_dvomi_kockami()

Po spustení môžeme dostať napr.

hodil si 1 a 4 a ich sucet je 5

Tento podprogram môžeme zavolať aj viackrát:

hadz_dvomi_kockami()
hadz_dvomi_kockami()
hadz_dvomi_kockami()
hadz_dvomi_kockami()
hadz_dvomi_kockami()

a po spustení môžeme vidieť napr. takýto výstup:

hodil si 3 a 3 a ich sucet je 6
hodil si 6 a 1 a ich sucet je 7
hodil si 1 a 2 a ich sucet je 3
hodil si 6 a 1 a ich sucet je 7
hodil si 3 a 2 a ich sucet je 5

Zrejme každé spustenie programu s najväčšou pravdepodobnosťou vygeneruje úplne inú päticu hodov dvomi kockami.

Grafika a náhodné čísla

Generátor náhodných čísel teraz využijeme na vygenerovanie náhodnej pozície umiestnenia nejakého útvaru. Napíšeme podprogram stvorec_nahodne, ktorý nakreslí štvorec veľkosti 50x50 na náhodné pozície. Keďže predpokladáme, že grafická plocha má rozmery približne 370x260, ľavý horný vrchol náhodného štvorca nech je od (10, 10) do (310, 200). Teda náhodná x-ová súradnica je náhodné číslo od 10 do 310 a y-ová od 10 do 200. Použijeme funkciu random.randint:

# program nakresli pat stvorcov na nahodne pozicie

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')

stvorec_nahodne()
stvorec_nahodne()
stvorec_nahodne()
stvorec_nahodne()
stvorec_nahodne()

Všimnite si:

  • na začiatok programu sme umiestnili riadok import tkinter aj riadok s import random

  • podobne ako pri hádzaní dvoch kociek, aj tu sme v podporgrame stvorec_nahodne vygenerovali dve náhodné hodnoty do premenných x a y, pričom každá z nich má iný interval

  • aj tu sme na záver päť krát zavolali príkaz stvorec_nahodne, aby sme dostali 5 náhodných štvorcov

Po spustení môžeme dostať nejaký podobný obrázok:

_images/08_01.png

Náhodný generátor môžeme využiť nielen na určenie náhodnej pozície, ale aj na veľkosti strán obdĺžnika. Nasledovný program je miernou modifikáciou predchádzajúceho programu, ktorý kreslil náhodné štvorce:

# program nakresli pat nahodne velkych obdlznikov na nahodne pozicie

import tkinter
import random

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

def nahodny_obdlznik():
    a = random.randint(10, 100)
    b = random.randint(10, 100)
    x = random.randint(10, 360-a)
    y = random.randint(10, 250-b)
    platno.create_rectangle(x, y, x+a, y+b, fill='lime green')

nahodny_obdlznik()
nahodny_obdlznik()
nahodny_obdlznik()
nahodny_obdlznik()
nahodny_obdlznik()

Po spustení môžeme dostať nejaký podobný obrázok:

_images/08_02.png

Úlohy

  1. Napíšte podprogram predpoved, ktorý vypíše správu:

    dnes bude 15 stupnov
    

    v ktorej číselný údaj podprogram zvolí náhodne z intervalu <-15, 35>.

  1. Napíšte program, ktorý nakreslí tesne vedľa seba 10 obdĺžnikov, ktorých šírka je 30 a výška je náhodné číslo od 10 do 200. Pre tieto obdĺžniky zvoľte rôzne farby, napr.

    _images/08_03.png

  1. Napíšte podprogram, ktorý vygeneruje náhodné tri sumy za náše nákupy (náhodné číslo od 1 do 15), vypíše ich a na záver vypíše ich súčet. Napr. takto:

    tvoj prvý nákup za 12 euro
    tvoj druhý nákup za 4 euro
    tvoj tretí nákup za 9 euro
    spolu si zaplatil 25 euro
    

  1. Podprogram v_sieti na náhodné políčko v sieti, v ktorej sú štvorčeky 50x50, položí štvorček. Po 10 zavolaniach to môže vyzerať napr. takto:

    _images/08_04.png

  1. Napíšte program, ktorý najprv zvolí dve náhodné čísla a a b s hodnotami od 10 do 190 a potom rozdelí štvorec 200x200 na štyri časti (obdĺžniky) pričom ľavá horná časť má rozmery a x b a pravá spodná časť má rozmery 200-a x 200-b. Každý z týchto obd=lžnikov zafarbite inou farbou, napr. takto:

    _images/08_05.png

Zhrnutie

čo sme sa naučili:

  • náhodné čísla sú pre informatikov, ale aj matematikov, užitočným nástrojom, pomocou ktorého dokážeme simulovať rôzne náhodné javy, napr. hádzanie kockou


1

Ďalšou podobne užitočnou funkciou z modulu random je random.randrange. Je na učiteľovi, ktorú z týchto dvoch použije. Na začiatok nie je vhodné uvádzať obe. Funkcia random.randrange môže mať jeden alebo dva parametre: random.randrange(hranica) alebo random.randrange(od, hranica). Teraz bude generovať náhodné čísla z intervalu <od, hranica-1>.