Wskaż zapisany w języku JavaScript warunek, który ma sprawdzić spełnienie przynajmniej jednego z przypadków:
1) dowolna naturalna liczba a jest trzycyfrowa
2) dowolna całkowita liczba b jest ujemna
A. ((a > 99) || (a < 1000)) || (b < 0)
B. ((a > 99) || (a < 1000)) && (b < 0)
C. ((a > 99) && (a < 1000)) || (b < 0)
D. ((a > 99) && (a < 1000)) && (b < 0)
Pytanie z egzaminu CKE, czerwiec 2017 (arkusz E.14-X-17.06).
Warunek ((a > 99) && (a < 1000)) || (b < 0) dobrze oddaje treść zadania, bo rozdziela dwa osobne przypadki i łączy je operatorem logicznym OR, czyli ||. Liczba naturalna a jest trzycyfrowa wtedy, gdy jest większa od 99 i jednocześnie mniejsza od 1000. To właśnie oznacza fragment (a > 99) && (a < 1000). Operator && wymaga spełnienia obu warunków naraz, więc odrzuca np. 50 oraz 1200, a przepuszcza 100, 345 czy 999. Drugi przypadek, czyli liczba całkowita b jest ujemna, zapisuje się prosto jako b < 0. Ponieważ zadanie mówi o spełnieniu przynajmniej jednego z przypadków, oba większe warunki trzeba połączyć przez ||. W praktycznym kodzie JavaScript taki zapis przydaje się np. przy walidacji formularza, gdy dopuszczamy użytkownika dalej, jeśli podał poprawny trzycyfrowy kod albo jakaś wartość kontrolna jest ujemna. Moim zdaniem nawiasy są tu bardzo dobrą praktyką, nawet jeśli JavaScript zna priorytety operatorów. Kod jest czytelniejszy, łatwiej go sprawdzić i trudniej o głupi błąd przy późniejszej rozbudowie warunku. W profesjonalnym kodzie często poszłoby się jeszcze krok dalej i sprawdziło typ danych, np. Number.isInteger(a), ale na poziomie tego pytania kluczowe są operatory && oraz ||.
W tym zadaniu najłatwiej pomylić znaczenie słów „i” oraz „lub” w warunkach logicznych. Sprawdzenie, czy a jest liczbą trzycyfrową, nie może być zapisane jako (a > 99) || (a < 1000), bo taki warunek jest w praktyce prawie zawsze spełniony. Dla liczby 50 prawdziwe jest a < 1000, dla liczby 5000 prawdziwe jest a > 99, więc operator || przepuści wartości, które wcale nie są trzycyfrowe. Żeby liczba była trzycyfrowa, musi jednocześnie przejść dolną i górną granicę zakresu, czyli trzeba użyć &&. To jest typowy błąd wynikający z czytania warunku po polsku zbyt szybko: „większa od 99 lub mniejsza od 1000” brzmi pozornie podobnie, ale logicznie znaczy coś zupełnie innego niż zakres od 100 do 999. Druga część zadania też jest ważna: polecenie mówi, że wystarczy spełnienie przynajmniej jednego przypadku. Dlatego warunek dotyczący trzycyfrowości a oraz warunek b < 0 muszą być połączone operatorem ||, a nie &&. Użycie && między tymi dużymi częściami oznaczałoby, że oba przypadki muszą zajść naraz, czyli a musi być trzycyfrowe i b musi być ujemne. To za mocne ograniczenie. Z mojego doświadczenia takie pomyłki często wychodzą przy walidacji formularzy albo filtrowaniu danych, gdzie jeden źle dobrany operator logiczny powoduje, że aplikacja akceptuje za dużo danych albo odrzuca poprawne przypadki. Dobra praktyka w JavaScript to stosować nawiasy grupujące i czytać warunek fragmentami: najpierw zakres liczby, potem osobny przypadek, na końcu połączenie całości.