Debugowanie za pomocą print()
Na początek zastosujmy najprostszą formę debugowania stosowaną przez najstarszych Indian😂
Printowanie, czyli wypisywanie stanu
Wypisywanie na konsolę wiadomości można nazwać pierwszą strategią mającą na celu poznanie stanu programu w danym momencie. Możemy to nazwać taką bardzo prymitywną (i wciąż bardzo szeroko stosowaną) formą debugowania.
W Pythonie użyjemy funkcji print(), która wypisze nam dowolny tekst na konsolę uruchomieniową. Przykładem użycia print() może być opis poszczególnych bloków programu. Usprawnijmy nasz kod o takie opisy:
# Cats inventory advanced manager
print("Starting program")
print("Preparing data")
cat1 = "Kitty"
cat2 = "Pussy"
cat3 = "Paw"
print("Initialising cats list")
cats = []
print("Adding cats to list")
cats.append(cat1)
cats.append(cat2)
cats.append(cat3)
print("Returning list")
print(cats)
Uruchamiamy ponownie program i tym razem widzimy taki oto wynik:
C:\Projects\cattify\venv\Scripts\python.exe C:/Projects/cattify/cats_main.py Starting program Preparing data Initialising cats list Adding cats to list Returning list ['Kitty', 'Pussy', 'Paw'] Process finished with exit code 0
Ok. Już wiemy więcej o wykonaniu programu i jego poszczególnych blokach… niby nie daje nam to zbytniej pomocy. Czy na pewno? Wykonajmy proste ćwiczenie.
Psujemy program
Celowo wprowadźmy błąd w postaci odniesienia do nieistniejącego kota. Zrobimy to dla linii:
cats.append(cat2)
Zmień ją na:
cats.append(cat233)
Następnie uruchom program. Powinieneś otrzymać taki wynik:
C:\Projects\cattify\venv\Scripts\python.exe C:/Projects/cattify/cats_main.py
Traceback (most recent call last):
File "C:/Projects/cattify/cats_main.py", line 14, in <module>
cats.append(cat233)
NameError: name 'cat233' is not defined
Starting program
Preparing data
Initialising cats list
Adding cats to list
Process finished with exit code 1
No jest błąd (w PyCharm powinieneś zobaczyć sporo czerwonego tekstu)… Zaczynając od końca. Zauważ, że na końcu ostatniej linii mamy exit code 1, co zdecydowanie oznacza niepoprawne zakończenie programu🤕
Następnie idąc w górę trafiamy na linię:
Adding cats to list
Hmm przejdźmy do kodu gdzie wpisujemy Adding cats to list. Kolejne kroki w naszym programie, które printujemy:
print("Returning list")
print(cats)
nie zostały wykonane. Czyli problem leży gdzieś pomiędzy ostatnim wyprowadzonym na konsolę printem a wiadomością, która nie została wypisana.
Miejsce problemu wydedukowane na podstawie printów:

AHA! Już mogę podejrzewać gdzie jest błąd!
Dzięki naszym printom wiem do jakiego momentu wykonał się nasz program. I mniej więcej potrafimy określić jaka część programu działa poprawnie.
Oczywiście informacja o błędzie na naszej konsoli:
Traceback (most recent call last):
File "C:/Projects/cattify/cats_main.py", line 14, in <module>
cats.append(cat233)
NameError: name 'cat233' is not defined
Mówi nam dokładnie, że błąd jest w line 14 oraz jaka jest prawdopodobna przyczyna problemów. Jednak to nie dyskwalifikuje naszych printów.
Za pomocą printów posiadamy informacje dodatkowe o tym co zostało zrealizowane i łatwiej nam się jest odnaleźć w obszarze gdzie wystąpił błąd.
Wypisujemy wartości
Kolejnym krokiem może być wypisanie wartości. W naszym przypadku mamy problem z listą. Dodajmy więc dodatkowe informacje w formie kodu:
print(f'cats list contains: {cats}')
W ten sposób wypiszemy zawartość listy, poprzedzonej opisem do jakiej zmiennej należy zawartość.
Zrobimy taki print dla każdej modyfikacji listy. Czyli w kodzie może to wyglądać tak:
# Cats inventory advanced manager
print("Starting program")
print("Preparing data")
cat1 = "Kitty"
cat2 = "Pussy"
cat3 = "Paw"
print("Initialising cats list")
cats = []
print(f'cats list contains: {cats}')
print("Adding cats to list")
cats.append(cat1)
print(f'cats list contains: {cats}')
cats.append(cat233)
print(f'cats list contains: {cats}')
cats.append(cat3)
print(f'cats list contains: {cats}')
print("Returning list")
print(cats)
Uruchomimy teraz nasz program. Wynik to:
C:\Projects\cattify\venv\Scripts\python.exe C:/Projects/cattify/cats_main.py
Traceback (most recent call last):
File "C:/Projects/cattify/cats_main.py", line 16, in <module>
cats.append(cat233)
NameError: name 'cat233' is not defined
Starting program
Preparing data
Initialising cats list
cats list contains: []
Adding cats to list
cats list contains: ['Kitty']
Process finished with exit code 1
Tutaj już bez problemu możemy przeczytać, że główny problem nastąpił gdzieś po dodaniu pierwszego kota 'Kitty' do listy. Możemy też przypuszczać, że przyczyna problemu tkwi w linii w, której do listy dodajemy zmienną z kolejnym kotem😾 Tym samym jeszcze bardziej zawęziliśmy obszar problemów.
Logowanie to osobny, niezwykle ważny temat. Z dobrych logów możemy rozszyfrować przyczynę błędu i zaawansowane debugowanie będzie wtedy znacznie efektywniejsze a czasami nawet niepotrzebne.
Naprawiamy i podziwiamy
Pozostało nam teraz tylko poprawić zepsutą linię:
cats.append(cat233)
Na poprawną:
cats.append(cat2)
I uruchomić program, dzięki czemu zobaczymy dość dokładny opis kroków programu i wartości listy:
Starting program Preparing data Initialising cats list cats list contains: [] Adding cats to list cats list contains: ['Kitty'] cats list contains: ['Kitty', 'Pussy'] cats list contains: ['Kitty', 'Pussy', 'Paw'] Returning list ['Kitty', 'Pussy', 'Paw']
No dobra, tak sobie prymitywnie podebugowaliśmy ale chyba nie będziemy wszędzie tych printów wrzucać? Na dłuższą metę byłoby to męczące. Wyobraź sobie, że będziemy mieć bardzo dużo różnych zmiennych – byłby niezły chaos z setkami printów w kodzie..
Dlatego poznamy bardziej zaawansowaną strategię debugowania a pomoże nam w niej potężne narzędzie, które otrzymujemy razem z PyCharmem.
