MASARYKOVA UNIVERZITA V BRNĚ FAKULTA INFORMATIKY
Diplomová práce
Výuka objektově orientovaného programování na středních školách
Brno, 2003
Tomáš Foltýnek
Prohlášení Prohlašuji, že tato práce je mým původním autorským dílem, které jsem vypracoval samostatně. Všechny zdroje, prameny a literaturu, které jsem při vypracování používal nebo z nich čerpal, v práci řádně cituji s uvedením úplného odkazu na příslušný zdroj.
Poděkování Děkuji RNDr. Jaroslavu Pelikánovi, Ph.D. za vedení této práce. Dále děkuji Mgr. Marku Blahovi za to, že mi věnoval svůj čas a zejména v počátcích mé práce mi poskytl cenné informace pramenící z jeho pedagogické praxe.
-2-
Shrnutí Tato práce obsahuje zhodnocení vývojových prostředí podporujících objektově orientované programování z hlediska jejich vhodnosti pro výuku na středních školách. Dále obsahuje praktickou realizaci sady programů v jazyce Object Pascal a prostředí Borland Delphi, na kterých si studenti středních škol osvojí zásady a metody objektově orientovaných návrhů aplikací. Jednotlivé programy jsou doplněny i metodickými pokyny pro učitele.
Klíčová slova OOP, Objektově orientované programování, programování, Příklady pro výuku programování,
-3-
Object
Pascal,
Delphi,
Výuka
Obsah
Obsah 1 ÚVOD .......................................................................................................................................................6 2 CÍLE VÝUKY INFORMATIKY NA STŘEDNÍ ŠKOLE ...................................................................8 3 CÍLE VÝUKY OOP..............................................................................................................................10 3.1 PROČ UČIT OOP................................................................................................................................10 3.2 KONKRÉTNÍ CÍLE VÝUKY ..................................................................................................................10 4 PROSTŘEDÍ PRO VÝUKU OOP .......................................................................................................12 4.1 OBJECT PASCAL ................................................................................................................................12 4.2 DELPHI..............................................................................................................................................12 4.3 C++ ..................................................................................................................................................12 4.4 EIFFEL ..............................................................................................................................................13 4.5 SMALLTALK .....................................................................................................................................13 4.6 JAVA .................................................................................................................................................14 5 POROVNÁNÍ OBJEKTOVÝCH JAZYKŮ .......................................................................................15 5.1 PROČ UČIT OBJECT PASCAL ..............................................................................................................15 5.2 PROČ NEUČIT OBJECT PASCAL ..........................................................................................................15 5.3 PROČ UČIT C++.................................................................................................................................15 5.4 PROČ NEUČIT C++ ............................................................................................................................16 5.5 PROČ UČIT DELPHI ............................................................................................................................16 5.6 PROČ NEUČIT DELPHI........................................................................................................................16 5.7 PROČ UČIT JAVU ...............................................................................................................................16 5.8 PROČ NEUČIT JAVU ...........................................................................................................................17 5.9 PROČ UČIT SMALLTALK....................................................................................................................17 5.10 PROČ NEUČIT SMALLTALK .............................................................................................................17 5.11 PROČ UČIT EIFFEL ...........................................................................................................................17 5.12 PROČ NEUČIT EIFFEL.......................................................................................................................17 5.13 CO TEDY UČIT .................................................................................................................................18 6 VÝUKA OBJECT PASCALU..............................................................................................................19 6.1 VSTUPNÍ ZNALOSTI ...........................................................................................................................19 6.2 ZAPOUZDŘENÍ ...................................................................................................................................19 6.3 DĚDIČNOST .......................................................................................................................................20 6.4 POLYMORFISMUS ..............................................................................................................................21 7 VÝUKA BORLAND DELPHI .............................................................................................................22 7.1 VSTUPNÍ ZNALOSTI ...........................................................................................................................22 7.2 SEZNÁMENÍ S PROSTŘEDÍM A VYTVOŘENÍ PRVNÍ APLIKACE ..............................................................22 7.3 PSANÍ KÓDU ......................................................................................................................................23 7.4 REAKCE NA UDÁLOST .......................................................................................................................23 7.5 UDÁLOSTI VYVOLANÉ MYŠÍ ..............................................................................................................24 7.6 KOMPONENTA TEDIT .......................................................................................................................26 7.7 KOMPONENTY TCHECKBOX A TRADIOBUTTON ...................................................................................27 7.8 VÝJIMKY...........................................................................................................................................28 7.9 PRÁCE S ČASEM A KOMPONENTA TMAINMENU ...................................................................................29 7.10 KOMPONENTA TSCROLLBAR ...........................................................................................................30 7.11 MODÁLNÍ A NEMODÁLNÍ FORMULÁŘE ............................................................................................31 7.12 VLASTNOSTI FORMULÁŘE A OBJEKT SCREEN ..................................................................................32 7.13 RTTI OPERÁTORY A PARAMETR SENDER .........................................................................................34 7.14 KOMPONENTY TLISTBOX A TCOMBOBOX .........................................................................................34 7.15 GRAFICKÝ VÝSTUP: TŘÍDA TCANVAS ..............................................................................................36 7.16 KOMPONENTA TIMAGE ...................................................................................................................38 7.17 VYTVÁŘENÍ KOMPONENT ZA BĚHU PROGRAMU ..............................................................................39 7.18 DIALOGY ........................................................................................................................................40 7.19 MŘÍŽKY ..........................................................................................................................................41 7.20 DYNAMICKÁ POLE ..........................................................................................................................43 7.21 KOMPONENTA TMEMO .....................................................................................................................43
-4-
Obsah 7.22 NÁSTROJOVÁ LIŠTA A STAVOVÝ ŘÁDEK .........................................................................................45 7.23 DALŠÍ VÝUKA .................................................................................................................................46 7.24 FUNKCE VÝVOJOVÉHO PROSTŘEDÍ ..................................................................................................47 7.25 FORMA VS. OBSAH ..........................................................................................................................48 7.26 PŘEDDEFINOVANÉ APLIKACE A EXPERTI .........................................................................................49 8 DLOUHODOBÉ PROJEKTY .............................................................................................................50 8.1 VÝHODY DLOUHODOBÝCH PROJEKTŮ ...............................................................................................50 8.2 NEVÝHODY DLOUHODOBÝCH PROJEKTŮ...........................................................................................50 8.3 DLOUHODOBÉ PROJEKTY: ANO ČI NE................................................................................................50 8.4 ZÁSADY DLOUHODOBÝCH PROJEKTŮ ................................................................................................51 8.5 TÉMATA DLOUHODOBÝCH PROJEKTŮ ...............................................................................................52 9 ZÁVĚR...................................................................................................................................................54 LITERATURA .........................................................................................................................................55 INTERNETOVÉ ZDROJE .....................................................................................................................56 PŘÍLOHA: DALŠÍ PŘÍKLADY.............................................................................................................57
-5-
Úvod
1 Úvod Informatika patří mezi nejmladší učební předměty, které se na našich školách vyučují. Pokud se zabýváme informatikou jako vědou, respektive společenským fenoménem, není pochyb o tom, že se jedná o obor velmi dynamický, jehož priority a základy se mění takřka z roku na rok. Není proto divu, že také informatika jako učební předmět, který má studenty připravovat k tomu, aby se ve světě výpočetní techniky dokázali orientovat, je předmět, jehož náplň prochází poměrně dramatickým vývojem. Informatika jako předmět totiž musí studenty naučit nejen orientaci v současném světě výpočetní techniky, ale i znalostem, které uplatní v každém vývojovém stadiu tohoto oboru. Mezi témata, které učitelé do výuky informatiky či výpočetní techniky zařazují, se poměrně nedlouho řadí také objektově orientované programování (dále jen OOP). Důvodů pro tuto skutečnost je hned několik. Tím prvním je bezesporu to, že znalost alespoň základních pravidel objektového programování je v praxi poměrně hodně ceněná. Aplikace s grafickým uživatelským rozhraním, které jsou zpravidla řízené událostmi, bychom si bez objektového přístupu představovali jen velmi těžko. Dalším důvodem je to, že výuka OOP přirozeně navazuje na výuku programování jako takového. Posledním důvodem je pak skutečnost, že OOP je odvětví poměrně moderní. Studenti, kteří se o výpočetní techniku zajímají také mimo školu, často slýchávají o věcech jako Delphi, C++ či Java, a rádi by se dozvěděli, co se za těmito názvy skrývá. Proto je to nezřídka právě iniciativa studentů, co učitele přivede k tomu, aby objektově orientované programování do výuky zařadil. Ne každý učitel má dostačující vědomostní základy na to, aby mohl objektově orientované programování učit. I ten, který má dostatečné vědomosti, se může potýkat s nedostatkem programátorské praxe v tomto oboru. Ani dobrá úroveň teoretických znalostí, ani programátorská praxe však nejsou uspokojivou zárukou pedagogického úspěchu. Učitel musí metodiku své výuky důkladně promyslet. Musí zvážit, jaké prostředky k výuce použije, jakým způsobem bude studenty motivovat, na co bude klást důraz, co naopak může uvést jen okrajově. To jsou však jen ty nejzákladnější okruhy učitelových úvah. Za každým okruhem se skrývá mnoho otázek, na které učitel, uvažující o výuce objektově orientovaného programování, bude muset odpovědět. Mnohdy budou odpovědi v kontextu konkrétní školy a konkrétní skupiny studentů zřejmé, mnohdy bude hledání odpovědi náročnější. Je třeba zdůraznit, že tato práce není učebnicí OOP. Znalost OOP, načerpaná např. z [28], je již u čtenáře této práce předpokládána. Úkolem této práce je především pomoci učitelům, kteří chtějí OOP učit. Přestože na spoustu otázek neodpoví přímo, uvádí možné výhody a nevýhody té či oné odpovědi. V žádném případě není cílem této práce jednoznačný závěr, jaký způsob je při vedení výuky OOP nejlepší. Ani být nemůže. Vše záleží totiž nejen na konkrétní škole, konkrétním učiteli, ale i očekávaném uplatnění studentů a aktuálním vývoji výpočetní techniky. Tato práce by měla být metodickou pomůckou do té doby, dokud bude OOP učebním tématem informatiky, ať se tento předmět jmenuje jakkoli. I zkušený učitel, který má v metodice výuky dávno jasno, zde však najde množství příkladů, které jsou při výuce použitelné buďto přímo, nebo mohou posloužit jako inspirace při vymýšlení příkladů nových. Přestože jsou všechny příklady napsány v prostředí Borland Delphi, velká většina z nich nevyužívá specifik tohoto prostředí a jsou tak s drobnými úpravami přenositelné na výuku OOP v jiném vývojovém prostředí nebo dokonce v jiném programovacím jazyce. Příklady tvoří těžiště této práce. Správnou metodiku lze totiž zvolit zejména na základě vrozených vloh, nabytého pedagogického vzdělání či konzultacemi se zkušenějšími kolegy. Ale příklady jsou věcí, bez nichž se při výuce neobejde nikdo. I sebezkušenějšímu učiteli tato práce může pomoci tím, že mu ušetří čas potřebný na jejich vymýšlení. Většina příkladů je včleněna přímo do textu práce, ostatní pak tvoří její přílohu. V nadpisu příkladu je vždy uvedeno slovo „Příklad“. Pro názornost je text příkladu doplněn obrázkem. Kromě toho je většina uvedených příkladů dostupná na doprovodném CD, a to včetně svých zdrojových kódů. Text ke každému příkladu je rozdělen do několika částí, přičemž některé z nich mohou být vynechány, pokud nejsou relevantní:
-6-
Úvod
Procvičované znalosti: Tento odstavec obsahuje heslovitý výčet dovedností, které se studenti na příkladu naučí. Je uveden především pro usnadnění orientace učitele. Legenda: Je-li příklad převzat z praxe nebo se k příkladu váže nějaká legenda, je uvedena právě v tomto odstavci. Text v této části může být použit pro motivaci studentů. Zadání: Zde je uvedeno stručné a pokud možno jednoznačné zadání toho, co mají studenti naprogramovat. V zadání se mohou vyskytnout odkazy na legendu. Zadání je formulováno ve vztahu ke studentům a je uváděno v imperativu. Poznámky: Zde jsou uvedeny instrukce a rady, které studentům pomohou zadaný problém řešit. Použitý algoritmus: Je-li úloha řešitelná různými algoritmy a algoritmus představuje stěžejní část příkladu, je uveden popis algoritmu použitého ve vzorovém řešení příkladu na doprovodném CD. Možná rozšíření: Každý program lze vylepšit. Platí to zejména o jednoduchých programech, které slouží jako příklady v této práci. Nadaní studenti, kteří zadání splní dříve než ostatní, mohou pracovat na vylepšení svého programu. Důležité upozornění: Možná rozšíření u některých příkladů vyžadují nadstandardní znalosti, které se mnohdy na středních školách nevyučují. Je proto třeba zvážit, zda je vhodné tato rozšíření studentům doporučovat, případně jim zajistit relevantní studijní materiály. Možné alternativy: Lze-li konkrétní programátorskou dovednost demonstrovat na více alternativách téhož příkladu, jsou možné alternativy u příkladu uvedeny.
-7-
Cíle výuky informatiky na střední škole
2 Cíle výuky informatiky na střední škole Na základním cíli informatiky jako učebního předmětu se asi všichni shodnou: Naučit studenty zacházet s počítačem. To je ovšem cíl natolik široký, že si jeho realizaci prakticky nelze konkrétně představit. Cílem výuky informatiky na základních školách a na nižších stupních víceletých gymnázií je naučit studenty zacházet s počítačem jako uživatelé. Musí se tedy naučit rozeznávat jednotlivé části počítače, pochopit základní principy jejich fungování a naučit se s počítačem komunikovat pomocí textového a grafického rozhraní. Další fází je pak výuka nejběžnějších uživatelských dovedností, jakými jsou psaní textů, práce s grafikou, tvorba tabulek a práce s různými aplikacemi. Na některých školách je již v tomto věku zařazována výuka programování jako prostředku k učení algoritmizace, logického a analytického myšlení a řešení problémů. Přestože dovednosti nabyté výukou programování studenti v drtivé většině případů v praxi nevyužijí, je jejich výuka důležitá zejména kvůli rozvoji zmíněných forem myšlení. V této fázi znalostí studentů většinou výuka informatiky končí. Pouze na specializovaných středních školách, například se zaměřením na matematiku nebo přímo na programování, výuka informatiky a programování pokračuje. Cílem těchto škol totiž není jen naučit studenty pracovat s počítačem jako uživatelé. U studentů specializovaných tříd se předpokládá studium vysoké školy příslušného zaměření a nezřídka i pozdější výzkumná práce. Cíl základní školy, která vychovává pouze konzumenty informačních technologií, je na takovýchto školách překonáván. Studenti roli konzumenta zpravidla dokonale zvládají a mají-li se v oblasti informačních technologií dále rozvíjet, je třeba si vytyčit cíl nový, vyšší. Máme zde na výběr několik možností:
Vychovat dobré programátory Vychovat schopné administrátory a správce sítě Vychovat teoreticky dobře připravené výzkumné a vývojové pracovníky
Nedá se jednoznačně říci, který z cílů bychom měli preferovat. Pro studenty je v tomto okamžiku také příliš brzo, aby si svůj cíl zvolili sami. Proto bychom jim na střední škole měli poskytnout dostatečný základ pro všechny zmíněné cíle. Při výběru vysoké školy se pak studenti rozhodnou, kterému z nich dají přednost. Rozhodně tedy výuku informatiky směřující k dalším cílům zahájíme tématem, které je nezbytné pro dosažení všech těchto cílů. Tímto tématem je bezesporu tvorba algoritmů a chápání počítačů „zevnitř“. Prvním úkolem tedy je, naučit studenty programovat, a to v kterémkoli vhodném programovacím jazyce. K výuce programování jako takového se nejčastěji používá jazyk Pascal, který byl pro výukové účely vytvořen. Otázkou k diskusi zůstává, jak moc je tento jazyk z výukového hlediska vhodný, nicméně to není tématem této práce. Naučit studenty programovat je však jen první krok, který musíme udělat. Jeho realizace nám zpravidla zabere časový úsek v délce okolo dvou let. Po něm máme na výběr několik možností. Jejich zvolením se ve větší či menší míře přiblížíme k některému ze zmíněných cílů, stále se však jedná o dovednosti, které uplatní pravděpodobně všichni.
Výuka jiného programovacího jazyka, nejčastěji jazyka C. Tento posun je pro studenty přínosem zejména v tom, že při řešení zadaných úkolů používají stejné principy v myšlení, pouze při komunikaci s počítačem používají jiný prostředek, zvláště pak jinou syntaxi. Abstrakce od konkrétní syntaxe je velice důležitá, pokud chceme, aby si studenti vštípili především obecné principy a konkrétní formě zápisu nepřikládali takovou důležitost. Důkladně si tak ujasní rozdíl mezi obsahem sdělení a jeho formou a v pozdější praxi nebudou tyto složky zaměňovat. Výuka teoretické informatiky. Do této kapitoly školy většinou zařazují výuku teorie formálních jazyků, gramatik, automatů a operačních systémů. Tyto znalosti pak studenti využijí na vysoké škole se zaměřením na informatiku, kde tak budou mít oproti studentům, -8-
Cíle výuky informatiky na střední škole
kteří touto výukou na střední škole neprošli, značný náskok. Pokud škola přistoupí k výuce těchto znalostí, je dobré hodiny informatiky rozdělit na teoretické, ve kterých se probírají zmíněné věci, a praktické, ve kterých se studenti učí praktické věci, které se zmíněnou teorií vůbec nesouvisejí nebo souvisejí jen velmi okrajově. Důvod je zřejmý: Teorie formálních jazyků a operačních systémů se takřka nedá procvičovat na počítači. Poslední oblastí, o které se zmíníme, je výuka objektově orientovaného programování. Ta patrně tvoří nejpřirozenější pokračování výuky, neboť přímo navazuje na nabyté znalosti programování a tvoří další stupeň programátorských znalostí a dovedností. Tato výuka u studentů prohlubuje analytické myšlení, učí správné dekompozici problémů a za jistých okolností může podporovat učení týmové spolupráce.
Velice záleží na konkrétní škole a na tom, kolik času výuce informatiky věnuje. Je tak ve většině případů prakticky nemožné stihnout studenty pořádně naučit všechny popsané oblasti. Podařit se to samozřejmě může, ale jen ve třídách, které mají dostatečný počet hodin informatiky už od prvních ročníků nižších tříd víceletého gymnázia, a i v takových třídách se to týká jen té nejlepší skupiny. Ve skupinách, ve kterých se nestihnou probrat všechny zmíněné oblasti, je třeba některým z nich přiřadit větší prioritu a ty pak učit, zatímco jiné probrat jen okrajově, popřípadě vypustit úplně. Těžko se hledají objektivní kritéria pro srovnání. Už jenom proto, že studenty dělí od nástupu do praxe téměř deset let, což je v informatice doba natolik dlouhá, že nikdo nemůže vědět, co budou studenti opravdu potřebovat. V následujícím textu se budeme věnovat především poslednímu tématu, a to výuce objektově orientovaného programování.
-9-
Cíle výuky OOP
3 Cíle výuky OOP 3.1 Proč učit OOP Nyní si uvedeme několik důvodů, proč učit studenty právě objektově orientovanému programování. Samozřejmě si lze představit minimálně stejně pádné argumenty, proč učit něco jiného. Tyto argumenty nám jistě poskytnou obdobné práce na jiná témata.
Objektově orientované programování učí dalšímu stupni analytického myšlení. Díky tomu, že je to k dokonalosti dovedené strukturované programování, studenti se s objektově orientovaným programováním naučí řádné dekompozici problémů. Tato schopnost se jim pak bude hodit nejen při řešení programátorských problémů, ale i při řešení praktických problémů běžného života. Studenti budou během výuky nuceni pochopit další stupeň abstrakce. Je jím rozdíl mezi objektovým typem (třídou) a konkrétní instancí objektu (objektem). To je něco zcela nového, s čím se doposud nesetkali. Rozšíří se tak obzory jejich chápání, což je opět věc, kterou využijí nejen při programování. Objektově orientované programování je velmi užitečné v praxi, a to zejména díky tomu, že přímo souvisí s událostmi řízeným programováním, bez nějž bychom si nedokázali představit jakékoliv grafické rozhraní. Okna, ikony, tlačítka – to vše jsou objekty, které nějakým způsobem reagují na události. Protože grafické rozhraní je věc, se kterou se studenti každodenně setkávají, máme tak při výuce jednak příklad, na kterém lze principy řízení událostmi předvádět, a jednak mají studenti pocit, že jim to později k něčemu bude, což je pocit velmi důležitý při výuce čehokoliv. Objektově orientované programování podporuje týmovou spolupráci. Je tak rozšířené mimo jiné proto, že je velmi jednoduché postupovat při řešení problému společně ve skupině vývojářů. Stačí se společně dohodnout na dekompozici problému a komunikačních rozhraních, poté už každý sám pokračuje tvorbou konkrétních objektů. Mají-li se studenti (alespoň někteří) v budoucnu živit jako programátoři, je velmi důležité naučit je pracovat v týmu. A to se nejlépe učí právě s využitím OOP. Opět je na místě dodat, že týmová spolupráce je věc, kterou studenti později využijí nejen při programování. Studenty bude výuka bavit. Jestliže máme skupinu studentů, kteří se naučili dobře programovat, lze předpokládat, že je programování jako takové baví, a že se mu věnují i mimo školu. V tom případě se nám bude OOP učit poměrně snadno, protože nebude potřeba studenty náročně motivovat (jako by tomu bylo například v případě výuky různých teorií).
3.2 Konkrétní cíle výuky Jak již vyplývá z výše zmíněného, výuka objektově orientovaného programování je prostředkem k dosažení určitých cílů. Toto bychom měli mít při výuce neustále na paměti. Nikdy se pro nás nesmí stát prostředek cílem. Nesmí tedy být cílem naučit studenty objektově programovat. Je to jen pomůcka, jejímž prostřednictvím si studenti osvojí daleko obecnější a užitečnější znalosti a dovednosti. Přestože už byly na různých místech zmíněny, uvedeme je ještě jednou, tentokrát stručně a na jednom místě.
Rozvoj analytického myšlení Rozvoj abstraktního myšlení Správná dekompozice problémů Týmová spolupráce Rozdíl mezi obsahem a formou
Až budeme s výukou objektově orientovaného programování hotovi, nemělo by nám jako učitelům k uspokojení stačit pouhé konstatování, že jsme studenty naučili objektově programovat. Měli bychom se zamyslet nad tím, zda jim naše výuka kromě nabytých - 10 -
Cíle výuky OOP dovedností dala něco víc, zda splnila vytčené cíle. Teprve pokud si na tuto otázku dokážeme odpovědět kladně, můžeme považovat výuku objektově orientovaného programování za úspěšnou.
- 11 -
Prostředí pro výuku OOP
4 Prostředí pro výuku OOP Jednou z prvních otázek, na kterou si učitel uvažující o výuce objektově orientovaného programování musí odpovědět, je bezesporu to, v jakém jazyce a v jakém vývojovém prostředí bude toto téma učit. Zde jsou základní charakteristiky dostupných vývojových prostředí, která pro výuku OOP přicházejí v úvahu.
4.1 Object Pascal Základem jazyka Object Pascal byl programovací jazyk Pascal, který vyvinul profesor Niclaus Wirth na konci šedesátých a začátku sedmdesátých let dvacátého století. První publikace o Pascalu je datována do roku 1971. Jméno Pascal bylo vybráno jako vzpomínka na francouzského matematika a filosofa Blaise Pascala. V roce 1983 byl dokumentem ISO 7185 definován standard tohoto jazyka. Objektovým se Pascal stal v polovině sedmdesátých let, kdy byla do jazyka zvaného Pascal Plus zavedena konstrukce ENVELOPE. První jazyk, nazývaný skutečně Object Pascal, byl v polovině osmdesátých let vyvinut Larrym Teslerem a Niclausem Wirthem za podpory firmy Apple Macintosh. Tento jazyk byl určen výhradně pro počítače Apple. Přibližně v roce 1990 byl do Quick Pascalu (Microsoft) a Turbo Pascalu (Borland) zaveden datový typ OBJECT. Podpora objektů je v obou systémech podobná, není však úplně shodná. Dnes se pod názvem Object Pascal většinou rozumí programovací jazyk používaný firmou Borland v jejím produktu Delphi.
4.2 Delphi Delphi, striktně vzato, není programovací jazyk. Delphi je vývojové prostředí pro programátory v Object Pascalu. Na druhou stranu, Delphi přináší do Object Pascalu některá rozšíření a úpravy přímo v definici jazyka, proto bychom se o něm zmínit měli. Navíc také proto, že je to významný kandidát na výukové prostředí, ve kterém se nakonec rozhodneme OOP učit. Delphi, produkt firmy Borland, je profesionální vývojové prostředí sloužící k tvorbě aplikací pod Microsoft Windows. Jeho základním rysem je tedy značná systémová závislost. Za zmínku stojí také Kylix, což je linuxová verze Delphi sloužící k psaní programů pro tento systém.
4.3 C++ C++ je objektové rozšíření jazyka C. Oproti jazyku C však zavádí i další novinky, které s objektovým přístupem souvisejí jen okrajově. Nalezneme zde mnohonásobnou dědičnost, virtuální třídy, možnost dynamického spravování paměti, využití šablon a již definovaných vzorů (kontejnery, seznamy...), plně podporovaný polymorfismus, přetěžování operátorů, funkcí a třídních metod. Jazyk C++ umožňuje také zajištění obsluhy a manipulaci s výjimkami, poskytuje silnou typovou kontrolu, velmi elegantní práci s vstupními/výstupními proudy a také použití ukazatelů. Struktura programů je přehledná a umožňuje snadné intuitivní pochopení problému. Jazyk C vytvořil v Bellových laboratořích AT&T Denis Ritchie v roce 1972. Záměrem bylo napsat jazyk pro snadnou a přenositelnou implementaci Unixu. Na tomto díle se dále podíleli Brian Kernighan a Ken Thompson, a tak v roce 1973 vznikl Unix napsaný v C. Jazyk C vznikl jako systémový jazyk pro systémové programátory. Po řadu let byla faktickou normou jazyka kniha Programovací jazyk C autorů Kerninghana a Ritchieho, která byla vydána v roce 1978. Jazyk umožňoval programátorům nejrůznější metody zhutňování zdrojového textu, které jej však činily značně nečitelným. Nicméně s postupem času se s C a Unixem seznamovali studenti na vysokých školách, odcházeli do praxe a začali používat C i v jiných než systémových oblastech. Uživatelé přirozeně požadovali, aby C bylo nejen mocným prostředkem (tím bylo od svého vzniku), ale i bezpečným a přehledným jazykem. Rovněž vznikl trend vedoucí k normalizaci jazyka. S postupem doby se nezastavila ani teorie - 12 -
Prostředí pro výuku OOP programování. Jestliže C umožňuje psát programy modulárně, dnešní trend vyžaduje i podporu objektového přístupu. Již v roce 1978 se začal Bjarne Stroustrup zabývat otázkou objektových přístupů v jazyce C a kolem roku 1981 se na světě objevil první jazyk C s třídami (prapředek C++). Vlastní C++ byl vyvinut v letech 1983 – 1985. V roce 1986 publikoval Stroustrup knihu The C++ Programming Language. Počátkem 90. let pak byl i tento jazyk normalizován. Stejně jako na Object Pascal navazují Delphi jako jeho grafické vývojové prostředí, navazují na C++ vývojová prostředí Borland C++ Builder, Microsoft Visual C++, IBM Visual Age C++ a další.
4.4 Eiffel Jazyk Eiffel, jak už jeho jméno napovídá, byl pojmenován podle francouzského stavitele Gustava Eiffela, konstruktéra známé Eiffelovy věže v Paříži. Jeho autorem je Dr. Bertrand Meyer spolu se svojí firmou Interactive Software Engineering. Vývoj začal v roce 1985 a už o rok později byl na trhu první překladač tohoto jazyka. Cílem tehdy bylo vytvořit nový jazyk kombinující spolehlivost a schopnost konstruovat komplexní architektury. Základními rysy jazyka Eiffel jsou polymorfismus, zapouzdření a vícenásobná dědičnost. Ačkoli vícenásobná dědičnost má mnoho odpůrců, její implementace v Eiffelu dokáže jejich výtkám úspěšně čelit. Jazyk Eiffel nachází uplatnění v telekomunikačních systémech, finančních aplikacích a je také vhodný pro účely výuky.
4.5 SmallTalk SmallTalk je čistě objektový programovací jazyk. Vznikl na počátku sedmdesátých let ve výzkumném středisku PARC (Palo Alto Research Center) firmy Xerox. Jeho autory jsou Alan Kay, Adele Goldberg a Dan Ingalls. Jeho syntaxe je do značné míry ovlivněná LISPem a na rozdíl od jiných programovacích jazyků se velmi podobá přirozenému jazyku. Právě díky kořenům v LISPu je jazyk jako takový velmi jednoduchý, s jasnými funkcionálními rysy. Jak bychom od čistě objektového jazyka očekávali, vše je objekt. Přestože toto tvrzení slýcháváme i o Javě, ve srovnání se Smalltalkem nemůže být o Javě jako o čistě objektovém programovacím jazyku řeč. Ve SmallTalku je totiž objektem nejen instance třídy, ale i třída samotná. SmallTalk navíc nezná nic jako primitivní datové typy, které objekty nejsou. SmallTalk se tak vyhýbá jakékoliv typové kontrole a typovým konverzím, což vede k tomu, že smalltalkový kód je velmi hutný, bez zbytečného zdvojování. K datům objektů nelze přistupovat přímo, ale jen prostřednictvím zasílání zpráv. Ve SmallTalku v podstatě nelze dělat nic jiného, než zasílat zprávy objektům. Dokonce i základní programátorské struktury, jako jsou větvení a cykly, jsou ve SmallTalku realizovány pomocí zasílání zpráv objektům. Programování ve SmallTalku se neobjede bez vývojového prostředí, kterých je v současné době k dispozici několik. Jejich společným rysem je jazyk jako takový, velmi se však liší tím, jaké knihovny programátorům nabízejí. Dalším společným rysem je také to, že až na nezbytné záležitosti nejnižší úrovně jsou vývojová prostředí napsána v samotném SmallTalku. Programování ve SmallTalku je nezávislé na platformě. Program je přeložen do tzv. byte-kódu, který je pro všechny platformy stejný. Ke spuštění programu na konkrétní platformě pak samozřejmě potřebujeme interpret SmallTalku pro danou platformu (zpravidla bývá součástí vývojového prostředí). Díky tzv. Just in Time (JIT) kompilaci pak není provádění interpretovaného kódu o mnoho pomalejší (ve srovnání s C++ se udává dvacetiprocentní zpomalení). Velkým propagátorem tohoto jazyka je firma IBM, která také vyvinula vlastní vývojové prostředí VisualAge obsahující knihovny, které programátorům zpřístupňují specifika počítačů IBM. Pro programování pod Windows je určeno vývojové prostředí Dolphin SmallTalk, které výborně implementuje klasický rys Windows – zasílání zpráv. Konečně, na zasílání zpráv je postaven samotný SmallTalk, tudíž implementace tohoto rysu byla samozřejmostí.
- 13 -
Prostředí pro výuku OOP Všechna ostatní vývojová prostředí (VisualWorks, Squeak, GNU SmallTalk, atd.) jsou určena pro programování pod unixovými operačními systémy, popřípadě jsou na platformě nezávislá. Přestože se v praxi se SmallTalkem příliš nesetkáme, na některých vysokých školách a výzkumných ústavech je poměrně hojně využíván. Například na Fakultě informačních technologií VUT v Brně je SmallTalk uznávanou platformou pro studentské projekty, výzkumné projekty a různé simulace.
4.6 Java Programovací jazyk Java začala vyvíjet firma Sun Microsystems v roce 1991. Poprvé byla světu Java představena v květnu roku 1995. O okamžitý nárůst popularity se nezasloužil jazyk samotný, ale spíše podpora pro tvorbu aplikací určených pro WWW. Všeobecně se tvrdí, že Java stojí na principech C a C++. Do značné míry je to pravda, nicméně nemalou část svých vlastností a schopností si vypůjčila i od jazyka SmallTalk. Mezi tyto vlastnosti patří to, že programy v Javě jsou nezávislé na platformě. Překladače Javy totiž netvoří spustitelné soubory, ale byte-kód uložený do souborů s příponou class. Teprve tento byte-kód je možné za pomoci interpretu spustit. Protože interpretované jazyky jsou znatelně pomalejší než nativní kód konkrétní platformy, javové interprety provádějí, stejně jako interprety SmallTalku, JIT kompilaci, při níž jsou důležité a často prováděné části kódu přeloženy do nativního kódu konkrétní platformy, v němž jsou poté vykonávány. Tím se rychlost programů oproti klasickému interpretování výrazně zvýší. Díky tomu, že byte-kód v souborech .class je pro všechny platformy stejný, se Java stala hitem právě pro programování webových aplikací, k nimž lidé přistupují z různých platforem. Na serveru tak může být jen jediný class soubor, jeho spuštění pak už záleží na konkrétním interpretu vestavěném do konkrétního prohlížeče běžícího na dané platformě. Java je čistě objektový jazyk. Jedinými výjimkami jsou tzv. primitivní datové typy, které samy o sobě objekty nejsou. Ke Každému primitivnímu datovému typu však existuje třída implementující metody pro práci s daným datovým typem. Datové typy vůbec představují v Javě velice podstatnou záležitost. Java totiž patří mezi silně typované jazyky. Vše má svůj typ a prakticky veškeré typové konverze musí být programátorem potvrzeny, což může být v některých situacích nevýhodné, avšak je to dobrá prevence proti programátorským chybám. Java nepodporuje vícenásobnou dědičnost. Důvodem jsou poměrně špatné zkušenosti s tímto rysem, které vedly k četným chybám. Tento mechanismus je nahrazen pomocí abstraktnější záležitosti, a sice rozhraní. V současné době se Java stává stále populárnějším programovacím jazykem, který se používá nejen v komerční sféře, ale v čím dál tím větší míře se začíná uplatňovat i jako výukový jazyk. Opět se tedy jedná o žhavého kandidáta na výuku OOP. V Javě je možné programovat buďto v libovolném textovém editoru a zdrojové soubory překládat pomocí překladače spuštěného z příkazové řádky, nebo je možné využít některé z grafických vývojových prostředí. Profesionální grafická vývojová prostředí jsou dostupná prakticky na všech platformách:
Java SDK – základní vývojové prostředí od firmy Sun pro operační systémy Solaris, Linux a Windows 9x/NT/2000. Další firmy vytvářejí vývojová prostředí pro další operační systémy (např. IBM). Nad těmito základními vývojovými prostředími vznikají grafická vývojová prostředí dalších firem, která umožňují pohodlnější vývoj aplikací (např. BlueJ). NetBeans – vývojové prostředí vytvořené českou firmou NetBeans, nyní rozvíjené jako OpenSource. Forte – vývojové prostředí založené na NetBeans vyvíjené a distribuované pod hlavičkou firmy Sun. Základní verze je distribuována zdarma.
Z dalších vývojových prostředí jmenujme alespoň IBM VisualJava, Jikes, Jlint, Jopt, Realj či JCreator.
- 14 -
Porovnání objektových jazyků
5 Porovnání objektových jazyků Nyní, když jsme si něco řekli o základních rysech dostupných objektových jazyků, budeme se zabývat jejich výhodami a nevýhodami z hlediska výuky OOP. Je důležité uvědomit si, že tatáž vlastnost může být z jednoho úhlu pohledu výhodou a z jiného nevýhodou, což může vytvářet dojem, že si argumenty protiřečí. Záleží pak na konkrétních podmínkách pro výuku, který úhel pohledu je důležitější.
5.1 Proč učit Object Pascal Výuka Object Pascalu je velmi výhodná, pokud je Pascal jazykem, na kterém se studenti učili programovat. Tomu tak ve většině případů skutečně bývá. Začneme-li učit objektové programování právě na Object Pascalu, studenti nebudou mít vůbec pocit, že by se učili něco úplně nového. V podstatě je budeme učit jen další oblast programování v Pascalu, tedy něco, co už učíme hodně dlouho. Teprve po nějaké době lze u studentů začít pěstovat skutečně objektové myšlení. Základní výhoda je tedy v tom, že se studenti budou s novou látkou seznamovat postupně a budou stavět na věcech, které už dobře zvládají, což je obecně pro výuku čehokoliv nesmírně výhodné. Díky tomu se Object Pascal stává odrazovým můstkem pro výuku dalších jazyků, zejména pak Delphi nebo Javy.
5.2 Proč neučit Object Pascal Object Pascal není čistě objektový programovací jazyk. Je to jen pouhá nadstavba nad neobjektovým imperativním jazykem. Myšlenky OOP zde nejsou tím základním, na čem jazyk stojí, ale tvoří jen rozšíření neobjektového jazyka. Studenty tak nebude nic nutit ke skutečné objektové analýze řešeného problému. Je zde nebezpečí, že při nevhodné volbě příkladů nebo při přílišné vynalézavosti studentů se studenti budou objektovému programování stále vyhýbat a budou se snažit maximum problémů řešit tak jak jsou zvyklí, tedy neobjektově. Další podstatnou nevýhodou Object Pascalu je jistý nesoulad v pojmenovávání oproti jiným jazykům. Klíčové slovo OBJECT zde totiž na rozdíl od běžné terminologie ostatních jazyků neoznačuje objekt, ale třídu. Obvyklý pojem objekt, tedy instance třídy, v terminologii Object Pascalu neexistuje, místo něj se používá termín „instance objektu“. Pokud si studenti zvyknou na toto nestandardní pojmenování, mohou mít problémy přecházet k libovolnému jinému objektovému jazyku, a to včetně Delphi, která, byť vystavěná na Object Pascalu, již třídy a objekty pojmenovávají tak, jak je v OOP zvykem.
5.3 Proč učit C++ Nezbytnou podmínkou k výuce jazyka C++ je důkladná znalost programování v jazyce C. O výuce C++ tedy v žádném případě nemá smysl uvažovat dříve, než studenti zvládnou jazyk C skutečně dobře. Pokud byl jazyk C jazykem, na kterém se studenti učili programovat, výuka C++ se zde přímo nabízí. Výhody takového postupu jsou zde přesně tytéž, jako v případě návaznosti Object Pascalu na obyčejný Pascal, tedy to, že nové učivo staví na dobře zvládnutých základech a není jej příliš velké množství najednou. Dokonce zde odpadá i jedna z nevýhod Object Pascalu navazujícího na Pascal, a sice zmatek v pojmenování. C++ používá standardní terminologii pro třídu a objekt coby instanci třídy. V případě, že studenti umí jak Pascal tak C a váháme, na kterém z nich učit jeho objektovou nadstavbu, jeví se z tohoto hlediska C++ jako výhodnější. Díky tomu, že jazyk C je esenciálním programovacím jazykem na unixových systémech, C++ i přes svou v současné době klesající popularitu zůstane jazykem poměrně hojně používaným. Opět tu tedy máme dobrý základ v tom, že studenti mají pocit užitečnosti toho, co je učíme.
- 15 -
Porovnání objektových jazyků
5.4 Proč neučit C++ Hlavní důvod je stejný jako u Object Pascalu. C++ není čistě objektový programovací jazyk, ale jen rozšířením jazyka neobjektového. Důsledky již byly popsány dříve. Další nevýhodou je, že tento jazyk má v komerční sféře klesající podporu. Značná část programátorů C++ již přešla nebo přechází na jazyk Java, který je C++ syntakticky velmi podobný. Proto se jako učitelé můžeme dostat do problému, když nebudeme schopni uspokojivě obhájit účelnost znalosti C++. Posledním, z pedagogického hlediska však velmi významným důvodem je složitost vývojových prostředí. Tento argument bude podrobně rozveden v podkapitole „Proč neučit Delphi“, nicméně vývojová prostředí C++ jsou zpravidla ještě složitější než Delphi. 5.5 Proč učit Delphi Delphi je profesionální vývojové prostředí sloužící k tvorbě aplikací pod Microsoft Windows. Mezi vývojovými prostředími pracující s objektovými jazyky je nejrozšířenější, což jistě souvisí s tím, že Microsoft Windows je nejrozšířenější operační systém. Studenti se tak svými výsledky mohou prakticky kdekoliv „pochlubit“, což zvyšuje jejich motivaci. Navíc, výuka toho, co je rozšířené, automaticky vyvolává ve studentech pocit, že se učí něco, co opravdu použijí, což opět zvyšuje jejich motivaci. Navíc, kromě Delphi pod Windows je dostupný i Kylix pod Linux, což do určité míry eliminuje případný protiargument o systémové závislosti programů v Delphi.
5.6 Proč neučit Delphi Problémem Delphi je značná složitost vlastního vývojového prostředí. Velké množství času a úsilí zabere pouhé vysvětlení toho, jak vytvořit projekt, k čemu jsou dobré jaké soubory a seznámení s ovládáním vývojového prostředí. Kdybychom studentům měli zároveň s tím vysvětlovat ještě nové programovací principy, bylo by nových věcí příliš mnoho najednou a studenti by v tom měli zmatek. Před používáním vývojových prostředí na počátku výuky varuje i [13] (str. 29-30): Pokud jste úplným začátečníkem, nepoužívejte žádné vývojové prostředí. Jejich složitost a nutnost mnoha administrativních úkonů, např. vytvoření projektu (jistěže pro pokročilého samé užitečné věci) vás bude stát spoustu času. Kromě toho se ztratíte v záplavě předgenerovaného kódu. Vývojová prostředí svádí k tomu, že lze snadno vytvořit „zadarmo“ okénka. To samozřejmě velice oceníme, ale v začátcích je nutné rozumět jazyku. Tuto nevýhodu se nám však podaří eliminovat tím, že před započetím výuky Delphi věnujeme nějaký čas výuce Object Pascalu. Tím se množství nových věcí rozloží a studenti je lépe zvládnou. Musíme však mít na paměti, že Object Pascal používá odlišnou terminologii než Delphi, na což je nutné studenty včas upozornit. Další nevýhodou výuky Delphi je, byť ne zcela pravdivé, ale značné rozšířené tvrzení, že hlavní přístup spočívá pouze ve výběru voleb a vizuálních elementů. Psaní kódu je jen jakési nutné zlo, které je potřeba mimochodem podstoupit proto, aby byly programy lepší ([4], str. 17, 937). Existuje zde tedy nebezpečí, že studenti začnou objektové programování chápat jen jako „vyklikávání okýnek a tlačítek“ a původní cíl výuky se zcela vytratí.
5.7 Proč učit Javu Java je čistě objektový programovací jazyk. Díky tomu zde máme vynikající příležitost naučit studenty objektově myslet, což je z hlediska uplatnění v praxi daleko důležitější než syntaktické zásady konkrétního jazyka. Díky nemožnosti používat jakékoliv globální objekty Java nutí programátora k důkladné objektové analýze řešeného problému. Naučit studenty objektově myslet je základní cíl naší výuky, proto bychom tento argument neměli podceňovat.
- 16 -
Porovnání objektových jazyků Java je velmi populární programovací jazyk, jehož popularita má navíc stále vzrůstající tendenci. Při výuce nám tedy nedá mnoho práce studentům vysvětlit, že to, co se učí, v budoucnu uplatní. Za rostoucí popularitu vděčí Java také tomu, že její implementace se nachází v mobilních telefonech. Někteří ze studentů takové telefony mají, což jejich motivaci ještě zvýší.
5.8 Proč neučit Javu Je pravda, že Java je populární. Otázkou však zůstává, zda je to dostatečný důvod. Nemůžeme si být jisti, zda se nejedná jen o módní vlnu, která časem opadne. V tom případě bychom studenty naučili něco, co v praxi neuplatní a velká část naší výuky by tak přišla vniveč. Výuka Javy s sebou přináší příliš mnoho nových věcí. Pokud studenti zvládají jen neobjektové imperativní programování, bude pro ně přechod na Javu tvořit obrovský problém, který se možná některým ani nepodaří překonat. V poměrně krátkém časovém úseku budou muset studenti pochopit principy objektového programování, objektové myšlení jako takové, a ještě syntaxi úplně nového jazyka. Toto riziko je menší, pokud studenti ovládají jazyk C, nicméně i tak se stále jedná o velký problém.
5.9 Proč učit SmallTalk SmallTalk je čistě objektový jazyk, na kterém se studenti mohou dobře naučit objektově myslet. Jeho čistota je navíc ve srovnání s Javou na daleko vyšší úrovni, takže máme dobrý předpoklad ve studentech vybudovat schopnost objektového myšlení na vysoké úrovni. Přestože se studenti budou muset naučit novou syntaxi, v případě SmallTalku to nebude takový problém, neboť jeho syntaxe je poměrně jednoduchá a je velmi podobná přirozenému jazyku. Pokud se navíc v minulosti setkali s nějakým funkcionálním jazykem (například s jazykem Logo, který se pro výuku základních algoritmů často používá na ZŠ), nebude představovat zvládnutí syntaxe SmallTalku vážný problém. Jako motivaci lze využít skutečnost, že se SmallTalk užívá na některých vysokých školách. 5.10 Proč neučit SmallTalk SmallTalk, jakkoli dobře navržený programovací jazyk, se bohužel nedočkal příliš velkého rozšíření v programátorské komunitě. Většina lidí o jeho existenci buďto vůbec neví a nebo o něm jen slyšeli, málokdo v něm však skutečně programoval. Těžko tak budeme studenty, kteří mají ve svém mobilním telefonu Javu, přesvědčovat o tom, že se učí užitečnou věc, kterou v praxi uplatní. Argument o objektovém myšlení u studentů také příliš neobstojí, neboť to je věc, po jejíž výuce přímo buďto vůbec netouží, anebo se tato výuka dá realizovat v rámci jiného objektového jazyka (např. Javy). 5.11 Proč učit Eiffel Zatímco Pascal je programovací jazyk navržený pro výuku imperativního programování, Eiffel je jazyk, při jehož návrhu bylo pamatováno i na to, aby se stal nástrojem pro výuku objektového programování. Z didaktického hlediska se tedy jedná o jazyk poměrně vhodný. Eiffel je čistě objektový jazyk, což se nám při formování objektového myšlení ve studentech bude hodit.
5.12 Proč neučit Eiffel Zatímco u SmallTalku jeho praktické využití najdeme, u Eiffelu již příliš ne. S nástupem Javy byl Eiffel definitivně zatlačen do pozadí a lze předpokládat, že se na něj v brzké době zapomene úplně. V praxi se jedná o jazyk prakticky nepoužívaný. Proto bychom učili něco, co studenti v praxi opravdu neuplatní, což nemá smysl.
- 17 -
Porovnání objektových jazyků
5.13 Co tedy učit Jak je vidět, každý programovací jazyk, respektive každé vývojové prostředí, má svá pro a proti. Při rozhodování o tom, který jazyk použijeme, musíme zvážit nejen tato pro a proti, ale také minulou výuku programování, úroveň znalostí studentů, jejich zájmy, zájmy školy a spoustu dalších hledisek, která se mnohdy ani nedají popsat, neboť jsou ryze subjektivní. Při rozhodování budou jistě hrát roli znalosti učitele. Pokud někdo neumí Javu, nemůže ji učit, i kdyby byl o jejích výhodách sebevíce přesvědčen. Tento problém je samozřejmě možné řešit, pokud si jej učitel uvědomí s předstihem, pro výuku je však nezbytná jistá zběhlost v daném programátorském prostředí. Významnou – z racionálních složek rozhodování možná nejvýznamnější – roli hrají vstupní znalosti studentů. Pokud studenti umí programovat pouze v Pascalu, je holý nesmysl pouštět se do výuky C++ a také výuka jazyka Java je v tomto případě velmi diskutabilní. Pokud studenti umí programovat v jazyce C, je naopak poměrně nevýhodné učit Object Pascal či Delphi a je lépe začít s C++ nebo rovnou s Javou. Pokud mají studenti dobré zkušenosti s funkcionálním programováním, může být vhodné učit je programovat ve SmallTalku. Dalším aspektem je zájem studentů. Z hlediska výuky objektového myšlení je poměrně lhostejné, jaký programovací jazyk použijeme. Důležité je naučit principy OOP a správnou analýzu problémů. Pokud tedy studenti mají eminentní zájem o výuku jednoho konkrétního jazyka, je dobré jim vyhovět. O motivaci tak máme postaráno a cíl výuky rozhodně nemusí být ohrožen. Při rozhodování hrají roli také ryze subjektivní argumenty. Jejich role je bohužel velice podstatná, ač si to v mnoha případech učitel ani neuvědomuje. Pokud se nám nějaký jazyk „líbí“, například proto, že v něm programujeme celý život, jsme niterně přesvědčeni o jeho užitečnosti. Ta sice může být po aplikaci racionálních argumentů zpochybněna, nicméně pravdou stále zůstává, že pokud jsme o něčem niterně přesvědčeni, ze své pozice jsme schopni přesvědčit i studenty o tom, jak je námi podporovaný jazyk jedinečný. Často se proto stává, že bez ohledu na racionální výhody a nevýhody učitelé učí právě to, co se jim nejvíce líbí. Vzhledem k tomu, že na většině českých středních škol se učí nejprve jazyk Pascal, který byl jako učební jazyk navržen, je přirozené navázat na znalosti studentů a pokračovat výukou Object Pascalu. Během výuky Object Pascalu se studenti seznámí s principy objektově orientovaného programování a se zásadami správného objektového návrhu aplikací. Poté je vhodné pokračovat výukou Delphi, neboť studenti již mají pro tuto výuku všechny potřebné znalosti. Pokud vynecháme výuku Object Pascalu a přejdeme rovnou na Delphi, studenti mohou mít problémy s příliš velkým množstvím nového učiva. Musí se vedle zásad objektového programování učit pracovat se zcela novým vývojovým prostředím. Vložení výuky Object Pascalu umožňuje nové učivo rozložit do delšího časového období, což je pro studenty přijatelnější. Dostaneme se tím sice do problémů plynoucích z terminologických odlišností Object Pascalu a Delphi, ale ty lze odstranit snáze než problémy plynoucí z příliš velkého množství učiva. Uvedeného modelu výuky se budeme držet i v následujících kapitolách.
- 18 -
Výuka Object Pascalu
6 Výuka Object Pascalu 6.1 Vstupní znalosti K výuce Object Pascalu lze přistoupit až poté, kdy studenti zvládnou znalosti pro tuto výuku nezbytné. Jsou to zejména:
Programátorská zběhlost v Pascalu. Studenti by již měli umět programovat v Pascalu natolik dobře, aby dokázali bez problémů vymýšlet a implementovat dílčí algoritmy, provádět rozklad problémů na dílčí podproblémy, chápat chybová hlášení překladače a umět opravovat logické chyby ve svých programech. Programátorem definované datové typy a datový typ záznam. Ačkoliv to na první pohled není zřejmé, programátorem definované datové typy zavádí určitý nový stupeň abstrakce, který je ke zvládnutí zásad OOP nezbytný. Datový typ záznam je z logického hlediska přímým předchůdcem třídy. Na první pohled je to v podstatě totéž, s výjimkou procedur a funkcí. Dynamické proměnné a datový typ ukazatel. Protože objekty je zpravidla výhodnější vytvářet dynamicky, je velice žádoucí, aby studenti před výukou OOP uměli s dynamickými proměnnými a ukazateli na ně pracovat. Programové jednotky (units). Přestože se bez znalosti programových jednotek při výuce Object Pascalu obejdeme a tato část je nezbytná až pro výuku Delphi, je vhodné ji zařadit do výuky dříve, než přistoupíme k výuce objektově orientovaného programování.
Během výuky OOP je nutné studenty naučit zejména objektově myslet. Je proto třeba dbát i na zdánlivé maličkosti a nutit studenty k důkladnému rozmyšlení objektového návrhu a důslednému dodržování zásad a rysů OOP. Na výuku jednotlivých rysů se nyní podívejme blíže. Znovu připomeňme, že Object Pascal je pouze „odrazovým můstkem“ pro Delphi, čemuž je třeba přizpůsobit rozsah výuky. Je zbytečné strávit výukou Object Pascalu mnoho času, studenti však musí pochopit princip OOP a mít jej důkladně zažitý. Protože Object Pascal používá jinou terminologii než je obecně zvykem, je namístě upozornit, že v dalším textu se přidržíme terminologie standardní, tedy třída – objekt, nikoliv objekt – instance objektu.
6.2 Zapouzdření Nejjednodušším rysem OOP je z hlediska výuky bezpochyby zapouzdření (enkapsulace), proto je vhodné tímto rysem začít hned, když studentům vysvětlujeme objekty. Velmi na místě je v tomto případě srovnání se záznamem, neboť studenti získají konkrétní představu, o čem je řeč. Jediné, co se jim zpočátku může jevit jako nepřirozené, je snaha o přistupování k datovým položkám výhradně přes metody, nikoliv přímo. První příklady, na kterých OOP učíme, obsahují jen jednoduché třídy s několika málo datovými položkami a metodami pro přístup k nim. Zároveň je vhodné od začátku vést studenty k tomu, aby měli jednotlivé třídy umístěné v programových jednotkách, což výrazně zvyšuje přehlednost programu a přenositelnost již naprogramovaných tříd. U následujících příkladů bude kromě zadané jednotky nutné vytvořit ještě ukázkový program demonstrující funkčnost vytvořené jednotky.
Příklad Člověk1
Procvičované znalosti: Základy OOP, zapouzdření. Zadání: Napište jednotku Clovek obsahující definici třídy TClovek, umožňující uchování jména, příjmení a pohlaví. Třídu doplňte o metody manipulující s těmito položkami.
- 19 -
Výuka Object Pascalu
Příklad Vektor Procvičované znalosti: Základy OOP, zapouzdření. Práce s vektory. Zadání: Napište jednotku Vektor, obsahující definici třídy TVektor, která bude uchovávat souřadnice trojrozměrného reálného vektoru a implementovat metody pro základní práci s vektorem (konstruktor pro vytvoření vektoru, metodu pro výpočet délky a metodu pro vypsání souřadnic vektoru). Možná rozšíření: Jednotku rozšiřte tak, aby umožňovala provádět základní operace s vektory (násobení reálným číslem, sčítání vektorů, skalární a vektorový součin).
Příklad Banka Procvičované znalosti: Základy OOP, zapouzdření. Parametr self. Zadání: Napište jednotku Banka, která bude obsahovat definici tří tříd: TClovek, TBanka a TUcet. Třída TClovek je totožná z třídou zadanou v příkladu Člověk1 (lze tedy tuto jednotku využít). Třída TUcet bude sloužit k uchování zůstatkové částky a manipulací s ní (vklad, výběr, převod na jiný účet). Kromě toho bude obsahovat informaci o majiteli účtu (ukazatel na příslušný objekt typu TClovek) a bance, u které je účet veden (opět ukazatel na objekt typu TBanka). Třída TBanka bude obsahovat název banky a metodu VytvorUcet, která vytvoří účet u této banky. Poznámky: Nejproblematičtější je metoda VytvorUcet, která musí při vytváření objektu typu TUcet vědět, která banka tuto metodu volá. K tomu slouží implicitní parametr self, v němž je předáván právě ukazatel na instanci, jež metodu volá.
Příklad Datum Procvičované znalosti: Základy OOP, zapouzdření. Zadání: Napište jednotku Datum, obsahující definici třídy TDatum. Tato třída bude sloužit k zadání, uchování a vypsání data. Jednotku doplňte o funkci umožňující vypočítat počet dnů uplynuvších mezi dvěma zadanými daty. Poznámky: Pro počítání s datem je vhodné neuchovávat datum jako tři čísla (den, měsíc a rok), ale jako počet dnů, které uplynuly např. od 1.1.1900 do zadaného data. Tomu je třeba přizpůsobit metody, sloužící pro vstup a výstup data. Možná rozšíření: Do třídy doplňte metodu pro výpočet dne v týdnu.
6.3 Dědičnost Druhým klíčovým rysem OOP je dědičnost. Abychom co nejlépe demonstrovali její využití, v maximální míře využijeme již naprogramovaných jednotek, které budeme vhodně rozšiřovat. Např. v příkladu Vektor lze využít prvků popsaných v odstavci „Možná rozšíření“ k vytvoření třídy TVektor2, dědící své základní vlastnosti po třídě původní a rozšiřující se právě o popsané prvky. Podobně lze postupovat i v příkladu Datum. Podrobně si tento postup ukážeme na příkladu Člověk. Příklad Člověk2
Procvičované znalosti: Základy OOP, dědičnost. Zadání: Napište jednotku Clovek2, obsahující definici třídy TClovek2, která bude potomkem třídy TClovek. Navíc bude tato třída obsahovat novou položku pro uchování data narození (viz příklad Datum) a metody pro její obsluhu.
Příklad Člověk3
Procvičované znalosti: Základy OOP, dědičnost. Zadání: Napište jednotku Pracujici, obsahující definici třídy TPracujici, která bude potomkem třídy TClovek2 z příkladu Člověk2. Navíc bude obsahovat položky pro uchování povolání a výše platu.
- 20 -
Výuka Object Pascalu Možná rozšíření: Za použití tříd z příkladu Banka lze příklad rozšířit o metody simulující reálné situace (např. výplatu). Fantazii pro implementaci dalších rysů (národnost, výška, hmotnost, délka vlasů, …) se meze nekladou.
6.4 Polymorfismus Posledním rysem OOP je polymorfismus (mnohotvárnost). Komplexní příklady ilustrující polymorfismus na manipulaci s grafickými objekty je možné nalézt v různých zdrojích (např. [28]). Jejich realizace je však velmi náročná a práce s grafikou nemusí být v této době probrána. Proto se zaměříme na textové aplikace, které však pro ilustraci polymorfismu mohou posloužit stejně dobře.
Příklad ZOO Procvičované znalosti: Základy OOP, dědičnost, polymorfismus. Přetypování. Zadání: Navrhněte jednotku Zivocich, implementující zjednodušenou hierarchii živočišných druhů. Základní třída TZivocich bude obsahovat datové položky společné všem živočichům (hmotnost, ohrožený druh,…) a metody pro práci s nimi. Dále bude obsahovat metodu GetInfo, vypisující informaci o objektu (ve třídě TZivocich tato metoda vypíše „Živočich“). Dále definujte potomky této třídy: TPtak, TSavec a TRyba s vhodnými vlastnostmi (rozpětí křídel, kopyta, druh vody,…). Potomky těchto tříd pak budou již konkrétní živočišné druhy (vrabec, holub, pes, tuleň, štika, kapr,…). Metoda GetInfo musí pro každý objekt vypisovat informace právě o daném objektu (např. TTulen.GetInfo bude podávat informaci typu „Hnědý tuleň vážící 230kg.“). Dále napište program ZOO, který bude obsahovat pole prvků typu TZivocich. Jednotlivé prvky tohoto pole budeme chápat jako klece s živočichy. Program bude umět umísťovat živočichy do klecí a vypisovat o nich informace pomocí metod GetInfo. Poznámky: Všem definovaným třídám je společná metoda GetInfo, která je polymorfní. Jmenuje se ve všech třídách stejně, v každé se však chová jinak. To nám umožní definovat zmíněné pole jako array of TZivocich. Jednotlivými prvky pole mohou být i potomky tohoto typu, tedy buď některý z typů TPtak, TSavec, TRyba, nebo konkrétní živočišný druh. Chceme-li se pomocí prvků pole, které jsou typu TZivocich, odkazovat na metody definované až v potomcích, je třeba využít přetypování. Např. PTulen(zahrada[1])^. UlovRybu(PRyba(zahrada[9])). Možné varianty: Namísto ZOO použijeme botanickou zahradu nebo arboretum. Podobná objektová hierarchie bude použita pro rostliny.
Příklad Geometrie Procvičované znalosti: Základy OOP, dědičnost, polymorfismus, geometrické útvary. Zadání: Navrhněte jednotku implementující hierarchii základních geometrických útvarů. Základní třída, TUtvar, bude popisovat pouze virtuální metodu GetInfo pro vypsání informací o objektu. Potomky této třídy budou třídy TBod, TUsecka, TTrojuhelnik a TKoule. Kromě předefinování metody GetInfo budou tyto třídy obsahovat relevantní datové položky (délka, poloměr, …) a metody pro základní výpočty (obsah, objem). Poznámky: Práci s jednotkou demonstrujte vhodným ukázkovým programem. Využijte polymorfismu. Objektové proměnné ukázkového programu mohou být typu TUtvar, přiřazovat jim však lze instance potomků.
- 21 -
Výuka Borland Delphi
7 Výuka Borland Delphi 7.1 Vstupní znalosti K tomu, abychom mohli studenty začít učit programovat v Delphi, potřebujeme určitou míru vstupních znalostí. Rozhodně není v žádném případě možné začít učit Delphi bez předchozí znalosti Pascalu. Zde tedy jsou nutné vstupní znalosti pro výuku Delphi:
Programové jednotky (units). Bez této znalosti se v Delphi neobejdeme. Každé okno, které studenti vytvoří, bude mít svoji vlastní jednotku. Studenti tak musí zvládat jednak obecnou strukturu jednotky a jednak propojování jednotek pomocí klausule uses. Měli by mít za sebou také vytvoření několika jednoduchých jednotek. Základy objektově orientovaného programování. Kdybychom začali učit Delphi studenty, kteří o OOP nic neslyšeli, bylo by toho na ně příliš mnoho najednou. Studenti by tak pod dojmem nezvládnutelnosti velkého množství nové látky ztratili motivaci. Vyjasnění terminologických rozdílů mezi Object Pascalem a Delphi.
7.2 Seznámení s prostředím a vytvoření první aplikace Přestože se jedná o věci, které spolu zdánlivě příliš nesouvisejí, musejí být probrány v jedné hodině. Protože výuka programování ve vyšších ročnících, kdy Delphi pravděpodobně budeme učit, probíhá zpravidla ve dvouhodinových blocích, neměl by to být velký problém. Ale i tam, kde máme k výuce pouze jednu vyučovací hodinu, by studenti měli být schopni vytvořit první program v první hodině, a to i za cenu toho, že se s vývojovým prostředím nenaučí příliš zacházet. Důvod k tomu je velmi jednoduchý. Studenti musí při výuce vidět své výsledky. A jistě není lepší výsledek programátora, než funkční program, spustitelný soubor. Pokud studenti nebudou mít hmatatelný výsledek co nejdříve, získají pocit, že to, co se právě učí, je příliš složité a že to nezvládnou. Přestože tomu tak ve skutečnosti být nemusí, tento jejich pocit povede k naprosté ztrátě motivace a následné rezignaci. A to je jedna z nejhorších věcí, která nás při výuce může potkat. Proto je třeba dbát na to, aby studenti motivaci neztratili. Nejen aby měli pocit, že to, co se učí, je dobré a užitečné, ale také, že to není těžké, a že to zvládnou. První spustitelný program v první hodině je k tomu nutnou podmínkou. Lze si všimnout, že drtivá většina knih, které čtenáře učí programovat, se snaží poskytnout hned v první kapitole návod, jak vytvořit první program. Zpravidla to bývá jednoduché Hello world! nebo něco podobného. Ale svědčí to o tom, že autoři těchto publikací si moc dobře uvědomují to, co bylo řečeno v předcházejícím odstavci. Kdyby totiž napsali první program dále než do první kapitoly, nikdo by si jejich knihu nekoupil, protože by měl pocit, že je to na něj příliš složité. Nyní tedy již k vlastnímu vývojovému prostředí. Po spuštění Delphi se studentům objeví prázdný formulář a kolem něj spousta věcí. Zpočátku si vystačíme s paletou komponent a Object Inspectorem. Studenti by si měli vyzkoušet umístit nějaké komponenty na formulář a nastavit jejich základní vlastnosti pomocí Object Inspectoru. Zde je dobré nezabíhat do přílišných detailů, protože většinu komponent budeme probírat v následujících hodinách. Nyní nám jde jen o obecné záležitosti, ne o konkrétní vlastnosti konkrétních komponent. V rámci seznamování s paletou komponent a Object inspectorem studenti mohou vytvořit okno příkladu Ahoj (nebo případně jakéhokoliv jiného příkladu, kterým jsme se rozhodli začít, ale příklad Ahoj je asi nejpřirozenější).
Příklad Ahoj Procvičované znalosti: Seznámení s vývojovým prostředím. Tvorba aplikací. Komponenta TLabel. Zadání: Napište program, který vytvoří okno, v němž bude nápis „Ahoj!!!“. - 22 -
Výuka Borland Delphi Poznámky: Na plochu formuláře umístěte komponentu TLabel (štítek). Do vlastnosti Caption této komponenty napište požadovaný text, v našem případě „Ahoj!!!“. Nyní přichází na řadu uložení programu. Zde je nutné studentům vysvětlit, co je to projekt a k čemu je dobrý. Také je dobré upozornit na to, že formulář, název souboru s formulářem a název projektu musí být různé. Je dobré zmínit některé konvence pro pojmenovávání souborů, na některé z nich se se studenty shodnout a tu posléze prosazovat i v dalších příkladech. Po vytvoření a uložení programu přichází na řadu jeho kompilace a spuštění. Protože se jedná o činnosti studentům důvěrně známé z programování v Pascalu, lze předpokládat, že je zvládnou rychle a bez problémů. První program je tak na světě, což neopomeneme zdůraznit. Dále je dobré se studenty probrat soubory, které v jejich adresářích vznikly. Je-li čas, je vhodné se na to zaměřit ještě v téže hodině. Pokud ale čas není, bez problémů lze tuto pasáž přesunout do hodiny následující. Studenti by měli vidět kód, který za ně Delphi vytvořily, když umísťovali komponenty do formuláře. Je důležité srovnat zdrojový kód formuláře s hlavním programem (.DPR), který neumí nic jiného než inicializovat a spustit aplikaci. Dále studentům ukážeme, že všechny vlastnosti, které nastavili pomocí Object Inspectoru, jsou dostupné v souboru .DFM. Samozřejmě upozorníme, že soubory *.~* lze mazat, neboť to jsou jen záložní kopie.
7.3 Psaní kódu Studenti by v žádném případě neměli nabýt dojmu, že Delphi jsou jen grafickou záležitostí, a že není potřeba psát žádný kód. Co nejdříve po základním seznámení s vývojovým prostředím je dobré studentům ukázat, jak napsat do programu kód, který něco vykoná. Jako první věc, kterou musíme studenty naučit, je nastavování vlastností komponent za běhu programu. Zpočátku můžeme vyzkoušet za běhu nastavovat i vlastnosti dostupné v Object Inspectoru, ale je dobré ukázat, že ne vše lze v Object inspectoru nastavit. Aby mělo nastavování vlastnosti za běhu smysl, je třeba použít hodnotu, která není v době kompilace programu známá, například parametr, se kterým je program spuštěn, jak ukazuje následující příklad.
Příklad Ahoj2
Procvičované znalosti: Seznámení s vývojovým prostředím. Čtení parametrů příkazové řádky. Komponenta TLabel. Zadání: Napište program, který po spuštění zjistí, zda byl spuštěn s parametrem. Pokud ne, vypíše do okna chybové hlášení. Pokud ano, předpokládá, že parametr je jméno v 5. pádě a do okna vypíše pozdrav (např. „Ahoj Pepíku!“, dostal-li slovo „Pepíku“ jako parametr). Poznámky: Využijte celočíselné proměnné ParamCount uchovávající počet parametrů příkazové řádky a řetězcové funkce ParamStr vracející jednotlivé parametry. V Delphi lze parametry předávané spouštěnému programu zadat pomocí menu Run –> Parameters. V případě, že chcete, aby parametr obsahoval mezeru, je potřeba jej celý uzavřít do uvozovek. Možná rozšíření: V tuto chvíli program využívá jen prvního parametru. Upravte jej tak, aby využil všech parametrů předpokládaje, že to jsou jména v pátém pádě. Tak např. spuštění příkazu „Ahoj Pepíku Honzíku Aničko“ způsobí, že program vypíše „Ahoj Pepíku, Honzíku a Aničko!“.
7.4 Reakce na událost Poté, co studenti alespoň okrajově umí nastavovat vlastnosti komponent a vkládat do programu kód, přichází nejvhodnější doba pro výuku reakcí na události. Této pasáži musíme - 23 -
Výuka Borland Delphi věnovat patřičnou pozornost, protože je to jedna z klíčových oblastí programování v Delphi. Následují jednoduché příklady, které lze pro výuku reakcí na události využít.
Příklad Ahoj3 Procvičované znalosti: Tvorba aplikací. Komponenty TLabel, TButton. Reakce na stisk tlačítka. Zadání: Napište program, který vytvoří okno s tlačítkem „Pozdrav“. Po stisknutí tlačítka se v okně objeví nápis „Ahoj!!!“. Poznámky: Tlačítko (komponenta TButton) má událost OnClick. Metoda napojená na tuto událost může za běhu změnit vlastnost Caption komponenty TLabel.
Příklad Text
Procvičované znalosti: Komponenty TLabel, TButton. Vlastnosti komponenty TLabel. Zadání: Napište program, jehož okno bude obsahovat štítek a 6 tlačítek. Tři tlačítka budou manipulovat s velikostí textu ve štítku (zvětšení, zmenšení a uvedení na původní velikost) a tři se budou starat o zarovnávání textu (vlevo, na střed, vpravo). Poznámky: Stisk tlačítka generuje událost OnClick komponenty TButton. Na tuto událost je potřeba napojit metodu, která bude manipulovat s příslušnou vlastností komponenty TLabel. Velikost textu je přístupná přes položku Font.Size, zarovnávání je pak v položce Alignment.
7.5 Události vyvolané myší Poté, co studenty naučíme základní principy obsluhy událostí na události OnClick, přichází na řadu další události. Nejpřirozenější je zpočátku se věnovat událostem generovaným myší, tedy OnClick, OnDblClick, OnMouseDown, OnMouseUp a OnMouseMove. Je vhodné studenty upozornit na to, že metody obsluhující různé jmenované události dostávají různé informace prostřednictvím svých parametrů. Např. metoda obsluhující událost OnClick neví, na kterém místě uživatel tlačítko myši stiskl, zatímco metoda obsluhující událost OnMouseDown tuto informaci má. Další příklady vztahující se k tomuto tématu jsou uvedené v příloze pod názvy CloseMe a CloseMe2. - 24 -
Výuka Borland Delphi
Příklad Barvy Procvičované znalosti: Komponenty TButton, TLabel. Reakce na stisk tlačítka a kliknutí myší na plochu formuláře. Vlastnosti komponenty TForm. Zadání: Napište program, který vytvoří okno se třemi tlačítky: „Červená“, „Zelená“ a „Modrá“. Po stisknutí některého z tlačítek se hlavní formulář přebarví odpovídající barvou. Navíc, v případě kliknutí na plochu formuláře (mimo tlačítka) se přebarví na bílo, v případě dvojitého kliknutí načerno. Poznámky: Stejně jako komponenta TButton, má i komponenta TForm události OnClick a OnDblClick. V metodách obsluhujících patřičné události nastavujte vlastnost Color komponenty TForm. Využijte předdefinovaných konstant clRed, clGreen, clBlue, clWhite a clBlack.
Příklad Barvy2 Procvičované znalosti: Reakce na stisk tlačítka a události OnMouseDown, OnMouseUp. Komponenty TForm, TButton. Zadání: Upravte program z příkladu Barvy tak, aby v případě kliknutí na plochu formuláře nastavil jeho barvu na černou nebo bílou toho, kterým tlačítkem uživatel kliknul. Poznámky: Metoda obsluhující události OnMouseDown a OnMouseUp dostává množství parametrů, mezi nimiž je i parametr Button nabývající hodnoty mbLeft nebo mbRight při stisku levého, resp. pravého tlačítka. Možná rozšíření: Alternativně lze program zpracovat tak, že černá nebo bílá plocha formuláře se po uvolnění tlačítka změní opět v původní barvu (např. žlutou).
Příklad Pohyb Procvičované znalosti: Komponenta TEdit nebo TLabel. Událost OnMouseMove. Funkce IntToStr. Zadání: Napište program, v jehož okně budou jen dva editační řádky nebo štítek (štítky) sloužící pro zobrazení souřadnic kurzoru myši nad oknem. Poznámky: Při pohybu myší je generována událost OnMouseMove. Metoda napojená na tuto událost dostane jako parametr souřadnice kurzoru myši vzhledem k levému hornímu rohu okna. Souřadnice převedené na řetězec pomocí funkce IntToStr zobrazíte zkopírováním do vlastnosti Text příslušného editačního řádku.
- 25 -
Výuka Borland Delphi
7.6 Komponenta TEdit Společně s touto komponentou, která představuje nejpoužívanější způsob, jak získat vstup od uživatele, uvedeme i příbuznou komponentu TSpinEdit a naučíme studenty základní práci s řetězci. Uvedení komponenty TSpinEdit má zejména ten význam, že studenti budou schopni získávat do svých programů číselné hodnoty, aniž by bylo nutné je extrahovat z řetězců za nutnosti ošetřování výjimek. Další příklady vhodné k procvičení práce s editačními řádky jsou uvedené v příloze pod názvy Jméno2, Hádej a Zlomky.
Příklad EditDemo Procvičované znalosti: Komponenty TEdit, TButton, TLabel. Reakce na stisk tlačítka. Zadání: Napište program, jehož okno bude obsahovat editační řádek, tlačítko a štítek. Vždy při stisku tlačítka se text zadaný do editačního řádku zkopíruje na štítek. Poznámky: Celý program se bude odehrávat v metodě obsluhující událost OnClick tlačítka. Komponenta TEdit (editační řádek) má vlastnost Text, kterou je třeba zkopírovat do vlastnosti Caption komponenty TLabel.
Příklad Jméno Procvičované znalosti: Komponenty TLabel, TEdit, TButton. Reakce na stisk tlačítka. Manipulace s řetězci. Volitelně komponenta TRadioButton. Zadání: Napište program, který po zadání jména a příjmení do dvou editačních řádků vypíše jméno i příjmení na štítek. Poznámky: Vypsání na štítek se provádí nastavením vlastnosti Caption komponenty TLabel. Spojení řetězců zařídí operátor „+“. Možná rozšíření: Přidejte editační řádek ještě na titul před jménem a titul za jménem. Dále přidejte možnost zadat přezdívku. Dejte uživateli možnost výběru umístění přezdívky ke jménu (Jaroslav Foglar – Jestřáb, Jestřáb – Jaroslav Foglar, Jaroslav „Jestřáb“ Foglar).
Příklad Faktoriál Procvičované znalosti: Komponenty TSpinEdit, TButton, TEdit. Reakce na stisk tlačítka. Funkce IntToStr. Datový typ Int64. Rekurze. Legenda: Faktoriál daného přirozeného čísla n je definován jako součin všech přirozených čísel menších nebo rovných n. Alternativně lze faktoriál pro přirozená čísla a nulu definovat rekurzivně: 0! = 1 n! = n·(n-1)! A právě tuto rekurzivní definici využijeme v našem programu. Zadání: Napište program, který bude obsahovat pole pro zadání hodnoty (tzv. spin edit), tlačítko a editační řádek. V případě, že uživatel stiskne tlačítko, bude vypočten faktoriál hodnoty zadané ve spin editu a hodnota bude zobrazena v editačním řádku. Poznámky: Výpočet faktoriálu provádějte rekurzivně. Pro hodnotu výsledku použijte datový typ Int64, tedy 64bitové celé číslo. Nastavte správně vlastnosti MaxValue a MinValue komponenty TSpinEdit (aby výsledek nepřetekl, nelze počítat faktoriál čísel větších než 20). K převodu číselné hodnoty výsledku na textový řetězec použijte funkci IntToStr.
- 26 -
Výuka Borland Delphi
7.7 Komponenty TCheckBox a TRadioButton Dalšími komponentami, se kterými studenty naučíme pracovat, jsou komponenty důvěrně známé z různých dialogových oken, a sice TCheckBox, TRadioButton a TRadioGroup. Vzhledem k tomu, že prakticky každá větší aplikace tyto komponenty v hojné míře používá, není třeba si příliš lámat hlavu s motivací studentů, neboť lze předpokládat, že se na tyto komponenty vysloveně těší. Příklad CloseQuery Procvičované znalosti: Událost OnCloseQuery. Komponenta TCheckBox. Volitelně funkce MessageDlg. Zadání: Napište program, který vytvoří okno s jedním zaškrtávacím políčkem „Lze zavřít“ a jedním tlačítkem „Zavřít“. Po stisknutí tlačítka „Zavřít“ nebo systémového zavíracího tlačítka se program ukončí, ale pouze v případě, že je zaškrtnuta volba „Lze zavřít“. Poznámky: Povolení zavření formuláře zajišťuje metoda obsluhující událost OnCloseQuery nastavením svého odkazem předávaného parametru CanClose na hodnotu True. Možné alternativy: Povolení zavření okna nezávisí na zaškrtávacím poli, ale na výsledku interakce s uživatelem pomocí funkce MessageDlg.
Příklad Jednotky
Procvičované znalosti: Komponenty TRadioGroup, TGroupBox, a TLabel. Legenda: Každý ví, jaké problémy přináší dětem na základní škole, když se mají učit různé předpony fyzikálních jednotek vyjadřující jejich násobky. Následující program by měl být užitečnou pomůckou a může navíc sloužit jako výukový program, který využijí učitelé fyziky. Zadání: Napište program, který vypíše seznam všech předpon, které se používají k udání násobku fyzikální jednotky. Při kliknutí na každou předponu pak vypíše, jaký násobek předpona znamená a jakou má značku. Pozor na značku mikro! Poznámky: Seznam předpon realizujeme pomocí komponenty TRadioGroup. V metodě obsluhující událost OnClick komponenty TRadioGroup budeme aktualizovat výstupní informace o předponě. V případě zvolení předpony mikro je potřeba změnit font štítku se značkou.
- 27 -
Výuka Borland Delphi
Příklad Keypress Procvičované znalosti: Události OnKeyDown, OnKeyUp, OnKeyPress. Komponenta TCheckBox. Zadání: Napište program, který bude reagovat na stisk klávesy tím, že vypíše, o jakou klávesu se jedná. V případě, že je klávesa stisknuta zároveň s některou z kláves Ctrl, Alt, Shift, zobrazí i tuto informaci. Poznámky: Stisk klávesy generuje událost OnKeyDown. Metoda obsluhující tuto událost dostane v parametrech jednak informaci o tom, jaká klávesa byla stisknuta, a jednak informaci o modifikátorových klávesách. Při uvolnění klávesy je generována událost OnKeyUp. Vzhledem k tomu, že události OnKeyDown/Up nelze poslat hlavnímu formuláři (protože nikdy nemá zaměření), musíme přidat nějakou komponentu, která bude tyto události přijímat (např. TEdit).
7.8 Výjimky Mechanismus výjimek je jedním ze stěžejních prvků, které Delphi programátorovi poskytují. Do této chvíle jsme studentům neustále vštěpovali, že musí důkladně testovat všechny možné vlastnosti vstupu a důkladně ošetřovat potenciální chyby. Mechanismus výjimek tuto vlastnost do značné míry popírá, neboť umožňuje bez předchozí kontroly vstupu „vyzkoušet“ provedení nějaké operace a teprve poté zjišťovat, zda došlo k chybě či nikoliv. Protože se jedná o zcela novou záležitost, se kterou se studenti doposud nesetkali, je potřeba jejímu probírání věnovat značnou péči a důkladně ji procvičit.
Příklad NSD & NSN Procvičované znalosti: Komponenty TEdit, TButton. Funkce StrToInt, IntToStr. Ošetření výjimek. Algoritmus pro výpočet NSD. Legenda: Výpočet největšího společného dělitele a nejmenšího společného násobku patří k důležitým tématům základoškolské matematiky. Následující program může sloužit například žákům základních škol ke kontrolám výsledků při procvičování tohoto učiva. Zadání: Napište program, který vypočítá největšího společného dělitele a nejmenší společný násobek daných dvou čísel. Poznámky: K zadávání čísel využijte komponentu TEdit. Při převádění textu na číslo funkcí StrToInt je třeba zachytávat výjimku EConvertError. K zobrazení číselného výsledku použijte inverzní funkci IntToStr, která už pochopitelně žádné výjimky negeneruje.
Příklad Soustavy Procvičované znalosti: Algoritmus převodu mezi číselnými soustavami. OOP. Komponenty TEdit, TSpinEdit, TButton. Reakce na událost OnClick. Vyvolávání výjimek. Legenda: Převody mezi číselnými soustavami jsou v informatice velmi důležité. Využití nacházejí zejména soustavy o základu 2,8 a 16, zatímco v běžném životě se nejčastěji setkáváme se soustavou desítkovou. Soustavy o základu větším než 10 používají místo číslic písmena (např. šestnáctková soustava používá cifry A–F). Zadání: Napište program, který číslo v zadané soustavě (o základu 2-36) převede do jiné zvolené soustavy (opět o základu 2-36). Naprogramujte třídu, která bude uchovávat číslo - 28 -
Výuka Borland Delphi v desítkové soustavě a bude obsahovat metody pro převod ze zadané soustavy a pro převod do zadané soustavy. Tuto třídu pak v programu využijte. Záporná a necelá čísla neuvažujte. Poznámky: Nezapomeňte, že tyto metody budou jako vstup (resp. výstup) používat řetězec. Aby se třída chovala korektně, je třeba ošetřit chybové stavy, tedy výskyt nepovolených znaků ve vstupním řetězci. V tom případě metoda vyvolá výjimku EConvertError, kterou je třeba v hlavním programu zachytit. Možná rozšíření: Pomocí zpracování syntaxe (xx)(xx) rozšiřte program o možnost převod do a z libovolné soustavy. Dále je možné rozšířit program o zpracování záporných a necelých čísel.
Příklad Kalkulačka Procvičované znalosti: Komponenty TButton, TEdit. Reakce na stisk tlačítka. Ošetření výjimek. Zadání: Implementujte kalkulačku, která bude umět sčítat, odčítat, násobit, dělit a odmocňovat. Poznámky: Je třeba správně vyřešit to, že oba operandy jsou zadávány ve stejném editačním okně. Dále nezapomeňte na to, že uživatel nemusí vždy zadat číslo (funkce StrToInt v takovém případě vyvolá výjimku EConvertError).
Příklad Trojúhelník Procvičované znalosti: Komponenty TEdit, TCheckBox. Ošetření výjimek. Metoda SetFocus. Zadání: Napište program, který pomocí editačních řádků načte tři čísla, která mají určovat délky stran trojúhelníka. Program nejprve ošetří, zda uživatel skutečně zadal čísla, dále ověří, že délky splňují trojúhelníkovou nerovnost a pokud ano, vypočte obvod a obsah trojúhelníka. Dále program vypíše informace o tom, zda je trojúhelník rovnoramenný, rovnostranný nebo pravoúhlý. Poznámky: Převod řetězce na číslo je realizován pomocí funkcí StrToInt a StrToFloat, které očekávají jako parametr řetězec a vracejí hodnotu požadovaného typu. V případě, že řetězec nelze na číslo převést, vyvolají výjimku EConvertError, kterou je potřeba ošetřit. K chybovým výstupům využijte štítek nebo funkci MessageDlg. Dbejte na to, aby v případě zadání chybného čísla měl uživatel možnost hodnotu hned upravit (tj. použijte proceduru SetFocus komponenty TEdit). K výpočtu obsahu trojúhelníka ze známých délek stran využijte Heronova vzorce: s:=(a+b+c)/2; VypObsah:=Sqrt(s*(s-a)*(s-b)*(s-c)); Pro zveřejnění informace o tom, zda je trojúhelník pravoúhlý, rovnostranný či rovnoramenný použijte zaškrtávací pole (komponenta TCheckBox), která mají vlastnost Checked. Možná rozšíření: Do programu připište funkce počítající vnitřní úhly trojúhelníka. Dále lze program rozšířit o výpočet délek výšek, těžnic, poloměr kružnice opsané a vepsané, atd.
7.9 Práce s časem a komponenta TMainMenu Delphi, na rozdíl od Pascalu, umožňují pracovat s datem a časem poměrně pohodlným způsobem, a to pomocí datových typů TDate a TDateTime. Komponentou, která s časem přímo souvisí, je komponenta TTimer, která umožňuje vykonávat určitou operaci v přesně stanovených časových intervalech. Menu tvoří základní ovládací prvek složitějších aplikací. Přestože s datem a časem vůbec nesouvisí, nic nám nebrání v tom, abychom oba prvky demonstrovali pomocí stejných příkladů. - 29 -
Výuka Borland Delphi Dalšími příklady, které lze pro ilustraci práce s datem a časem využít, jsou v příloze pod názvy Biorytmy a Videostop.
Příklad Hodiny Procvičované znalosti: Komponenty TTimer, TMainMenu. Datový typ funkce TDateTime. Volitelně InputBox. Zadání: Napište program, který bude ve svém okně neustále zobrazovat aktuální čas. Poznámky: Ke zjištění aktuálního času slouží funkce Time. K převodu času na řetězec slouží funkce TimeToStr, které se jako parametr předá čas (typ TDateTime) a výsledkem je řetězec obsahující zadaný čas zapsaný ve formátu místního nastavení systému Windows. Možná rozšíření: Rozšiřte program o budík, tedy možnost, aby uživatel zadal čas, v němž se na obrazovce objeví budící zpráva. Při buzení dejte uživateli možnost aktivovat opětovné buzení za 5 minut. Program rozšiřte o možnost volby fontu a barvy hodin.
Příklad Světelné noviny
Procvičované znalosti: Komponenty TTimer, TLabel, TMainMenu. Vlastnosti formuláře. Práce s více formuláři. Zadání: Napište program, který bude provozovat světelné noviny, tj. text, který se bude posouvat přes celou šířku okna zprava doleva. Když zmizí za levým okrajem, začne se opět vpravo objevovat. Dejte uživateli možnost zadat zobrazovaný text. Program dále rozšiřte o možnost být stále navrchu a skrýt okraje okna. Poznámky: Komponenta TTimer generuje ve stanovených intervalech událost OnTimer. Na tu budeme reagovat přesunutím textu. Je třeba ošetřit, že text vyjel levým okrajem. To, zda okno zůstane stále na povrchu je dáno vlastností FormStyle hlavního formuláře, okraje okna jsou definovány vlastností BorderStyle. Hlavní menu je zneviditelněno v případě, že zneviditelníme všechny jeho položky (vlastnost Visible). Možná rozšíření: Dejte uživateli možnost výběru typu písma a barvy pozadí. Dále nechejte uživatele zvolit rychlost pohybu textu.
7.10 Komponenta TScrollBar Komponenta TScrollBar (posuvník), je také studentům důvěrně známá, podobně jako tomu bylo u zaškrtávacích polí. K procvičení této komponenty uvedeme dva příklady, které pomocí funkce RGB nastavují barvu formuláře.
Příklad Barvy3 Procvičované znalosti: Komponenta TScrollBar. Funkce RGB. Zadání: Napište program, který vytvoří hlavní okno se třemi posuvníky (scrollbars). Každý posuvník bude příslušet jedné z barevných složek (červená, zelená, modrá). Přetahováním posuvníků se bude měnit barva hlavního formuláře tak, aby intenzita jednotlivých barevných složek odpovídala pozici posuvníků. - 30 -
Výuka Borland Delphi Poznámky: Komponenta TScrollBar rozpozná událost OnChange, která říká, že uživatel změnil pozici posuvníku. Aktuální pozice posuvníku je dostupná ve vlastnosti Position komponenty TScrollBar. K nastavení barvy formuláře využijte funkci RGB, která dostává tři hodnoty typu Byte odpovídající barevným složkám a vrací hodnotu typu TColor. Možná rozšíření: Ke každému posuvníku přidejte štítek, který bude zobrazovat číselnou hodnotu pozice posuvníku.
Příklad Barvy4
Procvičované znalosti: Komponenty TEdit, TScrollBar. Ošetření výjimek Zadání: Formulář příkladu Barvy3 rozšiřte o tři editační pole, která uživateli umožní zadat přímo číselnou hodnotu dané barevné složky. Po zadání čísla nastavte barvu formuláře i pozici posuvníku. Pozor na nečíselné nebo nepovolené hodnoty. Poznámky: K převodu řetězce (TEdit.Text) na číslo použijte funkci StrToInt, která v případě zadání jiného než číselného řetězce generuje výjimku EConvertError, kterou je třeba zachytit.
7.11 Modální a nemodální formuláře Přestože se studenti s modálními a nemodálními okny v praxi mnohokrát setkali, jsou pro ně tyto pojmy nové. Je tedy třeba vše důkladně vysvětlit. Navíc, program využívající více formulářů, musí obsahovat více programových jednotek, které musí být správně propojeny pomocí klausule uses. Následující příklad demonstruje rozdíly mezi modálními a nemodálními formuláři. Příklad Modal Procvičované znalosti: Programy s více formuláři. Funkce Show a ShowModal. Zadání: Napište program, který bude mít tři tlačítka: „Otevřít modální formulář“, „Otevřít nemodální formulář“ a „Zavřít“. První tlačítko otevře modální formulář s nápisem „Ahoj, já jsem modální formulář“, druhé tlačítko otevře nemodální formulář s nápisem „Ahoj, já jsem nemodální formulář“ a třetí tlačítko ukončí program. Poznámky: Modální okno je okno, které je aktivní, dokud jej uživatel nezavře (typicky dialogové okno). Nemodální okno lze deaktivovat bez zavírání. Z toho plyne, že nemodálních
- 31 -
Výuka Borland Delphi oken může být otevřeno více, zatímco modální může být v daný okamžik otevřeno jen jedno (samozřejmě za předpokladu, že se jedná o potomky téhož formuláře). K vytvoření tohoto programu budou potřeba tři formuláře (ve třech jednotkách). Dbejte na správné propojení klausulemi uses. Modální i nemodální okno jsou definovány stejně. Modalita je určena až za běhu programu tím, zda je okno vyvoláno metodou Show nebo ShowModal. Modální okno je program schopen kontrolovat, protože si může být jist, že dokud jej uživatel nezavře, nic dalšího se nestane. U nemodálního okna tomu tak není, proto jediný rozdíl v definici spočívá v tom, že do metody obsluhující událost OnClose nemodálního okna je třeba napsat příkaz Action:=caFree; Tento příkaz způsobí korektní zrušení dynamicky alokované paměti. Přidáním tohoto příkazu i do zavírací metody modálního formuláře sice nic nezkazíte, ale je to zbytečné. Možná rozšíření: Dejte do modálního okna možnost otevřít další modální okno. Okna umísťujte na náhodnou pozici na obrazovce.
7.12 Vlastnosti formuláře a objekt Screen Pomocí Delphi lze vytvářet kromě užitečných programů
i programy, které mohou uživatele trochu potrápit. Tyto programy zpravidla vyžadují nastavení určitých vlastností, které v běžných programech nevyužijeme. Zařazení příkladu tohoto typu, prakticky kdykoliv, je vhodné pro posílení motivace studentů, neboť se rozhodně jedná o program, jehož vytváření je bude bavit. Navíc se u toho naučí věci, které by se u běžných příkladů nenaučili, nebo naučili jen „uměle“. Rozhodně je třeba dbát na to, aby byl příklad tohoto typu zařazen až poté, kdy studenti ovládají „standardní“ učivo. Uvedeme zde příklad Shutdown, kde je potřeba kromě nastavení barvy a pozice štítku použít ještě objekt Screen a funkci RGB. Objekt Screen kromě informací o obrazovce uchovává také seznam písem dostupných v systému. Pro demonstraci práce s písmy poslouží příklad ScreenInfo.
- 32 -
Výuka Borland Delphi
Příklad Shutdown Procvičované znalosti: Vlastnosti komponenty TForm. Volitelně objekt Screen. Zadání: Napište program, který na obrazovce vytvoří dojem, že počítač je těsně před vypnutím (tj. vytvoří černou obrazovku s nápisem „Nyní můžete počítač bez obav vypnout“. Dbejte na to, aby efekt nerušil kurzor myši nebo hlavní panel Windows. Poznámky: K vytvoření tohoto programu není třeba psát téměř žádný kód. Vše se odehraje v okně Object Inspectoru nastavením požadovaných vlastností hlavního formuláře: BorderStyle := bsNone; Color := clBlack; WindowState := wsMaximized; Dále je potřeba umístit na plochu formuláře komponentu TLabel a upravit její vlastnosti tak, aby výstup odpovídal zadání. Protože hodnota crNone vlastnosti Cursor komponenty TLabel není v Object Inspectoru přístupná, je potřeba tuto vlastnost nastavit až za běhu programu v metodě FormCreate svázané s událostí OnCreate hlavního formuláře. V této metodě je potřeba též nastavit barvu písma komponenty TLabel na oranžovou (RGB 255, 127, 0), neboť tato barevná konstanta rovněž není v Object Inspectoru přístupná. Možné rozšíření: Takto napsaný program bude správně fungovat jen na monitoru se stejným rozlišením. Na monitoru s jiným rozlišením nebude nápis přesně uprostřed. Požadované přenositelnosti lze dosáhnout nastavením vlastností Left a Top komponenty TLabel za běhu programu v metodě FormCreate za využití globálního objektu Screen, který má vlastnosti Width a Height uchovávající horizontální a vertikální rozměr obrazovky. O objektu Screen více v příkladu ScreenInfo.
Příklad ScreenInfo
Procvičované znalosti: Objekt Screen. Komponenty TLabel, TComboBox. Zadání: Napište program, který vypíše informaci o rozměrech obrazovky a umožní ukázku všech typů písma instalovaných v systému. Poznámky: Obě informace lze získat pomocí globálního objektu Screen. Rozměry obrazovky jsou uloženy ve vlastnostech Width a Height. Názvy fontů jsou uloženy v poli řetězců Fonts. Toto pole můžeme zkopírovat například do vlastnosti Items komponenty TComboBox. Možná rozšíření: Vytvořte vzorník fontů instalovaných v systému, tj. upravte program tak, aby umožnil zobrazení ukázek všech fontů najednou.
- 33 -
Výuka Borland Delphi
7.13 RTTI operátory a parametr Sender RTTI (Run-Time Type Information) operátory slouží k ověřování typu různých objektů za běhu programu. Nejčastěji to bývá parametr Sender, tedy ukazatel na komponentu, která vyvolala nějakou událost. Na tomto místě uvedeme pouze příklad Dragging, k pozdějšímu procvičení poslouží příklady Matematico a RTTIDemo, uvedené v příloze.
Příklad Dragging
Procvičované znalosti: Přetahování pomocí myši. Operátory RTTI. Zadání: Napište program, jehož okno bude obsahovat velký štítek s nápisem a poté několik malých štítků, z nichž každý bude mít jinou barvu. Při přetáhnutí malého štítku na velký dojde ke zkopírování barvy malého štítku na velký štítek. Poznámky: Přetahování obsluhují události OnDragOver a OnDragDrop. První událost komponentě říká „Něco se nad tebou táhne“, druhá „Něco se nad tebe přetáhno“. Obsluhy obou událostí dostanou jako parametr Source ukazatel na objekt, který byl na počátku přetahování. Metoda obsluhující událost OnDragOver dostane navíc odkazem parametr Accept, kterým můžeme přetahování povolit nebo zamítnout. V našem případě přetahování povolíme právě tehdy, když zdrojem je štítek. Vlastní zkopírování barvy se provádí až v obsluze události OnDragDrop, tedy těsně poté, co uživatel přetahovaný objekt pustil.
7.14 Komponenty TListBox a TComboBox Tyto komponenty jsou si velmi podobné. Komponenta TListBox je nutná pro formátovaný a víceřádkový výstup, obě komponenty se dají navíc použít pro vstup. Variantou komponenty TListBox je komponenta TCheckListBox, použitá v příkladu Věty2 v příloze. Variantou komponenty TComboBox je komponenta TColorBox, použitá v příkladu Barvy5, rovněž uvedeném v příloze.
Příklad Prvočísla Procvičované znalosti: Komponenty TEdit, TButton, TListBox. Volitelně komponenta TRadioGroup. Funkce StrToInt a IntToStr. Ošetření výjimek. Zadání: Napište program, který zadané číslo rozloží na součin prvočinitelů. Poznámky: Číslo lze z řetězce získat pomocí funkce StrToInt. V případě, že uživatel zadá řetězec, který neurčuje číslo, funkce generuje výjimku EConvertError, kterou je třeba ošetřit. Číslo se na řetězec převádí pomocí funkce IntToStr. Zjištěná prvočísla ukládejte do položky Items komponenty - 34 -
Výuka Borland Delphi TListBox, čímž zajistíte jejich zobrazení. Možná rozšíření: Dejte uživateli možnost zvolit si, zda výstup bude seznam všech prvočísel (s povolením více výskytů) nebo jen seznam prvočísel (každé max. jednou) a jejich mocnin (tj. jestli 24 = 2⋅2⋅2⋅3 nebo 24 = 23⋅31).
Příklad Fibonacci Procvičované znalosti: Fibonacciho posloupnost. Komponenty TListBox, TSpinEdit, TButton. Reakce na událost OnClick. Funkce IntToStr. Legenda: Fibonacciho posloupnost je slavná posloupnost pojmenovaná po italském matematikovi Leonardu Pisánském (1170 – 1250), zvaném Fibonacci. Je definována rekurentně takto: a1 = 1 a2 = 1 an = an-1 + an-2 Každý její člen je tedy součtem dvou členů
předcházejících. Zadání: Napište program, který vygeneruje zadaný počet členů Fibonacciho posloupnosti. Přitom členy budou v seznamu stále přibývat, tj. pokud uživatel stiskne tlačítko podruhé, do seznamu přibude zadaný počet členů. Poznámky: K zadání počtu členů využijte komponentu TSpinEdit. Její použití je v tomto případě výhodnější oproti komponentě TEdit, neboť se nemusíte zabývat převodem řetězce na číselnou hodnotu. Aktuální hodnotu získáte z vlastnosti Value. Veškeré akce se budou odehrávat v metodě napojené na událost OnClick komponenty TButton, která je vyvolána pokaždé, když uživatel tlačítko stiskne. Pro zobrazování seznamu členů posloupnosti použijte komponentu TListBox. Její vlastnost Items (položky) je typu TStrings, což je třída reprezentující seznam řetězců a metody pro manipulaci s ním. Z nich využijeme zejména metodu Add, která na konec seznamu přidá nový řetězec. Číslo lze na řetězec převést např. pomocí funkce IntToStr. Možná rozšíření: Upravte program tak, aby vygeneroval n-tý člen Fibonacciho posloupnosti. V tom případě jej nepočítejte podle rekurentního vzorce (nebo dokonce rekurzivně!), protože pro velká n by to mohlo trvat dlouho (v případě rekurze by to bylo záhy omezeno velikostí zásobníku), ale rekurentní vzorec převeďte na vzorec pro n-tý člen.
Příklad Kurzory Procvičované znalosti: Komponenta TComboBox. Datový typ TCursor. Zadání: Napište program, jehož okno bude obsahovat pouze rozbalovací editační pole (combo box) s typy kurzorů. Při výběru typu kurzoru se aktuální kurzor formuláře změní podle výběru. Poznámky: Datový typ TCursor není nic jiného než celé číslo. Při vhodném uspořádání konstant tak můžeme vlastnosti Cursor hlavního formuláře přiřazovat drobně pozměněnou hodnotu ItemIndex rozbalovacího editačního pole. Možná rozšíření: Definujte vlastní kurzory a zahrňte je do programu.
- 35 -
Výuka Borland Delphi
Příklad Věty
Procvičované znalosti: Komponenty TListBox, TRadioGroup. Manipulace s řetězcem. Zadání: Napište program, který bude sestavovat anglické věty podle vzoru subject is preposition object. Ke zvolení podmětu a předmětu použijte komponentu TListBox. Použití termínu „předmět“ je v tomto případě zavádějící, neboť se jedná o příslovečné určení místa, nicméně je to asi nejnázornější označení, jaké lze nalézt. Poznámky: To, že má program sestavovat anglické a nikoliv české věty je zde z důvodu nutnosti skloňovat česká slova, což není předmětem tohoto příkladu. Text zvolené položky komponenty TListBox získáte pomocí konstrukce Items[ItemIndex]. Pole řetězců Items obsahuje seznam položek a proměnná ItemIndex určuje právě vybranou položku. Možná rozšíření: Rozšiřte program o možnost přidávání dalších položek mezi podměty i mezi předměty.
7.15 Grafický výstup: Třída TCanvas Použití třídy TCanvas je patrně nejjednodušší metodou, kterou lze pro grafický výstup použít. Její nevýhodou je však to, že při minimalizaci a opětovném obnovení okna, případně při překrytí okna jiným oknem, zmizí vše, co jsme na canvas vykreslili. Tento nedostatek odstraňuje až komponenta TImage. Příklad GraphDemo Procvičované znalosti: Komponenty TTimer a TPaintBox. Vlastnost Enabled. Třída TCanvas. Funkce Random a RGB. Zadání: Vytvořte alternativu známého programu BGIDemo dodávaného s Turbo Pascalem. Tj. napište program, který bude vykreslovat geometrické objekty. Formulář bude obsahovat panel s několika tlačítky: „Start“ spustí vykreslování, „Stop“ zastaví vykreslování, „Další“ způsobí vykreslování dalšího objektu, „Předchozí“ způsobí vykreslování předchozího objektu a „Konec“ ukončí program. Vykreslované objekty jsou obdélníky, elipsy, přímky a text. Vykresluje se vždy na náhodnou pozici objekt náhodné velikosti a náhodné barvy. Dbejte na to, aby tlačítka, jejichž stisknutí nemá v danou chvíli smysl, byla zakázána. Poznámky: Vykreslení jednoho objektu realizujte v obsluze události OnTimer komponenty TTimer. Komponenta TTimer má též vlastnost Enabled, která určuje, zda budou události OnTimer generovány. Tuto vlastnost nastavujte tlačítky „Start“ a „Stop“, která mají vlastnost Enabled také. - 36 -
Výuka Borland Delphi Možná rozšíření: Rozšiřte paletu vykreslovaných objektů o další objekty, které lze vykreslit jedinou metodou třídy TCanvas. Seznam metod vyhledejte v nápovědě Visual Component Library Reference.
Příklad Kuličky
Procvičované znalosti: OOP. Komponenty TButton, TTimer, TLabel. Třída TCanvas. Dlouhodobý projekt. Zadání: Napište program, který bude simulovat kuličky v gravitačním poli v bezodporovém prostředí a s dokonale pružnými odrazy. Program bude obsahovat tlačítko pro vytvoření nové kuličky, která bude vytvořena na náhodném místě, bude mít náhodnou rychlost a náhodnou barvu. Interakce kuliček neuvažujte. Poznámky: Nejprve implementujte jednotku obsahující třídu TKulicka a poté napište program, který bude vytvářet instance této třídy a manipulovat s nimi. Rychlost kuličky uchovávejte rozloženu na horizontální a vertikální složku. Horizontální zůstává konstantní, vertikální se stále zvětšuje a při odrazu od stěny se mění znaménko příslušné složky.
- 37 -
Výuka Borland Delphi Možná rozšíření: Rozšiřte program o možnost měnit parametry kuliček i po jejich vytvoření. Implementujte interakci kuliček mezi sebou (opět nechť se jedná o dokonale pružné odrazy).
Příklad Snell
Procvičované znalosti: Snellův zákon lomu. Třída TCanvas. Jednotka Math. Dlouhodobý projekt. Legenda: Dopadá-li světelný paprsek na rozhraní dvou látek, mohou nastat dvě možnosti: buďto se od tohoto rozhraní odrazí, nebo dochází k lomu. To, která možnost nastane a jak vypadá případný lom, určují tzv. indexy lomu příslušných látek. Index lomu n dané látky se vypočítá podle vztahu n = c/v, kde c je rychlost světla ve vakuu a v je rychlost světla v daném prostředí. Jestliže světlo prochází prostředím o indexu lomu n1 a dopadá na rovinné rozhraní s prostředím o indexu lomu n2 pod úhlem α1, určuje jeho chování Snellův zákon (někdy též označovaný jako zákon lomu): sin α1 / sin α2 = n2 / n1 Úpravou tedy dostaneme, že sin α2 = n1 / n2 · sin α1 V případě, že je hodnota pravé strany větší než 1, není úhel α2 definován. Znamená to, že nedochází k lomu, ale k odrazu a v tom případě platí známý zákon odrazu, tedy že úhel odrazu se rovná úhlu dopadu. Dochází-li k lomu, porovnáním úhlů α1 a α2 rozlišujeme lom ke kolmici a lom od kolmice. Zadání: Napište program, který pro zadané indexy lomu a úhel dopadu rozhodne, zda dojde k lomu či odrazu a vypočítá úhel α2. Dále nechť program zadanou situaci nakreslí (viz obrázek). Poznámky: Ke zpřístupnění goniometrických a cyklometrických funkcí je třeba do klausule uses přidat jednotku Math. Možná rozšíření: Rozšiřte program tak, aby pro zadané hodnoty indexů lomu vypočítal tzv. mezní úhel, kdy se paprsek láme přímo na rozhraní.
7.16 Komponenta TImage Jak již bylo řečeno v předchozí části, komponenta TImage uchová svůj vzhled i poté, co dojde k překreslení okna. Nevýhodou je určité zpomalení práce s grafikou, které však ve většině případů není na škodu. Příklad GraphDemo2 Procvičované znalosti: Komponenta TImage Zadání: Upravte program GraphDemo tak, aby namalované objekty nebyly zničeny minimalizací okna nebo překrytím jiným oknem. Poznámky: Do okna vložte komponentu TImage a kreslete pomocí TImage.Canvas. Komponenta TImage totiž svůj obsah ukládá do bitmapy, tudíž je schopna jej obnovit. Bohužel, ukládání informací je pomalé a program proto bude blikat. - 38 -
Výuka Borland Delphi
Příklad Gonio
Procvičované znalosti: Komponenty TImage, TRadioGroup. Třída TCanvas. Funkce IsInfinite, IsNAN. Ošetření výjimek. Dlouhodobý projekt. Zadání: Napište program, který nakreslí graf uživatelem zvolené goniometrické funkce na intervalu <0,2π>. Pozor na dělení nulou a nedefinované hodnoty funkcí tg a cotg. Velikost grafu nechť je dána velikostí okna. Poznámky: Kreslení realizujte pomocí položky Canvas komponenty TImage (obsahuje položku Pen a metody MoveTo a LineTo). Při kreslení grafu je výhodnější používat právě metodu LineTo oproti přirozenějšímu (a definici grafu jako množiny bodů více vyhovujícímu) způsobu, kdy obarvujeme jednotlivé body. V případě obarvování jednotlivých bodů totiž není výsledná křivka spojitá. Výběr funkce je realizován komponentou TRadioGroup. Jednotlivé položky se nastavují ve vlastnosti Items a právě zvolenou položku udává hodnota vlastnosti ItemIndex (pozor, první položka má ItemIndex roven 0). Možná rozšíření: Upravte program tak, aby uživatel mohl zvolit interval, na němž bude funkce vykreslována (a to jak osy x, tak osy y). Dále je možné program rozšířit tak, aby kreslil graf libovolné elementární funkce. Poté můžeme pomocí důkladné analýzy vstupu kreslit grafy libovolných funkcí.
7.17 Vytváření komponent za běhu programu Vytváření komponent za běhu programu je velmi užitečné ve chvíli, kdy chceme vytvořit velké množství komponent a jejich umísťování na formulář v době návrhu aplikace by bylo zdlouhavé. Přesný počet komponent navíc nemusí být v době návrhu aplikace znám. Příklad Matematico je příklad, v němž by bylo zdlouhavé nejen komponenty na plochu formuláře umísťovat, ale i vyhodnocování reakcí na události by bylo velice nepřehledné. Příklad Matematico Procvičované znalosti: Komponenta TButton a její vlastnosti. Parametr Sender. RTTI. Tvorba komponent za běhu programu. Dlouhodobý projekt. Legenda: Hra Matematico je v různých matematických třídách hrou dobře známou. Hraje se buď s kartami (všech 4x13 karet) nebo s kartičkami očíslovanými čísly 1-13 tak, že každé číslo je zastoupeno právě čtyřikrát. V případě, že se hraje s kartami, přiřadíme každé kartě patřičnou hodnotu: eso 1, kluk 11, dáma 12, král 13, ostatní karty mají své hodnoty. Hru je možno hrát jako solitér nebo s pomocí psacích potřeb ve skupině. Každý hráč si připraví čtvercovou síť 5x5 políček. Karty se zamíchají a poté jsou náhodně vytahovány. Úkolem hráčů je umísťovat tažená čísla do připravené sítě tak, aby měli na konci hry co největší bodové skóre. - 39 -
Výuka Borland Delphi Jednou umístěná čísla již nelze přesouvat. Hra končí v okamžiku, kdy je umístěno 25. číslo a síť je tak zaplněna. Poté si každý hráč spočítá dosažené body tak, že sečte body dosažené v každém řádku, sloupci a obou úhlopříčkách. Tyto body lze získat za to, že daný řádek, sloupec či úhlopříčka obsahuje: 10b. Dvojici stejných čísel 50b. Trojici stejných čísel 30b. Dvě různé dvojice stejných čísel Trojici stejných čísel a dvojici stejných čísel 80b. Čtveřici stejných čísel 100b. 100b. Postupku (ne nutně setříděnou) Nejvyšší postupku (9..13) 110b. 110b. Jen jedničky a třináctky V případě, že něco z toho je v úhlopříčce, přičítá se navíc bonus 10b. Zadání: Implementujte hru Matematico. Poznámky: Všech 25 tlačítek lze vyrobit dynamicky v metodě obsluhující událost OnCreate hlavního formuláře. Soustavou dvou vnořených cyklů for inicializujeme pole tlačítek a nastavíme jejich pozice a další vlastnosti. Dalším zjednodušením je použití položky Tag. Tuto položku obsahuje každá komponenta a jsou to 4B k uložení čehokoliv, implicitně hodnoty typu Integer. Této položky můžeme použít pro uložení hodnoty, kterou tak při vyhodnocování skóre nemusíme získávat z titulku tlačítka. Metodu obsluhující událost OnClick tlačítka stačí napsat jen jednou, napojit ji na každé tlačítko a pak se na to správné tlačítko odkazovat pomocí parametru Sender, který ukazuje na komponentu, která událost vyvolala (tedy tlačítko, které bylo stisknuto). Možná rozšíření: Napište proceduru, která tažená čísla uspořádá tak, aby bylo dosaženo nejvyššího možného skóre. Dále je možné program upravit tak, aby ukazoval bodové hodnoty u každého řádku, sloupce i úhlopříčky.
7.18 Dialogy Dialogová okna různého druhu jsou nezbytným prostředkem pro komunikaci programu s uživatelem. Jako vedlejší efekt některých dříve uvedených příkladů se již studenti naučili používat funkce ShowMessage a MessageDlg. Další možností komunikace jsou standardizovaná okna pro výběr barev (TColorDialog), otvírání souborů (TOpenDialog, TOpenPictureDialog) a ukládání souborů (TSaveDialog).
Příklad Obrázky Procvičované znalosti: Komponenty TMainMenu, TImage, TOpenDialog nebo TOpenPictureDialog. Zadání: Napište program, který umožní zobrazit vybraný obrázek uložený v souboru na disku. Poznámky: K získání jména souboru s obrázkem použijte komponentu TOpenDialog nebo alternativně komponentu TOpenPictureDialog. Obě komponenty mají metodu Execute, která vrací True v případě, že si uživatel vybral a stiskl tlačítko OK a False v případě, že uživatel ukončil dialog stiskem tlačítka Cancel. Jméno vybraného souboru je dostupné v položce FileName. Zobrazení obrázku se provádí pomocí položky Picture komponenty TImage, která má metodu LoadFromFile. Možná rozšíření: Rozšiřte program o možnost roztáhnout obrázek na celou plochu okna, volitelně se zachováním poměru šířky a výšky obrázku. Využijte k tomu vlastnosti Stretch a Proportional komponenty TImage. - 40 -
Výuka Borland Delphi
Příklad Barvy5
Procvičované znalosti: Popup menu. Procedura Close. Komponenta TColorDialog. Zadání: Napište program, který vytvoří prázdné okno, které po stisknutí pravého tlačítka myši vyvolá kontextové menu s volbami „Barva…“ a „Konec“. V případě, že uživatel zvolí se položku Barva, otevře standardní dialog pro výběr barvy a v případě, že uživatel vybral barvu a výběr potvrdil stiskem klávesy OK, nastaví se barva hlavního formuláře na uživatelem vybranou. V případě, že uživatel vybere volbu Konec, program bude ukončen. Poznámky: Ke spuštění dialogového okna využijte metodu Execute komponenty TColorDialog, která vrací True v případě, že si uživatel vybral a stiskl OK a False v případě, že uživatel ukončil dialog stiskem tlačítka Cancel (Storno). Vybraná barva je dostupná ve vlastnosti Color. K ukončení programu využijte metodu Close hlavního formuláře.
7.19 Mřížky Mřížky mají v aplikacích Delphi různou podobu a široké použití. Lze je využít jak pro vstup, tak pro výstup. Nejjednodušší mřížkou je komponenta TColorGrid, použitá pro výběr barvy v příkladu Kreslení. Příklady Miny a Patnáctka používají komponentu TDrawGrid, tedy mřížku, do které se kreslí a příklad Matice je založen na komponentě TStringGrid, tedy mřížky řetězců. - 41 -
Výuka Borland Delphi Příklad Miny je uveden v následující podkapitole, příklad Matice lze nalézt v příloze. Dalším relevantním příkladem je příklad Barvy7, uvedený rovněž v příloze.
Příklad Kreslení
Procvičované znalosti: Komponenty TColorGrid, TPaintBox. Třída TCanvas. Události OnMouseDown, OnMouseMove, OnMouseUp. Dlouhodobý projekt. Zadání: Napište jednoduchý kreslicí program. Okno bude mít na okraji mřížku pro výběr barvy popředí a barvy pozadí. Při tažení myší se stisknutým tlačítkem se bude na ploše okna kreslit čára barvy popředí (je-li stisknuto levé tlačítko) nebo pozadí (je-li stisknuto pravé tlačítko). Poznámky: Vzhledem k tomu, že událost OnMouseMove není generována nad každým bodem, je vhodné kreslení realizovat ne pomocí obarvování bodů, ale pomocí metody LineTo. Čára tak může být při rychlých pohybech myší kostrbatá, nicméně vždy bude spojitá. Možná rozšíření: Rozšiřte program o možnost kreslení úseček a následně také obdélníků a elips, které budou mít obrys barvy popředí a výplň barvy pozadí.
Příklad Patnáctka Procvičované znalosti: Komponenta TDrawGrid. Událost OnMouseDown nebo OnMouseUp. Legenda: Patnáctka patří mezi známé hlavolamy. Její implementace ve výpočetní technice je navíc poměrně jednoduchá, proto tvoří běžnou součást repertoáru her na mobilních telefonech a byla též nesčetněkrát implementována jako počítačová hra. V reálném světě se jedná o čtvercovou krabičku, v níž jsou uloženy čtvercové hrací kameny. Každý kámen má délku strany rovnu čtvrtině strany krabičky. Kamenů se do krabičky tedy vejde 16, ale je jich v ní jen 15, tudíž jedno místo zůstává stále volné a s kameny je tak možné posunovat. Každý kámen má na sobě jiné číslo od 1 do 15. Úkolem hráče je náhodně rozmístěné kameny pomocí přesouvání poskládat podle velikosti čísla. Pravé dolní políčko zůstane na konci hry prázdné.
- 42 -
Výuka Borland Delphi Dá se dokázat, že ne vždy je možné kameny správně poskládat. Jestliže počáteční rozmístění kamenů vzniklo přesouváním kamenů z uspořádané pozice, je to možné vždy. V případě náhodného rozmístění kamenů se může stát, že daná permutace má špatnou paritu a tudíž kameny poskládat nelze. Zadání: Implementujte hru Patnáctka. Pozor na to, aby šla dohrát! Poznámky: Pracovní plochu pokryjte komponentou TDrawGrid, v níž se bude vše odehrávat. Přesun realizujte v metodě obsluhující událost OnMouseDown/OnMouseUp komponenty TDrawGrid, neboť pak budete mít k dispozici souřadnice myši a tím i souřadnice políčka, na které uživatel kliknul (využijte funkci MouseToCell). Reakce na událost OnSelect, která je generována, když uživatel označí buňku, s sebou nese více problémů než užitku. Možná rozšíření: Umožněte hru hrát i v poli jiných rozměrů než 4x4.
7.20 Dynamická pole Dynamická pole jsou velmi mocným nástrojem, zejména proto, že jejich rozměry je možné použít např. jako parametry konstruktoru, který vytváří daný objekt. Dynamická pole jsou použita v příkladu Miny a dále v příkladech Bloudění, Matice a volitelně též Vlajky, uvedených v příloze.
Příklad Miny Procvičované znalosti: Komponenty TDrawGrid, TMainMenu, TStatusBar. Dynamická pole. Reakce na stisk myši v mřížce. Dlouhodobý projekt. Legenda: Uživatelům operačního systému Windows je hra Hledání min jistě notoricky známa. Na začátku je neprobádané minové pole. Uživatel klikáním myší může každé políčko buďto prozkoumat (levým tlačítkem) nebo označit jako zaminované (pravým tlačítkem). Pokud se rozhodne prozkoumat zaminované políčko, hra pro něj končí výbuchem. Pokud prozkoumává nezaminované políčko, zobrazí se mu počet min na sousedních osmi políčkách. V případě, že je tento počet nulový, sousedních osm políček se automaticky prozkoumá, atd. Úspěšný konec hry je ve chvíli, kdy jsou označena všechna zaminovaná políčka (a jen ta). Zadání: Implementujte hru Hledání min. Uživatel bude mít možnost zvolit si stupeň obtížnosti. Počet zbývajících min ukazujte ve stavovém řádku. Poznámky: K vykreslování minového pole použijte komponentu TDrawGrid. Vykreslování se provádí v metodě obsluhující událost OnDrawCell, která dostane jako parametr políčko, které se právě vykresluje. Nad formátem ukládání dat je potřeba trochu popřemýšlet, protože je třeba ukládat více informací, než se na první pohled zdá. Stavový řádek je realizován komponentou TStatusBar, jejíž vlastnost SimpleText uchovává řetězec zobrazený ve stavovém řádku. Možná rozšíření: Dejte uživateli možnost, aby přímo zadal rozměry minového pole a počet min.
7.21 Komponenta TMemo Komponenta TMemo je nezbytná v místě, kde chceme pracovat s holým textem, který je organizován po řádcích. Typická aplikace je pak textový editor, viz příklad Editor a jeho rozšíření Editor2 a Editor3 dostupná v následující podkapitole, respektive v příloze.
Příklad Soubory Procvičované znalosti: Komponenty TFileListBox, TMemo.
TDriveComboBox,
- 43 -
TDirectoryListBox,
Výuka Borland Delphi Zadání: Napište prohlížeč souborů, tedy program, který umožní procházet adresářovou strukturou a v případě zvolení konkrétního souboru zobrazí jeho obsah. Poznámky: K výběru diskových jednotek slouží komponenta TDriveComboBox, k výběru adresáře komponenta TDirectoryListBox a k výběru souboru komponenta TFileListBox. Tyto komponenty je ovšem třeba navzájem propojit. Komponenta TDriveComboBox má vlastnost DirList, jíž je třeba přiřadit komponentu TDirectoryListBox. Komponenta TDirectoryListBox má vlastnost FileList, které se přiřazuje komponenta typu TFileListBox. Zvolení konkrétního souboru generuje událost OnChange komponenty TFileListBox. Obsah souboru zobrazí komponenta TMemo, jejíž položka Lines obsahuje metodu LoadFromFile. Možná rozšíření: Za použití komponenty TFilterComboBox upravte program tak, aby zobrazoval skutečně jen textové soubory.
Příklad Editor Procvičované znalosti: Komponenty TMainMenu, TMemo, TOpenDialog, TSaveDialog, TFontDialog, TColorDialog. Funkce MessageDlg. Práce s více formuláři. Dlouhodobý projekt. Zadání: Implementujte textový editor, tedy okno, jež bude pokryto zejména editačním polem a bude obsahovat roletové menu s příkazy pro otevření souboru, jeho uložení či uložení pod jiným jménem. Dále bude obsahovat možnost volby typu písma a barvy pozadí v editačním poli a volbu zarovnávání textu. Samozřejmě nesmí chybět dialogové okno „O programu Editor“ obsahující informace o verzi a autorovi programu.
- 44 -
Výuka Borland Delphi Poznámky: Dejte pozor na to, aby uživatel nemohl zavřít program, jestliže jsou v souboru neuložené změny. K zobrazení obsahu souboru použijte komponentu TMemo, jejíž položka Lines obsahuje metody LoadFromFile a SaveToFile, kterým se jako parametr předává textový řetězec s názvem souboru. Nastavení fontu, barvy pozadí a zarovnávání se realizuje změnou příslušných vlastností na základě výsledku font-dialogu nebo color-dialogu.
7.22 Nástrojová lišta a stavový řádek U složitějších aplikací bývá často užitečné zjednodušit uživatelům ovládání programu pomocí nástrojové lišty s tlačítky, která odpovídají některým funkcím hlavní nabídky. K tomu slouží komponenty TToolBar a TSpeedButton. Vhodným doplňkem je komponenta TStatusBar, tedy stavový řádek, pomocí níž můžeme snadno a rychle uživatele informovat o činnostech prováděných programem a jejich stavu. Příklad Editor2
Procvičované znalosti: Komponenty TToolBar, TSpeedButton, TStatusBar. Událost OnHint.
- 45 -
Výuka Borland Delphi Zadání: Program Editor rozšiřte o nástrojovou lištu (toolbar) s tlačítky pro vytvoření nového souboru, otevření a uložení souboru, zarovnávání v editačním poli a zobrazení informací o programu. Dále opatřete editační pole vodorovným a svislým posuvníkem, jejichž zobrazení nechejte na vůli uživatele v nabídce Možnosti. V případě zrušení posuvníků dejte uživateli možnost volby, zda v editačním poli zalamovat řádky či nikoli. Dále program rozšiřte o stavový řádek, v němž se bude objevovat nápověda k položkám menu a informace o tom, zda byl aktuální soubor změněn. Poznámky: Nástrojovou lištu realizujte pomocí komponenty TToolBar a komponent TSpeedButton. Posuvníky jsou dány vlastností ScrollBars komponenty TMemo (využijte hodnoty ssNone a ssBoth). Zalamování textu realizujte vlastností WordWrap komponenty TMemo. Stavový řádek pak komponentou TStatusBar, která obsahuje pole Panels, v němž jsou informace o rozdělení stavového řádku a textové řetězce zobrazené v jednotlivých částech. Nejnáročnější částí tohoto příkladu je zobrazování nápovědy k položkám menu ve stavovém řádku. U každé položky menu je potřeba naplnit vlastnost Hint popisem. Pak je potřeba vědět, že při zaměření položky menu je generována událost OnHint objektu Application a Hint právě zaměřené položky je dostupný v proměnné Application.Hint. Na událost Application.OnHint je tedy potřeba napojit námi napsanou metodu, která obsah proměnné Application.Hint zkopíruje do stavového řádku.
7.23 Další výuka Delphi samozřejmě obsahují daleko více komponent, než bylo doposud v této kapitole uvedeno. Navíc se jich dá spousta nalézt na Internetu, nebo si dokonce mohou studenti vytvářet své vlastní komponenty. Vše záleží na tom, kolik času chceme výuce Delphi věnovat. Je zřejmé, že na některých školách není možné probrat vše, co bylo v předcházejících bodech navrženo. Ale jsou i školy, kde se toho stihne daleko více. Vše záleží na celkové koncepci, zaměření školy, zájmu studentů a schopnostech učitele. Pro doplnění a důkladné procvičení uvedeného učiva lze využít příklady uvedené v příloze, případně se zabývat dlouhodobými projekty, o nichž se zmíníme později. Během realizace dlouhodobých projektů může nastat (a pravděpodobně nastane) situace, kdy bude vhodné probrat některé z dalších témat. V úvahu přitom mohou připadat:
Schránka (jednotka ClipBrd), viz příklad Editor3 v příloze Komplexní čísla (jednotka VarCmplx), viz příklad Complex v příloze Záložky (komponenta TTabControl), viz příklad Obrázky2 v příloze MDI aplikace, viz příklad Obrázky3 v příloze Tvorba vlastních komponent Práce s databázemi Práce se sítí Práce s multimédii Multithreadové aplikace (jednotka TThread) atd. Kromě komponent, které je vhodné probrat, obsahují Delphi řadu komponent, bez kterých se naši studenti mohou bez problémů obejít. Typickým příkladem je komponenta TBitBtn. Umí toho stejně jako komponenta TButton, liší se jen bitmapou na svém povrchu. Každému je zřejmé, že tato komponenta se použije v případě, kdy chceme zlepšit grafickou úroveň našeho programu. Na jeho funkčnost vliv nemá, nepočítáme-li nepatrné zpomalení způsobené načítáním a vykreslováním bitmapy. Je proto zcela zbytečné, abychom studenty učili používat tuto komponentu, protože jediné, co bychom je naučili nového, je přiřazení bitmapy vlastnosti Bitmap této komponenty. Může se zdát, že to není problém, protože by nám to nezabralo příliš mnoho času, opak je však pravdou. Studenti by se začali velice intenzivně zabývat tím, aby na tlačítkách ve svých
- 46 -
Výuka Borland Delphi aplikacích měli co nejoriginálnější bitmapy a zcela by se tak vytratil smysl naší výuky, totiž učit je programovat. Další zbytečnou komponentou je komponenta TBevel, která nic neumí, jen na ploše formuláře vytváří čáry a 3D efekty. Někdy je samozřejmě užitečná pro zpřehlednění aplikačního prostředí, ale při naší výuce si jistě vystačíme s komponentou TPanel. Neznamená to, že bychom studentům použití zmíněných komponent zakazovali, to v žádném případě. Jejich nastudování však můžeme nechat na nich. Ti, kteří se budou programováním v Delphi zabývat i mimo naši výuku, dříve či později alespoň vyzkouší téměř všechny komponenty. Některé z nich se jim zalíbí více než jiné a pak je budou ve svých programech používat. Je potom na místě je pochválit za to, že něco nastudovali sami, ale také je vhodné poukázat (jen tak mezi řečí) na to, že přílišné používání těchto komponent zdržuje práci a odvádí nás od skutečného programování.
7.24 Funkce vývojového prostředí Je zřejmé, že hned v první hodině, kdy Delphi probíráme, musíme studenty seznámit se základními funkcemi, které integrované vývojové prostředí poskytuje. Bez toho by totiž pochopitelně nebyli schopni napsat, přeložit a spustit jediný program. Jak již bylo zmíněno, je nesmírně důležité, aby studenti hned v první hodině napsali a spustili funkční program. Protože vývojové prostředí poskytuje velké množství různých funkcí, nevyhneme se tomu, že při prvním seznámení s prostředím některé funkce vynecháme a jejich probrání odložíme na pozdější dobu. Navíc, mnohé funkce studenti zpočátku vůbec nevyužijí a těžko bychom je tedy přesvědčovali o jejich užitečnosti. Proto počkáme na vhodnou dobu, kdy studenty s těmito funkcemi seznámíme. Protože Delphi je vývojové prostředí pro profesionální programátory, je zřejmé, že ani v případě, že chceme výuce Delphi věnovat velmi mnoho času, nebude třeba studenty seznamovat úplně se vším, co Delphi profesionálním programátorům nabízí. Je proto na zvážení učitele, které funkce je naučí a které ne. Velkou roli v tom samozřejmě musí sehrát vlastní praxe, tedy to, které funkce učitel sám používá. Následující výčet uvádí příklady těch skutečně nejpoužívanějších funkcí:
Seznam komponent. Seznam komponent je v nabídce dostupný přes View –> Component List. Poskytuje abecedně tříděný seznam všech komponent dostupných v Delphi. Programátor tak nemusí přemýšlet nad tím, kde se daná komponenta v paletě komponent nachází a ušetří spoustu času jejím hledáním. Samozřejmě musí vědět jak se jmenuje, ale to je zpravidla menší problém. Vhodným okamžikem k seznámení studentů s touto funkcí je situace, kdy vidíme, že studenti mají s vyhledáváním komponent v paletě problémy. Když vidíme, jak někdo bezradně kliká a nemůže požadovanou komponentu nalézt, nebo se nás některý ze studentů zeptá, kde danou komponentu najde, kromě správné odpovědi je vhodný čas na to, abychom studenty upozornili na tuto funkci. Místa zastavení (breakpoints): Jestliže program v neznámém místě cyklí, nebo máme podezření že nedělá to, co bychom od něj očekávali, a přitom nevíme, kde je chyba, můžeme na podezřelá místa umístit breakpointy. Breakpoint se umisťuje kliknutím na levý okraj okna vedle řádku, na kterém chceme program zastavit. Poté program spustíme. Ten poběží až do chvíle, kdy narazí na breakpoint. V tu chvíli se zastaví a programátor vidí, ve kterém místě byl zastaven. Následně může použít některou z funkcí, které s breakpointy bezprostředně souvisejí. Vhodným okamžikem k probrání této funkce je situace, kdy studenti řeší složitější algoritmický problém, mají v programu chybu a nevědí jakou. Použití brakpointů, krokování a watch listu tak studentům velmi pravděpodobně pomůže, takže budou přesvědčeni o užitečnosti probírané funkce. Systém nápovědy. V žádném případě nemůžeme po studentech vyžadovat, aby si pamatovali přesné parametry předávané funkcím, jejich pořadí a vůbec všechny detaily. Bez detailů se však mnohdy neobejdeme, proto je vhodné, poté, co se studenti naučí základní úkony v integrovaném vývojovém prostředí, vysvětlit systém nápovědy a nadále pak vést studenty k jeho využívání. - 47 -
Výuka Borland Delphi
Krokování: Zastavený program lze krokovat, tedy provádět řádek po řádku. Pomůže nám to odhalit místo, kde se vyskytuje problém. Při volání funkce máme dvě možnosti, jak program krokovat. Buďto funkci vykonat v rámci jednoho kroku (Step over – F8) anebo krokovat i tělo funkce (Trace into – F7). Místo, kde je v programu logická chyba, se tak dá přesně lokalizovat. Zobrazení hodnot proměnných (Watch list): Tato funkce bezprostředně souvisí s krokováním po zastavení programu v určitém místě. Chování programu mnohdy závisí na hodnotách proměnných a je proto dobré vědět, jak se hodnoty proměnných mění v závislosti na vykonávaných příkazech.
7.25 Forma vs. obsah Delphi jako vizuální prostředí velice svádí k tomu, že programátor stráví daleko více času vizuálním návrhem aplikace, než tvorbou skutečného kódu. V komerční sféře, kde je každá aplikace nutně týmovou prací, jsou tyto úkoly rozděleny mezi různé lidi. Zatímco vzhled aplikace, uspořádání komponent a podobné záležitosti jsou spíše záležitostí psychologie a marketingu, tvorbu kódu mají na starosti programátoři, kteří se vzhledem programu příliš nezabývají. Po studentech budeme pochopitelně chtít obojí: Grafické uspořádání komponent a jejich vzhled, i tvorbu kódu. Při výuce však musíme dávat velký pozor na to, aby se uspořádávání komponent nestalo tím hlavním, co studenti v hodinách dělají. Výuka informatiky v tuto chvíli není o tom, naučit studenty skládat tlačítka a okénka, ale o tom, naučit je programovat. Zpočátku je proto nutné tuto skutečnost zdůrazňovat téměř každou hodinu a tomuto paradigmatu také přizpůsobit celkový styl výuky a volbu příkladů. Jako flagrantní příklady nepochopení úlohy vizuálního vývojového prostředí uveďme několik citací z knihy [4]: Kapitola 1, Formulář je okno, str. 17: „Mohli byste totiž nabýt dojmu, že programování s Delphi je pouze otázkou výběru voleb a vizuálních elementů. To je jistě hlavní přístup, ale přijde čas, kdy budete muset napsat i nějaký kód.“ Pokud kniha, která o sobě tvrdí, že je nejlepší učebnicí Delphi, obsahuje hned v první kapitole tuto větu, je to skutečně tristní. Čtenář tak lehce nabude dojmu, že v Delphi se dá téměř všechno „vyklikat“ a že psaní kódu je tam jen jaksi mimochodem a nebude příliš nutné. A přitom je to přesně naopak: důležitý je kód, nikoliv vizuální návrh. Důležitý je funkční program, nikoliv dobře vypadající program. Shrnutí kapitoly 11, Panel nástrojů a stavový pruh, str. 386: „Tuto kapitolu můžeme považovat za první krok k profesionálním aplikacím. Další kroky probereme v následujících kapitolách, ale už nyní se naše programy podobají nejprodávanějším aplikacím Windows, což může být pro naše klienty zásadní.“ To, že pro naše klienty může být zásadní, že se naše programy podobají nejprodávanějším aplikacím Windows, je mrzuté, ale bohužel je to pravda. Lidé velmi snadno podléhají dojmu dobře vypadajících a snadno se ovládajících programů. Jsou to samozřejmě vlastnosti důležité, ale v žádném případě nesmějí být považovány za důležitější než funkčnost. Bohužel, velmi často jsou. Studentům je vhodné podat problém přibližně následujícím způsobem: „Vzhled programu je jistě věc důležitá a na prodejnost programu má nezanedbatelný vliv. Ale to, co je u dobrého programu daleko důležitější, je jeho funkčnost. To, že dělá to co má, že to dělá dobře, rychle, efektivně a bezchybně. Pokud sebelépe vypadající program nebude funkční, nemá šanci. Je sice pravda, že pokud sebefunkčnější program nebude dobře vypadat, jeho šance jsou též omezené, ale forma (vzhled) se vždy mění snáze než obsah (funkčnost). My jsme tu proto, abychom se naučili programovat, nikoliv proto, abychom se naučili skládat tlačítka na plochu formuláře. Snažte se proto, aby vám grafický návrh aplikace nezabral déle než psaní kódu.“ Je nepříjemné, že se nevyhneme tomu, abychom hned u prvních programů tuto zásadu porušili. Studenti se totiž při psaní programů v Delphi nejprve seznámí se základními komponentami a teprve poté mohou psát kód, který tyto komponenty obsluhuje. Například v příkladu Ahoj, který je určen k tomu, aby byl prvním programem v Delphi, není ani řádek - 48 -
Výuka Borland Delphi kódu, vše je jen o nastavování vlastností komponent. Proto je nutné co nejdříve (nejlépe ve druhé či třetí hodině výuky Delphi) zařadit příklad, kdy kód bude důležitější než vizuální nastavení komponent (např. zjednodušená verze příkladu Světelné noviny, příklad Faktoriál, atp.). Názor, prezentovaný výše, má své velké ALE. Pokud studenty povedeme k tomu, aby se příliš nezabývali vzhledem své aplikace, hrozí reálné nebezpečí, že studenti svůj program odbudou. Prostě na povrch formuláře nějak „nahážou“ komponenty nezajímajíce se o to, zda jsou aspoň pod sebou či vedle sebe, a hned se vrhnou na psaní kódu. To je sice v souladu s naším přesvědčením, že psaní kódu je důležitější, ale program nebude udělán pořádně. Je pravda, že to, co na něm nebude pořádně, není pro nás příliš důležité, ale chybou je to, že vůbec něco nebude pořádně. A to bychom samozřejmě neměli dopustit. Studenti by si měli neustále uvědomovat, že když už něco dělají, měli by to dělat kvalitně. Je zde totiž nebezpečí, že pokud studenti odbudou grafický návrh, stejným způsobem odbudou i kód, což by byla neospravedlnitelná pedagogická chyba. Proto je třeba zvolit vhodný kompromis. Studenti by grafický návrh neměli odbýt, ale také by se jím neměli zabývat přehnaně dlouhou dobu. Alespoň urovnání komponent pod sebe a vedle sebe bychom tedy vyžadovat měli, přehnané vizuální záležitosti (bitmapy, bevely,…) už nikoli.
7.26 Předdefinované aplikace a experti Jedna z věcí, kterou si skuteční programátoři v Delphi velmi pochvalují, je to, že firma Borland už za ně udělala to, co by jinak museli dělat pokaždé znovu, a sice kostru aplikace. Programátor tak má k dispozici funkční grafické prostředí, ve kterém stačí zpravidla provést jen drobné změny, a může se rovnou zabývat tím, co má program umět a začít psát příslušný kód. Přestože je to v souladu ze zásadou popsanou dříve (zabývat se více kódem než vzhledem), je třeba před použitím těchto vymožeností v počátcích výuky varovat. Podívejme se, jak vypadá použití předdefinovaných formulářů: Programátor se prokliká nějakou strukturou až k aplikaci, kterou potřebuje, a Delphi ji vygenerují (resp. odněkud nakopírují). Výsledkem je množství souborů s množstvím kódu. Ten, kdo chce v takto předdefinovaném kódu něco měnit nebo dopisovat nějaký kód vlastní, se musí v tom, co Borland vyrobil, vyznat, což není možné bez předchozí praxe s programováním v Delphi. Kromě toho to není možné, pokud si programátor alespoň jednou sám nevyzkoušel vyrobit to, co mu teď předkládají Delphi. To, že takováto věc v Delphi existuje, je samozřejmě dobré studentům sdělit, ale až v době, kdy jsou v programování v Delphi zběhlí a dokážou se v předdefinovaném kódu vyznat. Jinak totiž riskujeme, že studenti budou měnit něco, co měnit nemají a aplikace se začne chovat nepochopitelně. Nám se tam budou těžko hledat chyby a studenti získají dojem, že je to příliš složité a že tomu nerozumí a ztratí motivaci k dalšímu učení.
- 49 -
Dlouhodobé projekty
8 Dlouhodobé projekty Chceme-li výuce Delphi věnovat větší množství času, což je v této souvislosti alespoň půl roku, budeme postaveni před problém, zda studentům zadat samostatný dlouhodobý úkol či nikoli. Zadání například pololetního projektu s sebou přináší spoustu výhod, ale bohužel také četná rizika, která je třeba zvážit. Tato kapitola poskytuje základní argumenty pro a proti, které učiteli pomohou při rozhodování, zda a jakým způsobem dlouhodobé projekty do výuky zařadit. Pro ty, kteří se rozhodnou pro dlouhodobé projekty, nabízí několik inspirativních příkladů.
8.1 Výhody dlouhodobých projektů Zadáním samostatné práce studenty nepřímo donutíme, aby se programování v Delphi věnovali i mimo čas stanovený k výuce. To pochopitelně povede k tomu, že se studenti v Delphi naučí programovat daleko lépe, než kdyby se mu věnovali pouze v době výuky. Je-li navíc programování kromě školního předmětu také koníčkem velkého procenta studentů, což pravděpodobně nastane, je-li programování volitelným předmětem, který si zapisují jen studenti, kteří o něj mají zájem, studenti takový úkol s velkou pravděpodobností dokonce uvítají. Necháme-li studentům velkou míru autonomie při volbě projektu, nebo dokonce povolíme týmovou spolupráci (viz dále), studenti se naučí „objektově myslet“ a možná i rozdělovat pracovní úkoly a spolupracovat v týmu, což jsou dovednosti, které v pozdějším životě rozhodně najdou uplatnění.
8.2 Nevýhody dlouhodobých projektů Asi tím nejpodstatnějším rizikem dlouhodobých projektů je potenciální nedostupnost potřebného vybavení pro studenty. Ne každý má doma počítač a rozhodně ne každý má doma Delphi, o jejich legálnosti nemluvě. Nemůžeme si proto v žádném případě dovolit deklarovat projekt jako domácí práci. Poskytuje-li škola svým studentům přístup k počítačům i mimo výuku informatiky, a studenti se tak mají šanci dostat k Delphi ve svém volném čase, je problém částečně vyřešen, stále je tu však potenciální kapacitní problém či riziko, že čas, kdy studenti mohou počítače využít, se některému z nich z vážných důvodů nebude hodit. Kromě individuálního přístupu (bez nějž bychom se pochopitelně stejně neobešli) a různých výjimek se nabízí také možnost nechat v některých vyučovacích hodinách studenty na svých projektech pracovat. Ti nadanější tak získají šanci stihnout vše ve škole a nebudou muset trávit nad domácími úkoly svůj volný čas, navíc budeme mít přehled o tom, jak studenti s tvorbou projektů postupují, budeme moci řešit vzniklé problémy, a donutíme studenty, aby svůj úkol řešili průběžně a ne až na poslední chvíli. Druhé možné riziko nastane zejména tam, kde programování není zároveň koníčkem a kde se Delphi učí v rámci povinného předmětu. Je jím nutnost věnovat větší množství volného času škole. To může u studentů, kteří nejsou programováním příliš nadšeni, vyvolat značnou nevoli a v konečném důsledku může vést ke zprotivení programování jako učebního předmětu, což je samozřejmě velmi nežádoucí. Navíc, pokud bychom studentům zadali dlouhodobý projekt zejména proto, aby se naučili programovat více, než by se naučili jen v době výuky, je to svým způsobem naše selhání, neboť nedokážeme studenty naučit stanovené učivo ve stanoveném čase. A takovéto selhání mohou negativně vnímat studenti, rodiče i vedení školy. 8.3 Dlouhodobé projekty: Ano či ne V případě konkrétní školy, konkrétního učitele a konkrétních studentů se jistě mohou objevit i další argumenty, které mohou uvažování nad tímto problémem značně posunout. V obecné rovině, bez uvážení dalších okolností, je závěr takový, že v případě výuky Delphi v rámci povinného předmětu je lepší dlouhodobý projekt do výuky nezařazovat, v případě volitelného předmětu to možné je. Ale i v takovém případě je vhodné studenty již v době volby volitelných předmětů na tuto skutečnost upozornit, ať vědí, co mají od předmětu očekávat. - 50 -
Dlouhodobé projekty V následujícím textu předpokládejme, že učitel zvážil všechna pro a proti vypisování dlouhodobých projektů a rozhodl se pro jejich vypsání. Budeme se tedy zabývat některými obecnými zásadami, kterými by se v takovém případě měl řídit.
8.4 Zásady dlouhodobých projektů Nejdůležitější je, aby studenti měli možnost zvolit či vymyslet si svůj vlastní projekt. Jistě se totiž mezi nimi najdou takoví, kteří už na něčem pracují ze svého vlastního zájmu, a budou tak moci svůj „soukromý“ projekt prohlásit za školní projekt. Kdybychom studentům něco vnucovali, ztratí motivaci. Protiargumentem ale může být, že se aspoň naučí tvořit programy na zakázku a přesně podle pokynů zadavatele, nicméně otázka motivace je v tuto chvíli důležitější. Ať však studentům necháme jakoukoliv míru autonomie, je nesmírně důležité ponechat si právo veta. Projekty, které si studenti vymyslí, musíme schválit. Vyhneme se tak pozdějším komplikacím. I když necháme studentům možnost vytvořit vlastní projekty, musíme dát těm, kteří si svůj projekt nevymyslí, možnost volby z námi předem připravených projektů. Nemělo by se stát, že budou dva lidé programovat to stejné a přitom by si každý měl vybrat projekt, který mu vyhovuje. Příkladů je proto potřeba vymyslet poměrně značné množství. Zde se pochopitelně uplatní schopnosti a kreativita učitele, jako dlouhodobé projekty mohou posloužit i některé z příkladů uvedených v této práci. Tím jsme tedy vyčerpali možnost, že každý student pracuje zcela samostatně na svém vlastním projektu. To ovšem není jediná možnost. Další možností je spolupráce všech studentů na témže projektu. Studenti se tak naučí sami rozložit komplexní úkol na dílčí problémy a tyto problémy si rozdělit tak, aby to bylo spravedlivé. Zároveň se naučí spolupráci a komunikaci v týmu. Budou muset předem definovat, co mají které třídy a funkce umět a s jakými parametry se mají volat. To znamená, že ještě před vlastním plněním úkolu budou muset provést jeho důkladnou analýzu. Nebojme se této domluvě věnovat i několik vyučovacích hodin, neboť to je jedna z nejdůležitějších věcí, které si studenti ze školy mohou odnést. Dále je dobré citlivými zásahy domluvu studentů usměrňovat, aby vše proběhlo „správně“. Největší kus práce by však měli udělat studenti sami. I zde je však dobré, aby celý projekt včetně rozdělení práce mezi jednotlivé studenty, prošel naším schválením. Ani tato druhá extrémní možnost náš výčet neukončuje. Kompromisním řešením je nechat studenty tvořit v libovolně početných (tedy i jednočlenných) skupinách. Hledisko skupinové spolupráce zde zůstane zachováno a výuka se nám navíc bude lépe organizovat. Obrovským rizikem je však to, že se mezi studenty najdou takoví, kteří budou mimo jakoukoliv skupinu a zůstanou na svůj projekt sami. Může to být způsobeno tím, že jim to tak vyhovuje a že to tak sami chtějí, což by bylo v pořádku, ale také tím, že je třídní kolektiv zavrhuje a ostatní s nimi nechtějí spolupracovat. Této situaci musíme za každou cenu zabránit. Buďto tím, že násilně stanovíme počet členů projektové skupiny, čímž studenty donutíme, aby si své spolupracovníky vybrali i mezi těmito „outsidery“, nebo tím, že jakékoliv skupiny zakážeme úplně. I v případě, že tento jev odhalíme pozdě, máme ještě možnost takovýmto studentům s tvorbou projektů pomoci a nepřímo je oproti týmovým projektům zvýhodnit, samozřejmě citlivě, abychom neudělali svým přístupem více škody než užitku. Mezi studenty mohou být samozřejmě znalostí rozdíly. Budeme mít ve třídě studenty, kteří se dokáží prosadit více, i studenty, kteří se dokáží prosadit méně. Naší povinností je dát šanci všem. Ani sebelepší znalosti, které předáme talentovaným studentům nemohou ospravedlnit pocity méněcennosti a ztrátu motivace těch méně schopných. Čím více dáme studentům autonomie, tím větší rizika podstupujeme. Studenti se sami nikdy nedomluví tak, aby to bylo zcela spravedlivé. Od toho jsme tam my, abychom je usměrnili. Pokud se na to necítíme, je lepší příliš autonomie studentům nedávat a nechat je pracovat samostatně na přidělených projektech. Takovéto autoritářství bude lepší než špatně řízená demokracie. Dobrý učitel by však měl umět dobře řídit demokracii mezi studenty. A toto je k tomu skvělá příležitost, pokud se dobře využije.
- 51 -
Dlouhodobé projekty
8.5 Témata dlouhodobých projektů Jak již bylo zmíněno, chce-li učitel vypisovat dlouhodobé projekty, musí mít sám připravenou zásobu témat, které bude přidělovat studentům, kteří nebudou schopni vymyslet vlastní téma. Některé příklady uvedené v příloze mohou být použity jako témata dlouhodobých projektů. Tato skutečnost je v charakteristice příkladů uvedena. Kromě těchto příkladů uvedeme ještě některá další možná témata, mezi nimiž budou i hry: Příklad Graf Procvičované znalosti: Komponenta TImage. Třída TCanvas. Syntaktická analýza vstupního řetězce. Elementární funkce. Dlouhodobý projekt. Zadání: Napište program, který ze vstupu načte funkční předpis jakékoliv funkce sestavené pomocí elementárních funkcí a nakreslí její graf. Rozšíření: Upravte program tak, aby kreslil graf v různém měřítku a zadaných výřezech.
Příklad Kuželosečky Procvičované znalosti: Komponenta TImage. Třída TCanvas. Kuželosečky. Dlouhodobý projekt. Zadání: Napište program, který bude kreslit reálné kuželosečky se zadanými parametry. Dejte uživateli možnost zadat kuželosečku pomocí matice i pomocí volby jejího typu a určujících parametrů. Rozšíření: Upravte program tak, aby kuželosečku nakreslil ve zvoleném měřítku. Dále umožněte uživateli zadat výřez kuželosečky, který chce nakreslit.
Příklad Tester Procvičované znalosti: Dynamická pole. Manipulace s řetězci. Práce se soubory. Dlouhodobý projekt. Zadání: Napište program, který bude sloužit jako univerzální testovací program. Program nejprve ze souboru načte seznam otázek a možných odpovědí k nim. Poté nechá uživatele zvolit u každé otázky odpověď, kterou považuje za správnou a nakonec uživatelův výkon ohodnotí. Rozšíření: U každé otázky je obrázek, kterého se daná otázka týká. Program tak najde aplikaci např. pro testování znalosti rostlin, živočichů, atd.
Příklad Piškvorky Procvičované znalosti: Komponenta TDrawGrid. Dynamická pole. Algoritmus piškvorků. Dlouhodobý projekt. Zadání: Napište program, který umožní hrát dvěma hráčům hru piškvorky na omezeném dvourozměrném poli. Dejte uživatelům možnost zvolit si rozměry pole a délku piškvorky. Rozšíření: Rozšiřte program tak, aby uměl hrát proti jednomu hráči. Rozšíření: Implementujte trojrozměrné piškvorky. Opět nejprve pro dva hráče, poté můžete zpracovat algoritmus, podle kterého bude hrát počítač.
Příklad Dáma Procvičované znalosti: Komponenta TDrawGrid. Události myši. Algoritmus hry Dáma. Dlouhodobý projekt. Zadání: Implementujte hru Dáma tak, aby mohli hrát dva hráči proti sobě. Rozšíření: Rozšiřte program tak, aby umožňoval hrát jednomu hráči proti počítači.
Příklad Tetris Procvičované znalosti: Komponenta TDrawGrid. Dynamická pole. OOP. Dlouhodobý projekt. Zadání: Implementujte hru Tetris. Dejte uživateli možnost zvolit si rozměry herní plochy, počáteční rychlost a počáteční zaplněnost herní plochy. - 52 -
Dlouhodobé projekty Rozšíření: Napište editor hracích kostek a dejte možnost hráčům zvolit si vlastní tvary, se kterými budou hrát.
Příklad Snipes Procvičované znalosti: Komponenta TDrawGrid. Dynamická pole. OOP. Algoritmus tvorby bludiště. Dlouhodobý projekt. Legenda: Snipes je prastará hra pod operační systém MS-DOS. V dvourozměrném bludišti, které tvoří povrch koule, je rozmístěno několik krabic, produkujících „záškodníky“. Záškodníci se mohou pohybovat a střílet. Úkolem hráče, který se může pohybovat, střílet a pohybovat dvojnásobnou rychlostí, je zlikvidovat všechny záškodníky a jejich líhně. Jakékoliv střely mohou mít jeden z osmi základních směrů. Hráčovy střely se navíc mohou odrážet od stěn. Zadání: Implementujte hru Snipes. Dejte hráči možnost zvolit si obtížnost hry, tedy počet líhní a rychlost líhnutí. Rozšíření: Upravte hru tak, aby náraz do stěny znamenal ztrátu života. Rozšíření: Upravte hru tak, aby se po smrti záškodník proměnil v ducha, který bude odebírat hráči životy tím, že do něj narazí. Ducha lze zlikvidovat opět střelbou. Rozšíření: Upravte hru tak, aby ji mohli hrát dva hráči. Ať už proti sobě, nebo spolupracující.
Příklad Červi
Procvičované znalosti: Komponenty TImage, TTimer. Třída TCanvas. Události klávesnice. Dlouhodobý projekt. Legenda: Hra Červi je určená teoreticky libovolnému počtu hráčů. Prakticky je jejich počet omezen tak, aby se vešli k jedné klávesnici. Hraje se na omezené hrací ploše. Každý hráč má svého červa, který se jen prodlužuje. Pomocí dvou kláves (vpravo a vlevo) každý hráč svého červa řídí. Kdo narazí do hranice herního území nebo těla libovolného červa (i vlastního), pro toho hra končí. Zvítězí hráč, který vydrží nejdéle. Zadání: Implementujte hru Červi. Dejte možnost volby počtu hráčů Rozšíření: Dejte hráčům možnost určit si klávesy, kterými budou své červy ovládat.
Příklad Tanky Procvičované znalosti: Komponenta TImage. Třída TCanvas. Šikmý vrh. Dlouhodobý projekt. Legenda: V krajině proti sobě stojí několik tanků, každý patří jednomu hráči. Hráči se pravidelně střídají. Ten, který je na tahu, zvolí zbraň, úhel a rychlost, a vypálí. Střela dopadne na místo určené rovnicí vrhu šikmého vzhůru, kde vybuchne a zničí vše do určité vzdálenosti, včetně případných tanků. Zvítězí hráč, jehož tank zůstane ve hře jako poslední. Zbraně se liší především svoji sílou, počet různě silných střel je však omezen. Hráč může nevhodnou střelou zničit nebo poškodit i sám sebe. Hra neprobíhá na rovině, ale v řezu náhodně vygenerované krajiny. Není proto třeba se zabývat azimutem střely, ale jen úhlem, který hlaveň tanku svírá se zemí. Po střelách zůstávají v zemi krátery, do nichž mohou tanky sklouzávat. Zadání: Implementujte hru Tanky. Rozšíření: Implementujte algoritmus, podle kterého bude počítač hrát za některé tanky. Rozšíření: Fantazii programátora se meze nekladou. Lze vymýšlet nové a nové zbraně (laser) a různě implementovat možnost volby zbraní, včetně nákupů zbraní mezi jednotlivými koly, kdy hráči ve zbraně proměňují svá skóre, která získali v předchozím kole.
- 53 -
Závěr
9 Závěr Začátek této práce je věnován cílům výuky informatiky na různých stupních škol. K naplnění těchto cílů může sloužit výuka OOP, proto jsme se jí v dalším textu zabývali podrobně. Uvedli jsme, jaké jsou cíle výuky OOP a jaké prostředky k tomu můžeme využít. Rozebrali jsme si výhody a nevýhody nejpoužívanějších objektových jazyků a na základě jejich analýzy jsme zvolili nejvhodnější postup při výuce OOP na střední škole. Konkrétně jsme dospěli k tomu, že k výuce základů OOP použijeme ve většině případů jazyk Object Pascal, na nějž co nejdříve navážeme výukou vývojového prostředí Borland Delphi. Další kapitoly této práce pojednávají v souladu se závěry z prvních kapitol o výuce Object Pascalu a Borland Delphi. Těžiště této práce spočívá především v konkrétních příkladech, na nichž bude výuka OOP realizována. Příkladů je přímo v textu práce uvedeno šedesát, dalších více než dvacet příkladů tvoří přílohu. Jsou zde uvedeny jak příklady jednoduché, na kterých se studenti naučí pracovat s konkrétní komponentou či funkcí, tak příklady složitější, které ze strany studentů vyžadují komplexní analýzu řešeného problému a spojení dílčích poznatků v jeden celek. Mezi příklady najdeme i takové, které přesahují rámec informatiky. Studenti v nich využijí znalosti z matematiky, fyziky, angličtiny či zeměpisu, což pozitivně ovlivní jejich všeobecný rozhled a propojí informatiku s běžným životem. Většina příkladů je pro názornost doplněna obrázkem. U každého příkladu se zamýšlíme nad tím, co studenty naučí. U každého příkladu jsou též uvedeny rady, které mohou studentům pomoci při plnění zadání příkladu. Některé příklady je možné dále rozšiřovat; možná rozšíření jsme rozebrali. Vzorové řešení většiny z uvedených příkladů je dostupné na doprovodném CD. Všechny příklady jsou formulovány tak, aby mohly být bez dalších úprav převzaty a předány studentům, a to jak ve formě mluveného slova, tak ve formě tištěné či jako WWW prezentace. Hotová vzorová řešení lze využít – např. za použití datového projektoru – pro názornou demonstraci zadání. V poslední kapitole této práce jsme se zabývali dlouhodobými projekty jako prostředkem ke zdokonalení výuky OOP. Uvedli jsme jejich výhody, nevýhody a podmínky, za nichž je možné je do výuky zařadit. Dále jsme uvedli zásady, které je při zařazení dlouhodobých projektů do výuky potřeba dodržovat, rizika, kterým musí učitel předcházet, a nastínili několik příkladů, které mohou jako zadání dlouhodobých projektů sloužit. Středoškolští učitelé informatiky, kteří uvažují o zařazení OOP do výuky, mohou v této práci nalézt argumenty, které jim jejich rozhodování usnadní. Příklady zde uvedené pak mohou být cennou inspirací pro ty, kteří se rozhodnou výuku OOP realizovat.
- 54 -
Literatura
Literatura [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32] [33] [34] [35] [36] [37]
Bendl, S.: Školní kázeň. Praha, ISV, 2001 Blažek, B.: Tváří v tvář obrazovce. Praha, Sociologické nakladatelství, 1995 Cangelosi, J.S.: Strategie řízení třídy. Praha, Portál, 1994 Cantú, M.: Mistrovství v Delphi 2. Brno, Computer Press, 1996 Cimrman, J., Smojlak, L.: Vyšetřování ztráty třídní knihy. Praha, Paseka, 1992 Čáp, J.: Psychologie pro učitele. Praha, 1954 Černochová, M., Komrska, T., Novák, J.: Využití počítače při vyučování. Praha, Portál 1998 Dmitrijev, J.: Savci známí i neznámí, lovení i chránění. Praha, Lidové nakladatelství, 1987 Ezzel, B.: Object Oriented Programming in Turbo Pascal® 5.5. Addison-Wesley Publishnig Company, 1988 Fanderlík, V.: Listy Jurovi. Brno, Blok, 1991 Gates, B.: Informační dálnice, Praha, Management Press, 1997 Hejný, M.; Kuřina, F.: Dítě, škola, matematika. Konstruktivistické přístupy ve vyučování. Praha, Portál 2001 Herout, P., Rudolf, V., Šmrha, P.: ABC programátora v jazyce C: ANSI C, BORLAND C, C++. České Budějovice, Nakladatelství KOPP, 1992 Herout, P.: Učebnice jazyka Java. Nakladatelství KOPP, 2001 Hohl, P.: Jak učit OOP (diplomová práce). Brno, Fakulta Informatiky MU, 1996 Horák, F. a kol. Didaktika základní a střední školy. Praha, SPN, 1990 Horák, F. a kol.: Aktivizační didaktické metody ve výchovně vzdělávacím procesu. Olomouc, KPÚ, 1981 Hutchinson, T.: Project English 3. Oxford University Press, 1987 Chan, M.C., Griffith, S.W., Iasi, A.F.: 1001 tipů Java. Brno, UNIS Publishing, 1997 Kalhous, Z., Obst, O. a kol.: Školní didaktika. Praha, Portál, 2002 Kohout, J.: Rétorika. Umění mluvit a jednat s lidmi. Praha, Management Press, 1996 Kol.: Rozum do kapsy, malá encyklopedie. Praha, Albatros, 1988 Kyriacou, Ch.: Klíčové dovednosti učitele (Cesty k lepšímu vyučování). Praha, Portál, 1996 Lewis, D.: Tajná řeč těla. Praha, Victoria Publishnig, 1995 Macek, P.: Adolescence. Praha, Portál, 1999 Mareš, J., Křivohlavý, J.: Komunikace ve škole, Brno, Masarykova univerzita, 1995 Mikulčák, J., Klimeš, B., Široký, J., Šůla V., Zemánek Fr.: Matematické, fyzikální a chemické tabulky pro střední školy. Praha, SPN, 1989 Ochranová, R., Kozoubek, M.: Objektové programování v Turbo Pascalu, Brno, Masarykova Univerzita, 1993 Pařízek, V.: Učitel a jeho povolání. Praha, SPN, 1988 Pelikán, J.: Mýty v pedagogice a empirický výzkum. Učitelské listy č. 1/1999-2000 Pitner, T.: Metodika OOP a událostmi řízeného programování (diplomová práce). Brno, Fakulta Informatiky MU, 1995 Prokeš, J.: Člověk a počítač aneb svítání digitální kultury. Sursum, Tišnov, 2000 Průcha, J.: Moderní pedagogika, Praha, Portál, 1997 Rys, S.: Příprava učitele na vyučování. Praha, SPN, 1979 Slavík, J., Novák, J.: Počítač jako pomocník učitele. Praha, Portál, 1997 Svojsík, A.B.: Základy Junáctví, Praha, Merkur, 1991 Zapletal, M.: Rádce skautské družiny. Praha, Skauting, 1991
- 55 -
Internetové zdroje
Internetové zdroje [38] [39] [40] [41]
Janoušek, V.: Smalltalk. Fakulta Informačních technologií VUT, Brno, 1997, http://www.fit.vutbr.cz/~janousek/smalltalk/smalltalk.html Panici, J.D.: Have You Considered Smalltalk?. In: Why Smalltalk, 2002, http://www.whysmalltalk.com/articles/considered.htm Kol.: Wikipedia, The Free Encyclopedia, http://www.wikipedia.org/ Kol.: The Eiffel Programming Language, http://www.engin.umd.umich.edu/CIS/course.des/cis400/eiffel/eiffel.html
- 56 -
Příloha: Další příklady
Příloha: Další příklady Příklad Barvy6
Procvičované znalosti: Komponenta TColorBox. Zadání: Napište program, který vytvoří okno s rozbalovacím okénkem pro výběr barvy. Pokaždé, když uživatel v rozbalovacím okně vybere barvu, změní se barva hlavního formuláře. Poznámky: Událost OnChange komponenty TColorBox je generována při výběru nové barvy. Vybraná barva je dostupná ve vlastnosti Selected. Možná rozšíření: Pomocí Object Inspectoru upravte barevné konstanty, které si uživatel může vybrat.
Příklad Barvy7 (Vzorník barev)
Procvičované znalosti: Komponenty TColorGrid, TScrollBar, TRadioButton. Dlouhodobý projekt Zadání: Napište program, který vygeneruje vzorník barev. Protože prostor barev zobrazitelných v režimu true color je trojrozměrný a obrazovka počítače jen dvourozměrná, postupujte tak, že uživatel bude mít možnost jednu zvolenou barevnou složku pevně zafixovat na zvolené - 57 -
Příloha: Další příklady hodnotě. Poté program vygeneruje dvourozměrnou mřížku, kdy se v jednom směru bude zvyšovat jedna barevná složka a ve druhém druhá. Protože možností je 256 x 256, což by bylo pomalé, velké a nepřehledné, hodnota barevné složky v sousedním políčku bude vyšší vždy o vhodnou hodnotu (8,16,…). Poznámky: K vygenerování vzorníku použijte komponentu TDrawGrid. Vykreslování mřížky se provádí v metodě obsluhující událost OnDrawCell, která dostane velmi užitečné parametry: Souřadnice mřížky a výřez (TRect) obrazovky, ve kterém se kreslí. Nezapomeňte, že políčka, která mají některou souřadnici nulovou, tvoří záhlaví tabulky a místo barevného čtverce je potřeba do nich vypsat hodnotu příslušné barevné složky. Možná rozšíření: Když uživatel klikne na některé políčko, zobrazí se hlášení s konkrétními hodnotami barevných složek daného políčka. Když uživatel klikne na některé políčko, zobrazí se nový vzorník, který bude upřesňovat hodnoty daného políčka. Uživatel tak bude mít možnost prohlédnout si všech 256 x 256 x 256 barev.
Příklad Biorytmy Procvičované znalosti: Komponenta TMonthCalendar. Funkce InputBox. Typ TDate. Dlouhodobý projekt. Legenda: Někteří psychologové tvrdí, že to, v jaké je člověk fyzické formě, jakou má náladu a jak dobře se mu přemýšlí, je dáno pravidelně se opakujícími cykly. Polovina každého cyklu je tvořena tzv. pozitivní fází, polovina negativní fází, a dny, kdy se tyto fáze střídají, jsou kritické dny. Fyzický cyklus, který určuje, jak se člověk cítí fyzicky, a zda je schopen podávat náročné výkony, trvá 23 dnů. Psychický cyklus určující duševní stav a náladu má 28 dnů a intelektuální cyklus, určující schopnost používat inteligenci, trvá 33 dnů. Všechny cykly začínají v den narození. Souhrnně se označují pojmem biorytmus a graf, do nějž je pro každý den zanesen stav všech cyklů, se nazývá kondiciogram. Díky různé délce cyklů pak během života většinou nastanou všechny možné kombinace pozitivních, negativních a kritických dnů. Kondiciogramy jsou hojně využívány vrcholovými sportovci. Některé výzkumy ukazují, že statisticky významné procento dopravních nehod se stává v kritické dny a některé aerolinky dokonce plánují lety svých pilotů s ohledem na jejich biorytmus (viz [18], str. 104). Zadání: Napište program, který po zadání data narození vypočítá kondiciogram. Poznámky: K implementaci je možné využít buďto komponentu TMonthCalendar, nebo nějakou jinou „kalendářovou“ komponentu, popř. vyřešit výstup úplně jinak, fantazii se meze nekladou. K výpočtu počtu dní, jež uplynuly od narození, využijte datový typ TDate a funkci Date, která vrací dnešní datum právě v typu TDate. TDate není nic jiného než počet dnů, které uplynuly od 31.12.1899 (1.1.1900 má tedy hodnotu 1). Prostým odečtením hodnot TDate tak získáte počet dní uplynuvších mezi dvěma daty. Po zadání data narození uživatelem je toto možné převést na datum pomocí funkce StrToDate, která vrací hodnotu typu TDate nebo vyvolá výjimku EConvertError. Možná rozšíření: Zadaná data narození společně se jmény uživatelů ukládejte do souboru a po spuštění programu je načtěte. Uživatel, který bude váš program používat častěji, tak nebude obtěžován neustálým zadáváním svého data narození.
- 58 -
Příloha: Další příklady
Příklad Bloudění
Procvičované znalosti: OOP. Algoritmus tvorby bludiště. Komponenta TDrawGrid. Dynamická pole. Dlouhodobý projekt. Zadání: Vytvořte jednotku Bludiste, která bude implementovat metody pro vytvoření a procházení bludiště zadaných rozměrů. Bludištěm se v tomto případě rozumí obdélníkové pole, jehož jednotlivá políčka jsou nebo nejsou oddělena stěnou. V bludišti musí mezi každými dvěma políčky existovat právě jedna cesta. Dále napište program, který bude tuto jednotku používat a umožní uživateli zadat rozměry bludiště, vytvoří bludiště a umožní bludiště projít. Poznámky: Bludiště je vhodné implementovat jako třídu TBludiste, jejíž stěžejní datová struktura bude dynamické pole položek typu TPolicko obsahujících informaci o zdech ohraničujících dané políčko. Bludiště vytvořte pomocí konstruktoru Create, který dostane jako parametry právě rozměry bludiště. Rozměry dynamického pole se nastavují pomocí funkce SetLength (NázevPole, Rozměr1 [, Rozměr2, ...]). Pozor na okrajové části, bludiště musí být uzavřené! V implementaci doprovodného programu využijte komponentu TDrawGrid (kreslicí mřížka). Ta obsahuje událost OnDrawCell, která je vyvolána pokaždé, když se překresluje políčko mřížky. Parametry předávané metodě obsluhující tuto událost pak umožní velice přesně a efektivně bludiště nakreslit. Pomocí parametrů Col a Row udávajících souřadnice právě vybrané buňky a reakce na událost OnSelect, která nastane pokaždé, když uživatel označí (myší či klávesnicí) některou buňku, lze nastavením hodnoty CanSelect regulovat procházení mřížky. Použitý algoritmus: Při implementaci tohoto příkladu bylo použito algoritmu postupného probourávání zcela zazděného bludiště. Zpočátku vybíráme náhodná sousední políčka, která propojujeme. Každé políčko uchovává „číslo oblasti“, které je na začátku pro každé políčko jedinečné. Probouráním zdi mezi dvěma sousedními políčky dojde ke spojení oblastí a v jedné z oblastí je tak potřeba všechna políčka přečíslovat. Tímto mechanismem je zajištěno, že políčka se stejným číslem jsou propojená. Pokud navíc nebudeme probourávat stěny mezi políčky se stejným číslem oblasti, máme jistotu, že tato políčka jsou propojená právě jednou cestou tak, jak požaduje zadání. Protože spojování náhodně vybraných políček je od určité doby značně neefektivní, přejde program na systematický průchod bludiště, v němž propojí to, co doposud propojeno nebylo. Třída TPolicko obsahuje převedším vlastnosti ZedNahore a ZedVlevo, které jsou typu Boolean a určují, zda je nahoře, resp. vlevo políčko zazděné. Je - 59 -
Příloha: Další příklady zřejmé, že vlastnosti ZedVpravo a ZedDole by byly redundantní, neboť tyto vlastnosti plynou z hodnot patřičných vlastností sousedních políček (pravý a spodní okraj bludiště je ošetřen zvlášť). Možná rozšíření: Libovolná počítačová hra založená na bludišti. Fantazii se meze nekladou.
Příklad CloseMe
Procvičované znalosti: Vlastnost Visible. Událost OnMouseMove. Zadání: Napište program, jehož okno bude obsahovat tlačítko „Zavřít“, při jehož stisku se program ukončí. Poté program upravte tak, aby kdykoliv se uživatel přiblíží kurzorem myši k zavíracímu tlačítko, toto tlačítko zmizelo. Poznámky: Komponenta TButton obsahuje vlastnost Visible, jejímž nastavením na hodnotu False se komponenta stane neviditelnou. Opětovným nastavením na True je komponenta opět zviditelněna. Nastavování provádějte v metodě obsluhující událost OnMouseMove hlavního formuláře, která dostane jako parametry souřadnice kurzoru myši. Tyto souřadnice porovnávejte s hodnotami vlastností Left, Top, Width a Height komponenty TButton. Metodu, která skryje tlačítko, je vhodné napojit i na událost OnMouseMove tlačítka, neboť v případě, že uživatel pohne myší hodně rychle, systém nestihne generovat událost OnMouseMove nad každým bodem pohybu kurzoru a mohlo by se stát, že kurzor myši dorazí nad tlačítko dříve, než jej stihnete skrýt. Možná rozšíření: Formulář může zavíracích tlačítek obsahovat více. Dále lze program upravit tak, aby nebylo možné jej ukončit stiskem systémového zavíracího tlačítka v titulku (využijte událost OnCloseQuery).
Příklad CloseMe2
Procvičované znalosti: Událost OnMouseMove. Změna vlastností komponenty za běhu programu. Zadání: Napište program, jehož okno bude obsahovat tlačítko zavřít podobně jako v příkladu CloseMe. Rozdíl oproti příkladu CloseMe bude spočívat v tom, že pokaždé, když se uživatel kurzorem myši přiblíží k tlačítku, tlačítko se posune tak, aby se k němu uživatel nedostal. Poznámky: V metodě obsluhující událost OnMouseMove hlavního okna, která dostane jako parametry aktuální pozici kurzoru myši, nastavujte vlastnosti Top a Left tlačítka. Pozor na to, aby uživatel nemohl vytlačit tlačítko z plochy formuláře. Možná rozšíření: Opět lze umístit na formulář více zavíracích tlačítek nebo zabránit zavírání okna systémovým tlačítkem. - 60 -
Příloha: Další příklady
Příklad Complex
Procvičované znalosti: Jednotka VarCmplx. Počítání s komplexními čísly. Dlouhodobý projekt. Zadání: Napište program, který pomocí editačního řádku načte komplexní číslo v algebraickém tvaru a vypíše jeho absolutní hodnotu a argument. Program poté rozšiřte o možnost zadání druhého komplexního čísla a provedení uživatelem zvolené operace (sčítání, odčítání, násobení, dělení). Poznámky: K implementaci použijte funkce z jednotky VarCmplx, která umožňuje implementovat komplexní čísla v rámci datového typu Variant. Základní konstruktor komplexního čísla je funkce VarComplexCreate, která dostává jako parametr textový řetězec tvaru a+bi a vrací hodnotu typu Variant. Na takto utvořená komplexní čísla lze pak aplikovat standardní operátory +,–,*,/ funkce VarComplexAbs a VarComplexAngle, které zjišťují absolutní hodnotu a argument. Možná rozšíření: Kalkulačka v komplexním oboru
Příklad Editor3
Procvičované znalosti: Jednotka ClipBrd. Práce se schránkou. Dlouhodobý projekt. Zadání: Rozšiřte program Editor2 o možnost použití schránky (Clipboardu), a to jak pomocí klávesových zkratek, tak pomocí menu a nástrojového pruhu.
- 61 -
Příloha: Další příklady Poznámky: Do klausule uses je třeba přidat jednotku ClipBrd. Tím se nám zpřístupní globální objekt ClipBoard, který obsahuje metodu HasFormat, která jako parametr obdrží formát schránky (v našem případě to bude konstanta CF_TEXT) a vrací True nebo False podle toho, zda jsou data ve schránce zadaného formátu. Komponenta TMemo obsahuje vlastnost SelLength, která udává délku označeného textu (délka je nulová, jestliže není označen žádný text). Kopírovat nebo vyříznout text do schránky je možné jen tehdy, je-li nějaký vybrán (SelLength <> 0). Vkládat ze schránky je možné jen tehdy, jsou-li v ní data správného formátu. Proto je potřeba zakázat a povolit ty správné položky v menu Úpravy. Nejlepším místem, kde to lze udělat, je metoda napojená na událost OnClick položky menu Úpravy, tedy okamžik, kdy je rozvinuto menu Úpravy. V případě tlačítek na nástrojové liště je třeba reagovat na události TForm.OnActivate (jiná aplikace mohla umístit do schránky textová data) a TMemo.OnMouseUp a OnKeyUp (uživatel mohl označit text myší nebo klávesnicí). Možná rozšíření: Vyhledávání v dokumentu. Tisk dokumentu.
Příklad Hádej Procvičované znalosti: Komponenty TSpinEdit, TButton, TLabel. Zadání: Napište program, který vygeneruje náhodné číslo od 1 do 100 a poté nechá uživatele hádat. Po každém pokusu vypíše, zda uživatelem zvolené číslo je větší či menší než vygenerované, anebo že se uživatel trefil. Poznámky: Uživatelovu sázku je možné implementovat pomocí komponenty TSpinEdit, která má vlastnost Value, z níž můžeme přímo přečíst požadovanou hodnotu bez nutnosti převádění textu na číslo a ošetřování výjimek. K zobrazení informace o úspěšnosti uživatelova pokusu použijte komponentu TLabel, u níž budete nastavovat vlastnost Caption. Možná rozšíření: Upravte program tak, aby počítal uživatelovy pokusy a počet pokusů zobrazoval. Dále můžete program upravit tak, aby bylo možné zadat rozsah generovaných čísel.
Příklad Jednotky2 (Převody jednotek)
- 62 -
Příloha: Další příklady Procvičované znalosti: Komponenty TRadioGroup, TGroupBox, TLabel, TEdit. Datový typ Extended. Legenda: Každý si jistě vzpomíná na záludné otázky základoškolské fyziky typu: Kolik milimetrů čtverečních je na ploše 3,256 dm2? Nebo: Kolik hektolitrů má 1 kilometr krychlový? A podobně. Částečné řešení pro ty, kteří již jednotky převádět umí, pouze je to obtěžuje a nechtějí dělat zbytečné chyby, představuje následující příklad, který lze rozšířit tak, aby poskytl odpověď i na výše uvedené otázky. Zadání: Napište program, který spočítá, jakým číslem je potřeba násobit při převádění jednotek. Dále hodnotu zadanou v jedněch jednotkách převede do druhých jednotek. Pro zadávání jednotek použijte dva stejné seznamy předpon (podobné jako v příkladu Jednotky). Poznámky: Protože některá čísla jsou velmi malá a jiná velmi velká, je potřeba použít datový typ Extended, který svým rozsahem pokrývá všechny možné hodnoty. Možná rozšíření: Rozšiřte příklad o mocniny jednotek (tj. např. o plošné a objemové jednotky). Dále je možné program rozšířit o převody mezi různými jednotkami, které se používají k vyjádření hodnoty téže veličiny. Například se jedná o převod stupňů na radiány či převody teploty mezi °C, °F a K. Dále lze program rozšířit o propočty známých fyzikálních závislostí, např. mezi tlakem a nadmořskou výškou.
Příklad Jednotky3 (Převody jednotek informací)
Procvičované znalosti: Komponenty TRadioGroup, TGroupBox, TLabel, TEdit. Datový typ Extended. Jednotky informací. Legenda: To, že 1 byte má 8 bitů, ví každý. Hůře jsme na to s odpovědí na otázky typu „Za jak dlouho si stáhnu obrázek, který má 1MB přes modem, který komunikuje rychlostí 56Kb/s? Zadání: Napište program, který bude převádět mezi bity a byty a jejich násobky. Poznámky: K určení násobku i k určení toho, zda se jedná o bit nebo byte použijte komponentu TRadioGroup. Do komponenty TLabel zapisujte převodní vztah a k vlastnímu převodu jednotek použijte komponenty TEdit. Možná rozšíření: Rozšiřte program o možnost zadávat přenosovou rychlost a počítat čas přenosu zadaného objemu dat nebo přenesený objem dat v zadaném čase. Program by tak měl umět dát odpověď na otázky nastolené v legendě.
Příklad Jméno2 Procvičované znalosti: Komponenty TEdit, TButton. Reakce na stisk tlačítka. Manipulace s řetězci. Funkce ShowMessage. Volitelně komponenta TRadioButton. - 63 -
Příloha: Další příklady Zadání: Upravte program Jméno tak, aby jméno nevypisoval na štítek, ale zobrazil jej v novém dialogovém okně. Poznámky: Dialogové okno se vyvolává pomocí procedury ShowMessage, která jako jediný parametr dostává textový řetězec, který se má v okně vypsat. Možná rozšíření: Opět lze, stejně jako v příkladě Jméno, přidat titul před jménem a za jménem, nebo přezdívku ve volitelném formátu.
Příklad Kalkulačka2 Procvičované znalosti: Manipulace s řetězci. Dlouhodobý projekt. Zadání: Rozšiřte program Kalkulačka tak, aby obsahoval tlačítka s čísly 0 až 9 a desetinnou čárkou. Tato tlačítka budou plnit očekávatelnou funkci: Budou přidávat daný znak k řetězci na displeji. Dále přidejte funkci odmocnina (sqrt) a rozšiřte kalkulačku o paměť. Poznámky: Je nutné ošetřit levostranné nuly. Jedna levostranná nula je naopak žádoucí u čísel tvaru 0,xxx. Možná rozšíření: Inspirujte se svoji kalkulačkou nebo vědeckou kalkulačkou systému Windows. Lze tedy přidat zejména goniometrické a cyklometrické funkce, exponenciální a logaritmické funkce, konstanty e a π či závorky.
Příklad Matice
Procvičované znalosti: OOP. Operace s maticemi. Komponenty TStringGrid, TButton, TRadioGroup, TGroupBox, TEdit. Dynamická pole. Dlouhodobý projekt. Zadání: Implementujte jednotku pro operace nad maticemi. Třída TMatice bude obsahovat konstruktor, který matici zadaných rozměrů vytvoří, dále bude obsahovat dynamické pole pro uchování hodnot a metody pro transponování matice, převod na schodovitý tvar, výpočet determinantu a výpočet inverzní matice. Do jednotky dále přidejte funkce pro sčítání, odčítání a násobení matic. Dále předpokládejte, že data budete získávat z řetězcové mřížky - 64 -
Příloha: Další příklady (TStringGrid), do níž je budete i ukládat. Proto napište metody pro převod obsahu mřížky na matici a zpět. Pozor na ošetření výjimek! Dále napište program, který bude používat vytvořenou jednotku a demonstrovat její funkčnost. Jedná se tedy o jakousi maticovou kalkulačku. Uživatel bude moci zadat dvě matice a provést s nimi některou z operací, vypočítat determinant, inverzní matici, transponovat matici nebo převést matici na schodovitý tvar. Zároveň je vhodné, aby program umožnil použít výslednou matici k dalším operacím. Poznámky: Rozměry dynamického pole se nastavují pomocí funkce SetLength (NázevPole, Rozměr1[, Rozměr2, ...]). Rozměry řetězcové mřížky jsou uloženy ve vlastnostech ColCount a RowCount. Samotné řetězce (data v mřížce) jsou uloženy v poli Cells, indexovaném, jako každé dynamické pole, od nuly. Možná rozšíření: Protože počítání s desetinnými čísly je kvůli zaokrouhlování nepřesné, implementujte počítání s racionálními maticemi. Racionální číslo ukládejte jako uspořádanou dvojici čitatel, jmenovatel. Můžete k tomu využít jednotku z příkladu Zlomky.
Příklad Množiny
Procvičované znalosti: Komponenty TListBox, TSpinEdit. Datový typ Set. Dlouhodobý projekt. Zadání: Implementujte množinovou kalkulačku. Bude se jednat o program umožňující definovat dvě množiny (tj. přidávat do nich prvky a také je odebírat), porovnávat je a provádět s nimi standardní množinové operace (sjednocení, průnik, rozdíl). Pro jednoduchost pracujte s množinami čísel (Set of Byte). Poznámky: K uchovávání dat v množinách použijte datový typ množina (Set). Prvky množiny mohou být jen data ordinálního typu a množina nesmí mít více než 256 prvků. Na množiny lze aplikovat operátory + (sjednocení), * (průnik) a – (rozdíl). Přítomnost prvku v množině lze testovat klíčovým slovem in. Možná rozšíření: Program rozšiřte o možnost testování, zda zadané číslo je prvkem množiny. Dále naprogramujte funkci na zjištění počtu prvků množiny.
Příklad Mobil Procvičované znalosti: Komponenty TMemo, TTimer, TButton, TLabel. Reakce na různé události. Parametr Sender. Vlastnost Tag. Vlastnosti komponenty TMemo. Dlouhodobý projekt. Legenda: Téměř každý si už jistě vyzkoušet psát na mobilním telefonu krátké textové zprávy (tzv. SMSky). Každému tlačítku mobilního telefonu přísluší více písmen. Když je tlačítko stisknuto několikrát za sebou, vybere se patřičný znak. Pokud se chvíli nic neděje, je zvolený znak vybrán definitivně a kurzor se posune na následující pozici. Totéž se stane v případě, že je - 65 -
Příloha: Další příklady stisknuto jiné tlačítko. Protože se jedná o poměrně zajímavý algoritmický problém, stojí zato vyzkoušet si naprogramovat simulátor klávesnice mobilního telefonu. Zadání: Napište simulátor klávesnice mobilního telefonu při psaní krátkých textových zpráv. Implementujte také možnost zadávat velká písmena, malá písmena a čísla. Nezapomeňte na interpunkční znaménka a další speciální znaky. Poznámky: To, zda bylo stisknuto stejné tlačítko jako minule, se dá testovat například pomocí vlastnosti Sender.Tag. Do vlastnosti Tag se dá uložit jakákoliv čtyřbajtová informace (integer, ukazatel,…). V komponentě TMemo lze při vhodném nastavení vlastností použít místo standardního seznamu řetězců Lines vlastnost Text. Vhodné nastavení se týká zejména zalamování řádků. Kurzor se v komponentě TMemo zobrazuje jen tehdy, má-li zaměření. Po stisku tlačítka je tedy vždy třeba zavolat metodu TMemo.SetFocus. Při implementaci vlastnosti, že po chvíli od stisknutí tlačítka je kurzor přesunut na následující pozici, využijete (jak jinak) komponentu TTimer. V tomto případě se namísto neustálého zakazování a povolování časovače (vlastnost Enabled) jeví jako vhodnější nechat časovač stále povolený a při každé události OnTimer snížit virtuální odpočet o 1. Při stisku tlačítka pak lze tento virtuální odpočet nastavit na nějakou definovanou hodnotu. Přesun kurzoru a potvrzení stávajícího znaku se pak provede ve chvíli, kdy odpočet dosáhne nuly. Jen je třeba ošetřit jednu drobnost, a sice zamezit tomu, aby se kurzor nepřesouval stále dál, pokud se na klávesnici vůbec nesahá. Možná rozšíření: Přidejte tlačítko k vymazání znaku a tlačítka k přesunu kurzoru vlevo a vpravo.
Příklad Obrázky2
- 66 -
Příloha: Další příklady Procvičované znalosti: Komponenta TTabControl. Dlouhodobý projekt. Zadání: Upravte program Obrázky tak, aby bylo možno otevřít více obrázků zároveň. Otevřené obrázky budou dostupné přes záložky v horní části pracovní plochy okna. Poznámky: Možnost otevřít více obrázků najednou má na starosti vlastnost AllowMultipleSelect komponenty TOpenDialog/TOpenPictureDialog. Záložky jsou realizovány komponentou TTabControl, jejíž vlastnost Tabs uchovává pole řetězců s názvy záložek. Při výběru záložky je generována událost OnChange. Metoda obsluhující tuto událost pak musí zajistit překreslení obrázku. Možná rozšíření: Přidejte možnost zavřít obrázek. Nezapomeňte ošetřit krajní možnosti (zavírání posledního obrázku).
Příklad Obrázky3
Procvičované znalosti: MDI aplikace. Dlouhodobý projekt. Zadání: Program Obrázky upravte tak, aby bylo možno otevřít více obrázků a každý se otevřel ve svém vlastním okně, které bude potomkem hlavního okna. Zároveň zajistěte, aby se položka menu Možnosti (roztáhnout na celou plochu okna a zachovat poměr výšky a šířky) vztahovala vždy k právě aktivnímu oknu. Hlavní menu rozšiřte o standardní položky zajišťující uspořádání oken (kaskáda, dlaždice, uspořádání ikon). Poznámky: Je třeba definovat dva formuláře: Jeden typu fsMDIForm a druhý fsMDIChild. Hlavní formulář (MDIForm) bude umět vyvolat otevírací dialog a vytvořit a zrušit okno potomka (MDIChild). Formulář MDIChild bude obsahovat na celé své ploše komponentu TImage pro zobrazení obrázku. Seznam potomků je dostupný v poli MDIChildren. Na právě aktivní okno ukazuje položka ActiveMDIChild. Položka menu Možnosti nebude položka menu hlavního okna, ale bude definována v okně potomka. Menu hlavního okna a menu potomka pak budou automaticky spojeny v jediné menu viditelné v hlavním okně. Správné pořadí položek lze zajistit nastavením hodnot GroupIndex. Možná rozšíření: Přidejte možnost zavřít všechna okna.
- 67 -
Příloha: Další příklady
Příklad RTTI Demo
Procvičované znalosti: RTTI operátory. Parametr Sender. Metoda ClassName. Zadání: Napište program, jehož hlavní okno bude obsahovat množství různých komponent. Když uživatel na některou z nich klikne, objeví se ve štítku její název. Program dále upravte tak, aby kliknutí na komponentu založenou na tlačítku vyvolalo zprávu o tom, že bylo kliknuto na komponentu založenou na tlačítku. Dále zajistěte, aby kliknutí na komponentu založenou na editačním poli zobrazilo v této komponentě nějaký text, např. aktuální datum nebo čas. Poznámky: Jméno komponenty, resp. jméno třídy lze zjistit pomocí metody ClassName parametru Sender (ukazatel na komponentu, která vyvolala událost OnClick). Testování, zda je komponenta nějakého typu, se provádí pomocí operátoru is. Pokud chceme s komponentou pracovat a jsme si jisti, že je nějakého typu a máme k dispozici jen ukazatel obecnějšího typu (parametr Sender), lze jej přetypovat pomocí operátoru as.
Příklad Rychlost Procvičované znalosti: Komponenty TRadioGroup, TLabeledEdit. Vlastnost Enabled. Funkce StrToFloat, FloatToStr. Ošetření výjimek. Legenda: Každý, kdo někam cestuje, chce znát, jak dlouho tam pojede, popřípadě, jak rychle musí jet, aby to stihl v určitém čase. Odpověď na tyto otázky dává následující program. Zadání: Napište program, který ze dvou hodnot z množiny {vzdálenost, čas, rychlost} dopočítá hodnotu třetí. Poznámky: Volbu hodnoty, kterou chceme dopočítávat, realizujte pomocí komponenty TRadioGroup. Zvolená položka je dostupná pomocí vlastnosti ItemIndex. Dbejte na to, aby příslušný editační řádek (kvůli jednoduchému popisu jej realizujte komponentou TLabeledEdit) bylo zakázané (vlastnost Enabled nastavte na False). Pro převod řetězce na číslo použijte funkci StrToFloat. Nezapomeňte ošetřit možný výskyt výjimky EConvertError. Možná rozšíření: Upravte program tak, aby dokázal počítat jak s kilometry za hodinu, tak s metry za sekundu.
- 68 -
Příloha: Další příklady Možné alternativy: Ve fyzice se vyskytuje více veličin, které jsou spolu v jednoduchém vztahu X=Y/Z. Vzpomeňme například na hustotu coby podíl hmotnosti a objemu, Ohmův zákon nebo stavové rovnice ideálního plynu. Místo rychlosti můžete použít některý ze zmíněných zákonů. Zůstaneme-li jen u pohybu a jeho rychlosti, lze program rozšířit tak, aby počítal rovnoměrně zrychlený pohyb, volný pád či šikmý vrh.
Příklad Věty2
Procvičované znalosti: Vlastnosti komponenty TListBox nebo komponenta TCheckListBox. Manipulace s řetězcem. Zadání: Rozšiřte program z příkladu Věty tak, aby umožňoval do věty zahrnout více podmětů. Nezapomeňte jednotlivé podměty oddělovat čárkou a před poslední vložit spojku and. Zároveň myslete na to, že je-li použit jen jeden podmět, je třeba užít sloveso is, v opačném případě are. Poznámky: Jsou dvě možnosti implementace: 1. Pomocí komponenty TCheckListBox, která umožňuje u každé položky zaškrtnout políčko. Zvolené hodnoty jsou pak dostupné v poli Checked, jehož prvky jsou typu Boolean. 2. Nastavit vlastnost MultiSelect komponenty TListBox na hodnotu True. Tím bude uživateli umožněno vybrat v ListBoxu více položek. Jejich seznam pak získáme pomocí pole Selected. Možná rozšíření: Rozšiřte program o možnost přidat jak k podmětu, tak k předmětu přívlastky.
Příklad Videostop Procvičované znalosti: Komponenty TTimer, TLabel, TButton. Legenda: Videostop je prastará televizní hra, ve které bylo úkolem hráčů poznávat ukázky z filmů. Ten, který byl nejlepší, mohl na konci vyhrát některou z věcných cen. To, kterou cenu vyhraje, určovala závěrečná hra, při níž počítač jakoby házel jednou ze tří šestistěnných kostek a na monitoru zobrazoval hodnoty všech tří kostek. Bez hráčova zásahu počítač generoval stále nové a nové kombinace. Hráč mohl kdykoliv házení přerušit stiskem tlačítka. Stisknul-li tlačítko ve chvíli, kdy byly na kostkách dvě stejné hodnoty, byl mu připsán určitý bodový zisk. Stiskl-li tlačítko ve chvíli, kdy nesly všechny tři kostky stejnou hodnotu, byl jeho bodový zisk několikanásobně větší. Po určitém čase se hra zastavila a podle dosaženého skóre byla určena výhra. Zadání: Implementujte hru Videostop. Pro jednoduchost nevykreslujte hrací kostky, ale zobrazujte čísla 1 až 6. Hru neomezujte časem, ale určitým počtem hráčových pokusů. - 69 -
Příloha: Další příklady Poznámky: Soustavné generování nových možností zajistíme pomocí komponenty TTimer, která v určených intervalech generuje událost OnTimer. Metoda obsluhující tuto událost pak bude mít za úkol náhodně vybrat kostku a její novou hodnotu. Tuto hodnotu pak zobrazí. Komponenta TTimer má vlastnost Enabled, která určuje, zda časovač generuje události OnTimer či nikoliv. Nastavením hodnoty False se tedy časovač zastaví. Toho lze využít k chvilkovému přerušení hry, kdy obarvením štítků se stejným číslem oznamujeme hráči výsledek jeho pokusu. Možná rozšíření: Upravte program tak, aby místo zobrazování čísel maloval příslušné stěny šestistěnných kostek. Dále program upravte tak, aby se kostky překreslovaly stále rychleji v závislosti na odehraných pokusech.
Příklad Vlajky
Procvičované znalosti: Komponenty TColorGrid, TPanel, TComboBox. Volitelně typový soubor a dynamická pole. Dlouhodobý projekt. Legenda: Na světě je mnoho států, jejichž vlajka je složená ze tří pruhů, ať už svislých (Francie, Itálie, Rumunsko) či vodorovných (Rusko, Německo, Nizozemsko). Zadání: Napište program, který bude vykreslovat třípruhové vlajky. Okno bude obsahovat komponentu TRadioGroup, ve které bude mít uživatel možnost zvolit orientaci vlajky (vodorovně nebo svisle) a barevnou mřížku, kde si uživatel bude volit barvu. Největší část okna bude zabírat vlastní vlajka o zvolené orientaci. Při kliknutí na některý pruh se tento pruh přebarví barvou zvolenou v mřížce. Dále přidejte Rozbalovací okénko, ve kterém budou názvy zemí s třípruhovými vlajkami. Při zvolení některé země se automaticky nastaví orientace pruhů a jejich barvy tak, aby vznikla vlajka dané země.
- 70 -
Příloha: Další příklady Poznámky: Barevnou mřížku realizujte pomocí komponenty TColorGrid. Vlajku je vhodné (nikoliv však nutné) implementovat jako tři komponenty TPanel. Při změně orientace se tak pouze změní pozice a velikost panelů, zatímco s barvami, které jsou vlastností jednotlivých panelů, nebude třeba manipulovat. Jednotlivé země ukládejte do záznamu, jehož položky budou název země, orientace vlajky a tři barvy. Komponenta TComboBox generuje při zvolení některé z položek událost OnChange. Zvolená položka je zjistitelná pomocí vlastnosti ItemIndex. Možná rozšíření: Umožněte uživateli přidávat do rozbalovacího okna další země. Informace o vlajkách ukládejte do typového souboru, ze kterého je po spuštění programu (událost OnCreate hlavního okna) načítejte.
Příklad Zlomky Procvičované znalosti: OOP. Komponenty TSpinEdit a TButton. Zadání: Napište jednotku, která implementuje třídu pro práci se zlomky. Tj. bude ukládat zlomek jako čitatele a jmenovatele, bude umět převést zlomek do základního tvaru, sčítat, odčítat, násobit a dělit zlomky. Dále napište program, který tuto jednotku využije pro zlomkovou kalkulačku. Program bude načítat zlomky pomocí spin editů a provádět s nimi požadované operace. Poznámky: K převádění zlomků do základního tvaru využijte Euklidův algoritmus pro hledání největšího společného dělitele. Možná rozšíření: Napište metodu, která převede zlomek na desetinné číslo a naopak. Ošetřete periodické rozvoje.
- 71 -