Výpis souhrnů
Vývoj programů
Podtémata
Ladění, hledání chyb
Jen málokdy napíšeme napoprvé bezchybný kód. Riziko chyb snižuje snaha o kvalitní kód, chybám se ale zcela nevyhneme, proto je potřeba chyby aktivně hledat. Chyby v kódu se někdy označují anglickým termínem bug. Proces ověřování správnosti kódu nazýváme testování, proces zjišťování příčiny chyby a její odstranění nazýváme ladění (někdy též „debugování“, angl. „debugging“).
Typy chyb
Rozlišujeme chyby syntaktické (chybný zápis programu – program nelze spustit) a sémantické (program se vykoná, ale nesplňuje požadované chování). Speciálním případem sémantické chyby je zacyklení (program se nikdy nezastaví, např. protože podmínka cyklu nikdy nepřestane platit).
Příklady chyb
Několik příkladů častých sémantických chyb:
- prohození pořadí příkazů (např. pořadí zatáčení a posunu vpřed)
- chybný počet opakování cyklu
- chybné vymezení těla cyklu (např. chybí odsazení příkazu, který se má opakovat)
- záměna cyklu a podmíněného příkazu (
dokudmístopokud) - záměna ostré a neostré nerovnosti (
x < ymístox ≤ y) - záměna logické spojky (
P a QmístoP nebo Q) - prohození srovnávaných proměnných (
x < ymístoy < x) - prohození přiřazované proměnné a hodnoty (
x ← ymístoy ← x) - záměna proměnných (použití chybné proměnné, hrozí zejména při nevhodném pojmenování)
- použití špatného typu proměnné (řetězec
“3”místo čísla3) - chybná hodnota parametru (např. nesprávný úhel, o který je potřeba zatočit)
- záměna argumentů při volání funkce (
f(a, b)místof(b, a)) - záměna výpisu a vrácení z funkce (
vypišmístovrať)
Znalost běžných chyb umožňuje zaměřit při ladění pozornost na místa, kde by se mohla chyba ukrývat.
Postup při ladění programu
Pokud program nevrací správné výsledky, spustíme si ho krok po kroku a sledujeme, kdy se odchýlí od našeho očekávání. Pokud program netvoří grafický výstup, lze si hodnoty proměnných průběžně vypisovat, nebo použít nástroj, který umožňuje program krokovat a sledovat hodnoty proměnných (tzv. debugger). Místo v programu, kde se program odchyluje od našeho očekávání, zkusíme upravit.
Tipy k ladění programů
- Po každé úpravě je vhodné program znovu spustit, abychom si ověřili efekt úpravy.
- Pokud není jasné, jak přesně kód upravit (např. o jaký úhel zatočit), může pomoct nakreslit si obrázek.
- Pokud není jasné, proč se v nějakém bodě program chová určitým způsobem, je lepší to nejprve pochopit, než začneme dělat změny.
- Pokud si nejsme jistí, co dělá některá použitá jazyková konstrukce (příkaz, operátor), vyhledáme si její chování na internetu a ověříme naše porozumění vyzkoušením jednoduchého kódu s danou konstrukcí.
- Pokud je kód zbytečně složitý nebo používá nevhodná jména proměnných, může být po odstranění těchto nedostatků (např. přejmenování proměnných) chyba zjevná.
- Rozložení do funkcí usnadní hledání chyby – můžeme totiž testovat jednotlivé funkce izolovaně.
Úprava programů
Kvalitní kód je takový, který se snadno čte, testuje a upravuje. Kvalitu kódu je vhodné průběžně vylepšovat opravami následujících problémů.
Nepoužitý kód
Části kódu, které se buď neprovedou, nebo sice provedou, ale nijak neovlivňují jeho chování, zbytečně komplikují pochopení programu a je proto vhodné je odstranit. Zbytečný může být příkaz, cyklus, podmínka, proměnná i celá funkce.
Příkaz bez efektu
Efekt nemá opakované přiřazení stejné hodnoty (např. nastavení aktuální barvy malující želvy), přiřazení hodnoty do proměnné, se kterou se již dále nepracuje, nebo matematické operace, které nemění hodnotu (přičtení 0, vynásobení 1).

Cyklus provedený jednou/vůbec
Pokud se cyklus provede vždy právě jednou, není potřeba – nedochází k žádnému opakování. Cyklus odstraníme, ponecháme však příkazy, které byly v jeho těle. Pokud se tělo cyklu neprovádí vůbec, lze cyklus odstranit včetně jeho obsahu. Obě tyto situace jsou nejsnáze vidět u cyklu opakuj N×, ale mohou nastat u všech typů cyklů.

Podmínka platící vždy/nikdy
Pokud podmínka platí vždy, nahradíme podmíněný příkaz obsahem větve pokud. Pokud podmínka neplatí nikdy, nahradíme ho obsahem větve jinak (pokud větev jinak nemá, tak celý podmíněný příkaz smažeme).

Prázdná větev podmíněného příkazu
Pokud větev jinak neobsahuje žádný příkaz, lze ji vypustit.

Pokud neobsahuje žádný příkaz první větev, lze větve prohodit (a prázdnou vypustit) negací podmínky.

Nepoužitá proměnná
Proměnná, do které se pouze zapisují hodnoty, ale nikdy se z ní hodnota nečte, nemá na běh a výstup programu žádný vliv a lze ji tedy odstranit.

Nezavolaná funkce
Funkce, kterou pouze definujeme, ale nikde nevoláme, je zbytečná a lze ji odstranit.
Zbytečně složitý kód
Pokud lze kód zjednodušit, zvýší to většinou jeho čitelnost. Relativně jednoduché jsou případy, kdy lze sloučit dva příkazy, cykly, nebo podmínky. Kód lze ale také někdy zjednodušit použitím vhodnější programovací konstrukce (např. cyklu opakuj N× místo opakuj dokud) nebo rozkladem programu (zavedením pomocných funkcí).
Sloučitelné příkazy
Sloučení dvou po sobě jdoucích akcí do jedné. Například dvě otočení o 90° a 30° lze nahradit jediným otočením o 120°.

Sloučitelné cykly
Pokud je v těle cyklu pouze vnořený cyklus, lze je sloučit do jediného. Sloučení lze také provést u dvou bezprostředně následujících cyklů, které mají stejné tělo.

Sloučitelné podmínky
Pokud podmíněný příkaz obsahuje ve svém těle pouze další podmíněný příkaz, lze se vyhnout vnoření použitím složené podmínky.

Sloučit lze také dva podmíněné příkazy s opačnou podmínkou (pomocí úplného podmíněného příkazu).

Zjednodušitelná negace
Pokud lze logické výrazy zjednodušit, je to typicky vhodné udělat. Častým případem je aplikace negace na nerovnost nebo složenou podmínku. (V případě úplného podmíněného příkazu lze alternativně prohodit příkazy ve větvích pokud a jinak a negaci vypustit.)

Nevhodný typ cyklu
Pokud je počet opakování dopředu známý, použijeme cyklus s daným počtem opakování, který je jednodušší.


Cyklus místo podmíněného příkazu
Pokud se má příkaz provést nejvýše jednou, použijeme podmíněný příkaz, nikoliv cyklus.

Chybějící rozklad
Pokud je hlavní program nebo některá funkce příliš složitá, je vhodné program nebo funkci rozložit do více funkcí tak, aby každá funkce měla jasný účel.
Duplicitní kód
Pokud se v programu opakují stejné nebo podobné kousky kódu, program to nejen zbytečně natahuje, ale také to komplikuje jeho úpravy – je potřeba změnit více míst (a pokud některé místo upravit zapomeneme, zaneseme do programu chybu).
Duplicitní úseky kódu
Pokud jsou dva úseky kódu hodně podobné, lze je často zobecnit do společné pomocné funkce.

Duplicitní příkazy v posloupnosti
Posloupnost stejných příkazů lze nahradit cyklem. Cyklem lze nahradit také posloupnost příkazů, které se liší pouze hodnotou proměnné, která se mění pořád stejným způsobem.


V některých případech nepotřebujeme zavádět nový cyklus, ale upravit stávající.


Duplicity v těle podmíněných příkazů
Pokud mají po sobě jdoucí větve podmíněného příkazu úplně stejné tělo, lze je spojit využitím složené podmínky.

Když se těla liší, ale máme na začátku / na konci všech větví podmíněného příkazu stejný příkaz (nebo více stejných příkazů), lze tento příkaz přesunout před/za podmíněný příkaz.

Pokud všechny větve podmíněného příkazu obsahují cyklus se stejnou hlavičkou, lze se duplicity zbavit přesunutím podmíněného příkazu dovnitř cyklu.
Nevhodná jména
Nevhodně zvolená jména proměnných a funkcí komplikují pochopení programu a nezřídka vedou k chybám při psaní programu (nebo při jeho pozdějším rozšiřování).
Nepopisná jména
Volíme taková jména, která jasně vyjadřují účel proměnné či funkce, i za cenu delšího názvu. Jednopísmenné názvy jsou vhodné jen v omezených případech (řídící proměnná cyklu, souřadnice bodu, krátké ukázky kódu).

Zavádějící jména
Ještě nebezpečnější než jména nepopisná jsou jména, která vypadají popisně, ale popisují proměnnou či funkci chybně.

Překrývající se jména
V rámci jednoho kontextu není vhodné použít jedno jméno pro více různých věcí – ani v případě, že se už na původní proměnnou odkazovat nepotřebujeme. Takové překrývání komplikuje pochopení programu a vede k chybám při jeho úpravách.
Vývojové diagramy
Vývojové diagramy představují způsob, jak můžeme graficky reprezentovat postup nebo návod pro nějakou činnost. Takový postup může být například recept na bábovku, návod na sestavení skříně nebo i počítačový program. Grafická reprezentace nám umožňuje lépe vidět místa, kde se návod větví na více možností (vyhodnocení podmínky u pokud, dotaz na typ spotřebiče), a kde můžeme očekávat cykly (příkaz dokud, opakování pro každý z muffinů).
Základní prvky vývojového diagramu
Každý příkaz programu (například přiřazení nebo výpis) reprezentujeme jako samostatný obdélník. Dva po sobě jdoucí příkazy spojíme šipkou ve směru provádění programu.
Podmínky nebo obecně místa, kde se tok programu větví na více možných cest, značíme kosočtvercem. Z nich pak vedou dvě šipky, jedna označená „ano“ nebo „pravda“, druhá „ne“ nebo „nepravda“.
Podmínky mohou být použity pro samostatné větvení, nebo jako součást cyklu. Podmínku může mít cyklus na začátku, jak ukazuje diagram programu, nebo na konci, jak ukazuje příklad se zatloukáním hřebíku. Šipka vedoucí z posledního příkazu cyklu vede před první příkaz tohoto cyklu. V takovém případě by vedlo více šipek do jednoho bloku, čemuž se obecně snažíme vyhnout. Vyřešíme to tak, že obě vstupní šipky spojíme plným kolečkem.
Pokud chceme znázornit, že diagram znázorňuje celý program a ne jen jeho část, můžeme přidat prvky „start“ a „konec“, které zakreslíme do obdélníků s oblými rohy.

Podobnost s jinými modely
Kromě vývojových diagramů máme i kapitolu na entitně-vztahové modely. Hlavním rozdílem je, že vývojový diagram zobrazuje posloupnost, v jaké se provádí jednotlivé kroky postupu, zatímco entitně-vztahový diagram popisuje vztah a vlastnosti mezi objekty.
Kromě vývojových diagramů a entitně-vztahových modelů můžeme vztahy nebo cesty mezi objekty znázorňovat například i pomocí grafů.
Nahoru