• No results found

Chtěl bych zde poděkovat všem, kteří neváhali, a věnovali mi svůj čas, když jsemse potřeboval poradit, když jsem potřeboval podpořit, či si jen odpočinout v jejichspolečnosti. Díky. Poděkování

N/A
N/A
Protected

Academic year: 2022

Share "Chtěl bych zde poděkovat všem, kteří neváhali, a věnovali mi svůj čas, když jsemse potřeboval poradit, když jsem potřeboval podpořit, či si jen odpočinout v jejichspolečnosti. Díky. Poděkování"

Copied!
45
0
0

Loading.... (view fulltext now)

Full text

(1)
(2)
(3)
(4)
(5)

Chtěl bych zde poděkovat všem, kteří neváhali, a věnovali mi svůj čas, když jsem se potřeboval poradit, když jsem potřeboval podpořit, či si jen odpočinout v jejich společnosti.

Díky.

Poděkování

(6)

Abstrakt:

Tato práce popisuje proces rozšíření funkčnosti existujícího prototypu výukové aplikace „Slacker Memo“. Tento proces zahrnuje analýzu stávajícího zdrojového kódu, jeho případnou restrukturalizaci s ohledem na plánovaná rozšíření a imple- mentaci těchto rozšíření. Práce také popisuje neočekávané problémy, které při práci nastaly.

Klíčová slova:

výuková aplikace, opakování s prodlevami, rozšíření, C#

Annotation:

This thesis describes process of extending functionality of educational application called „Slacker Memo“. This process includes analysis of existing code, its appropriate restructuralization with planned improvements in mind and implementation of these improvements. Thesis also describes not so obvious problems, which occured during work.

Keywords:

educational application, spaced repetition, improvements, C#

(7)

Obsah

1.Úvod...7

2.Teoretická část...8

2.1.Analýza funkčnosti stávající aplikace...8

2.2.Rozšíření stávajícího programu...9

2.3.Přehled existujících řešení...10

2.4.Architektura prototypu programu...16

3.Praktická část...20

3.1.Změny architektury programu...20

3.2.Implementace v jazyce C#...27

3.3.Problémy při realizaci práce...31

4.Závěr...36

5.Seznam použitých zdrojů...37

6.Seznam ilustrací...37

7.Seznam ukázek kódu...37

8.Přílohy...38

(8)

1. Úvod

Již dříve jsem si všiml, že poměrně velkou část času, stráveného na počítači, se věnuji věcem, které jsou relativně náročné na čas, ale nenáročné na soustředění.

Zajímalo mne, zda by se nedalo této skutečnosti nějak využít, například k memorování dat a faktů, která se nedají odvodit, ale je třeba je mít v paměti. K tomuto účelu lze použít techniku učení plánování s prodlevami (spaced repetition), která je často používána na memorování slovíček při výuce cizího jazyka.

Vzhledem k několika mým předchozím pokusům s učením na počítači, které skončily neúspěšně kvůli mé slabé vůli, bylo také jasné, že toto zkoušení musí probíhat automaticky, a musí se, do jisté míry, také vnutit do pozornosti uživatele. V tomto bodě jsem se nechal inspirovat webovou službou Grooveshark [1], která zobrazovala neregistrovaným uživatelům v pravidelných intervalech malý reklamní dotazník. Tento dotazník se zobrazoval ve formě malého panelu s otázkou, a combo- boxem na výběr odpovědi. Vzhledem k jednoduchosti a nenáročnosti odpovědi, kdy uživateli stačilo myší zvolit odpověď, se mi toto jevilo jako ideální kompromis mezi vtíravostí a jednoduchostí pro účely automatického zkoušení uživatele. Dostatečně vtíravé na to, aby upoutalo uživatelovu pozornost (i přes onu zmiňovanou slabou vůli), a dostatečně jednoduché na to, aby mohl uživatel ihned odpovědět a vrátit se opět k původní práci.

Toto by měl být hlavní rys mého programu, odlišující ho od jiných výukových programů. V rámci bakalářského projektu jsem vypracoval prototyp programu, umožňující práci s jednoduchými textovými otázkami, a požádal několik přátel, aby zkusili program nějakou dobu používat a poté mi sdělit své dojmy a připomínky.

Ukázalo se, že většina z nich by podobný program ocenila, zejména během studia na střední, či vysoké škole. To mě utvrdilo v přesvědčení, že má cenu pokračovat ve vývoji programu a zahrnout do něj některá z navrhovaných rozšíření.

7

(9)

2. Teoretická část

2.1. Analýza funkčnosti stávající aplikace

Základním prvkem v programu je otázka. Ke každé otázce musí být uvedena právě jedna správná odpověď. Volitelně je možné doplnit k otázce nápovědu, a 5 alternativ odpovědi (chybné odpovědi pro zobrazení během zkoušení v režimu volby). Dále pak každá otázka obsahuje údaje o úspěšnosti odpovědí a údaj o tom, zda je otázka aktivní, či neaktivní. Neaktivní otázky nejsou při zkoušení zobrazovány.

Otázky jsou obsaženy v sadách ,které umožní vytvoření tématicky zaměřených sad otázek. Sady se ukládají na disk pomocí binární serializace. Pro samotné zkoušení uživatel vytvoří zkušební plán, ve kterém bude definováno, z jakých sad se budou klást otázky, podle jakého algoritmu se bude losovat následující otázka, a jakým způsobem se bude na otázky odpovídat. Zkušební plán může být vytvořen buď jednorázově, kdy je po ukončení zkoušení odstraněn z paměti , nebo ho lze pomocí serializace uložit na disk, odkud může být zpětně načten pro opakované zkoušení.

Program funguje ve dvou režimech. Prvním je režim administrace, ve kterém uživatel vytváří, upravuje či odstraňuje otázky, sady otázek a zkušební plány. V tomto režimu program funguje jako klasická desktopová aplikace s grafickým rozhraním, tvořeným jedním hlavním formulářem, jehož obsah se mění v závislosti na požadovaných akcích. Druhým režimem je režim zkoušení, kdy je aplikace reprezentována pouze ikonou v oznamovací oblasti hlavního panelu a hlavní formulář je skrytý. Během tohoto režimu je uživatel upozorňován na otázky, kladené programem, pomocí informačních bublin. V závislosti na uživatelském nastavení je nová otázka doprovázena také zvukovým upozorněním. Samotný formulář s otázkou se zobrazí teprve po kliknutí na bublinu. Z ikony je dostupné také hlavní menu programu, a to po kliknutí pravým tlačítkem myši na ikonu.

(10)

2.2. Rozšíření stávajícího programu

Jak jsem již zmínil, od přátel jež jsem požádal o testování aplikace jsem obdržel také několik připomínek a nápadů na vylepšení stávající verze programu. Mezi nejčastěji zmiňované úpravy programu patřily tyto návrhy:

• Možnost vkládání multimédií do otázek

• Snadnější vytváření alternativ k odpovědím

• Výslovnost u slovíček cizího jazyka

• Rychlé opakování špatně zodpovězených otázek

• Distribuování hotových sad otázek s programem, aby se uživatel nemusel namáhat s jejich vytvářením

První návrh byl celkem logickým vyústěním limitace čistě textových otázek. Roz- hodl jsem se tedy zahrnout do programu možnost přidat k otázce obrázky a krátké zvukové klipy. Druhý návrh se týkal možnosti ke každé otázce zadat i několik ne- správných možností odpovědí, mezi kterými musí uživatel zvolit odpověď správnou.

Uživatelům se líbila možnost výběru správné odpovědi, ale nechtělo se jim většinou zadávat ony alternativy. Tento problém jsem se rozhodl částečně řešit možností gene- rovat alternativy k odpovědi ze správných odpovědí ostatních otázek. Toto by mělo snížit pracnost tvorby sad otázek, ale pouze za předpokladu, že se v sadě nenachází duplicitní otázky. Třetí návrh je, vzhledem k jednomu z předpokládaných použití – učení cizích slovíček, celkem logický, ale implementace se mi jeví jako problema- tická. Došel jsem k názoru, že jsou možné dva způsoby realizace: Uživatel si sám ob- stará zvukové klipy s výslovností, které přiloží k otázce, nebo budou zvukové klipy získávány z webových služeb (např. Google překladač). První způsob je obtížný pro uživatele, druhý může narazit na omezení bezplatných účtů, či změnu API dané služ- by a je využitelný pouze on-line. Poslední návrh jsem uvedl spíše jako příklad po- někud utopických přání uživatelů. Opravdu není v mých silách vytvořit zrovna takové sady otázek, které si uživatel přeje, nehledě na to, že účinnost učení se používáním hotových cizích sad snižuje. Chtěl bych ale s programem distribuovat testovací sadu/sady na demonstraci možností programu. Vzhledem k zaměření programu na

9

(11)

„línější“ uživatele jsem se ještě rozhodl vytvořit typ otázky, zaměřený přímo na výu- ku cizích slovíček, kde by program měl umožňovat záměnu směru překladu (např. z angličtiny do češtiny, či naopak), která by ušetřila práci při vytváření sad slovíček.

2.3. Přehled existujících řešení

Po vytvoření seznamu rozšíření, která bych chtěl do programu zahrnout jsem už měl poměrně jasno, jak by měla hotová aplikace vypadat. Rozhodl jsem se tedy ještě jednou prozkoumat již existující řešení, abych neprogramoval něco, co již existuje.

Mezi existujícími programy najdeme zástupce jak klasických desktopových aplikací (např. SuperMemo, Anki, Mnemosyne), tak webové služby (např. Memrise, Quizlet, Brainscape), které se, hlavně s rozmachem „chytrých“ mobilních zařízení, stávají čím dál více populární. Dalším kritériem může být, zda se jedná o programy/služby placené (SuperMemo, AnkiApp), či volně dostupné (Anki, Mnemosyne, Memrise).

Vzhledem k plánovanému použití mého programu, ze kterého vyplývá, že aplikace bude stále spuštěna na pozadí ostatní uživatelovy práce, jsem z přehledu vynechal webové služby, které se mi zdály nevhodné z důvodů nutnosti stálého připojení k internetu a omezených možností upozornění uživatele na novou otázku. Dále jsem také vynechal placené programy/služby, a do přehledu zařadil pouze volně dostupné desktopové programy.

Z tohoto krátkého přehledu lze především zjistit, že prakticky všechny programy vyždaují aktivní účast uživatele, v tom smyslu, že si uživatel musí každý den program spustit a vyhradit si čas jen a pouze na zkoušení. Toto je s největší pravděpodobností zapříčiněno tím, že tento přístup víceméně znamená odklon od běžně používaného systému metody učení plánovaného učení s prodlevami, což může vyústit v méně efektivní způsob učení. Většina programů tedy používá nějakou formu Leitnerova systému [5], kdy uživatel sám hodnotí míru znalosti dané otázky jednou z pěti hodnot, a tím určí, jak se bude měnit doba příštího vytažení otázky (dobrá znalost interval prodlouží, zatímco špatná znalost působí opačně). Zkoušení souběžně s jinou prací umožňoval pouze program EasyWords, jehož kvalita je ale bohužel dostačující pouze na velmi nenáročné použití. Z tohoto důvodu si (i přes vyšší riziko méně

(12)

efektivního zkoušení) myslím, že vytvoření nového programu má smysl. Znovu je ale třeba připomenout, že mnou tvořený program si neklade za cíl konkurovat existujícím řešením (zde mám na mysli zejména program Anki, které je stále aktivně vyvíjen, má širokou uživatelskou základnu a působí nejprofesionálnějším dojmem), protože je vytvářen s odlišnou myšlenkou a pro jinou skupinu uživatelů než tyto programy.

11

(13)

a) EasyWords

Jednoduchý program, zaměřený pouze na výuku slovíček. Obsahuje několik již hotových sad slovíček v různých jazycích. Poskytuje jednoduchý editor k vytváření vlastních sad, ale neumožňuje například editovat již vytvořenou otázku. Otázky jsou čistě textové, bez možnosti vkládat multimédia. Umožňuje nastavit interval, jak často budou otázky zobrazovány, a zvolit způsob odpovídání na otázky (přesná odpověď, či výběr z možností). Možnosti jsou automaticky generované z ostatních slov v sadě. Při zkoušení náhodně volí směr překladu. Obsahuje také „non-stop“ režim pro rychlé zkoušení, kdy je následující otázka zobrazena hned po zodpovězení otázky předchozí, a možnost pozastavení zkoušení. Podle slov autora program využívá algoritmus pro přednostní zobrazování otázek s nižší úspěšností správné odpovědi, a algoritmus, vybírající možnosti podle podobnosti se správnou odpovědí, ale přesnější informace o těchto algoritmech chybí. Během zkoušení je program skryt a komunikace s uživatelem probíhá přes ikonu v oznamovací oblasti.

• jednoduché rozhranní, zkoušení probíhá souběžně s prací uživatele, automatická tvorba možností a střídání směru překladu

• málo funkcí

(14)

b) FullRecall

Pokročilý program, využívající Leitnerův systém (uživatel si po přečtení otázky nechá zobrazit odpověď a ohodnotí, jak bylo obtížné si ji vybavit) umožňující vkládání obrázků, zvuků, či webových odkazů. U těchto multimediálních příloh lze zvolit, zda se mají při vytvoření otázky kopírovat do databáze programu, či zda se má do otázky vložit pouze odkaz na zvolený soubor. Uživatel má k dispozici několik ukázkových sad, editor pro vytváření vlastních otázek a možnost importu z textových souborů. U otázek lze snadno určit vzhled písma a také zda budou obousměrné (záměna otázky a odpovědi). Zajímavá je funkce nápovědy, která po každém kliknutí na tlačítko odkryje jedno písmeno z odpovědi. K dispozici je velké množství nastavení od vzhledu programu po nastavení algoritmu, kterými lze program individuálně přizpůsobit. Toto, spolu s mírně nepřehledným uživatelským rozhraním, bohužel přispívá k nepříliš přívětivému ovládání, zejména pro začátečníky. Mezi dalšími funkcemi jsou také statistiky celých sad, jednotlivých otázek, možnost vyhledat duplicity v sadách, a také režim vynuceného zkoušení, nehledě na interval vypočtený algoritmem.

• možnosti nastavení, škálovatelné uživatelské rozhraní

• místy nepřehledné a složité

13

(15)

c) Mnemosyne

Program obsahuje všechny základní funkce jako možnost vkládání multimédií do otázek, editor otázek, možnost importu a exportu otázek a zobrazení statistiky.

Základní instalace neobsahuje hotové zkušební sady, ale sady, vytvořené ostatními uživateli, jsou dostupné na webové stránce programu. Z pokročilých možností program obsahuje označení otázek štítky (tagy), vyhledávání duplikátů, vyhledávání nepoužitých multimediálních příloh, dočasné vyřazení otázek ze zkoušení, rozšíření funkcí programu pomocí zásuvných modulů (např. Nárazové non-stop zkoušení, které neovlivní dlouhodobé statistiky), synchronizaci s dalším zařízením a web server pro zkoušení přes webový prohlížeč. Možnosti nastavení jsou omezenější než u programu FullRecall (ale dostatečné) a program je díky tomu jednodušší na ovládání. Grafické rozhraní je přehlednější než u výše zmíněného programu, ale vkládání multimédií je poměrně neintuitivní, a zobrazování otázek trpí několika chybami (obrázek vložený v otázce se vždy zobrazí v plné velikosti, zvuk u otázky se přehrává i poté, co je okno s otázkou zavřeno).

• přehledné škálovatelné rozhraní, snadné nastavení, pokročilé funkce

• problematické zobrazení otázek s vloženými multimédii

(16)

d) Anki

Anki je zřejmě nejpropracovanější programem z výběru. Tento fakt je s největší pravděpodobností také důsledkem toho, že autor má tvorbu programu a zpoplatněné verze pro iPhone jako hlavní zaměstnání. Ze základních funkcí poskytuje možnost vytváření otázek s vloženými multimédii, vytváření otázek „doplňovaček“ (tzv.

Cloze deletion), automatického vytváření reverzních otázek, označování otázek štítky, tvorby šablon pro vzhled otázek, import a export sad, detailní statistiky a zkoušení mimo studijní plán. Dále umožňuje kontrolu duplicit a nepoužitých multimediálních příloh, synchronizaci sad na webový server a rozšíření funkcionality pomocí zásuvných modulů. Hotové sady otázek i zásuvné moduly lze získat z webové stránky programu. Grafické rozhraní je, až na výjimky, přehledné, možnosti nastavení jsou někde mezi Mnemosyne a FullRecall, kdy si uživatel může nastavit prakticky všechny potřebné věci, bez toho, aby ovládání programu bylo příliš komplikované.

• přehledné škálovatelné rozhraní, pokročilé funkce

15

(17)

2.4. Architektura prototypu programu

Tato kapitola obsahuje stručný, zjednodušený popis jednotlivých tříd, tvořících jádro prototypu programu, a vazeb mezi nimi. Tento popis zmiňuje pouze nejdůležitější atributy a funkce tříd, nutné k orientaci v architektuře prototypu, která je použita jako základ pro rozšíření programu.

Třída Question

Třída reprezentující základní jednotku dat v programu. Textové Atributy Otázka a Odpověď jsou povinné, Alternativy a Nápověda jsou volitelné. Atribut Úspěšnost obsahuje procentuální úspěšnost odpovědí a atribut Aktivní značí, zda bude otázka zahrnuta do zkoušení. Metoda ZodpovězOtázku slouží k aktualizaci statistických údajů na základě správnosti odpovědi.

Třída QuestionSet

Třída pro sdružování otázek do tématických celků. Atribut Jméno je použit k identifikaci v programu a s tímto názvem je také uložen soubor se sadou. Popis slouží k podrobnějšímu popisu sady pro snažší orientaci. Atribut Sada obsahuje reference na otázky, obsažené v sadě. Dále třída poskytuje metody pro práci se sadou (přidání, smazání, vrácení otázky a vrácení počtu otázek v sadě).

Ilustrace 1: UML entita třídy Question

Ilustrace 2: UML entita třídy QuestionSet

(18)

Třída Questioner

Jedná se o abstraktní třídu, od které jsou odvozeny další třídy, reprezentující rozdílné algoritmy, použité k určení následující otázky.

Atribut Sada obsahuje referenci, udávající, nad kterou sadou otázek bude tento objekt pracovat.

Metoda VraťIndexDalšíOtázky vrací index další otázky, v závislosti na použitém algoritmu. Jedná se o abstraktní metodu, kterou musí přepsat všechny odvozené třídy. V prototypu jsou tyto 4 třídy, implementující 4 různé algoritmy.

QuestionerSimple prochází dokola sekvenčně celou sadu otázek.

QuestionerRepeatingRandom vrací náhodnou otázku z celé sady.

QuestionerNonrepeatingRandom vrací náhodnou otázku z fronty otázek, které nebyly v daném kole zkoušení ještě zodpovězeny. QuestionerUnsuccesfulFirst vrací otázku s nejnižší úspěšností odpovědí.

Třída ExamPlanItem

Tato třída představuje jednotku, ze kterých je složen zkušební plán. Obsahuje sadu otázek společně s parametry zkoušení pro danou sadu.

Atribut VoličOtázky obsahuje referenci na objekt určující následující otázku, a atribut ZpůsobOdpovídání určuje způsob zobrazení formuláře s otázkou. Tato třída je vytvořena tak, aby nebyly ukládány atributy, u kterých by uchování jejich stavu postrádalo smysl, nebo by vedlo k uchovávání redundantních informací. K znovuvytvoření těchto objektů, které nejsou serializovány, dochází v metodě PoDeserializaci.

17

Ilustrace 4: UML entita třídy ExamPlanItem

Ilustrace 3: UML entita třídy Questioner

(19)

Třída ExamPlan

Třída reprezentující objekt zkušebního plánu, vytvořeného uživatelem. Atribut PoložkyPlánu obsahuje reference na objekty ExamPlanItem, zahrnuté do zkoušení.

Položka, ze které se bude načítat aktuální otázka, je určena atributem AktuálníPoložka. Atribut NázevPlánu slouží k identifikaci zkušebního plánu v programu a s tímto názvem je také uložen soubor, obsahující serializovaný plán. Třída poskytuje metody pro práci s obsaženými položkami zkušebního plánu, kde kromě administrace je potřeba také aktualizace úspěšnosti u zodpovězené otázky, a následně serializace a znovunačtení sady, ve které je otázka obsažena. Toto je zajištěno metodou AktualizujStatistikyPoložky.

Ilustrace 5: UML entita třídy ExamPlan

(20)

19

Ilustrace 6: UML class diagram prototypu aplikace

(21)

3. Praktická část

3.1. Změny architektury programu

Nápady na plánovaná rozšíření by se daly rozdělit na skupinu týkající se uživatel- ského rozhraní (v podstatě jen kosmetické změny) a skupinu týkající se jádra progra- mu, jejichž implementace může vyžadovat úpravu architektury programu. Například zavedení multimédií, coby součást otázek, si vyžádá změnu ukládání a práce s uživa- telskými sadami otázek, protože stávající způsob ukládání celé sady otázek do jednoho souboru pomocí binární serializace by mohl vést k neefektivní práci s ope- rační pamětí. Rychlé opakování špatně zodpovězených otázek zase vyžaduje dílčí změny v třídě reprezentující zkušební plán. Celkově bych však řekl, že díky předcho- zímu času, strávenému s návrhem architektury prototypu, nejsou tyto změny tak ve- liké. U změn v rámci bakalářské práce se navíc jedná spíše o změny v jednotlivých prvcích programu, než o změny vzájemných vazeb těchto prvků.

Vzhledem k tomu, že jsem už od začátku práce na projektu počítal s případným rozšířením, snažil jsem se i návrh projektu udělat co nejvíce modulární, umožňující snadnou rozšiřitelnost. Prvním krokem bylo rozdělení projektu na jádro nezávislé na uživatelském rozhraní a odpovídající grafické rozhraní. Dále jsem se snažil přizpůso- bit objektový návrh jádra programu tak, aby byly prvky programu rozděleny podle funkcionality, kterou poskytují a aby byly jasné vazby mezi objekty a jejich místo v programu. Díky tomu by mělo být možné provést změny v programu s minimálním dopadem na ostatní části. Správný objektový návrh programu by měl, v ideálním případě, eliminovat nutnost větších změn ve fázi implementace a umožnit snadné pozdější změny (samozřejmě pouze v případě že se nejedná o radikální změny vyžadující celkovou změnu návrhu), za cenu delší návrhové fáze. I tak je ale možné riziko, že se počáteční návrh ukáže jako nevyhovující a je třeba ho změnit. Tento případ nastal i během mé práce, když jsem se zhruba v půlce práce rozhodl změnit koncepci typů otázek a sad. Naštěstí se potřebné změny promítly prakticky pouze do těchto dvou tříd, a zbytek zůstal beze změny (viz Ilustrace 6 a Ilustrace 7).

Domnívám se, že pravděpodobnost případných chyb v návrhu je nejvíce závislá na zkušenosti vývojáře, a v počátcích se jí nelze úplně vyhnout.

(22)

a) Způsob vkládání multimédií do otázek

Prototyp programu obsahoval pouze textové otázky, nebyl tedy problém ukládat pomocí serializace celou sadu na disk jako jeden soubor, a při běhu programu uchovávat všechny sady, obsažené ve zkušebním plánu v operační paměti tak, jak byly pomocí deserializace načteny. Ovšem v případě rozsáhlejší sady, obsahující například delší zvukové klipy, obrázky ve vyšším rozlišení, či videoklipy, by čas, potřebný k ukládání a načítání sad narůstal, stejně jako paměťové nároky takto navrženého programu.

Jako vhodnější způsob jsem tedy zvolil ukládání multimédií zvlášť do samostatného adresáře, a do otázky je ukládána pouze cesta k obsaženému souboru.

Díky tomu může samotné ukládání sad pomocí serializace zůstat prakticky beze změny. Aby bylo možné hotové sady snadno distribuovat mezi uživateli, rozhodl jsem se, že každá sada bude mít své vlastní úložiště multimédií, v ních obsažených.

Tento způsob sebou ale nese několik dílčích problémů, které je třeba řešit. Za prvé je nutné vyřešit případné kolize názvů již uložených a nově kopírovaných souborů.

Druhým problémem, související spíše s optimalizací, je zamezit ukládání duplicitních souborů, v případě, že bude soubor bude přiložen k více otázkám, a místo toho použít již uložený soubor. Řešit je třeba také situace při přejmenování, přesunutí, či smazání souboru přiloženého k otázce.

Řešením prvních dvou problémů je využití otisku souboru, takzvaného hashe.

Jeho obsažením v názvu souboru zamezíme kolizím při kopírování souborů a porovnáváním otisků již uložených souborů s otiskem nově kopírovaného souboru můžeme odhalit duplicitní soubor. Posledně jmenované problémy lze vyřešit důsledným ošetřením vstupů v kódu, aby v případě problému nedošlo k pádu aplikace.

21

(23)

b) Změny na úrovni otázek a sad otázek

Nejjednodušším řešením, jak implementovat nové funkce na úrovni otázky, je přidání nových atributů a metod do stávající třídy Question. Tento postup má ale již na první pohled zřejmou nevýhodu z hlediska budoucí rozšiřitelnosti. Přidáváním nových metod pro případné další typy otázek by se kód stal záhy nepřehledným, což by snížilo rychlost implementace a zvýšilo pravděpodobnost výskytu chyb. Vzhledem k tomu, že pro různé typy otázek by byly vyžadovány různé atributy, vzrostla by náročnost validace otázek, a také návrh rozhraní pro práci s takovými objekty by byl, vzhledem k množství kombinací vnitřních stavů objektu, složitější. Rozhodl jsem se tedy, že každý typ otázky bude reprezentován samostatnou třídou, takže jejich atributy a metody budou od sebe odděleny. To by mělo umožnit v budoucnu snadno implementovat nový typ otázky, bez výraznějšího nárustu složitosti kódu. Abych omezil opisování základních kusů kódu stále dokola, vytvořil jsem rodičovskou třídu, která obsahuje základní funkce, které musí každá otázka v programu mít, a kterou všechny odvozené typy otázek dědí.

Konkrétně tedy v programu došlo k vytvoření rodičovské třídy Question Basic, a tříd Question Normal, Question Dictionary a Question MediaAnswer.

(24)

Question Basic

Rodičovská třída, reprezentující nezbytné minimum, informací, které musí každá otázka obsahovat. Tato třída v podstatě kopíruje objekt otázky z prototypu aplikace, jedinou výraznější změnou je možnost více správných odpovědí a přizpůsobení výpočtu úspěšnosti odpovědi tomuto faktu.

Question Normal

Třída, odvozená od Question Basic, přidávající možnost přiložení obrázku, či zvukového klipu k otázce.

Question Dictionary

Třída, odvozená od Question Normal, vytvořená pro výuku slovíček. Pro možnost obousměrného překladu přidává atribut uchovávající alternativy i v druhém jazyce.

Pro implementaci strojového překladu jsou zde přítomné atributy určující zdrojový a cílový jazyk.

Question MultimediaAnswer

Třída, odvozená od Question Normal, umožňující odpovídání na otázku výběrem správného multimediálního objektu. V současné době je implementováno použití obrázků a zvukových klipů.

QuestionSet

Třída, reprezentující sadu otázek, zůstala, v podstatě beze změny. Díky využití dědičnosti, kdy všechny otázky mají společného předka, třídu Question Basic, je možné všechny typy otázek ukládat v kolekci tohoto rodičovského typu. Přibyl tedy akorát slovník otisků souborů, přiložených k otázkám v sadě, pro zamezení duplicit, a několik metod pro práci s tímto slovníkem.

23

(25)

c) Změny na úrovni prvků zkušebního plánu a zkušebního plánu

Třída, repezentující prvek zkušebního plánu, prošla podobnými změnami, jako třída představující otázku. Pro snažší implementaci funkcí nových typů otázek byla tato třída rozdělena na rodičovskou třídu, obsahující základní funkce, shodné pro všechny typy otázek, a odvozené třídy pro konkrétní typ otázek. Tyto odvozené třídy pak mohou obsahovat libovolný kód, potřebný k implementaci rozšiřujících funkcí.

Třída zkušebního plánu pak prodělala pouze menší změny kvůli implementaci opakování špatně zodpovězených otázek, limitace zkoušení a volby prvku, ze kterého bude tažena následující otázka.

ExamPlanItem Basic

Základní třída, použitelná pro typ otázek neobsahují žádné speciální funkce, a rodičovská třída pro ostatní odvozené třídy prvků zkušebního plánu. Obsahuje nezbytné minimum funkcí, převzaté z třídy prvku zkušebního plánu obsažené v prototypu aplikace a nově přidanou možnost automatického generování alternativ z odpovědí ostatních otázek v sadě. V současné verzi aplikace je tato třída využita pro vytvoření prvku zkušebního plánu obsahujícího otázky typu Question MultimediaAnswer.

ExamPlanItem Normal

Třída, odvozená od třídy ExamPlanItem Basic, určená pro otázky s textovou odpovědí, obsahující navíc příznak pro ignorování diakritiky u odpovědi. V současné verzi aplikace je tato třída využita pro vytvoření prvku zkušebního plánu obsahujícího otázky typu Question Normal.

(26)

ExamPlanItem Dictionary

Třída, odvozená od třídy ExamPlanItem Normal. Vzhledem k zaměření na slovíčka cizích jazyků obsahuje navíc příznak pro záměnu směru překladu, a překrývá původní metodu na automatické generování alternativ upravenou verzí metody, která generuje alternativy s ohledem na zvolený směr překladu. V současné verzi aplikace je tato třída využita pro vytvoření prvku zkušebního plánu obsahujícího otázky typu Question Dictionary.

Exam Plan

Kvůli funkci opakování špatně zodpovězených otázek byla do třídy přidána fronta pro jejich uchování a pozdější zobrazení. Při volání metody, zajišťující vrácení následující otázky, je pak v pravidelných intervalech zjišťováno, zda jsou ve frontě nějaké otázky, a tyto jsou pak vraceny přednostně. Dále přibyly atributy nastavující nově přidané parametry zkoušení (volba limitace doby zkoušení časem či počtem otázek a přepínání aktivních prvků zkušebního plánu náhodně, po jedné otázce, či po dokončení celé sady). Vzhledem k nárůstu parametrů prvků zkušebního plánu, potřebných ke správnému zobrazení formuláře s otázkou, je kromě samotné otázky vracena také reference na prvek zkušebního plánu, ze kterého je otázka vybrána.

25

(27)

Ilustrace 7: UML class diagram aplikace po implementaci změn v architektuře

(28)

3.2. Implementace v jazyce C#

Samotná implementace architektury v programu C# byla spíše jednotvárnou prací, kdy naprostá většina kódu je, z programátorského hlediska, standardní, ničím nezajímavá. Nastalo ale i několik situací, které si vyžádaly využití zajímavějších postupů. Podobná situace byla i během tvorby grafického rozhraní. Tato kapitola tedy přináší ukázky těchto situací.

a) Přehrávání zvukových klipů u otázek

Pro přehrávání zvuku v prototypu byla použita komponenta frameworku .Net SoundPlayer. Tento jednoduchý nástroj ale nedokáže již pracovat se soubory mp3 či ogg. Vzhledem k plánovaným rozšířením tedy bylo nutné najít jinou alternativu. K přehrávání zvukových klipů tedy byly v aplikaci použity volně dostupné knihovny NAudio a Nvorbis.

Pro přehrání zvuku je nejprve nutné vytvořit instanci objektu, který čte data ze zadaného zvukového souboru a v případě, že se jedná o komprimovaný soubor, provede jejich dekódování. Referenci na tento objekt je pak předána objektu, který zajišťuje přehrávání již dekódovaných dat přes zvolené rozhraní.

27 private IWavePlayer waveOut;

private AudioFileReader audioFileReader;

private NVorbis.NAudioSupport.VorbisWaveReader ogg_reader;

if (System.IO.Path.GetExtension(fileName) == ".ogg") {

ogg_reader =

new Nvorbis.NaudioSupport.VorbisWaveReader(fileName);

waveOut.Init(ogg_reader);

} else {

audioFileReader =

new AudioFileReader(fileName);

waveOut.Init(audioFileReader);

}

waveOut.Play();

Kód 1: Ukázka použití knihovny NAudio

(29)

b) Správa mediálních příloh pomocí slovníku otisků

Kopírování multimédií, přiložených k otázkám, do podadresáře sady ssebou přineslo problém duplicity souborů. Pokud by byly v jedné sadě dvě otázky, se stejnými přiloženými soubory, program by daný soubor kopíroval pokaždé znovu.

Aby se tomuto zabránilo, každa sada obsahuje slovník otisků souborů, které jsou k sadě přiloženy. Otisk souboru je použit jako klíč, a název souboru v podadresáři sady je hodnota. Při vytváření či editaci otázky se tedy nejprve vytvoří otisk média, které má být k otázce přiloženo a následně se program pomocí tohoto otisku pokusí získat ze slovníku název souboru. Pokud uspěje, vloží tuto hodnotu do otázky, a uloží ji do sady. V případě, že slovník otisk neobsahuje, je zvolený soubor zkopírován do podadresáře sady, a do slovníku je přidán příslušný záznam.

static public string GetMD5Hash(string filename) {

MD5 md5_hasher = MD5.Create();

Stream s = null;

try {

s = File.Open(filename, FileMode.Open);

return BitConverter.ToString

(md5_hasher.ComputeHash(s)).Replace("-", "").ToLower();

}

finally {

s.Close();

} }

string hash = GetMD5Hash(filename);

string filename_from_dictionary =

question_set.GetValueFromHashDictionary(hash);

if (filename_from_dictionary != null) return filename_from_dictionary;

else {

File.Copy(filename, storage_path + filename_to_be_copied);

question_set.InsertInHashDictionary(hash, filename_to_be_copied);

return filename_to_be_copied;

}

Kód 2: Ukázka práce se slovníkem otisků

(30)

c) Získávání zvukových klipů s výslovností z Google překladače

Pro tuto funkci jsem využil možnosti internetového překladače Google, který disponuje funcí strojového čtení textu (takzvané tts – text to speech). Pro neregistrované uživatele je délka vstupního textu omezena na 100 znaků, což by ale, vzhledem k plánovanému použití, nemělo představovat probém. Po zaslání HTTP požadavku, obsahujícího text k přečtení a jazyk, který má být ke čtení použit, poskytne překladač jako odezvu data s vygenerovanou výslovností ve formátu mp3.

Tyto data lze uložit na disk, nebo je rovnou z proudu přečíst. V aplikaci je nyní použita první možnost, kvůli problémům se zaseknutím vlákna během čtení dat z proudu, které se zatím nepodařilo vyřešit.

29 text_to_read = Uri.EscapeUriString(text_to_read);

string url =

String.Format("http://translate.google.com/translate_tts?

tl={0}&q={1}", language, text_to_read);

FileStream fileStream = File.Create(filename)) Stream s =

WebRequest.Create(url).GetResponse().GetResponseStream()) byte[] buffer = new byte[32768];

int read;

while ((read = s.Read(buffer, 0, buffer.Length)) > 0) {

fileStream.Write(buffer, 0, read);

}

Kód 3: Získání souboru s vygenerovanou výslovností pomocí Google překladače

(31)

d) Grafické rozhraní

Grafické rozhraní je vytvořeno v knihovně WinForms, která obaluje komponenty Windows API pro snadné použití ve frameworku .Net. Koncept grafického rozhraní jsem převzal v prakticky nezměněné formě z prototypu, kde se mi osvědčil, pro svou jednoduchost a snadnou rozšiřitelnost. Rozhraní je tedy tvořeno jedním hlavním formulářem programu, ve kterém jsou pak zobrazovány pomocné formuláře. Touto cestou lze snadno přidat nový pomocný formulář pro editaci dalšího typu otázky, či jiné funkce programu (například vynucené zkoušení v hlavním okně programu).

Vzhledem k tomu, že prototyp programu byl brán pouze jako prostředek, jak zjistit ohlasy uživatelů na podobný typ aplikace, nebylo grafickému rozhraní věnováno příliš pozornosti. Jedním z témat, kterému jsem nevěnoval žádnou pozornost byla například možnost přizpůsobení velikosti uživatelského rozhraní. Při provádění rešerše existujících programů jsem ale narazil na pouze jediný program, který neměl vyřešenu změnu velikosti uživatelského rozhraní (viz příloha 9). To mě utvrdilo v tom, že je tato vlastnost standardem, jehož ignorováním bych zbytečně snižoval komfort uživatelů aplikace. Proto je rozhraní aplikace navrženo již takovým způsobem, aby se, v rámci možností, všechny formuláře byly schopné přizpůsobit rozměrům okna.

private Form content;

public void SetContent(Form f) {

if (f != null) {

this.content_panel.Controls.Clear();

content = f;

content.TopLevel = false;

content.Show();

this.content_panel.Controls.Add(content);

} }

Kód 4: Metoda pro zobrazení pomocného formuláře uvnitř komponenty Panel

(32)

3.3. Problémy při realizaci práce

V této kapitole bych chtěl zmínit některé neočekávané problémy, které při vývoji aplikace vznikly a které měly dopad na dobu vývoje. Zejména se jedná o takové problémy, jejichž řešení, ač často poměrně jednoduché, nebylo zcela zřejmé. Pokud to problém umožňoval, je u něj také zmíněno možné řešení.

a) Příliš omezující architektura aplikace

Prvním problém nastal při návrhu rozšíření architektury, kdy jsem zpočátku chtěl, v rámci přehlednosti, rozdělit otázky na co nejmenší celky. Ty by obsahovaly prakticky jen povinné informace, bez kterých by daný typ otázky neměl smysl, a naprosté minimum volitelných informací, jako například nápověda, či alternativy. V mém případě by tedy program obsahoval tyto typy otázek: textová otázka, otázka s obrazovou odpovědí, otázka se zvukovou odpovědí a jejich kombinace s přiloženým obrázkem, či zvukem (celkem tedy šest typů otázek, ze kterých by musel uživatel při vytváření vybírat). Toto rozdělení by se dále promítlo také do třídy reprezentující sady otázek, kde by rovněž došlo k rozdělení na sady jednotlivých typů, které obsahovaly pouze daný typ otázek.

To celé by přineslo jednodušší kontrolu dat vytvářené otázky, zda má otázka s takovými daty smysl (Nechybí otázka, nebo odpověď? Není řetězec otázky prázdný, či složen jen z bílých znaků? Není řětězec odpovědi u textového typu otázky také prázdný, či neobsahuje pouze bílé znaky? Nechybí obrázek u typu otázky s obrázkem?). Dále by tento přístup, kdy by většina dat byla povinná, by pak mohl mít za následek vyšší kvalitu uživatelských dat, která by díky tomu nemohla obsahovat nedokončené otázky s chybějícími daty. V neposlední řadě by pak menší množství dat v jednotlivých otázkách také usnadnilo tvorbu jednoduššího, přehlednějšího uživatelského rozhraní. Na druhou stranu by takový přístup byl mnohem náročnější na uživatele, kteří by museli při tvorbě nových dat mít více promyšleno rozdělení otázek do jednotlivých typů otázek a sad. Bez toho by taková aplikace pravděpodobně působila na uživatele omezujícím dojmem.

31

(33)

Rozhodl jsem se tedy, po konzultaci s vedoucím práce, zachovat ideu oddělených typů otázek, ale v omezené míře tak, aby do samostatných tříd byly umístěny pouze výrazně odlišné typy otázek, a multimediální přílohy byly volitelné. U sad otázek jsem se pak rozhodl využít vlastností dědičnosti, a faktu, že všechny typy otázek budou vycházet ze společného předka, a zvolil jsem tohoto předka jako datový typ kolekce otázek. Díky tomu je možné uložit do této kolekce všechny typy potomků, což odstranilo nutnost mít pro každý typ otázky nový typ sady. Celkově je tento přístup kompromisem mezi omezením uživatelských možností a kontrolou kvality dat, což také znamenalo, že jsem se vzdal zčásti naivní představy, že budu zodpovědný za kvalitu uživatelských dat, a ponechal tuto starost na uživateli.

Bohužel, pro tuto změnu jsem se rozhodl až během implementační fáze, což sebou neslo neplánované zdržení při změně architektury i již naprogramovaných částí programu.

b) Implementace funkcí z prototypů

Kvůli minimalizaci problémů během implementační fáze jsem se rozhodl složitější funkce nejprve vyzkoušet naprogramováním prototypů, aby byla následná implementace do programu co nejvíce bezproblémová. Ve většině případů byl daný úkol splněn, ale nastaly i výjimky, které vedly ke zdržení vývoje.

První výjimkou byl protoyp formuláře pro tvorbu a editaci otázek. Prototyp umožňoval vytvoření nové otázky a načtení předem vytvořené testovací otázky. Vše bylo bezproblémové, až do implementace do programu. Poté se začaly v programu objevovat chyby, vždy při ukládání editované otázky do sady otázek. Po zdlouhavém zkoumání byl odhalen zdroj chyb, kterým byl prvek pro zobrazení přiloženého obrázku. Tento prvek totiž nechával otevřený přístupový kanál k zobrazovanému obrázku, který se program následně snažil zkopírovat do adresáře s multimédii pro danou sadu. V prototypu, kde neprobíhalo ono kopírování, tedy vše fungovalo, zatímco v programu již nikoliv. Řešením bylo zobrazovat v editoru kopii obrázku vytvořenou v paměti (viz Kód 5), aby poté mohl program k danému souboru přistoupit a zkopírovat ho.

(34)

Druhým případem byla lokalizace uživatelského rozhraní, kdy jsem se rozhodl načítat příslušná data z přiložených souborů lokálních zdrojů (tvz. resource soubory).

Opět v prototypu vše fungovalo, ale po zavedení do programu se nedařilo soubor se zdroji načíst. Problém byl v identifikátoru souboru se zdroji, kdy v prototypu byl použit název sestavení místo názvu jmenného prostoru. Vzhledem k tomu, že tyto dva názvy byly shodné, vše fungovalo. Po přenesení do programu, kde se názvy lišily, nemohl ResourceManager najít požadovaný soubor. Řešením bylo použití názvu jmenného prostoru v identifikátoru souboru.

c) Deserializace slovníků objektů

Třída ExamPlanItem, obsahující referenci na sadu otázek a objekt pro výběr následující otázky, je serializována v rámci ukládání zkušebního plánu. Z důvodů optimalizace jsou ony dva výše zmíněné atributy vyjmuty z procesu serializace, a po deserializaci jsou, dle parametrů, obsažených v jiném atributu třídy, znovu vytvořeny.

Pro uchování parametrů byl použit slovník objektů s klíči v podobě řetězce. Nastal však problém při deserializaci, kdy v průběhu metody onDeserialization, která se provádí automaticky při deserializování a kde byly zmíněné dva atributy generovány, nebyl slovník, na rozdíl od ostatních atributů, dostupný. Po delším zkoumání a konzultaci s vedoucím práce jsem zjistil, že se nejedná o chybu v mém kódu, ale o limitaci .Net frameworku, která není na první pohled zřejmá. Řešení tohoto problému bylo v podstatě provést deserializaci explicitně, na začátku metody onDeserialization.

33 if (filename != null)

{

byte[] imageBytes = File.ReadAllBytes(filename);

MemoryStream msImage = new MemoryStream(imageBytes);

picture_box.Image =

System.Drawing.Image.FromStream(msImage);

}

Kód 5: Ukázka načtení obrázku z proudu

public void OnDeserialization(object sender) {

this.options.OnDeserialization(sender);

QuestionSet question_set =

IOHandler.DeserializeSet((string)options["set_safename"]);

Kód 6: Ukázka ošetření deserializace slovníku

(35)

d) Absence vizuální dědičnosti u některých prvků

Při tvorbě formuláře pro zobrazení otázky během zkoušení, jsem se rozhodl opět vytvořit jeden základní formulář, obsahující základní prvky, který bude sloužit jako rodičovský formulář. Podobný přístup se také již dříve osvědčil při tvorbě editoru zkušebního plánu. V tomto případě ale došlo k situaci, kdy nebylo možné vzhled odvozených formulářů dále upravovat pomocí návrháře ve vývojovém prostředí. Opět se jednalo o limitaci frameworku .Net, kdy některé komponenty, použité v rodičovském formuláři pro rozvržení prvků (jmenovitě TableLayoutPanel a FlowLayoutPanel) nepodporují vizuální dědičnost. Tyto komponenty lze tedy na odvozeném formuláři upravovat pouze z kódu, což sebou nese jisté ztížení vývoje.

Řešením by bylo vytvořit rozvržení pomocí jiných komponent, což by ovšem bylo mnohem komplikovanější, a pracnější, než stávající situace.

e) Tvorba dynamického grafického rozhraní

Ačkoliv Framework .Net a knihovna WinForms nabízí pro snažší tvorbu dynamických rozhraní několik vlastností a komponent, vytvoření rozhraní, které má být dynamické, ve smyslu, měnícího se počtu a velikosti zobrazovaných prvků, a zároveň snadno velikostně přizpůsobitelné, nebylo lehkým úkolem. Zejména použití automatického přizpůsobení velikosti řádku a sloupců u komponenty TableLayoutPanel vedlo často k nepředvídatelným změnám velikosti. K vytvoření některých složitějších rozvržení pak bylo nutné vnořit několik těchto komponent do sebe, což celý problém zhoršovalo. Řešením by mohlo být například použití externí (většinou placené) knihovny s propracovanějšími komponentami, či jednodušší, nebo statické rozhraní.

f) Změna cílové verze frameworku sestavení

Při vývoji aplikace byla pro všechny sestavení jako cílová verze zvolena verze frameworku .NET Framework 4 Client Profile, jenž je určená pro tvorbu klientských aplikací. Při implementaci funkce pro získání souboru s výslovností z internetového překladače, byla pro kódování parametrů použita funkce HttpUtility.UrlEncode, která se nachází v knihovně System.Web. Tato knihovna není ovšem v použité verzi

(36)

frameworku dostupná, a její použití změnilo cílovou verzi sestavení jádra programu z Client Profile na plnohodnotnou verzi. Běh programu poté končil chybou kvůli nenalezení původní verze sestavení. Řešením bylo použít na kódování parametrů jinou funkci, která nevyžadovala plnohodnotnou verzi frameworku a změnit cílovou verzi sestavení zpět na verzi Client Profile. Bohužel, vzhledem k tomu, že v dokumentaci frameworku nebyla tato závislost zmíněna, trvalo nalezení řešení zbytečně dlouhou dobu.

35

(37)

4. Závěr

V době odevzdání bakalářské práce (16.5. 2014) se program nachází v nedokončené verzi. Příčinou nedokončení práce byla zejména nezkušenost autora s projektem podobného rozsahu. Původní myšlenka vytvoření jednoduché aplikace se záhy začala rozrůstat o další nápady a s nimi rostly ambice a ctižádost autora. Celý vývoj aplikace byl realizován jen jednou osobou, občas chyběly různé úhly pohledu, které by pomohly v rozhodování. To vedlo k situacím, kdy autor strávil příliš mnoho času nad některými dílčími problémy a snaha najít co nejlepší řešení vedla k zby- tečnému zdržení vývoje. Vývoj tímto datem ale nekončí, chybějící funkce budou po- stupně doplňovány.

Co není hotové?

V aktuální verzi aplikace není dokončen režim zkoušení z důvodu chybějících formulářů pro zobrazování otázek typu Dictionary a MultimediaAnswer.

Co je hotové?

Obsahuje editory pro všechny implementované typy otázek (Normal, Dictionary, MultimediaAnswer), editor zkušebních plánů s možností nastavení jednotlivých položek plánu dle typu obsažených otázek, a formulář pro zobrazení základního typu otázek. Umožňuje přikládat k otázkám multimédia a umožňuje také generovat alternativy k otázkám. Implementována je také funkce využití internetového překladače Google pro generování zvukových klipů s výslovností cizích slov. Dále je také, navíc proti původním cílům, rozpracována lokalizace uživatelského rozhraní do více jazyků.

Budoucí vývoj

Během vývoje autor shromáždil množství dalších nápadů. Z významnějších jsou to možnost vynuceného zkoušení, nový typ otázky (tzv. „doplňovačka“), částečná implementace Leitnerova systému v podobě variabilních intervalů kladení otázek dle jejich úspěšnosti a import/export rozšířených formátů z jiných programů. Mezi ty méně významné patří vylepšení uživatelského rozhraní, refaktorizace hotového kódu a jeho okomentování. Plánována je také možnost výměny sad mezi uživateli na webu.

(38)

5. Seznam použitých zdrojů

[1] Grooveshark. Grooveshark [online]. 2012 [cit. 2013-05-19]. Dostupné z:

http://grooveshark.com/

[2] Christian Nagel, Bill Evjen, Jay Glynn, Karli Watson, Morgan Skinner: C# 2008, Programujeme profesionálně, Computer Press, duben 2009, ISBN: 978-80-251-2401- 7

[3] PUŠ, Petr. Poznáváme C# a Microsoft.NET: serializace. In: Zive.cz [online]. 2005 [cit. 2013-05-14]. Dostupné z: http://www.zive.cz/clanky/poznavame-c-a-

microsoftnet-40-dil--serializace/sc-3-a-126553/default.aspx

[4] PUŠ, Petr. Poznáváme C# a Microsoft.NET: výjimky. In: Zive.cz [online]. 2005 [cit.

2013-05-14]. Dostupné z: http://www.zive.cz/clanky/poznavame-c-a-microsoftnet- 13-dil--vyjimky/sc-3-a-123149/default.aspx

[5] Sebastian Leitner. Flashcard Learner [online]. 2012 [cit. 2014-05-14]. Dostupné z:

http://www.flashcardlearner.com/articles/sebastian-leitner/

6. Seznam ilustrací

Ilustrace 1: UML entita třídy Question...16

Ilustrace 2: UML entita třídy QuestionSet...16

Ilustrace 3: UML entita třídy Questioner...17

Ilustrace 4: UML entita třídy ExamPlanItem...17

Ilustrace 5: UML entita třídy ExamPlan...18

Ilustrace 6: UML class diagram prototypu aplikace...19

Ilustrace 7: UML class diagram aplikace po implementaci změn v architektuře...26

7. Seznam ukázek kódu

Kód 1: Ukázka použití knihovny NAudio...27

Kód 2: Ukázka práce se slovníkem otisků...28

Kód 3: Získání souboru s vygenerovanou výslovností pomocí Google překladače...29

Kód 4: Metoda pro zobrazení pomocného formuláře uvnitř komponenty Panel...30

Kód 5: Ukázka načtení obrázku z proudu...33

Kód 6: Ukázka ošetření deserializace slovníku...33

37

(39)

8. Přílohy

A) ukázky programu EasyWords

Příloha 1: Zobrazení otázky v programu EasyWords

Příloha 2: Možnosti nastavení programu EasyWords jsou velmi omezené

(40)

B) ukázky programu FullRecall

39

Příloha 3: Zobrazení otázky s obrázkem v programu FullRecall

Příloha 4: Možnosti nastavení programu FullRecall jsou velmi obsáhlé, ale také poměrně nepřehledné

(41)

C) ukázky programu Mnemosyne

Příloha 5: Zobrazení větších obrázků, přiložených k otázkám, není v programu Mnemosyne vyřešeno nejlépe

Příloha 6: Editace otázek s přiloženými multimédii není příliš uživatelsky přívětivá

(42)

D) ukázky programu Anki

41

Příloha 7: Editor sice nevypadá nejpřívětivěji, ale všechny důležité funkce jsou snadno dostupné

Příloha 8: Prohlížeč karet nabízí pokročilé možnosti filtrování, ale je poněkud nepřehledný

(43)

E) ukázka nevhodně navrženého grafického rozhraní

Příloha 9: Nefunkční přizpůsobení velikosti formuláře programu EasyWords

(44)

F) ukázky z programu SlackerMemo

Příloha 10: Administrace sad otázek

Příloha 11: Editor otázek v sadě

(45)

Příloha 12: Editor zkušebního plánu

Příloha 14: Zobrazení otázky Příloha 13: Upozornění na další otázku

References

Related documents

Na farmě žije celkem zvířat. a) Kolik snesly slepičky celkem vajíček od pondělí do pátku? Pomoz Amálce vyplnit tabulku. b) Na kolik dní vydrží zásoba vajíček

Jedná se zejména o dodržení všestrannosti a dobře vedeného tréninku, sportovní aktivity by neměly přinášet příliš velkou únavu a měly by být zajištěny pravidelné

Z grafu je možné vyčíst, že všechny druhy optimalizace, které byly použity, jsou podstatně rychlejší než výpočet NoDB, který volá program React pro výpočet všech buněk

Jestliže dítě nemluví včas či správně, je dobré neváhat a požádat o logopedické vyšetření. Někdy může být ve 3 letech dítěte ještě brzy na

Cílem této práce bylo analyzovat současný způsob ve firmě JRM Speedway Factory s.r.o. včetně informačního toku průběhu zakázky výrobním systémem, a

SEZNAM POUŽITÝCH ZDROJŮ .... Vzhledem k oboru, který studuji, jsem chtěla, aby má bakalářská práce nějakým způsobem souvisela s vězeňstvím. Na toto téma už

Hodnocení vybraných v|astností tenkých vrstev je na vysoké technické úrovni, i kdyŽ i zde postrádám zkoušení a pozornost zaměřenou na Životnost povrchu

Cílem práce je také zjistit, jaké typické autistické projevy mají největší vliv na poskytování služby, koho problémové nejvíce ovlivňuje a zda mají jedinci