Program zapisany w języku PHP ma za zadanie obliczyć średnią ocen ucznia od 2 do 5, czyli z pominięciem ocen niedostatecznych i celujących (oceny są liczbami całkowitymi od 1 do 6). Warunek wybierania ocen w pętli liczącej średnią powinien zawierać wyrażenie logiczne
A. $ocena > 2 and $ocena < 5
B. $ocena > 2 or $ocena < 5
C. $ocena >= 2 and $ocena <= 5
D. $ocena >= 2 or $ocena <= 5
Warunek $ocena >= 2 and $ocena <= 5 jest właściwy, bo sprawdza jednocześnie dwie granice przedziału: ocena ma być większa lub równa 2 oraz mniejsza lub równa 5. Czyli do średniej trafią dokładnie wartości 2, 3, 4 i 5, a zostaną pominięte 1 oraz 6. To jest klasyczny test przynależności liczby do przedziału domkniętego. W praktyce przy filtrowaniu danych zawsze trzeba jasno określić, czy granice są wliczane. Tutaj sformułowanie od 2 do 5 oznacza, że 2 i 5 też mają być brane pod uwagę. Moim zdaniem to jedno z tych miejsc, gdzie drobny znak równości robi dużą różnicę. W PHP taki warunek można zastosować np. w instrukcji if wewnątrz pętli przechodzącej po tablicy ocen: jeśli warunek jest spełniony, dodajemy ocenę do sumy i zwiększamy licznik. Dobrą praktyką w PHP jest też często używanie operatora && zamiast and, bo ma bardziej typowy priorytet i mniej zaskakuje przy przypisaniach, ale w samym warunku if zapis z and jest czytelny i poprawny.
W tym zadaniu najważniejsze jest zrozumienie, że chodzi o jednoczesne spełnienie dwóch warunków: ocena nie może być za mała i nie może być za duża. Operator or oznacza alternatywę, czyli wystarczy spełnienie tylko jednej części warunku. To często prowadzi do bardzo podstępnego błędu. Wyrażenie $ocena > 2 or $ocena < 5 będzie prawdziwe praktycznie dla każdej szkolnej oceny od 1 do 6, bo nawet 1 spełnia warunek $ocena < 5, a 6 spełnia warunek $ocena > 2. W efekcie program nie odfiltruje poprawnie ani niedostatecznych, ani celujących. Podobny problem występuje przy $ocena >= 2 or $ocena <= 5, ponieważ dla ocen z zakresu 1-6 każda wartość spełni przynajmniej jedną stronę takiego testu. To nie jest filtr przedziału, tylko bardzo szeroka alternatywa. Z kolei zapis $ocena > 2 and $ocena < 5 używa już dobrego operatora logicznego, bo and wymaga spełnienia obu warunków naraz, ale granice są dobrane źle. Taki warunek przepuści tylko 3 i 4, a przecież oceny 2 oraz 5 również mają być liczone do średniej. Typowy błąd myślowy polega tu na pomyleniu zwrotu od 2 do 5 z przedziałem otwartym. W programowaniu trzeba bardzo pilnować operatorów porównania: > i < wykluczają granice, natomiast >= i <= je włączają. Z mojego doświadczenia najlepiej przetestować taki warunek na kilku konkretnych wartościach, np. 1, 2, 5 i 6, bo wtedy od razu widać, czy logika działa tak, jak zakładamy.