Cichy Fragles

skocz do treści

Dlaczego programiści robią tyle błędów

Dodane: 27 czerwca 2019, w kategorii: Varia

Nie ma chyba zawodu, którego przedstawiciele popełnialiby więcej błędów niż programiści. No, może oprócz futurologów i ekspertów politycznych, ale oni nie ponoszą konsekwencji swoich błędów – opinia publiczna zwykle zapomina o prognozach, zanim się zdążą okazać błędne, więc można się bezkarnie mylić notorycznie. Programiści tak dobrze nie mają – błędy muszą systematycznie poprawiać, a poprawki te kosztują przy przeciętnym projekcie około jednej trzeciej czasu pracy. Czemu jest tak źle, skoro programowaniem – w przeciwieństwie do polityki – nie zajmują się przecież byle kretyni?

Cóż, pokażmy na przykładzie, jak to tajemnicze programowanie wygląda.

Żeby rzecz była zrozumiała dla laików, pomińmy wszelkie możliwe szczegóły techniczne i wiedzę tajemną. Zamiast tego wyobraźmy sobie, że możemy zaprogramować komputer, po prostu opisując mu pożądane działania po ludzku – i spróbujmy w ten sposób przedstawić jakieś prościutkie zadanie. Na przykład działanie budzika w komórce. Powiedzmy, że chcemy mieć prostacki budzik, w którym ustawiamy godzinę i minutę, a on będzie nam codziennie dzwonić. Mniejsza o samo ustawianie czasu – załóżmy, że to już mamy zrobione razem z całym interfejsem i ładnym czerwonym przyciskiem do wyłączania budzika, musimy więc tylko zaimplementować dzwonienie.

Jeśli aktualny czas w zegarku jest równy czasowi ustawionemu w budziku, włącz dzwonek.
Jeśli został wciśnięty czerwony przycisk, wyłącz dzwonek.

Nic prostszego, prawda? No to ustawmy budzik i przetestujmy… Ups, nie działa. Czemu? Ano temu, że w budziku ustawiamy tylko godzinę i minutę, a w zegarku są jeszcze sekundy – a dla komputera 7:00:00 to nie to samo co 7:00, więc warunek nie jest spełniony. Poprawmy:

Jeśli aktualna godzina i minuta jest równa godzinie i minucie ustawionej w budziku, włącz dzwonek.
Jeśli został wciśnięty czerwony przycisk, wyłącz dzwonek.

Testujemy ponownie – i dzwonek się ładnie włączył, ale wyłączyć się nie chce. Dlaczego? Dlatego, że podane warunki są sprawdzane w kółko, więc natychmiast po wyłączeniu dzwonka komputer stwierdza, że godzina i minuta się zgadza, więc włącza go ponownie i nie ma sposobu, żeby temu zapobiec, dopóki nie minie pełna minuta, czas przestanie się zgadzać i czerwony przycisk w końcu zadziała. Robimy zatem kolejną poprawkę:

Jeśli aktualna godzina i minuta jest równa godzinie i minucie ustawionej w budziku i nie wciśnięto czerwonego przycisku, włącz dzwonek.
Jeśli został wciśnięty czerwony przycisk, wyłącz dzwonek i zapamiętaj, że wciśnięto czerwony przycisk.

Dobra, teraz dzwonek grzecznie się wyłącza – ale następnego dnia już nie włącza się w ogóle. Co tym razem? No cóż, komputer cały czas pamięta, że wciśnięto czerwony przycisk, więc warunek na odpalenie dzwonka nie jest spełniony – i już nigdy nie będzie. Jak to naprawić?

Jeśli aktualna godzina i minuta jest równa godzinie i minucie ustawionej w budziku i nie wciśnięto dzisiaj czerwonego przycisku, włącz dzwonek.
Jeśli został wciśnięty czerwony przycisk, wyłącz dzwonek i zapamiętaj, że wciśnięto czerwony przycisk.

Teraz budzik działa już codziennie – ale jeszcze nie ma happy endu. Co się bowiem stanie, jeśli po przebudzeniu przestawimy go na późniejszą godzinę? No właśnie – budzik nie zadzwoni, bo przycisk został już dzisiaj wciśnięty. Jeszcze jedna poprawka…

Jeśli aktualna godzina i minuta jest równa godzinie i minucie ustawionej w budziku i nie wciśnięto dzisiaj czerwonego przycisku, włącz dzwonek.
Jeśli został wciśnięty czerwony przycisk, wyłącz dzwonek i zapamiętaj, że wciśnięto czerwony przycisk.
Jeśli czas w budziku został zmieniony, zapomnij, że wciśnięto czerwony przycisk.

Uff, nareszcie wszystko działa jak należy.

I w tym momencie wchodzi klient, cały na biało, i oznajmia, że jednak musimy dorobić jeszcze przycisk drzemki. Klient nasz pan, więc dorabiamy – tu już litościwie oszczędzę Wam kolejnych kroków, ograniczając się do efektu końcowego:

Jeśli aktualna godzina i minuta jest równa godzinie i minucie ustawionej w budziku i nie wciśnięto dzisiaj żadnego przycisku, włącz dzwonek.
Jeśli rezerwowy budzik jest aktywny, aktualna godzina i minuta jest równa godzinie i minucie ustawionej w rezerwowym budziku i nie wciśnięto w ciągu ostatniej minuty przycisku drzemki, włącz dzwonek.
Jeśli został wciśnięty czerwony przycisk, wyłącz dzwonek i zapamiętaj, że wciśnięto czerwony przycisk.
Jeśli został wciśnięty przycisk drzemki, wyłącz dzwonek, zapamiętaj, że wciśnięto przycisk drzemki, aktywuj rezerwowy budzik i ustaw go na godzinę o pięć minut późniejszą od aktualnej.
Jeśli czas w budziku został zmieniony, deaktywuj rezerwowy budzik i zapomnij, że wciśnięto którykolwiek przycisk.

Czy na pewno końcowego? A może została tu jeszcze jakaś niedoróbka? Śmiało, spróbujcie przeanalizować ten niby-kod i odpowiedzieć w komentarzu (obecnych na sali programistów proszę o niepodpowiadanie).

Ten przykład daje chyba wystarczające wyobrażenie, jak łatwo jest zrobić błąd przy pisaniu kodu. A przecież cały czas mówimy tu o programiku zupełnie trywialnym, który nawet napisany w prawdziwym kodzie zmieściłby się z grubsza na ekranie – cóż więc powiedzieć o dużych profesjonalnych projektach, przy których budzik wygląda jak fajerwerk przy rakiecie kosmicznej, z całymi tonami drobnych niuansów i zależności…

Wierzę, że mając to wszystko na uwadze, spojrzycie na programistów i ich nieuniknione błędy nieco łaskawszym okiem.


Komentarze

Podobne wpisy