1E: Błędy

Im więcej będziesz programować, tym więcej, w sposób naturalny, napotkasz błędów (errors lub bugs). Poznanie przyczyny, zrozumienie i naprawienie błędów jest ważną częścią programowania. Python dokłada wszelkich starań, aby uruchomić wszystko, co każesz mu zrobić, ale jeśli nie potrafi zrozumieć tego, o co prosisz, nie uruchomi programu i wyświetla informacje o błędach. W ten sam sposób Python próbuje przekazać ci trochę informacji o tym, co poszło nie tak, aby pomóc Ci to naprawić.

Oto dwa przykłady błędów w Pythonie.

Przykład: A Syntax Error

W tym pierwszym przykładzie zapomniano o nawiasach, które są wymagane przy poleceniu print(...). Python nie rozumie, co próbujesz zrobić.

Tutaj znajduje się drugi przykład błędu w Pythonie.

Przykład: A Run-Time Error

W drugim przykładzie zapomniano zdefiniować zmienną greeting. Python wie, co chcesz, ale ponieważ nie zdefiniowano greeting, pojawia się błąd.

Błąd składniowy (syntax error) jest wtedy, gdy Python nie może zrozumieć, co od niego chcesz. Błąd wykonania (run-time error) jest wtedy, gdy Python rozumie to, co mówisz, ale ma problem z wykonaniem twoich instrukcji.

W języku polskim błąd składnikowy (syntax error) byłby podobny do zdania:

Proszę kot pies małpa.

Gramatyka tego zdania nie ma sensu. Z punktu widzenia gramatyki brak jest czasownika (działania). Nie można zrozumieć, o co chodzi w tym zdaniu. Składnia w programowaniu oznacza to samo co gramatyka dla języka polskiego.

W języku polskim błąd wykonania (run-time error) byłby podobny do zdania:

Proszę zjedz pianino.

Z perspektywy gramatycznej zdanie ma sens - we właściwym miejscu znajduje się czasownik i rzeczownik - więc wiesz, o co poproszono. Ale napotykasz problemy, gdy zaczniesz starać się jeść fortepian (chyba, że jesteś termitem). Jest to błąd wykonania (run-time error), ponieważ występuje po uruchomieniu programu.

Mówimy również o błędach logicznych (logic errors), kiedy program działa bez awarii, ale nadal generuje nieprawidłowy wynik. Przykład

Proszę zamknąć tylne drzwi tak, aby nie dostały się insekty.

Jeśli drzwi przednie są również otwarte, byłoby to błąd logiczny: mimo że polecenie ma sens i można zamknąć tylne drzwi, to w rzeczywistości nie osiąga się celu, jakim jest zabezpieczenie przed insektami, ponieważ będą one mogły nadal wchodzić przednimi drzwi.

Typowe błedy składniowe w Pythonie

Oto kilka dodatkowych przykładów błędów składniowych w Pythonie. Jedną z rzeczy, która może się zdarzyć, jest to, że Python napotyka specjalny symbol w miejscu, którego się nie spodziewa.

Przykład: Syntax Error

Python mówi SyntaxError: invalid syntax i wskazuje symbolem ^ na ! wykrzyknik. Problemem jest następujący, ! nie ma określonego znaczenia w Pythonie. Błąd składniowy znikłby, gdybyśmy mieli wydrukować ("Hello, World!"), Ponieważ wtedy Python zrozumiałby, że ! jest częścią tekstu Hello, World.

Oto inny błąd składniowy (syntax error), bardziej subtelny.

Przykład: Syntax Error

Problem polega na tym, że class jest specjalnym słowem w Pythonie. Gdy by napisać course zamiast class, byłoby dobrze. Kliknij tutaj, aby wyświetlić listę wszystkich specjalnych "słów kluczowych" w Pythonie.

Jeśli chcesz użyć cudzysłowów wokół tekstu, ale zapominasz o drugim ze znaków, lub używasz nawiasów i zapominasz o drugim z nawiasów, wtedy otrzymasz błąd składniowy (syntax errors):

Przykład: Syntax Error
Zapomnienie drugiego cudzysłowu

W tym błędzie (EOL to skrót od End Of Line): Python spodziewał jeszcze jednego znaku ", ale linia zakończyła się przed jego znalezieniem.

Przykład: Syntax Error
Zapomnienie drugiego nawiasu

Podobnie (EOF to skrót od End Of File): Python szukał drugiego ), ale plik programu zakończył się, zanim został on znaleziony.

Czasami dwa bardzo podobne błędy składniowe (syntax errors) mogą dać dwa bardzo różne komunikaty o błędach. Ale każdy komunikat o błędzie próbuje przekazać jakieś informacje naprowadzające.

Błędy wykonania

Oto kilka typowych błędów wykonania (run-time errors). Python potrafi zrozumieć, co program mówi, ale ma problem z wykonaniem instrukcji:

  • używając niezdefiniowanej zmiennej lub funkcji. Może się zdarzyć, że używasz dużych liter niezgodnie z nazwą zmiennej:
    Przykład
    Niezdefiniowanie zmiennej
  • dzieląc przez zero, co nie ma sensu w matematyce. (Ponieważ 0 razy dowolna liczba wynosi 0, więc nie ma rozwiązania dla 1 = X * 0, zatem 1/0 jest niezdefiniowane).
    Przykład
    Dzielenie przez zero
  • używając operatorów do nieprawidłowych typów danych
    Przykład
    Dodawanie tekstu i liczby

Gdy dowiesz się więcej o Pythonie, poznasz więcej sytuacji, w których powstają błędy.

Jaka jest różnica techniczna pomiędzy błędem składniowym a błędem wykonania? Oto przykład porównujący błąd wykonania z błędem składni. Spójrz na wyjście każdego programu.
Przykład: Run-Time Error
Przykład: Syntax Error
Program z błędem wykonania (run-time error) wyświetlił pewne dane wyjściowe, ale program z błędem składniowym (syntax error) nie. Dzieje się tak, ponieważ Python działa w dwóch krokach:

  1. Python sprawdza, czy program ma poprawną składnię, czy ma określoną strukturę i części.
  2. Jeśli w kroku 1 nie napotka błędów składniowych, program zostanie wykonany.

Zatem, program z błędami składniowymi nie wykona żadnego kroku, ale program z błędem wykonania wykona kroki do miejsca przed wystąpieniem błędu.

Błędy logiczne

Twój program może działać bez awarii (nie ma błędów składni ani błędów wykonania), ale nadal może nie robić tego co trzeba. Na przykład, jeśli chcesz, aby program obliczył średnią z dwóch liczb x i y zdefiniowaną jako:

\displaystyle{\frac{x+y}{2}}

Dlaczego ten program nie działa?

Przykład
Ten przykład nie oblicza średniej.

Średnia powinna być

\displaystyle{\frac{x+y}{2}=\frac{3+4}{2}=\frac{7}{2}=3.5}

ale program wyświetla 5.0! Ten błąd ma teraz związek z "kolejnością operacji" w arytmetyce. Kiedy piszesz x + y / 2, ma to samo znaczenie matematyczne co: x + (y / 2) = 3 + (4 / 2) = 3 + 2 = 5. Aby rozwiązać ten problem, trzecia linia naszego programu powinna być zapisana jako średnia = (x + y) / 2, co czyni jasne dla Pythona, że my wartości: \frac{x+y}{2}, gdzie najpierw dodajemy a potem dzielimy.

Błędy logiczne mogą wystąpić, gdy program nieprawidłowo zostanie zaprojektowany lub gdy kod zostanie nieprawidłowo wpisany (tak jak w przykładzie ze średnią). Błędy logiczne mogą być trudne do zauważenia, zwłaszcza w dłuższym programie, ale im lepszy będziesz w pisaniu kodu, tym łatwiej będziesz unikać błędów logicznych. Lekcja 6D zawiera wskazówki dotyczące unikania błędów logicznych.

Ćwiczenia

Teraz, gdy lekcja jest kompletna, mamy trzy ćwiczenia dotyczące debugowania (identyfikowania i naprawiania błędów w programach). Przed uruchomieniem programów można spróbować wykryć błędy, albo najpierw uruchomić je i użyć podpowiedzi Python, w celu ustalenia, co trzeba zmienić.

Kod każdego programu jest już odpowiednio dla Ciebie przygotowany. Aby naprawić każdy z programów, wystarczy zmienić kilka znaków (litery/symbole/cyfry). Automatyczny tester odrzuci rozwiązania ze zbyt wieloma zmianami znaków. Wybierz opcję Resetuj kod, jeśli chcesz przywrócić pierwotną wersję.

Zadanie na kodowanie : Sumowanie
Popraw błąd składniowy w następującym programie tak, aby wydrukować sumę wszystkich liczb od 1 do 10. Możesz zmienić co najwyżej jeden znak.

Zadanie na kodowanie : Hello Joe
Napraw błąd wykonania w programie tak, aby wydrukował on Hello w pierwszej linii i Joe w drugiej linii. Możesz zmienić co najwyżej dwa znaki.

Zadanie na kodowanie : Zakupy
Idziesz na zakupy po mięso i mleko, ale produkty te są opodatkowane. Mleko kupujesz za 2,00zł a mięsa za 4,00zł, a podatek wynosi 3%. Wydrukuj całkowity koszt twoich artykułów spożywczych (nie wyświetlaj znaku waluty). Wskazówka

Kiedy pozbędziesz się wszystkich błędów, możesz przejść do następnej lekcji!