DoDo / Programování

Mirek Kučera - vvendigo@seznam.cz

23. září

Instalace jazyka Python pro Windows

Stačí v Microsoft Store zahledat Python a nechat nainstalovat verzi 3.10 (ale pro naše účely lze použít i jakoukoli jinou verzi > 3.1).

Druhou možností, např. pro jiný operační systém, je stáhnout a nainstalovat balík z python.org.

V nabídce programů přibude Python a IDLE.

IDLE

Po spuštění se objeví tzv. konzole, do které můžeme psát matematické výrazy i jakékoli příkazy jazyka Python. Po stisknutí klávesy Enter se daný příkaz vyhodnotí.

Například:

>>> 1 + 1
2
>>> max(1, 3, 2)
3
>>> "+" * 20
'++++++++++++++++++++'

První program

V menu IDLE vlevo nahoře, zvolíme File -> New File a otevře se okno editoru. První program bude opravdu jednoduchý:


print("Ahoj, Světe!")

Program spustíme pomocí menu editoru Run -> Run module. Před spuštěním musíme program uložit, spouští se ze souboru z disku.

Spuštění lze urychlit použitím klávesových zkratek: Ctrl+S (uložit) a pak F5 (spustit modul).

30. září

Funkce print()

Tato funkce tiskne na obrazovku parametry, které jí dáme. Parametry píšeme do závorek za jméno funkce. Vyzkoušet to lze v konzoli. Např.

>>> print("Ahoj!")
Ahoj!
>>> print("Cislo jedna:", 1)
Cislo jedna: 1

Po vytištění parametrů funkce ukončí ("skočí na nový") řádek. Pokud nezadáme parametr žádný, vytiskne jen prázdný řádek. To jsem použil v programu ukazujícím odlet rakety:

print("  I  ")
print(" XXX ")
print(" XOX ")
print(" XXX ")
print("XXXXX")
print("XXXXX")
print("XX XX")

print()
print()
print()
print()
print()
print()
print()
print()
print()
print()
print()
print()
print()
print()
print()

Zmínil jsem pojem ASCII art - kreslení pomocí znaků.

for cyklus

Opakované psaní stejné funkce je dost otravné. Proto počítačové jazyky obsahují konstrukci cyklu. V případe Pythonu je trochu specifická: for JMENO_PROMENNE in POSLOUPNOST_DAT:. Následující řádky, odsazené o stejný počet mezer jsou pak vykonány tolikrát, kolik je prvků v POSLOUPNOST_DAT (této skupině řádků se říká tělo cyklu). Pro naší raketu jsem to použil takto:

print("  I  ")
print(" XXX ")
print(" XOX ")
print(" XXX ")
print("XXXXX")
print("XXXXX")
print("XX XX")

for X in range(0, 40):
    print()

Funkce range(OD, DO, KROK) vyrobí potřebnou posloupnost dat - čísel od OD do čísla DO-1. Abychom viděli čísla co vyrobí v konzoli, musíme ji předat jako parametr do funkce list(), která z nich vyrobí seznam:

>>> range(0, 10)
range(0, 10)
>>> list( range(0, 10) )
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list( range(0, 10, 2) )
[0, 2, 4, 6, 8]
>>> list( range(10, 0, -1) )
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

V našem případě nás ta čísla ale nezajímají, jde nám jen o ten počet opakování cyklu. Kdybychom ale chtěli, můžeme v těle cyklu pracovat s proměnnou X (do které Python postupně dává čísla z posloupnosti), jak jsem ukazoval na "odpočtu před startem".

Proměnná

Použil jsem termín proměnná. Zjednodušeně lze říct, že je to pojmenování místa v paměti počítače, kam si ukládáme nějakou hodnotu. Např. číslo nebo text ("řetězec").

Proměnnou vyrobíme přiřazením - napíšeme nějaké jméno (může obsahovat velká a malá bez diakritiky, číslice a "podtržítka" [znak _]), znak = a hodnotu. Následně můžeme používat název proměnné tam, kde bychom jinak použili hodnotu:

>>> vyska_stromu = 12
>>> print("Strom měří", vyska_stromu, "metrů.")
Strom měří 12 metrů.
>>> jmeno = "Karel"
>>> print("Jmenuje se", jmeno, "a stoji u stromu mericiho", vyska_stromu, "metru.")
Jmenuje se Karel a stoji u stromu mericiho 12 metru.

Proměnné se hodí tam, kde chceme nějakou hodnotu použít opakovaně. Zároveň pak máme možnost ji měnit změnou na jednom místě programu.

Knihovny (moduly)

Python sám nabízí jen nejnutnější funkce. Pokud potřebujeme něco víc, musíme si do programu přidat knihovnu, která danou funkci obsahuje. Už základní instalace Pythonu ale obsahuje spoustu šikovných knihoven.

Nám by se hodilo odlet rakety trochu zpomalit. Na to lze použít funkci sleep() z knihovny time. Knihovnu načteme příkazem import:

import time

print("  I  ")
print(" XXX ")
print(" XOX ")
print(" XXX ")
print("XXXXX")
print("XXXXX")
print("XX XX")

for _ in range(0, 10):
    print(" ...")
    time.sleep(0.2)

for _ in range(0, 30):
    print("")
    time.sleep(0.1)

Přerušení programu

Program lze přerušit stisknutím kláves Ctrl + C.

Nápověda

Python nabízí nápovědu. Jednak při psaní v editoru, ale i v konzoli, kde se vyvolá příkazem help():

>>> help(print)
print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
    
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.

O printu se tu dozvíme například to, že můžeme změnit znaky oddelující vytištěné hodnoty (sep) i znak, který se vytiskne na konci řádku (end - '\n' je speciální znak, který ukončuje řádek). Jsou to takzvané "pojmenované parametry", protože jim může předcházet libovolné množství hodnot, které chceme prostě vytisknout. Vidíme i hodnoty, které se použijí, pokud nastavení nezměníme (defaults).

Můžeme tak vyrobit např. jednoduchý program, který vytiskne posloupnost čísel na jeden řádek:

for cislo in range(0, 10):
    print(cislo, end="")

Pokud zkusíte help(range), zjistíte, že to vlastně žádná funkce není. Je to něco daleko složitějšího, ale to zatím nebudeme rozebírat. :)

7. října

Komentáře

Do programu si můžeme psát poznámky, takzvané "komentáře". Jde to dvěma způsoby:

# <- pouzitim "hashtagu" - zbytek radku za timto znakem pocitac ignoruje

# lze ho napsat na samostatny radek

print("ahoj!") # ale i na konec radku, ktery neco vykonava

print("ale hashtag # uvnitr retezce jako komentar nefunguje")

# print(a + b) # komentar lze pouzit i na docasne "vypnuti" casti programu

# druhou moznosti je pouziti viceradkoveho retezce (misto jednech uvozovek se uzavira do trech):
"""
toto je
viceradkovy
komentar

tento kod se nevykona:
print("huhu")
"""

Funkce input()

Funkce input() dává uživateli možnost zadat nějakou vstupní hodnotu. Jako parametr se jí dává text výzvy:

a = input("Zadejte cislo: ")
a = int(a)

b = input("Zadejte druhe cislo: ")
b = int(b)

print("Souctem", a, "a", b, "je", a + b)

Typy proměnných

Narazili jsme na to, že Python rozlišuje typ proměnné nebo hodnoty. Například je rozdíl mezi číslem a řetězcem, protože některé operace nemusí pro různé typy hodnot dávat smysl. Třeba dělení řetězce číslem nebo jiným řetězcem:

>>> "karel" / 2
Traceback (most recent call last):
  File "", line 1, in 
TypeError: unsupported operand type(s) for /: 'str' and 'int'

# Ani retezec obsahujici cislo nebude fungovat.
# Python obsah retezce nezkouma, je to pro nej proste spatny typ hodnoty pro deleni:

>>> "6"/2
Traceback (most recent call last):
  File "", line 1, in 
TypeError: unsupported operand type(s) for /: 'str' and 'int'

Vlastní modul/knihovna

Udělat si vlastní modul v Pythonu není nic těžkého. Je to prostě soubor s definicemi funkcí a případně proměnných apod.

Důležité je, aby byl buďto ve stejném adresáři jako program, kde ho chcete použít, nebo v adresáři, který ma Python nastaven pro hledání knihoven. Přednostně se hledá v adresáři s programem.

# soubor mujmodul.py

def ahoj(jmeno):
    print("Ahoj", jmeno, "!")
# program
import mujmodul

mujmodul.ahoj("mami")

Druhá možnost importu (pouze určité funkce apod.):

from mujmodul import ahoj

ahoj("mami")

Pár odkazů

Slíbil jsem nějaké odkazy. Tu jsou:

14. října

Podmínka IF

Často potřebujeme vykonat některé příkazy jen za určitých podmínek. Na to slouží konstrukce if LOGICKY_VYRAZ: následovaný blokem příkazů, které jsou vykonány, pokud platí LOGICKY_VYRAZ (má výslednou hodnotu True). Případně můžeme ještě doplnit blok else:, který se vykoná v opačném případě.

# priklady vyrazu

>>> 1 > 2
False

>>> 10 == 10
True

# to stejne s promennymi:
>>> a = 5
>>> b = 3
>>> 
>>> a > b
True
>>> a == b
False
>>> a < b
False

Příklad programu:

cislo = input("Zadejte cislo mensi nez 10: ")
cislo = int(cislo)

if cislo < 10:
    print("Velmi spravne!")
    print("Cislo", cislo, "je mensi nez 10.")
else:
    print("Ale, ale!")
    print("Cislo", cislo, "neni mensi nez 10.")

if cislo > 15:
    print("Je vetsi, a to o hodne!")

Náhodná čísla

Další šikovnou knihovnou/modulem je random. Pro nás bude nejužitečnějčí funkce randint(MIN, MAX). Vrací náhodné celé číslo mezi MIN do MAX, včetně krajních hodnot.

>>> from random import randint
>>> randint(1, 3)
2
>>> randint(1, 3)
1
>>> randint(1, 3)
3
>>> randint(1, 3)
3
>>> randint(1, 3)
1

21. října

Velmi stručný tahák pro Python

Online na Google Docs.

Hra na hádání čísla

from random import randint

print("Myslim si cislo od 1 do 10.")
print("Hadej, ktere to je!")

cislo = randint(1, 10)
tipovane_cislo = None

while tipovane_cislo != cislo:
    vstup = input("Zadej svuj tip (1-10): ")
    tipovane_cislo = int(vstup)
    if tipovane_cislo < cislo:
        print("Me cislo je vetsi!")
    if tipovane_cislo > cislo:
        print("Me cislo je mensi!")

print("Spravne, je to", cislo, "!")

4. listopadu

Hra kámen-nůžky-papír

Kombinuje cyklus, použití seznamu (přesněji tuple) a složité podmínky.

from random import choice

moznosti = ("kamen", "nuzky", "papir")

while True:
    volba = input("Zadejte svou volbu (kamen/nuzky/papir): ")

    if volba not in moznosti:
        print(volba, "nelze pouzit!")
        continue

    volba_pocitace = choice(moznosti)
    print("Pocitac zvolil", volba_pocitace)

    if volba == volba_pocitace:
        print("Nerozhodne.")
    elif volba == "kamen":
        if volba_pocitace == "nuzky":
            print("Pocitac prohral.")
        elif volba_pocitace == "papir":
            print("Prohral jste.")
    elif volba == "nuzky":
        if volba_pocitace == "papir":
            print("Pocitac prohral.")
        elif volba_pocitace == "kamen":
            print("Prohral jste.")
    elif volba == "papir":
        if volba_pocitace == "kamen":
            print("Pocitac prohral.")
        elif volba_pocitace == "nuzky":
            print("Prohral jste.")

Vztah mezi písmeny a čísly

Každý znak (písmeno, číslice, symbol) je v počítači kódován pomocí čísla. Základní znaky odpovídají číslům 0-127 a jsou popsány ASCII tabulkou. Rozšířená verze tabulky obsahuje pak znaky až do 255.

Zjednodušeně lze říct, že dalším rozšířením tabulky vzniklo kódování Unicode, které už obsahuje miliony znaků a možnosti jejich kombinace.

Pro převod mezi čísly a znaky má Python funkce ord(ZNAK) a chr(CISLO).

>>> ord('a')
97
>>> ord(" ")
32
>>> ord('ž')
382
>>> chr(98)
'b'
>>> chr(99)
'c'

Generování náhodných slov

Za pomoci generování náhodných čísel můžeme tedy vyrábět náhodná slova.

from random import randint

delka_slova = 8

kod_a = ord('a')
kod_z = ord('z')

slovo = ''

for _ in range(0, delka_slova):
    slovo += chr(randint(kod_a, kod_z))

print(slovo)

Budou to ale podivné řetězce jako bclsmvhc nebo nvivvtht. Pokud chceme něco lepšího, je třeba počítat se slabikami.

from random import choice

slabiky = ('ba', 'la', 'ka', 'ro', 'so', 'de', 'bu', 'hu', 'si', 'li') # atd...

delka_slova = 8
slovo = ''

while len(slovo) < delka_slova:
    slovo += choice(slabiky)

print(slovo)

Ještě sofistikovanější je použití Markovových řetězců (a není to tak složité, jak by se z Wikipedie možná zdálo ;) ).

11. listopadu

Hra kámen-nůžky-papír, kde počítač podvádí

O dost jednodusší variace předchozí hry.

moznosti = ("kamen", "nuzky", "papir")

while True:
    volba = input("Zadejte svou volbu (kamen/nuzky/papir/konec): ")

    if volba == 'konec':
        break

    if volba not in moznosti:
        print(volba, "nelze pouzit!")
        continue

    volba_pocitace = "nuzky"

    if volba == "kamen":
        volba_pocitace = "papir"
    elif volba == "nuzky":
        volba_pocitace = "kamen"

    print("Pocitac zvolil", volba_pocitace, 'a vyhral!')

print("Ahoj! Tak zase nekdy priste.")

Datový typ dict(slovník)

Hodí se tam, kde chceme za běhu programu ukládát hodnoty pod různými názvy, nebo pokud prostě potřebujeme něco jako slovník.

Například převod různých možností zadání slov v naší hře:

moznosti = {
    "kamen": "kamen",
    "nuzky": "nuzky",
    "papir": "papir",
    "kámen": "kamen",
    "nůžky": "nuzky",
    "papír": "papir",
    "k": "kamen",
    "n": "nuzky",
    "p": "papir"
}

while True:
    volba = input("Zadejte svou volbu ([k]amen / [n]uzky / [p]apir / konec): ")
    # prevod na mala pismena
    volba = volba.lower()

    if volba == 'konec':
        break
    # existuje takovy klic ve slovniku?
    if volba not in moznosti:
        print(volba, "nelze pouzit!")
        continue
    # prevedeme klic na hodnotu
    volba = moznosti[volba]

    print("Zvolil jste", volba)

    # Atd...

Nebo spočítání výskytů písmen v řetězci:

text = "Ondatra udatne plovala kolem stavidla."

pocitadlo = {} # nebo dict()

for p in text: # projde text po jednotlivych pismenech
    if p in pocitadlo:
        pocitadlo[p] += 1
    else:
        pocitadlo[p] = 1

print(pocitadlo)

# pokud buchom chteli treba pocet pismen 'a':
# print("Acek je", pocitadlo["a"])

Ošetření chyb za běhu programu (výjimky)

Pokud dojde k chybě pro kterou nemá funkce nebo výraz vhodnou návratovou hodnotu, dojde k vyvolání výjimky. Zde například ValueError:

>>> int("abc")
Traceback (most recent call last):
  File "", line 1, in 
ValueError: invalid literal for int() with base 10: 'abc'

Výjimku můžeme takzvaně "odchytit" pomocí konstrukce try ... except ...:

vstup = input("Zadejte cislo: ")
try:
    cislo = int(vstup)
except:
    print("To nebylo cislo!")

Podrobněji je to popsáno třeba tady. A ještě podrobněji tady.

25. listopadu

Základní práce se soubory

Soubor musíme otevřít pomocí "funkce" open(JMENO, MOD), kde JMENO je řetězec se jménem souboru (příp. s celou cestou) a MOD je typ používání (také řetězec) - "w" zápis (založí nový, nebo otevře existující a smaže jeho obsah), "a" pokračovat v zápisu na konci souboru, "r" čtení. Lze kombinovat ještě třeba s písmenem "b" (binární přístup). Dalším mozným parametrem je kodování (pro textové soubory - když neuvedeme, použije se UTF-8). Kompletní popis je v dokumentaci


# priklady:

soubor = open("soubor.txt", "r") # budeme cist, textove

soubor = open("soubor.jpg", "rb") # budeme cist, "binarne"

soubor = open("soubor.txt", "w") # budeme zapisovat, textove

soubor = open("soubor.txt", "a") # budeme pridavat na konec, textove


soubor.read() # precte cely soubor a vrati jeho obsah jako retezec nebo binary() (podle toho jak jsme ho otevreli)

soubor.read(123) # precte a vrati 123 bytu nebo znaku ze souboru

soubor.write("moje data\n") # zapise do souboru radek textu


# pokud chceme praci se souborem ukoncit, "zavreme" ho:

soubor.close()
# zapiseme textove:
soubor = open("soubor.txt", "w")
soubor.write("Řádek textu.\n")
soubor.close()

# precteme textove:
soubor = open("soubor.txt", "r")
print(soubor.read())
soubor.close()

# Vytiskne:
#Řádek textu.
#

# precteme "binarne":
soubor = open("soubor.txt", "rb")
print(soubor.read())
soubor.close()

# Vytiskne: (je videt kodovani znaku mimo ASCII rozsah)
#b'\xc5\x98\xc3\xa1dek textu.\n'

Knihovna os

Obsahuje zajímavé funce používající operační systém.

os.getlogin() # vrati uzivatelske jmeno

os.getcwd() # vrati adresar (slozku), kde program prave pracuje (a bude tam napr. zakladat soubory, pokud jim nezadame celou cestu)

os.makedirs(CESTA) # zalozi slozku (adresar), vcetne neexistujicich nadrazenych slozek

Více v dokumentaci modulu os.

Hříčka: počet spuštění programu

Program, který si pamatuje kolikrát byl spuštěn

import os

nazev_souboru = 'pocet.txt' # aby se dal lehce zmenit, dam si ho do promenne

pocet = 0

# pokud soubor existuje, nactu z nej pocet
if os.path.exists(nazev_souboru):
    soubor = open(nazev_souboru, "r")
    pocet = int(soubor.read())
    soubor.close()

pocet = pocet + 1

print('Tento program byl spusten po ', pocet, '.', sep='')

# zapisu zvyseny pocet
soubor = open(nazev_souboru, "w")
soubor.write(str(pocet))
soubor.close()

2. prosince

HTML

HTML je "hypertextový značkovací jazyk". Neslouží k programování, ale strukturování textu. Je to základ všech webových stránek.

Pro první pokusy stačí jakýkoli editor, který pracuje s prostým textem. Třeba notepad.

Základní struktura stránky

Celá stránka musí být "obalena" značkou <html>. V ní je hlavička <head> do které se píší různé informace o stránce (například znaková sada textu stránky <meta charset>), po které následuje značka <body>, obsahující to, co se bude zobrazovat v okně prohlížeče.

Webové prohlížeče ale chtějí zobrazit co možná nejvíc stránek a proto promíjí řadu chyb ve formátování a zobrazí stránku, pokud jim výsledek dává aspoň trochu smysl.

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Titulek pokusné stránky</title>
  </head>
  <body>
    <h1>Hlavní nadpis pokusné stránky</h1>
    <p>První odstavec pokusné stránky</p>
    <h2>Podnadpis pokusné stránky</h2>
    <p>Druhý odstavec pokusné stránky</p>
  </body>
</html>

Většina značek (tagů) je párová a může obalovat další, zanořené značky a texty.

Narozdíl od Pythonu nemá v HTML odsazení žádný význam. Můžeme klidně napsat celou stránku na jeden řádek.

Další značky

<p></p> - odstavec

<span></span> - označení části řádku, pokud mu například chceme změnit styl

<h1></h1> - nadpis (1 největší - 6 nejmenší)

<a href="adresa">text odkazu</a> - odkaz na jinou stránku nebo soubor

<div></div> - definuje prostě část stránky podobně jako <span>, například pro stylování

<br> - vynucení konce řádku (v HTML má textový konec řádku [enter] stejný význam jako mezera)

<img src="jmeno_souboru_s_obrazkem"> - obrázek

Každé značce lze zadávat i parametry. V předchozím výčtu jsem uvedl jen ty nezbytné. Ukazovali jsme si například parametr style, kterým můžeme měnit styl jednotlivých značek.

Značek a možností formátování je mnoho. Existuje starý a stále celkem dobrý web v češtině, kde se dá najít skoro všechno. Nebo třeba velmi dobrý referenční web od Mozilly v angličtině, který je zcela aktuální.

Webhosting

Pokud chcete své výtvory dát na web, stačí nakopírovat HTML soubor (a případné obrázky apod) na nějaký webový server. Zkuste zahledat webhosting zdarma třeba na Seznamu. :) Ale vyhněte se těm, co nabízí, že si můžete stránky nějak "naklikat" bez znalosti HTML, jako Wix.

Existuje dost různých hostingů nabízejících místo na serveru zdarma pod nějakou jejich subdoménou (např. http://nejaky-vas-nazev.ten-hosting.cz/). Někdy do stránek vkládají své reklamy.

9. prosince

Webové stránky

Použili jsme free hosting wz.cz, kde jsem založil společný účet a stránky dodo.wz.cz.

Lze tam publikovat HTML a PHP stránky.

URL

Adresa webové stránky, nebo-li URL, říká jak najdeme konkrétní data na internetu. Je tvořena několika základními částmi:


/--+-- protokol (muze zde byt https, ftp, webdav apod., zalezi co server podporuje)
|  |
|  |   /--------+--- domena na ktere bezi server
|  |   |        |
http://dodo.wz.cz/mirek/index.html
                 |               |
                 \---------------+-- cesta a jmeno souboru na serveru

Součástí URL mohou být i přihlašovací údaje, parametry a odkaz do těla stránky, například:

https://uzivatel:heslo@wendigo.online-siesta.com/dodo/prgani/?parametr_k_nicemu=hodnota&druhy_parametr=hodnota2#lekce10

Soubor index.html

Soubor index.html server standardně vrací, pokud použijeme adresu končící adresářem (složkou). Takže místo http://dodo.wz.cz/mirek/index.html stačí psát http://dodo.wz.cz/mirek.

16. prosince

PHP

PHP je skriptovací jazyk, který vznikl přímo pro tvorbu dynamických webových stránek. Server vezme soubor (s příponou php), provede části v PHP a výstup z programu se stane součástí výsledné HTML stránky.

<html>
  <head>
    <title>Stranka pouzivajici PHP</title>
  </head>
  <body>
    <h1>Cisla</h1>

    <h2>Cisla od 0 do 9</h2>
    <?php

      for ($i=0; $i<10; $i = $i+1) {
        echo("$i <br>");
      }

    ?>

    <h2>Cisla od 10 do 19</h2>
    <?php

      for ($i=10; $i<20; $i = $i+1) {
        echo("$i <br>");
      }

    ?>
  </body>
</html>

JavaScript

Další možností jak stránku oživit je JavaScript. To je pro změnu skriptovací jazyk, který "běží" přímo v prohližeči, takže program se spustí, až když se stánka zobrazí. Má přístup ke všem objektům ve stránce a řadě funkcí prohlížeče.

6. ledna

Příkazová řádka

Když do vyhledávání v dolní liště windows napíšeme cmd najdeme aplikaci příkazový řádek. Ten se nám hodil pro instalaci knihovny pygame.

c:\Users\Programovani\> pip install pygame

Základy práce s příkazovou řádkou se nám hodí i v budoucnu. Základní standardní příkazy:

/--------------------+--- Disk a cesta k adresari, kde se nachazime, takzvany prompt
|                    |
c:\Users\Programovani> dir
                       | |
                       \---- zadavany prikaz
# vypise obsah adresare(slozky) ve kterem se zrovna nachazime

c:\Users\Programovani> cd Desktop
# prechod do podadresare/podslozky

c:\Users\Programovani\Desktop> cd ..
# navrat o adresar "vys"

Příkaz/aplikace pip slouží k instalaci dalších pythonových knihoven. Kromě install má řadu dalších příkazů/parametrů, papříklad:

pip -h
# vypise napovedu

pip uninstall JMENO_KNIHOVNY
# odinstalovani knihovny

pip list
# vypise seznam nainstalovanych knihoven

pip show JMENO_KNIHOVNY
# vypise informace o knihovne

pip -V
# vypise informace o verzi pip-u a o verzi pythonu pro kterou knihovny instaluje

# pokud mame na pocitaci vice verzi Pythonu a nevyhovuje nam verze pipu spoustena standardne,
# spoustime pip s cislem verze:
pip3.10 install ATAKDALE...

Program používající pygame jsme spouštěli z příkazové řádky (a z IDLE používali jen editor), protože při spuštění přes IDLE nastává jakýsi problém s přenosem událostí mezi grafickým oknem a programem.

c:\Users\MujUzivatel\Desktop\slozkaSprogramem> python mujprogram.py

Inicializace Pygame

Dokumentaci najdeme na webu Pygame. Inicializace grafického módu je popsána tady.

# Inicializace pygame a grafickeho modu. Otevre okno a po 5 sekundach okno zavre a skonci.

import pygame
from time import sleep

pygame.init() # nutno zavolat pred prvnim pouzitim pygame, aby si osahala system

rozmery = (640, 480)
flags = 0

plocha_okna = pygame.display.set_mode(rozmery, flags)

sleep(5)
# take lze pouzit input('Stisknete enter')
# ale je pak treba prekliknout na okno prikazove radky a enter stisknout tam

Pokud jde o parametr flags, pro začátek pro nás bude zajímavá asi jen hodnota pygame.FULLSCREEN, kterou můžeme aktivovat zobrazení přes celou obrazovku.

Kreslení

Skončili jsme prvním nakresleným obdélníkem (rectangle), já tu nakreslím třeba kruh a nechám ho chvíli blikat:

from time import sleep

pygame.init()

rozmery = (640, 480) # sirka, vyska
flags = 0

plocha_okna = pygame.display.set_mode(rozmery, flags)

stred = (320, 240) # x, y v pixelech
polomer = 100 # pixelu

for _ in range(0, 25):
    barva = (0, 255, 0) # zelena barva
    pygame.draw.circle(plocha_okna, barva, stred, polomer)
    pygame.display.flip()
    sleep(0.1)
    barva = 'red' # cervena barva
    pygame.draw.circle(plocha_okna, barva, stred, polomer)
    pygame.display.flip()
    sleep(0.1)

Dokumentace kreslení dalších tvarů je zde.

Důležité je nezapomínat zavolat funkci pygame.display.flip() pro zobrazení překreslené obrazovky.

Kódování barev

Narazili jsme na způsob zadání barvy. Je to trojice barevných složek "r" (red - červená), "g" (green - zelená) a "b" (blue - modrá). Výsledná barva vznikne smícháním těchto tónů. Každý z nich má rozsah hodnot od 0 (nejtmavší) do 255 (nejsvětlejší), takže (0, 0, 0) vytvoří černou barvu, (255, 255, 255) jasně bílou a např. (0, 0, 128) tmavě modrou.

13. ledna

Události (events)

Vstup z klávesnice a myši, příp. jiných zařízení a některé další operace produkují takzvané události (Event). Každý event má svůj typ a případné další vlastnosti. Stisknutí nebo uvolnění klávesy má příslušný kód a znak, událost myši má zase pozici či číslo stisknutého tlačítka.

Události se řadí do "fronty", kde na konec systém přidává nové a na začátku si můžeme události odebírat a zpracovávat. Zní to možná složitě, ale v praxi jde o to, že máme funkce, které nám vrátí nejstarší událost (a tím ji odeberou z fronty) a o víc se nemusíme starat.

Udělali jsme si jednoduchý program, který nám tiskl události do konzole:

import pygame

pygame.init()

rozmery = (640, 480) # sirka, vyska
flags = 0

plocha_okna = pygame.display.set_mode(rozmery, flags, vsync=0)

while 1:
    udalost = pygame.event.wait() # tato funkce ceka, dokud se nejaky event neobjevi
    print(udalost)
    # pokud prijde event typu QUIT, prerusime cyklus
    if udalost.type == pygame.QUIT:
        break

Po spuštění vidíme v konzoli všechny události, které se važí k oknu aplikace, včetně jejich vlastností (atributů). Okno už jde zavřít standardním způsobem.

Vidíme událost MouseMotion, která uvádí nejen novou pozici myši (pos), ale také změnu souřadnic od poslední události (rel). Toho můžeme využít třeba pro kreslení myší:

import pygame

pygame.init()

rozmery = (640, 480) # sirka, vyska
flags = 0

plocha_okna = pygame.display.set_mode(rozmery, flags, vsync=0)

while 1:
    udalost = pygame.event.wait()
    if udalost.type == pygame.QUIT:
        break
    if udalost.type == pygame.KEYDOWN:
        if udalost.key == 8: # stisknuti klavesy backspace (<-) smaze obrazovku
            plocha_okna.fill((0,0,0)) # vyplnime ji cernou barvou
    if udalost.type == pygame.MOUSEMOTION:
        barva = (128, 255, 128) # svetla zelena
        start = udalost.pos
        konec = (udalost.pos[0] - udalost.rel[0], udalost.pos[1] - udalost.rel[1]) # vypocet predchozi souradnice)
        pygame.draw.line(plocha_okna, barva, start, konec)
    pygame.display.flip()

Dokumentace k eventům na stránkách Pygame. Pro naše účely asi postačí funkce pygame.event.wait() a pygame.event.get(). Také tam najdeme konstanty všech možných typů eventů.

20. ledna

Ovládání klávesami

Pokud chceme, aby program reagoval na trvající stisk klávesy, musíme si po stisku někam poznamenat, že klávesa je stlačená a dál pracovat s touto informací. Po přijetí eventu KEYUP dané klávesy pak tuto hodnotu přepíšeme, abychom věděli, že klávesa už ztisknuta není.

Další věc na kterou jsme narazili je to, ze funkce pygame.event.wait() je tzv. blokující volání. Program čeká, dokud se nějaký event neobjeví. Nahradili jsme ji proto voláním funkce pygame.event.poll(), která vrátí prázdný event typu pygame.NOEVENT, pokud není žádný k dispozici.

# neni to kompletni program, jen potrebne konstrukce:

y = 0

k_nahoru = False # neni stisknuto
k_dolu = False # neni stisknuto

while 1:
    udalost = pygame.event.poll()

    if udalost.type == pygame.QUIT: # radeji sem dam i reakci na ukonceni...
        break

    if udalost.type == pygame.KEYDOWN: # stisk klavesy
        if udalost.key == pygame.K_UP: # je to klavesa "sipka nahoru"
            k_nahoru = True # ulozim si, ze je stisknuto
        if udalost.key == pygame.K_DOWN: # je to klavesa "sipka dolu"
            k_dolu = True # ulozim si, ze je stisknuto

    if udalost.type == pygame.KEYUP: # uvolneni klavesy klavesy
        if udalost.key == pygame.K_UP: # je to klavesa "sipka nahoru"
            k_nahoru = False # ulozim si, ze neni stisknuto
        if udalost.key == pygame.K_DOWN: # je to klavesa "sipka dolu"
            k_dolu = False # ulozim si, ze neni stisknuto

    # a k ovladani pouziju hodnoty svych promennych:
    if k_nahoru:
        y = y - 1
    if k_dolu:
        y = y + 1

Konstanty pro všechny klávesy najdete tady. Je to lepší způsob, než opsat číselnou hodnotu z vytištěného eventu.

Zpracování eventů pro každou klávesu zvlášť je hodně psaní, které si můžeme ušetřit třeba za pomoci proměnné typu dict:

# opet jen uryvek...
y = 0
klavesy = {} # slovnik pro ukladani stavu klaves

while 1:
    udalost = pygame.event.poll()

    if udalost.type == pygame.KEYDOWN: # stisk klavesy
        klavesy[udalost.key] = True # ulozi jakoukoli stisknutou klavesu

    if udalost.type == pygame.KEYUP: # uvolneni klavesy klavesy
        klavesy[udalost.key] = False # ulozi jakoukoli pustenou klavesu

    # ovladani:
    if klavesy.get(pygame.K_UP): # vrati True, pokud byla stisknuta, jinak None nebo False
        y = y - 1

Obrázek

# nacteni obrazku a ulozeni do promenne:
obrazek = pygame.image.load("mujobrazek.png")

# pozor! cesta k obrazku se odvozuje od slozky ze ktere program spoustite,
# takze "mujobrazek.png" musi lezet ve stejne slozce kde spoustite program.
# Pokud mate obrazky treba v podslozce "obrazky", musite napsat "obrazky/mujobrazek.png"


# vykresleni obrazku do obrazovky (v promenne pojmenovane "hlavni_okno") na souradnice x a y:
hlavni_okno.blit(obrazek, (x, y))

# pokud krome souradnic uvedeme jako dalsi parametr ctverici cisel (sx, sy, sirka, vyska),
# rikame tim, ze se ma z obrazku vykreslit jen jeho cast dana temito souradnicemi a rozmery
# dale muzeme nastavit zpusob vykresleni, viz https://www.pygame.org/docs/ref/surface.html#pygame.Surface.blit

27. ledna

JavaScriptová konzole

Užitečná věc v prohlížeči - Hlavní nabídka > Další nástroje > Nástroje pro vývojáře (názvy se v různých prohlížečích drobně liší, ale jsou všude) kde najdeme konzoli. Ta funguje podobně jako pythonová.

Některé rozdíly mezi JS a Pythonem

JS je podobný spíše C nebo PHP. Místo odsazení se bloky uzavírají do složených závorek. Příklady:

// komentar - misto # se pouzivaji dve lomitka
/*
   viceradkovy
   komentar */

// prikazy se v JS ukoncuji strednikem

// promenna se deklaruje prikazem var:
var cislo = 1;
var retezec = "abc";
// (tim zalozime promenne, se kterymi muzeme pracovat v danem bloku a v blocich zanorenych
// [s deklaraci promennych je to v JS trochu slozitejsi nez v pythonu])

// definice funkce:
function nazev_funkce(parametr1, parametr2) {
    var vysledek = parametr1 + parametr2;
    return vysledek; // vrati soucet parametru
}

// odsazeni je dobrovolne, dulezite je uzavrit blok do slozenych zavorek: { }

// while cyklus:
while (podminka) {
    // prikazy
}

// if
if (podminka) {
    // prikazy
}

Pozor! V JS se používá řízení událostmi, ne hlavní programová smyčka jako v Pythonu. Pokud uděláte nekonečný (nebo hóódně dlouhý) cyklus, skončí to varováním prohlížeče, že skript přestal reagovat.

Věci o kterých jsem mluvil nebo mi přijdou šikovné do začátku:

setTimeout(FUNKCE, MILISEKUNDY); // zadava se jmeno funkce (bez zavorek), nebo primo takzvana anonymni funkce
document.getElementById(ID); // vrati element oznaceny danym id
alert('Text varovani'); // zobrazi okenko s danym textem a zastavi vykonavani skriptu
confirm("nejaka otazka"); // zobrazi potvrzovaci okenko s danym textem a vrati hodnotu True, pokud clovek zvoli OK
prompt("nejaky text"); // otevre okenko se vstupnim polem, kam muze clovek neco napsat, pak to vrati jako hodnotu

// priklad: mam nekde input s id "jmeno_uzivatele" a chci ho pouzit ve skriptu:
var ten_input = document.getElementById("jmeno_uzivatele");
console.log(ten_input.value); // vypise hodnotu do konzole
ten_input.value = 'XYZ'; // prenastavi hodnotu inputu

// v JS je definovana promenna jmenem 'document', ktera umoznuje pristup k zobrazene strance
document.body // telo stranky
document.body.innerHTML = "<h1>Jen nadpis!</h1>"; // nahradi obsah stranky timto nadpisem
document.location // adresa stranky (a zaroven objekt, ktery ma metody jako reload(), replace() apod.)
document.location = "https://www/seznam.cz/"; //nasmeruje prohlizec na seznam
document.location.reload(); // znovu nacte soucasnou stranku