Mirek Kučera - vvendigo@seznam.cz
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.
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 '++++++++++++++++++++'
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).
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
cyklusOpakované 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".
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.
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)
Program lze přerušit stisknutím kláves Ctrl
+ C
.
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. :)
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") """
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)
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'
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")
Slíbil jsem nějaké odkazy. Tu jsou:
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!")
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
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, "!")
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.")
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'
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 ;) ).
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.")
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"])
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.
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'
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
.
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()
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
.
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.
<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í.
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.
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.
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
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
.
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>
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.
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
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.
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.
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.
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ů.
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
# 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
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á.
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.
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