Kopenogramy
Co jsou to kopenogramy
Kopenogramy jsou jedním z grafických způsobů zápisu algoritmů a dat. Akronym KOPENOGRAM vyjadřuje základní myšlenku tohoto grafického zápisu: Keep Our Program in Embedded Noted Oblongs for Graphical Representation of Algorithmic Modules.
Původní idea grafického zápisu algoritmů vznikala v osmdesátých letech minulého století v diskusi tří programátorů (Kofránek, Novák, Pecinovský) jako reakce na nedostatky existujících způsobů strukturovaného zápisu algoritmů a datových struktur (vývojové diagramy, Jacksonovy diagramy, Nassi-Schneidermanovy struktogramy aj.). Záhy se však ukázalo, že zvolenou notaci je možno využít i pro názornou demonstraci strukturování algoritmů a dat ve výuce. Pod názvem kopenogramy (což byl původně pracovní název z příjmení autorů) se v tehdejším Československu a později v České a Slovenské republice začaly využívat jako výuková pomůcka při výuce základů programování.
Kopenogramy byly navrženy tak, aby je bylo možno snadno znázornit i na alfanumerických displejích, na nichž bylo možno Nassi-Schneidermanovy diagramy díky používání šikmých čar zobrazovat jen obtížně. Pokud znaková sada obsahovala znaky pro jednoduchou čárovou grafiku, bylo zobrazení kopenogramů vysloveně komfortní.
Grafické možnosti současných počítačů umožňují vylepšenou implementaci kopenogramů s možností plynulého zvětšování a zmenšování vytvořených diagramů. Současné vývojové nástroje (integrated development environments – IDE) navíc umožňují jejich snadné a přirozené začlenění formou pluginů.
Implementace kopenogramů do IDE
Kopenogramy v BlueJ
Vzhledem k tomu, že základní programovací kurz oboru aplikovaná informatika je vyučován v programovacím jazyce Java a při výuce je využíváno výukové vývojové prostředí BlueJ, byl vyvynut plugin pro toto vývojové prostředí.
Pro prostředí MS Windows je možné si upravené BlueJ včetně možnosti vytváření kopenogramů ze zdrojových kódů metod stáhnout zde Δ
Kopenogramy v NetBeans
Vývojové prostředí NetBeans je následně využíváno v navazujícím kurzu Softwarové inženýrství. Byl tedy vyvynut i plugin pro toto prostředí. Ten je možné stáhnout zde.
Pro instalaci a používání pluginu je k dispozici jednoduchá uživatelská příručka.
Syntaxe kopemogramů
Základní stavební prvek kopenogramu je blok, který vždy znázorňuje konkrétní prvek v programu. Tento blok je znázorněn obdélníkem, vybarveným příslušnou barvou, v závislosti na významu prvku, který zobrazuje. Jednotlivé prvky jsou pak do sebe zanořovány, čímž znázorňují strukturu příslušného algoritmu. Podoba některých algoritmických bloků se v závislosti na jejich významu liší. Jednotlivé elementy tak mohou obsahovat následující části:
- Hlavička – tvoří horní část daného bloku a je podbarvena tmavším odstínem jeho barvy. Obsahuje text s názvem příslušného prvku, případně jinou formu popisu jeho významu.
- Tělo – tělo bloku tvoří jeho největší část a je vybarveno světlejším odstínem příslušné barvy. Může obsahovat další bloky. Ty jsou pak na dané úrovni vždy zobrazovány pod sebou, což dobře znázorňuje jejich sekvenční provádění.
- Zápatí – spodní část bloku, rovněž využívající tmavší odstín dané barvy se používá ke znázornění konce těla cyklu.
Tyto části jsou od sebe odděleny vodorovnou dělicí čarou. Kromě toho jsou navíc některé prvky složeny z několika samostatných prvků, které na sebe horizontálně či vertikálně navazují (tedy nikoliv ve smyslu výše popsaném). Následující podkapitoly rozeberou jednotlivé prvky podrobněji.
Základní stavební prvky
Jak bylo zmíněno, jednou z nedílných a velmi důležitých součástí kopenogramů jsou barvy. Ty s sebou nesou výhodu v podobě snadné orientace v algoritmu, a to i na větší vzdálenost, tedy bez nutnosti čtení popisků jednotlivých prvků. Základ tvoří následující čtyři barvy:
- Žlutá barva, jejíž odstíny znázorňují metody (procedury/funkce) a jejich rekurzivní volání.
- Zelená barva, která se používá k zobrazení cyklů.
- Modrou barvou jsou znázorněny podmíněné příkazy a přepínače.
- Červená barva slouží k podbarvení bloků, znázorňujících jednotlivé akce, kromě té v podobě zmíněného rekurzivního volání.
Příklad metody, tvořené těmito základními algoritmickými konstrukcemi znázorňuje následující obrázek.
Jak si lze všimnout, metoda je reprezentována největším obdélníkem s hlavičkou obsahující její název (zde pouze ilustrační). V těle metody je pak modrou barvou znázorněn rozhodovací blok (if – else if – else). Jedná se o složený prvek, zmiňovaný v předchozí kapitole. Jednotlivé rozhodovací větve jsou vzájemně odděleny svislými čarami. Jejich hlavičky pak tvoří vstupní podmínky (podmíněné výrazy) do dané větve (části bloku). V těle bloku s hlavičkou IF je znázorněn cyklus, testující podmínku před zahájením iterace (cyklus whi-le). Prvek v jeho těle vybarven červeně pak znázorňuje, že při každém průchodu tímto cyk-lem bude provedena uvedená akce (v tomto případě Akce_1). Zápatí s černou šipkou směřující vzhůru naznačuje fakt, že po každém průchodu se přechází opět na testování podmín-ky (proto tento směr šipky). Ve vedlejší větvi, v bloku ELSE IF je situace podobná. Jediný rozdíl spočívá v tom, že uvedený cyklus testuje podmínku až po provedené iteraci, v níž je prováděna Akce_2 (tato akce je tedy bez ohledu na podmínku vykonána minimálně jed-nou). Z toho důvodu je „prohozena“ hlavička se zápatím. Nevyhovuje-li ani jedna z dvojic podmínek IF – ELSE IF, provádí se Akce_3a. To vyjadřuje část modrého bloku, která je nejvíce vpravo. Poslední, žlutý prvek, mající stejný název jako popisovaná metoda znamená, že v této části programu probíhá její rekurzivní volání.
Další prvky kopenogramů
Jak je uvedeno, kopenogramy slouží k zobrazování strukturovaných algoritmů. Strukturované algoritmy jsou ty, které jsou tvořeny pouze lineární sekvencí příkazů (jednotlivé příkazy jsou prováděny jeden po druhém). Členy této posloupnosti mohou být kromě jednoduchých příkazů i opakování (kdy jsou určité příkazy vykonávány, dokud není dosaženo nějakého stavu) a výběr (v závislosti na stavu programu je provedena příslušná množina příkazů). Jednotlivé členy pak mají vždy právě jeden vstup a jeden výstup. Nyní je již zřejmé, proč prvky kopenogramu, popsané v předchozí kapitole, jsou označeny jako základní.
V některých situacích však výhradní dodržování pravidel strukturovaného programování může řešení daného problému spíše zkomplikovat. Proto byly v rámci strukturovaného programování zavedeny i příkazy, které na jednu stranu narušují jeho hlavní zásadu, ale zápis algoritmu ve výsledku usnadňují a zpřehledňují. Jedná se o předčasné ukončení cyklu (příkaz break a continue) a předčasné ukončení celého algoritmu (příkaz return). Je zřejmé, že po zavedení těchto příkazů již není splněná výše popsaná podmínka jednoho výstupu. Způsob znázornění těchto prvků v kopenogramu ukazuje následující obrázek, kde červený obdélník s bílými trojúhelníky představuje příkaz break, k opuštění cyklu WHILE za podmínky IF.
Příkaz continue se obvykle značí podobně, s tím rozdílem, že bíle trojúhelníky směřují nahoru.
S příchodem jazyka Java se stala běžnou součástí začátečnických kurzů programování práce s výjimkami. Proto bylo nutné tento fakt zohlednit i v kopenogramech. Na zobrazení mechanizmu zpracování výjimek se lze dívat jako na speciální složený blok, skládající se z bloku, v němž lze očekávat vyhození výjimky a z jednoho nebo více bloků, které vyvolanou výjimku zachycují a zpracovávají.
Příklady
Jak jsou jednotlivé struktury programovacího jazyka Java převedeny do kopenogramů ukazují následující příklady. Metody jsou napsány velmi schématicky a na jejich základě jsou vygenerovány kopenogramy.
public void ifStatement()
{
statement(0);
if(condition(0)) {
statement(1);
}
statement(2);
}
public void ifThenElseStatement()
{
statement(0);
if(condition(0)) {
statement(1);
}
else if (condition(0)) {
statement(2);
statement(3);
}
else {
statement(5);
}
statement(4);
statement(5);
}
public void switchStatement()
{
String s = "";
statement(0);
switch(s)
{
case "":
statement(1);
statement(2);
break;
case "A":
statement(0);
break;
case "B":
statement(5);
default:
statement(6);
}
statement(7);
statement(2);
}
public void breakWithLabelStatement()
{
statement(0);
Label:
{
do {
statement(1);
if (condition(0)) {
break Label;
}
statement(2);
} while(condition(1));
statement(3);
}
statement(4);
}
public void throwingException()
{
statement(0);
try {
statement(1);
}
catch (Exception ex) {
statement(2);
}
finally {
statement(3);
}
statement(4);
}