Hlavní navigace

Základy programování ve Squeaku - dokončení popisu syntaxe a sémantiky jazyka

19. 8. 2010
Doba čtení: 15 minut

Sdílet

V sedmé části seriálu o programovacích jazycích vhodných pro výuku dokončíme popis syntaxe a sémantiky Squeaku. Řekneme si, jakým způsobem lze použít zprávy se selektory whileTrue, whileFalse, whileTrue: a whileFalse:, dále si ukážeme použití lokálních proměnných a vysvětlíme si význam objektů, tříd a metatříd.

Obsah

1. Práce s lokálními proměnnými

2. Cykly s podmínkou testovanou na začátku každé iterace

3. Cykly s podmínkou testovanou na konci těla smyčky

4. Třídy a objekty

5. Zjišťování informací o objektech

6. Metatřídy

7. Instanční proměnné (atributy objektů) a metody

8. Obsah následující části seriálu

9. Odkazy na Internetu

1. Práce s lokálními proměnnými

V předchozích částech tohoto seriálu jsme si sice již řekli poměrně značnou část informací nutných pro úspěšnou tvorbu aplikací ve Squeaku, ovšem zbývá nám doplnit ještě několik poměrně důležitých údajů. Nejprve si řekneme, jakým způsobem se ve Squeaku (přesněji řečeno ve Smalltalku a jeho dialektech) pracuje s proměnnými. Ve Squeaku lze vytvářet a používat několik typů proměnných. Jedná se o takzvané instanční proměnné (tj. atributy objektů), třídní proměnné (ty v některých dalších dialektech Smalltalku neexistují), sdílené slovníky a především lokální proměnné, jejichž platnost je omezena na jednu metodu popř. na programový blok. Pravidla pro pojmenovávání proměnných se příliš neliší od jiných programovacích jazyků, snad s jedinou výjimkou – v názvu proměnné se nesmí používat podtržítko, protože to má, především z historických důvodů, poněkud odlišný význam. Původně se totiž pro přiřazení hodnoty (objektu) k proměnné používal namísto dvojznaku := symbol šipky doleva ←, který se pro účely snadnějšího zápisu i zobrazení na různých typech displejů a tiskáren nahrazoval právě podtržítkem.

Obrázek 1: Konvence psaní identifikátorů CamelCase připomínala jejím autorům (resp. autorům tohoto názvu) velbloudí hrby.

Ve Squeaku je dodržováno pravidlo, že názvy lokálních proměnných, tj. proměnných platných pouze v rámci jedné metody nebo programového bloku, začínají malým písmenem a každé další slovo v názvu proměnné začíná písmenem velkým (jedná se o takzvanou CamelCase konvenci). Příklad pojmenování lokálních proměnných: x, var1, onlyLocalVari­able. Proměnné globální začínají naopak písmenem velkým. Vzhledem k tomu, že i třídy jsou ve Squeaku globálními proměnnými (viz též další kapitoly), začínají i jejich jména velkým písmenem, například Color, WarningDialog (jedná se o stejnou konvenci, jaká je dodržována i v jiných programovacích jazycích). Před svým použitím musí být lokální proměnné deklarovány, a to velmi jednoduchým způsobem – postačuje zapsat identifikátor či identifikátory všech lokálních proměnných mezi znaky | (pipe). Viz též následující příklad:

| x y var1 localVariable |
x := true
y := 42
var1 := y * y

Lokální proměnné mohou být deklarovány a použity i v rámci programového bloku. V tomto případě se jejich deklarace vkládá až za seznam výrazů, opět mezi znaky pipe (to znamená, že první z těchto znaků není součástí deklarace proměnných, ale jedná se o oddělovač názvu parametrů od zbytku bloku), viz následující dvojice příkladů:

[ :par1 :par2 | | local | local := par1 * par2. local ] value: 6 value: 7
42

Blok s dvojicí parametrů a dvojicí lokálních proměnných:

[ :par1 :par2 | | var1 var2 | var1 := par1 - par2. var2 := par1 + par2. var1*var2 ] value: 12345 value: 6780
106430625

2. Cykly s podmínkou testovanou na začátku každé iterace

Programové bloky, jimiž jsme se poměrně podrobně zabývali především v předchozí části tohoto seriálu, umožňují díky zprávám se selektory ifTrue:, ifFalse atd. vytváření částí programového kódu, který se provede pouze při splnění nějaké podmínky. Jedná se o ekvivalenty podmíněných příkazů a podmíněných výrazů známých z ostatních programovacích jazyků, které jsou však ve Squeaku implementovány pomocí „obyčejného“ posílání zpráv, tj. nejedná se o žádný syntaktický prvek jazyka. Podobným způsobem, tj. opět bez „magického“ přispění speciální syntaktické kategorie, lze vytvářet i ekvivalenty programových smyček (cyklů), u nichž se podmínka testuje buď vždy před provedením další iterace nebo naopak až po provedení každé iterace. Pro tyto účely jsou ve Squeaku vytvořeny ve třídě BlockContext (představující programový blok) metody zajišťující příjem zpráv se selektory whileTrue, whileFalse, whileTrue: a whileFalse:. Povšimněte si, že první dva selektory se používají pro unární zprávy, protože za svým jménem nemají uvedenou dvojtečku.

Nejprve si popíšeme zprávy se selektory whileTrue: a whileFalse:, pomocí nichž je možné vytvořit ekvivalent programových smyček s testem prováděným před začátkem každé iterace. Zprávy s těmito selektory je možné poslat instancím třídy BlockContext, tj. programovým blokům (které jsou příjemci zprávy). Parametrem těchto zpráv je opět programový blok, přičemž příkazy v něm umístěné představují tělo cyklu. Blok představující příjemce zprávy je před každou iterací spuštěn, přičemž jeho návratová hodnota je použita pro rozhodnutí, zda se má tělo smyčky provést či nikoli (připomeňme si, že výsledek posledního příkazu v bloku je současně i jeho návratovou hodnotou). Pomocí zprávy se selektorem whileTrue: se vytváří ekvivalent klasické universální smyčky while, zatímco zpráva se selektorem whileFalse: se používá v těch případech, kdy se vyhodnocuje opačná podmínka (ušetří se jedna negace). V následujícím demonstračním příkladu je ukázáno, jakým způsobem je možné vytvořit cyklus, který postupně vypisuje do okna Transcript druhé mocniny základu 2. Povšimněte si, jakým způsobem jsou odděleny jednotlivé zprávy ve druhém bloku pomocí znaku tečka:

Transcript clear
|n|
n := 1
Transcript show: n
Transcript cr
[ n < 1000 ] whileTrue: [ Transcript show: n. Transcript cr. n := n*2 ]

Obrázek 2: Programová smyčka se v předchozím demonstračním příkladu zastaví po dosažení takové mocniny základu 2, která převyšuje hodnotu 1000.

Vzhledem k tomu, že tělo příjemce zprávy whileTrue: či whileFalse: může obsahovat libovolné množství příkazů, lze pomocí těchto zpráv implementovat, i když poněkud složitěji, i smyčky typu do-while či repeat-until, tj. programové smyčky s testem prováděným na konci každé iterace:

Transcript clear
|val|
val := 0
[
    val := val + 1
    Transcript show: val
    Transcript cr
    val < 10
] whileTrue: [ ]

Obrázek 3: Předchozí demonstrační příklad po svém spuštění ve Squeaku. Povšimněte si, že se vytiskne i hodnota 10, která již splňuje podmínku pro ukončení smyčky. Ovšem tato podmínka je testována až poté, co je daná hodnota vypsána.

3. Cykly s podmínkou testovanou na konci těla smyčky

V předešlém demonstračním příkladu, který byl uvedený v předchozí kapitole, jsme si ukázali jednu variantu programové smyčky implementované pomocí zprávy whileTrue:, u níž se podmínka pro další iteraci testovala až po (alespoň jednom) provedení těla smyčky. Vzhledem k tomu, že použití prázdného bloku ve zprávách se selektory whileTrue: a whileFalse: je nadbytečné a zbytečně zhoršuje čitelnost programového kódu, byla ve třídě BlockContext vytvořena ještě jedna dvojice metod, které akceptují unární (bezparametrické) zprávy se selektory. Jedná se o zprávy nazvané whileTrue a whileFalse. Použití těchto zpráv je velmi jednoduché, o čemž se ostatně můžete přesvědčit po shlédnutí následujících dvou demonstračních příkladů. První z těchto demonstračních příkladů po svém spuštění vypíše sekvenci celých čísel od jedničky do desíti:

Transcript clear
|val|
val := 0
[
    val := val + 1.
    Transcript show: val.
    Transcript cr.
    val < 10
] whileTrue

Obrázek 4: Výsledek běhu předchozího demonstračního příkladu ve Squeaku.

Druhý příklad slouží pro vygenerování prvních několika prvků Fibonacciho řady (jedná se o implementaci bez rekurze a bez použití pomocných polí):

Transcript clear.
|x y|
x := 1
y := 1
[
  Transcript show: x.
  Transcript cr.
  y := x + y.
  x := y - x.
  x < 100
] whileFalse

Obrázek 5: Fibonacciho řada vygenerovaná demonstračním příkladem.

Důležitá poznámka na závěr: výše uvedené metody implementující zprávy se selektory whileTrue, whileFalse, whileTrue: a whileFalse: jsou optimalizovány na úrovni bajtkódu Squeaku. To mimo jiné znamená, že i když se z hlediska zdrojového kódu stále jedná o posílání zpráv programovým blokům, při běhu programu se ve skutečnosti žádná zpráva bloku nepošle – namísto toho se spustí inline kód, což je samozřejmě rychlejší, zejména v případech, kdy je počet opakování programové smyčky vysoký.

4. Třídy a objekty

Již v úvodním článku o programovacím jazyce Squeak jsme si řekli základní informace o jeho objektovém systému, který se v některých ohledech odlišuje například od objektového systému Javy nebo C++. Připomeňme si, že prakticky vše, s čím ve Squeaku programátor přichází do styku, jsou objekty; dokonce i samotné třídy jsou objekty. Každý objekt může obsahovat privátní atributy a (obecně neprivátní) metody. Objekty mezi sebou komunikují výhradně pomocí mechanizmu nazvaného posílání zpráv, přičemž zprávy mohou být tří typů (unární, binární a slovní), v tomto případě se ovšem spíše jedná o syntaktickou záležitost vedoucí ke zpřehlednění posílání unárních a binárních zpráv. Objekt buď dokáže na zprávu, která mu byla zaslána, nějakým způsobem zareagovat, tj. zavolá nějakou svoji metodu, která zprávu zpracuje, nebo může při přijetí zprávy, které nerozumí (a nebo nechce rozumět!) vyvolat výjimku MessageNotUnder­stood.

5. Zjišťování informací o objektech

S objektovým systémem Squeaku úzce souvisí i jeho reflexivita, která mj. umožňuje získávat za běhu některé důležité informace o libovolném objektu. Každému objektu, který existuje ve virtuálním stroji Squeaku je například možné poslat unární zprávu se selektorem class, přičemž výsledkem této zprávy je reference na „svoji“ třídu, tj. na třídu, jejíž instancí daný objekt vznikl. Můžeme si jednoduše vyzkoušet, že unární zprávu class je skutečně možné poslat jakémukoli objektu, tj. například i programovému bloku (který sám o sobě prozradí, že je instancí třídy BlockContext), speciální proměnné nil či false nebo řetězci:

42 class
SmallInteger
42 factorial class
LargePositiveInteger
[ 42 ] class
BlockContext
(1/2) class
Fraction
nil class
UndefinedObject
true class
True
false class
False
Object new class
Object
'hello' class
ByteString

Dotazování z jaké třídy nějaký objekt vznikl je sice v některých případech užitečné (i když ne v takové míře, jako ve staticky typovaných jazycích), většinou je však mnohem důležitější zjistit, zda objekt dokáže zpracovat zprávu s určitým selektorem. I to je samozřejmě možné jednoduše zajistit – postačuje objektu poslat zprávu se selektorem respondsTo:. Parametrem této zprávy je symbol představující selektor zprávy, o které chceme zjistit, zda ji objekt dokáže nebo naopak nedokáže zpracovat. Výsledkem poslání zprávy respondsTo: je samozřejmě hodnota true či false. Ukažme si vše na několika demonstračních příkladech. Povšimněte si především toho, že se skutečně jako parametr zprávy respondsTo posílá symbol, nikoli selektor samotný. Taktéž si povšimněte, že součástí selektoru zprávy je i dvojtečka na konci jeho názvu, viz rozdíl mezi výrazy „true respondsTo: #ifTrue“ a „true respondsTo: #ifTrue:“.

42 respondsTo: #+
true
42 respondsTo: #abs
true
42 respondsTo: #toString
false
42 respondsTo: #asString
true
true respondsTo: #asString
true
true respondsTo: #not
true
true respondsTo: #ifTrue
false
true respondsTo: #ifTrue:
true
[] respondsTo: #whileTrue
true
[] respondsTo: #whileTrue:
true

6. Metatřídy

Objektový systém Sqeaku je zkonstruovaný takovým způsobem, že každý objekt je instancí nějaké třídy (ostatně tak je tomu i v mnoha dalších objektově orientovaných jazycích). Vzhledem k tomu, že jsme si v předchozích kapitolách řekli, že i třídy jsou objekty, vyplývá z toho, že třídy musí být instancí jiné třídy či jiných tříd. Ve Squeaku a samozřejmě i ve Smalltalku tomu tak skutečně je. Třída, jejímiž instancemi jsou jiné (běžné) třídy, se nazývá metatřída (metaclass). Tuto třídu (pojmenovanou Metaclass) je samozřejmě možné si prohlédnout v System Browseru, konkrétně ji lze nalézt v sekci Kernel-Classes. Zajímavá je zejména implementace metody new, z níž je patrné, že v celém systému existuje pouze jedna jediná instance třídy Metaclass, což dává smysl, protože je tímto „omezením“ zaručeno konzistentní chování celého prostředí Squeaku (a navíc není nutné, aby existovalo více metatříd, když se všechny mají chovat stejným způsobem):

new
    "The receiver can only have one instance. Create it or complain that one already exists."
    thisClass class ~~ self
        ifTrue: [^thisClass _ self basicNew]
        ifFalse: [self error: 'A Metaclass should only have one instance!']

7. Instanční proměnné (atributy objektů) a metody

V této kapitole si stručně řekneme, jakým způsobem se zapisují metody a instanční proměnné (atributy). Jako příklad nám poslouží třída Random, kterou najdeme v System Browseru ve skupině (kategorii) Kernel-Numbers. Objekty, které jsou instancemi této třídy, obsahují instanční proměnné nazvané seed, a, m, q a r. Instanční proměnné nejsou ve Sqeaku viditelné mimo danou instanci třídy (na rozdíl od jiných jazyků, kde je možné viditelnost měnit), proto, pokud potřebujeme získat hodnotu některé z instančních proměnných, musí pro ně být nadefinován příslušný getter, tj. metoda pojmenovaná stejně jako daná instanční proměnná, která explicitně vrátí její hodnotu. Naproti tomu pokud je zapotřebí nastavit hodnotu instanční proměnné, je nutné nadefinovat setter, což je metoda pojmenovaná stejně jako daná instanční proměnná, ovšem za jejím jménem je uvedena dvojtečka. Tato konvence v pojmenování dává smysl – getter je zavolán pomocí unární zprávy (bez parametrů), zatímco setter vždy s jedním parametrem.

Pokud má metoda vracet nějakou hodnotu, musí její poslední příkaz začínat symbolem ^ (stříška, popř. šipka nahoru). Tento příkaz se při zavolání metody vyhodnotí a jeho výsledek se vrátí jako návratová hodnota celé metody. Ukažme si nyní několik metod třídy Random:

Privátní getter pro instanční proměnnou seed:

seed
        ^ seed

Veřejný setter, kterým se nastavuje „semínko“ generátoru náhodných čísel (tj. privátní instanční proměnná nazvaná seed):

seed: anInteger
        seed := anInteger

Veřejná metoda bez parametrů, která vrátí další hodnotu ze sekvence pseudonáhodných čí­sel:

next
        "Answer a random Float in the interval [0 to 1)."
        ^ (seed _ self nextValue) / m

Veřejná metoda s více parametry vracející hodnotu. Povšimněte si, že tato metoda má dvě lokální proměnné attacks a defends:

check: nAttack against: nDefend difficulty: diff
        "Roll some dice, WoD-style."
        | attacks defends |
        attacks := self check: nAttack difficulty: diff.
        attacks < 0 ifTrue: [^ attacks].
        defends := self check: nDefend difficulty: diff.
        ^ attacks - defends min: 0

S tvorbou nových tříd, popř. s úpravou tříd stávajících se seznámíme příště při vysvětlování objektové hierarchie grafického uživatelského rozhraní Squeaku.

CS24_early

8. Obsah následující části seriálu

V následující části seriálu o programovacích jazycích vhodných pro výuku programování se již nebudeme zabývat popisem syntaxe a sémantiky Squeaku. Namísto toho se zaměříme na oblast jeho grafického uživatelského rozhraní, možností tohoto rozhraní, měnitelnosti jednotlivých komponent (widgetů) atd. Ostatně není bez zajímavosti, že koncepty grafického uživatelského rozhraní (GUI) založeného na bitmapové grafice (což byla v té době žhavá novinka) vznikaly právě ve Smalltalku jehož je Squeak dialektem. Prvním komerčně dostupným počítačovým systémem s plnohodnotným grafickým uživatelským rozhraním byl mikropočítač Xerox 8010 Star Information System z roku 1981, který předběhl jak osmibitový mikropočítač Apple Lisa z roku 1983, tak i mnohem slavnější Macintosh z roku 1984, jehož uživatelské rozhraní bylo z velké míry založeno právě na výsledcích projektů naprogramovaných ve Smalltalku na počítačových systémech firmy Xerox.

Obrázek 6: Ukázka grafického uživatelského rozhraní počítačového systému Xerox 8010 Star Information System.

9. Odkazy na Internetu

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