Hlavní navigace

Základy programování ve Squeaku

29. 7. 2010
Doba čtení: 16 minut

Sdílet

V dalším článku o programovacích jazycích pro výuku programování částečně navážeme na část předchozí, protože si popíšeme další vlastnosti grafického rozhraní Squeaku. Budeme se zabývat funkcí oken Inspector, Explorer a System Browser. Dále se budeme zabývat samotnou syntaxí a sémantikou Squeaku.

Obsah

1. Základní operace prováděné v GUI Squeaku

2. Zobrazení atributů objektů v okně Inspector

3. Zobrazení vlastností objektů v okně Explorer

4. Okno System Browser

5. Okno Hierarchy Browser

6. Objektově orientované programování ve Squeaku

7. Posílání zpráv

8. Tři typy zpráv posílaných objektům

9. Odkazy na Internetu

1. Základní operace prováděné v GUI Squeaku

V předchozí části seriálu o programovacích jazycích vhodných či dokonce přímo vytvořených pro výuku programování jsme se seznámili se základními vlastnostmi programovacího jazyka Squeak i jeho vývojového a běhového prostředí založeného na projektu Morphic. Víme již, že definice všech objektů používaných Squeakem jsou uloženy v jediném (neměnném) zdrojovém souboru s koncovkou .source, změny oproti původním definicím se průběžně ukládají do textového souboru s koncovkou .changes a atributy objektů (tj. jejich datové složky) jsou uloženy v binárním souboru majícím koncovku .image – všechny objekty jsou tedy neustále „živé“, pouze se v případě ukončení běhu Squeaku hibernují a mohou být kdykoli obnoveny, a to dokonce na zcela jiné platformě, protože běhové prostředí Squeaku obsahuje i platformně nezávislý virtuální stroj zpracovávající velmi jednoduchý bajtkód.

Obrázek 1: Změnový soubor (.changes) vygenerovaný Squeakem na platformě Wintel.

Výše popsanému principu se, i když poněkud vzdáleně, podobá například serializace všech objektů aktivních ve virtuálním stroji jazyka Java (JVM – Java Virtual Machine), ovšem Squeak je v několika ohledech poněkud pružnější, mj. i díky tomu, že samotné třídy jsou objekty (každá třída je instancí takzvané metatřídy, což je pojem, který si vysvětlíme později). Minule jsme se taktéž ve stručnosti seznámili s grafickým uživatelským rozhraním Squeaku založeného na projektu Morphic, které je navrženo tak, aby bylo přenositelné a chovalo se do co největší míry stejně či alespoň velmi podobně i na zcela odlišných platformách, zařízeními PDA a SmartPhony s malým displejem i výpočetním výkonem počínaje, přes běžné osobní počítače až po výkonné superpočítače.

Obrázek 2: Ukázka některých možností grafického uživatelského rozhraní Squeaku.

Z poměrně velkého množství různých typů oken nabízených tímto prostředím jsme si ukázali a popsali základy použití okna Workspace, které lze považovat za interaktivní konzoli, do níž je možné zapisovat příkazy a ty následně spouštět a taktéž okna Transcript. Toto okno si můžeme poněkud zjednodušeně představit jako standardní terminálový výstup, do nějž mohou různé procesy (či přesněji řečeno vlákna) zapisovat libovolné informace, například posláním zprávy se selektorem show: objektu Transcript. Jakým způsobem je toto poslání zprávy provedeno se dozvíme v následujících kapitolách; jedná se totiž o základní operaci, která se v programech psaných ve Squeaku provádí.

Obrázek 3: Ve Squeaku lze vytvářet i grafické tvary, které se chovají jako plnohodnotné objekty.

2. Zobrazení atributů objektů v okně Inspector

Okno Workspace, které bylo popsané v předchozí části tohoto seriálu, slouží nejenom pro editaci a spouštění uživatelem zapsaných příkazů, ale je možné ho taktéž použít k vyvolání mnoha dalších více či méně užitečných operací.

Obrázek 4: Otevření okna Workspace z World Menu vyvolaného většinou levým tlačítkem myši na pracovní ploše Squeaku.

Již v předchozí části tohoto seriálu jsme si řekli, že zapsané příkazy lze spouštět buď z kontextového menu vyvolaného „modrým“, tj. většinou pravým tlačítkem myši příkazem do it nebo pomocí klávesové zkratky CTRL+d (používá se malé písmeno „d“, protože prostředí Squeaku při vyhodnocování klávesových zkratek rozlišuje mezi kombinací CTRL+písmeno a CTRL+PÍSMENO). Dalším již popsaným příkazem je příkaz print it mající klávesovou zkratku CTRL+p, který spolupracuje s oknem Transcript.

Obrázek 5: Zápis příkazu – poslání zprávy objektu Transcript.

Následujícím příkazem dostupným z okna Workspace, který je velmi užitečný a taktéž často používaný, je příkaz inspect it. Tento příkaz lze vyvolat jak z kontextového menu (viz obrázek číslo 6), tak i pomocí klávesové zkratky CTRL+i. Příkaz inspect it slouží k zobrazení nového okna Inspector pro objekt, na němž se nachází kurzor (tento objekt je barevně zvýrazněn).

Obrázek 6: Vyvolání okna Inspector z kontextového me­nu.

Okno Inspector je rozděleno do tří sekcí, které můžeme vidět na obrázku číslo 7. V levé horní sekci se nachází seznam všech atributů objektu, v pravé horní sekci aktuální hodnota vybraného atributu (samozřejmě pouze v tom případě, pokud je nějaký atribut vybrán) a v sekci spodní se nachází textové pole, do nějž lze zadávat libovolné zprávy posílané vybranému objektu (v tomto případě se využívá klíčové slovo self zastupující vybraný objekt). Tímto způsobem lze například jednoduše otestovat chování objektu nebo dokonce měnit chování celého vývojového prostředí (samozřejmě pokud se pošlou zprávy těm správným objektům :-). Poznamenejme, že okno Inspector je možné vyvolat i z několika dalších míst grafického uživatelského rozhraní Sqeaku, například je dostupné i pro geometrické tvary umístěné na pracovní ploše, protože i tyto prvky jsou ve Sqeaku považovány za plnohodnotné objekty s atributy a metodami.

Obrázek 7: Zobrazené názvy a hodnoty atributů objektu.

3. Zobrazení vlastností objektů v okně Explorer

Dalším typem okna, které se v několika ohledech podobá výše popsanému oknu Inspect, je okno nazvané příhodně Explorer. Toto okno lze vyvolat z Workspace (ale i z několika dalších typů oken) stiskem klávesové zkratky CTRL+I (zde je mimochodem vidět rozdíl mezi klávesovou zkratkou CTRL+i a CTRL+I) nebo pomocí kontextového menu takovým způsobem, jaký je naznačen na následujícím obrázku. Okno Explorer je rozděleno na dvě části. Dolní část je shodná s textovým polem okna Inspect a v horní části se nachází strom s atributy objektu. V některých případech je atribut ve stromu reprezentován více způsoby – zkuste si například vyvolat menu Explorer nad celočíselnou konstantou (která je ve Sqeaku taktéž plnohodnotným objektem) s jediným atributem, jímž je samotná hodnota, nebo nad objektem Workspace, který mj. obsahuje i celočíselný atribut format. Některé další typy atributů, například barva objektu či barva jeho obrysu, může být reprezentována graficky.

Obrázek 8: Vyvolání okna Explorer z kontextového me­nu.

Podobně jako v případě výše popsaného okna Inspect, i zde je možné pro každý atribut (jenž je objektem) vyvolat k němu vázané okno Inspect nebo Explorer. Pro první možnost postačuje provést dvojklik na příslušném atributu, druhou možnost lze vyvolat z kontextového menu nebo klávesovou zkratkou. Pokud jste si vyzkoušeli možnosti oken Explorer a Inspector, jistě jste si všimli, že některé jejich funkce jsou buď podobné nebo zcela totožné. Jedná se o jednu z poměrně typických vlastností Squeaku, která spočívá v tom, že nějakou operaci lze provést z několika různých míst a mnohdy i navzájem odlišnými způsoby; záleží pouze na uživateli (či programátorovi), který způsob preferuje nebo který mu v dané chvíli lépe vyhovuje. Tento přístup má tu výhodu, že uživatel většinou nemusí nějakou operaci, o níž ví, že existuje, složitě hledat – většinou ji nalezne v nejbližším kontextovém menu.

Obrázek 9: Zkoumání objektu v okně Explorer.

4. Okno System Browser

Velmi důležitým typem okna, které bylo mimochodem převzato i do několika dalších vývojových prostředí, je okno nazvané System Browser. Toto okno slouží pro vyhledávání a prohlížení tříd, jejich metod, hierarchie, zděděných metod atd. System Browser lze vyvolat buď z kontextového menu (viz obrázek číslo 10), nebo z mnoha míst vývojového prostředí, například z okna Workspace (což je mimochodem jedna z nejjednodušších možností, jak najít nějakou třídu), pomocí klávesové zkratky CTRL+B. Okno System Browseru obsahuje několik různých sekcí, z nichž nejdůležitější je čtveřice seznamů zobrazená v jeho horní části. V prvním seznamu jsou vypsány takzvané kategorie, do nichž jsou rozděleny všechny dostupné třídy. Ve druhém seznamu se zobrazují třídy spadající do vybrané kategorie. Třetí seznam obsahuje výpis protokolů pro vybranou třídu – protokol přitom odpovídá skupině metod se stejným či podobným významem – stejně jako jsou příbuzné třídy seskupeny do kategorií, jsou příbuzné metody každé třídy seskupeny do protokolů.

Obrázek 10: Vyvolání okna Browser z kontextového me­nu.

Na samotném začátku seznamu protokolů je uveden pseudoprotokol nazvaný –all–, pod nějž spadají všechny metody vybrané třídy (u tříd s malým počtem metod se protokoly ani nedefinují, takže automaticky „padnou“ do pseudoprotokolu –all–). Pokud je při vyvolání System Browseru kurzor umístěn na identifikátoru objektu (například v okně Workspace), je příslušná třída v System Browseru automaticky vybrána; v opačném případě je nejdříve zapotřebí vybrat příslušnou kategorii i třídu, popř. použít možnost hledání třídy podle jejího názvu. Povšimněte si taktéž, že po výběru nějaké kategorie, třídy, protokolu či metody se ve spodní části okna System Browser zobrazuje dokumentace přidaná ke třídě nebo přímo zdrojový kód vybrané metody. Například při výběru třídy SmallInteger, která je umístěna v kategorii Kernel-Numbers, se vypíše následující text (nebo podobný text, v závislosti na konkrétní verzi Squeaku):

My instances are 31-bit numbers, stored in twos complement form.
The allowable range is approximately +- 1 billion (see SmallInteger minVal, maxVal).

Pokud dále vybereme metodu = (tj. vlastně implementaci operátoru ekvivalence), můžeme se o ní dozvědět tyto údaje:

= aNumber
        "Primitive. Compare the receiver with the argument and answer true if
        the receiver is equal to the argument. Otherwise answer false. Fail if the
        argument is not a SmallInteger. Essential. No Lookup. See Object
        documentation whatIsAPrimitive. "
        <primitive: 7>
        ^super = aNumber

Obrázek 11: Kategorie tříd, seznam tříd ve vybrané kategorii, seznam protokolů pro vybranou třídu a seznam metod pro daný protokol.

5. Okno Hierarchy Browser

S oknem System Browser popsaným v předchozí kapitole poměrně úzce souvisí i další typ okna – Hierarchy Browser. Každá třída, která se v prostředí Squeaku nachází, totiž spadá do jednotné hierarchie, kterou je možné jednoduše zobrazit právě pomocí tohoto typu okna. Hierarchy Browser lze vyvolat například přímo ze System Browseru po stisku tlačítka Hierarchy, které se stane aktivní ve chvíli, kdy je vybrána nějaká třída. Funkce okna Hierarchy Browser se v mnoha ohledech podobá předchozímu oknu, tj. pro každou třídu ve vybrané hierarchii se zobrazí seznam jejich protokolů a taktéž seznam metod spadajících do vybraného protokolu (i další ovládací prvky jsou prakticky shodné). Příklad jednoduché hierarchie objektů je zobrazen na dvanáctém obrázku. Jedná se o všechny třídy, které jsou předky třídy SmallInteger, tj. třídy jejíž instance představují celočíselné hodnoty.

Obrázek 12: Hierarchie tříd.

Obrázek 13: Graf dědičnosti pro zvolenou metodu.

6. Objektově orientované programování ve Squeaku

V předchozích kapitolách jsme si popsali všechny typy oken, které budeme potřebovat při tvorbě jednoduchých programů ve Squeaku (popravdě řečeno budeme pro většinu operací používat pouze okno Workspace). Ovšem ještě než se pustíme do programování, musíme si říci základní informace o tom, jaký je vlastně Squeak programovací jazyk. Již v předchozí části tohoto seriálu jsme si řekli, že Squeak je založen na programovacím jazyku Smalltalk, tj. na programovacím jazyku, který plně podporuje objektově orientované programování, a to dokonce do takové míry, že prakticky všechny prvky, se kterými se v programech setkáme, jsou objekty. Dokonce i třídy jsou objekty, konkrétně se jedná o instance takzvané metatřídy (metatřída je taková třída, jejíž instance jsou jiné třídy). Ve Smalltalku (a tím pádem i ve Sqeaku) jsou za plnohodnotné objekty považována i čísla či booleovské (pravdivostní) hodnoty, což s sebou přináší poměrně značné zjednodušení syntaxe, jak si ukážeme v následujících kapitolách.

Obrázek 14: Ve Squeaku je plnohodnotným objektem řetězec…

Obrázek 15: … celé číslo …

Obrázek 16: … i geometrický tvar umístěný na pracovní ploše.

Tak jako v jiných objektově orientovaných jazycích, i ve Squeaku může každý objekt obsahovat atributy (instanční proměnné) a metody. Atributy nejsou mimo daný objekt viditelné, takže se pro přístup k nim používají přístupové metody (dnes se obvykle nazývají settery a gettery). Ovšem Squeak se od některých dalších objektově orientovaných jazyků, například od C++ či od Javy odlišuje v tom, že atributy jsou dostupné jen v rámci dané instance třídy, popř. z některé odvozené třídy, nikoli ze všech instancí stejné třídy. Pro zamyšlení pro znalce Javy či C++: jakým způsobem bude následující kód pracovat a půjde vůbec přeložit, když se v jedné instanci třídy Test snažíme měnit privátní atribut jiné instance téže třídy?

public class Test
{
    private int atribut;
    public void change(Test test)
    {
        test.atribut=10;
    }
    public String toString()
    {
        return "" + this.atribut;
    }
    public static void main(String[] args)
    {
        Test test1 = new Test();
        Test test2 = new Test();
        System.out.println("test1: " + test1);
        System.out.println("test2: " + test2);
        test1.change(test2);
        System.out.println("test1: " + test1);
        System.out.println("test2: " + test2);
    }
}

7. Posílání zpráv

Jednotlivé objekty, které „žijí“ v prostředí Squeaku, mezi sebou komunikují pomocí takzvaného „posílání zpráv“. Na první pohled by se mohlo zdát, že posílání zpráv je naprosto stejná operace jako volání metod, ovšem jiná terminologie odráží poněkud odlišnou filozofii Squeaku, popř. Smalltalku a podobných objektově orientovaných programovacích jazyků oproti jazykům mainstreamovým. Zatímco voláním metody programátor přímo v programu (a mnohdy, i když ne vždy, již v čase překladu) vybranému objektu přesně nařizuje, jakou činnost má objekt provést, posláním zprávy se přesně neříká, jaký kód se má spustit – rozhodnutí, jakým způsobem objekt, který je příjemcem zprávy, na tuto zprávu zareaguje, je ponecháno na samotném objektu, který se navíc „rozhoduje“ až v čase běhu programu (runtime time), nikoli při jeho překladu (compile time). To je sice časově poněkud náročnější, než přímé zavolání metody, na druhou stranu je však toto řešení mnohem flexibilnější, což oceníme především v následujících částech seriálu při popisu některých pokročilejších programátorských postupů.

Obrázek 17: Zařazení malých celých čísel do kategorie tříd.

8. Tři typy zpráv posílaných objektům

Ve Squeaku je možné při komunikaci s objekty používat tři typy zpráv. Nejjednodušší jsou zprávy unární, které nemají žádný argument. Objekt se rozhoduje, jakým způsobem na zprávu zareaguje, přímo z toho, o jakou zprávu se jedná. Typickým příkladem je zápis 42 factorial, kterým se pošle zpráva „factorial“ objektu 42 (tj. instanci třídy SmallInteger). Objekt 42 tuto zprávu zpracuje a jako výsledek vrátí nový objekt představující hodnotu 1405006117752­879898543142606244511569­936384000000000, což je (pravděpodobně :-) skutečně výsledek výpočtu 42!. Jiným příkladem unární zprávy může být Transcript clear, jejíž význam je zřejmý.

Obrázek 18: Vlastnosti instance třídy EllipseMorph; na tomto obrázku je patrné, že okno Explorer dokáže některé atributy objektu zobrazit i graficky, například barvu.

Druhým typem zpráv jsou zprávy binární. Tyto zprávy obsahují přesně jeden argument, který se zapisuje za jméno zprávy. Ve Squeaku jsou jména binárních zpráv představována následujícími znaky nebo jejich kombinacemi:

+ -- / \ * ~ < > = @ % | & ? ,

Příkladem binární zprávy je například zápis 6 * 7, kterým se objektu 6 posílá binární zpráva * s argumentem 7. Objekt 6 tuto zprávu zpracuje a jako výsledek vrátí objekt 42. Dalším příkladem binární zprávy je zápis 6 = 7, jehož výsledkem je objekt false. Vidíme, že díky zavedení binárních zpráv je možné zapisovat i aritmetické výrazy s operátory (ovšem bez rozlišení priority), i když podpora pro výrazy není v samotném jazyku nijak zakotvena. Na binární zprávy může reagovat jakýkoli objekt, takže se vlastně bez většího úsilí dosáhlo toho, že Squeak alespoň syntakticky podporuje přetěžování operátorů.

root_podpora

Obrázek 19: Selektory a argumenty zpráv.

Třetím typem zpráv jsou zprávy s obecným počtem parametrů. Tyto zprávy obsahují ve svém zápisu takzvané selektory, přičemž vždy za každým selektorem následuje argument. Příkladem tohoto typu zprávy může být například zápis: 3 raisedTo: 3 modulo: 2, jehož výsledkem je objekt s hodnotou 1 (povšimněte si, že za selektorem následuje dvojtečka). Tímto typem zpráv se budeme podrobněji zabývat v následující části tohoto seriálu.

9. Odkazy na Internetu

  1. Squeak home page
    http://www.squ­eak.org/
  2. XO: The Children's Machine
    http://wiki.lap­top.org/go/The_Chil­dren's_Machine
  3. Squeak na Wikipedii EN
    http://en.wiki­pedia.org/wiki/Squ­eak
  4. Squeak na Wikipedii CZ
    http://cs.wiki­pedia.org/wiki/Squ­eak
  5. Squeak by Example
    http://squeak­byexample.org/
  6. Squeak Land
    http://www.squ­eakland.org/
  7. SqueakNotes
    http://squeak­.zwiki.org/Squ­eakNotes
  8. Squeak FAQ
    http://wiki.squ­eak.org/squeak/471
  9. Learning Squeak
    http://c2.com/cgi/wi­ki?LearningSqu­eak
  10. Scratch home page
    http://scratch­.mit.edu/
  11. Scratch (programming language)
    http://en.wiki­pedia.org/wiki/Scrat­ch_(programmin­g_language)
  12. Lazarus (Software)
    http://en.wiki­pedia.org/wiki/La­zarus_%28softwa­re%29
  13. FreePascal
    http://www.fre­epascal.org/
  14. „Why I Love Python“ slides
    http://www.min­dviewinc.com/dow­nloads/pub/ec­kel/LovePython­.zip
  15. „Why I love Python“ (presentation)
    http://www.sli­deshare.net/di­dip/why-i-love-python
  16. První jazyk: Python
    http://macek.san­dbox.cz/texty/prvni-jazyk-python/
  17. Programovací jazyk Python
    http://www.py­.cz/FrontPage
  18. Python – Wikipedia CS
    http://cs.wiki­pedia.org/wiki/Pyt­hon
  19. IPython
    http://en.wiki­pedia.org/wiki/I­python
  20. IPython: an interactive computing environment
    http://ipython­.scipy.org/mo­in/
  21. Category:Python
    http://rosetta­code.org/wiki/Ca­tegory:Python
  22. Educational programming language
    http://en.wiki­pedia.org/wiki/E­ducational_pro­gramming_langu­age
  23. Seriál Letní škola programovacího jazyka Logo
    http://www.ro­ot.cz/serialy/let­ni-skola-programovaciho-jazyka-logo/
  24. Logo Tree Project:
    http://www.eli­ca.net/downlo­ad/papers/Logo­TreeProject.pdf
  25. Language Poster (O'Reilly):
    http://www.ore­illy.com/news/grap­hics/prog_lan­g_poster.pdf
  26. Informace o Comenius Logu:
    http://www.com­logo.input.sk/in­dex.html
  27. Stránka nabízející stažení Comenius Loga:
    http://www.com­logo.input.sk/nas­tiahnutie.html
  28. Seminární práce o Comenius Logu:
    http://nwit.ped­f.cuni.cz/rotal9ap/lo­go/
  29. Informace o LEGO/Logu:
    http://educati­on.otago.ac.nz/nzlnet/L­ogo/legologo.html
  30. Informace o systému Elica:
    http://www.eli­ca.net/site/in­dex.html
  31. Informace o systému NetLogo:
    http://ccl.nor­thwestern.edu/ne­tlogo/
  32. Stažení NetLoga:
    http://ccl.nor­thwestern.edu/ne­tlogo/download­.shtml
  33. Uživatelský manuál NetLoga ve formátu PDF:
    http://ccl.nor­thwestern.edu/ne­tlogo/docs/Net­Logo%20User%20Ma­nual.pdf
  34. NetLogo FAQ:
    http://ccl.nor­thwestern.edu/ne­tlogo/docs/faq­.html
  35. Domácí stránka Daniela Azumy (autora implementace Turtle Tracks):
    http://alumnus­.caltech.edu/~da­zuma/home/
  36. Informace o aUCBLogu:
    http://www.phy­sik.uni-augsburg.de/~miche­ler/
  37. Domácí stránka MSW Loga:
    http://www.sof­tronix.com/lo­go.html
  38. Karel online
    http://karel.ol­dium.net/
  39. EDU-SIG: Python in Education
    http://www.pyt­hon.org/commu­nity/sigs/curren­t/edu-sig/
  40. Guido van Robot
    http://en.wiki­pedia.org/wiki/Gu­ido_van_Robot
  41. The Guido van Robot Programming Language
    http://gvr.sou­rceforge.net/
  42. An Introduction to Programming with Karel J. Robot
    http://blog.thin­goid.com/2003/10­/karel-intro/
  43. Teaching a young robot new tricks
    http://blog.thin­goid.com/2003/11­/karel-new-tricks/
  44. Karel and Company – More Robots
    http://blog.thin­goid.com/2003/12­/karel-and-company/
  45. Karel heads for the stars
    http://blog.thin­goid.com/2004/03­/karel-star/
  46. Karel programming language documentation
    http://mormegil­.wz.cz/prog/ka­rel/prog_doc.htm
  47. Karel J. Robot
    http://www.ma­inlandregional­.net/dklipp/Ho­nors%20Computer%20Sci­ence%20Java.htm
  48. Karel (programming language)
    http://en.wiki­pedia.org/wiki/Ka­rel_(programmin­g_language)
  49. Richard E. Pattis
    http://en.wiki­pedia.org/wiki/Richar­d_E._Pattis
  50. XKarel home page
    http://xkarel­.sourceforge.net/en­g/
  51. XKarel – screenshoty oken
    http://xkarel­.sourceforge.net/en­g/program.php#Ok­na
  52. Greenfoot
    http://www.gre­enfoot.org/abou­t/whatis.html
  53. Computer programming – Educational programming languages
    http://www.kid­slike.info/com­puter_program­ming_educatio­nal_programmin­g_languages
  54. Making Great Programmers: Why BASIC is Still Relevant
    http://kidbasic­.sourceforge.net/en/why­.html
  55. Gambas Wiki
    http://en.wiki­books.org/wiki/Gam­bas
  56. Free tool offers ‚easy‘ coding
    http://news.bbc­.co.uk/2/hi/tec­hnology/6647011­.stm
  57. Scratch Lowers Resistance to Programming
    http://www.wi­red.com/gadge­tlab/2009/03/scrat­ch-lowers/
  58. Základy želví grafiky
    http://www.ro­ot.cz/clanky/za­klady-zelvi-grafiky/
  59. Bill Kendrick's Web Turtle
    http://www.so­nic.net/~nbs/web­turtle/

Byl pro vás článek přínosný?

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.