Jak uniknąć debugowania

Prawdopodobnie najważniejsza lekcja na temat debugowania to fakt, że można go w dużej mierze uniknąć, jeżeli pracujesz uważnie.

  1. Zacznij powoli Jest to prawdopodobnie jedna z najważniejszych rad dla programistów na każdym stopniu wtajemniczenia. Kuszące jest oczywiście, aby siąść do komputera i napisać cały program na raz. Ale, kiedy program nie będzie działał, a jest to nieuniknione, będziemy mieli miliarady możliwych rzeczy, które mogły pójść nie tak. I skąd teraz zacząć? Gdzie spojrzeć najpierw? Jak pojąć co poszło źle? Wrócimy do tego w kolejnej części. Tak więc – zacznij od czegoś naprawdę małego. Może jedynie dwie linie na początku i upewnij się, że one działają. Naciśnięcie guzika „uruchom” jest łatwe i szybkie, a daje nam od razu odpowiedź na pytanie, czy to co właśnie napisałem jest poprawne czy nie. Innym pożytkiem posiadania choćby małego kawałka kodu jest to, że mamy coś, co możemy już komuś przekazać. Zawsze lepiej oddać nieduży, niekompletny program niż nie oddawać nic.
  2. Utrzymuj działający kod Jak już mamy małą, ale działającą część naszego programu to kolejnym krokiem jest wymyślenie jak dodać do niego kolejny nieduży kawałek kodu. Jeżeli będziecie dodawać małe części kodu na raz to będzie znacznie łatwiej zrozumieć, co poszło nie tak. Najczęściej problem będzie leżał w tym kawałku kodu, który właśnie dodaliście. Im mniej nowego kodu na raz, tym łatwiej zrozumieć, gdzie leży błąd.

Idea, by stworzyć i utrzymać coś, co działa jest jak mantra, którą możecie sobie powtarzać w czasie swojej kariery programisty. Jest to znakomita metoda, aby uniknąć pojawienia się frustracji wspomnienej powyżej. Pomyśl o tym w ten sposób - za każdym razem, gdy osiągasz nawet mały sukces, twój mózg uwalnia niewielką porcję substancji chemicznej, która sprawia, że jesteś szczęśliwy. Tak więc jesteś w stanie utrzymywać się w stanie szczęśliwości oraz spowodować, że programowanie będzie znacznie bardziej przyjemne poprzez doprowadzenie do szeregu małych zwycięstw.

Spójrzmy na przykład. Spróbujmuy rozwiązać problem z problemu numer 3, który można znaleźć na końcu rozdziału Podstawy Python. Zapytaj użytkownika o aktualny czas (godzinę z przedziału 0 - 23) oraz o liczbę godzin, jaką musimy odczekać. Wasz program powinien zwracać, jaka będzie godzina, kiedy wyłączymy alarm.

Jak zatem zacząć? Problem ten wymaga dwóch danych od użytkownika, Zaczniemy więc od tego i upewnimy się, że dostaniemy takie dane, których potrzebujemy.




(db_ex3_1)

Póki co wszystko dobrze. Teraz pójdziemy dalej. Musimy obliczyć, która będzie godzina, gdy minie wait_time godzin. Całkiem niezłym pierwszym przybliżeniem będzie proste dodanie obu czasów wait_time i current_time i wydrukowanie na ekranie wyniku tych obliczeń. Spróbujmy.




(db_ex3_2)

Jeżeli uruchomimy teraz ów przykład to okaże się, że dzieje się coś dziwnego.

debug-2-1: Które zdanie najlepiej oddaje to, co dzieje się z naszym programem?




Błąd ten najprawdopodobniej bardzo łatwo zauważyć, ponieważ drukujemy końcową wartość final_time i widać gołym okiem, że obie liczby są po prostu sklejone ze sobą, a nie dodane do siebie. Jak sobie poradzić z tym problemem? Musimy przekształcić zarówno current_time jak i wait_time do typu int. Na tym stopniu nauki programowania może przydać się proste dopisanie typu zmiennej do jej nazwy. Przyjrzyjmy się kolejnemu przybliżeniu programu, a w szczególności zamianie do typu int.




(db_ex3_3)

Teraz jest już dużo lepiej, a tak naprawdę w zależności od godzin, jakie podacie może być nawet zupełnie poprawnie. Jeżeli wprowadzicie 8 jako godzinę obecną oraz 5 dla czasu oczekiwania, to otrzymacie poprawną liczbę 13. No, ale jeżeli wprowadzicie 17 dla czasu obecnego i 9 dla czasu oczekiwania, to wynikiem będzie liczba 26, która nie jest do końca poprawna. Ilustruje to niezwykle ważny aspekt testowania programu z użyciem sporego zakresu możliwych danych wejściowych. Szczególnie istotne jest przetestowanie swojego kodu pod kątem działania dla warunków brzegowych. W tym przypadku przydałoby się przetestować program dla różnych czasów, włączając w to liczby 0 oraz 23 i kilka innych z tego przedziału. Dobrze byłoby przetestować czas oczekiwania dla liczby 0 oraz kilku innych, naprawdę dużych liczb. A co z liczbami ujemnymi? Nie mają one za bardzo sensu w tym konkretnym przypadku, ale ponieważ nie mamy na razie narzędzi, by sobie z tym problemem poradzić tak, by przekazać użytkownikowi, że coś jest nie tak nie będziemy się tym przez chwilę przejmować.

Ostatecznie musimy sobie poradzić z liczbami, które są większe od 23. Aby to zrobić w ostatnim przybliżeniu użyjemy operatora modulo.




(db_ex3_4)

Oczywiście nawet przy tej prostej rozbudowie można pobłądzić na kilka sposobów. Teraz zidentyfikujemy i przyjrzymy się kilku takim problemom.

Następna część - Wstępne uwagi na temat debugowania