NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Lekce 4 - PyCharm - Debugging

V minulé lekci, PyCharm - Scopes, Live Templates, Databáze, Pluginy, jsme se zabývali scopes, Live Templates, databázemi a pluginy.

V dnešním Python tutoriálu si vysvětlíme, jak debugovat Python aplikace za pomocí IDE PyCharm. Vše si vyzkoušíme na jednoduchém příkladu.

Debugging

O debuggingu, tedy o procesu odstranění chyb v programu, se někdy hovoří také jako o jeho "ladění". Chyby v programu se většinou projevují tím, že je v nějaké proměnné nesprávná hodnota, která zapříčiní jeho nefunkčnost. Určitě jste se již dostali do situace, když váš program nefungoval správně.

Proč a kdy debugovat?

Možná jste prováděli zdlouhavé kontrolní výpisy různých proměnných, abyste zjistili, kde je chyba. Chybu lze ovšem odhalit mnohem snadněji, a to pomocí debugování. Program proto nejdříve spustíme ve speciálním debugovacím režimu, kde máme dovoleny určité "cheaty", jako např. program pozastavovat a nahlížet do obsahu proměnných.

Pozor, není ovšem pravda, že debugujeme jen když program nefunguje. Naopak, používáme jej co nejvíce to jde, a to i třeba pro kontrolu správnosti na kritických místech.

Příklad - Krokování cyklu

Mějme jednoduchý cyklus, ve kterém budeme vypisovat e-mailové adresy spojením jména a jednotné koncovky např. @abc.cz:

jmena = ['anna', 'pavel', 'lucie']
for jmeno in jmena:
    mail = jmeno + '@abc.cz'
    print(mail)

Jak si můžeme ověřit výše, program funguje korektně. Přesto si jej zkusíme oddebugovat, než se pustíme na nefunkční kód.

Breakpointy

Breakpoint je základní stavební kámen při debugování. Je to "bod" označující řádek, na kterém se program zastaví. Nám, jako programátorům, se v tu chvíli zobrazí kompletní kontext programu, tedy např. co je v tu chvíli kde uloženo. Protože program stojí, můžeme si vše snadno zkontrolovat.

Přidání breakpointu

Nyní se naučíme vkládat breakpointy a zastavovat na nich program. V PyCharm se breakpoint na daný řádek vkládá kliknutím do prostoru mezi číslem řádku a kódem (v editoru). Breakpoint pak poznáme podle červeného kolečka a červeného řádku. Vložme tedy breakpoint na řádek, kde se vypisují e-maily do konzole (print(mail)).

Debug režim

Breakpoint máme přidaný. Když však program nyní spustíme, nic zvláštního se nestane. Aby se program opravdu zastavil, je potřeba ho spustit ve speciálním debugovacím režimu. K tomu slouží zelené tlačítko Debug main (hned vedle zeleného tlačítka "Play"), na které klikneme. Program se následně spustí a zastaví se, až narazí na náš breakpoint:

PyCharm - Pokročilá práce

Záložka Debug

Otevřela se nová záložka Debug, která obsahuje velké množství informací:

PyCharm - Pokročilá práce

Pojďme si popsat, co vidíme:

  • Část výše na obrázku, ohraničená zeleně, obsahuje seznam všech aktuálně viditelných proměnných a jejich hodnoty.
  • Žlutě ohraničená část obsahuje zásobník volání všech funkcí, které se zavolaly před breakpointem.
  • Dále jsou na obrázku ještě červeně zvýrazněny dvě části (ovládání programu a breakpointů a krokování), které si popíšeme v následujících podkapitolách.
Ovládání programu a breakpointů

V první ohraničené červené části (svisle vlevo) se nachází tlačítka pro kontrolu ovládání programu a breakpointů:

  • Rerun '(název_souboru)' Ctrl + F5 - Ukončí aktuální program a znovu ho spustí.
  • Modify Run Configuration - Zobrazí nastavení pro debug.
  • Resume Program F9 - Uvolní program z breakpointu a nechá program běžet a případně se zastaví o další breakpoint.
  • Pause Program - Pozastaví vykonávání vybraného vlákna - funguje podobně jako breakpoint, pouze se nezobrazí žádné proměnné.
  • Stop '(název_souboru)' Ctrl + F2 - Ukončí aktuální program.
  • View Breakpoints Ctrl + Shift + F8 - Zobrazí seznam všech breakpointů.
  • Mute Breakpoints - Potlačí všechny breakpointy. Když program narazí na breakpoint v debug módu, breakpoint bude ignorován.
Krokování

Ve druhé červeně ohraničené části (vodorovně) se nachází tlačítka pro krokování programu. Pomocí krokování můžeme nechat program pokročit na další řádek a zase zastavit:

  • Step Over F8 (krok přes) - Provedeme další krok přes danou řádku s breakpointem, na které program aktuálně stojí. Pokud se na řádce volá funkce, necháme ji jen vykonat a pak přejdeme na další řádek.
  • Step Into F7 (krok do) - Provedeme další krok "do" dané řádky. Dělá to samé co Step Over až na rozdíl, že pokud se na řádku volá funkce, přejdeme na první řádek ve funkci.
  • Step Into My Code Alt + Shift + F7 (vynucený krok do) - Vynutí přechod do funkce na řádku i v případě, že se nejedná o naši metodu.
  • Step Out Shift + F8 (krok ven) - Pomocí kroku ven vystoupíme z aktuálně prováděné funkce.

My se nacházíme v cyklu, kde pouze postupně vypisujeme jednu hodnotu. Když se podíváme do výpisu konzole, zatím neuvidíme žádný výpis (kromě možných hlášek od IDE). Stiskem tlačítka Step Over (krok přes) se do konzole vypíše první hodnota (v našem případě první e-mail) a my se v programu dostaneme na řádek s for cyklem (for jmeno in jmena:). Když tlačítko Step Over stiskneme znovu, uvidíme v editoru kódu posun na další položku seznamu, pro kterou se zase vykoná blok kódu (do konzole se tedy vypíše druhý e-mail). Provedeme další krok přes danou řádku s breakpointem, na které program aktuálně stojí. Pokud se na řádce volá funkce, necháme ji jen vykonat a pak přejdeme na další řádek. Tímto způsobem si můžeme odkrokovat celý cyklus:

PyCharm - Pokročilá práce

Příklad - Debugování programu

Nakonec si dáme příklad opravdu k procvičení debugování. Máme např. tyto dva vnořené cykly, které by měly vypsat malou násobilku (0-9). Výstup by měl vypadat takto:

Konzolová aplikace
0 0 0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7 8 9
0 2 4 6 8 10 12 14 16 18
0 3 6 9 12 15 18 21 24 27
0 4 8 12 16 20 24 28 32 36
0 5 10 15 20 25 30 35 40 45
0 6 12 18 24 30 36 42 48 54
0 7 14 21 28 35 42 49 56 63
0 8 16 24 32 40 48 56 64 72
0 9 18 27 36 45 54 63 72 81

Poblém ale je, že výstup po spuštění programu vypadá takto:

n = 10
for i in range(n):
    for j in range(n):
        print(i * i, end=" ")
    print()

Chybu budeme chtít najít a opravit za pomoci breakpointů a krokování. I když je možné vidět chybu na první pohled, pojďme si to společně odkrokovat. Ve složitějších aplikacích chyba takto snadno vidět nebude a proces debugování bude nutný.

Postup řešení příkladu

Breakpoint umístíme na řádek s vnějším for cyklem (for i in range(n):) a spustíme program v debug režimu. Bude nás zajímat, jak se hodnoty inkrementují. Tlačítkem Step Into (krok do) budeme postupně procházet přes oba cykly a pozorovat proměnné i a j. Postupným krokováním zjistíme, že vnitřní cyklus inkrementuje proměnné i a j správně (sledujeme postupně v editoru kódu), ale výstupy v konzoli odpovídají jiným hodnotám. Zaměříme se proto na print(), kde opravíme chybné i * i na i * j a program již spustíme bez breakpointu. Výsledkem je očekávaná malá násobilka čísel (0-9):

n = 10
for i in range(n):
    for j in range(n):
        print(i * j, end=" ")
    print()

V příští lekci, PyCharm - Pokročilý debugging, si rozšíříme znalosti debugování a zaměříme se na nástroje usnadňující celý proces.


 

Předchozí článek
PyCharm - Scopes, Live Templates, Databáze, Pluginy
Všechny články v sekci
PyCharm - Pokročilá práce
Přeskočit článek
(nedoporučujeme)
PyCharm - Pokročilý debugging
Článek pro vás napsala Aneta Siobos
Avatar
Uživatelské hodnocení:
49 hlasů
Autor se věnuje datové analýze.
Aktivity