czwartek, 6 kwietnia 2023

Czym jest operator logiczny i instrukcja warunkowa - czyli teoria teorii programowania #2

Ostatni poznaliśmy pojęcie zmiennej. Teraz czas na nieco bardziej rozbudowane zagadnienia, czyli operatory logiczne oraz instrukcje warunkowe.




Pojęcie "operator logiczny" może wydawać się niezwykle skomplikowane jednak w rzeczywistości są to bardzo proste operacje.

Najprościej mówiąc to operatory logiczne, sprawdzają czy dane zdarzenie jest "logiczne" czyli prawdziwe. 

Wyobraźmy sobie, że gramy w piłkę nożną. Zawodnik kopnął w piłkę i aby zaliczyć gol muszą zostać spełnione następujące elementy:

  1. Piłka musi wpaść do bramki,
  2. Zawodnik nie może być na pozycji "spalonej".
Mamy więc prostą logikę. Jeżeli zostanie spełniony tylko jeden z tych warunków np. piłka wpadła do bramki (przeciwnika 😉) jednak zawodnik był na pozycji "spalonej" wówczas nie możemy uznać gola. 
Analogicznie, jeżeli piłka nie wpadła do bramki (np. odbiła się), ale zawodnik nie był na pozycji spalonej wówczas również nie możemy uznać gola.

Operator logiczny koniunkcja inaczej AND


Proste? Może inny przykład. 

Jeżeli chcemy zaparzyć herbatę musimy mieć:
  1. Kubek,
  2. Gorącą wodę,
  3. Torebkę z herbatą,

Teraz musimy tylko zalać kubek z herbatą gorącą wodą.

Jeżeli mamy gorącą wodę (w czajniku), torebkę z herbatą jednak nie mamy kubka. Nie możemy zrobić herbaty. 
Analogicznie, jeżeli mamy kubek, ale nie mamy ani gorącej wody, ani torebki z herbatą? Wówczas też nie możemy zrobić herbaty.

Przedstawione tutaj operacje to tzw. operacje koniunkcji. Koniunkcja zakłada, że każdy warunek musi zostać spełniony. Podam jeszcze jeden przykład.

Chcemy iść na koncert, ale są następujące warunki:
  1. Musimy mieć 18 lat lub więcej (to ważne),
  2. Musimy mieć bilet na koncert.
Jeżeli mamy 18 lat lub więcej oraz mamy bilet wówczas możemy wejść na koncert. 
Jeżeli nie mamy mniej niże 18 lat, ale mamy bilet. Niestety, ale nie możemy wejść na koncert.
Jeżeli mamy 18 lat lub więcej, ale nie mamy biletu, również nie możemy wejść na koncert.

Dlaczego "lub więcej" jest ważne ? Ponieważ warunek musi sprawdzić czy 18 lat jest poprawne.
Prosta arytmetyka:
> oznacza większe
>=  oznacza większe LUB równe

Jeżeli nasz warunek oznacza musisz mieć przynajmniej 18 lat oznacza, że mając 18 lat spełniamy warunek. Jednak, jeżeli warunek oznaczał by więcej niż 18 lat, wówczas wartości powyżej 18 lat są poprawne. 

Kolejnym operatorem logicznym jest alternatywa. Jest to taka bardziej liberalna forma koniunkcji.
Alternatywa zakłada, że przynajmniej 1 warunek musi być poprawny, aby wszystko zadziałało.

Operator logiczny alternatywa inaczej OR


Załóżmy, że chcemy zjeść płatki z mlekiem.
Musimy mieć:
  1. Mleko
  2. Płatki
Jeżeli mamy mleko i płatki możemy zjeść płatki z mlekiem - wynik najlepszy.
Jeżeli mamy mleko, ale nie mamy płatków, możemy wypić mleko - alternatywa.
Jeżeli nie mamy mleka, ale mamy płatki, możemy zjeść płatki - alternatywa.
Jeżeli nie mamy mleka ani płatów, wówczas nie możemy nic zjeść. 

Operator alternatywy nie zawsze jest możliwy. Nasz przykład z piłką nożną tutaj nie mógłby zostać użyty, ponieważ wynik jaki chcemy uzyskać to gol. On może zostać uznany tylko po spełnieniu wszystkich warunków. Przykład z płatkami i mlekiem zakłada, że chcemy coś zjeść i jeżeli chociaż jeden warunek jest poprawny, możemy to wykonać.

To są 2 najpopularniejsze argumenty.
Koniunkcja - zakłada, że każdy warunek musi zostać spełniony.
Alternatywa - zakłada, że chociaż jeden warunek musi zostać spełniony.

Jest jeszcze jeden argument, nazywa się negacją. Sprawia on, że to co było prawdą staje się fałsze, i odwrotnie. Fałsz staje się prawdą.

Przykładowo.

Chcemy sprawdzić czy piłkarz po strzale zdobędzie gola, warunki są następujące.
Musi piłka wpaść do bramki,
Piłkarz nie może być na pozycji spalonej.

Więc sprawdzamy
Piłka wpadła - prawda
Pozycja spalona - fałsz - czyli dobrze
Więc musimy dokonać negacji "Pozycja spalona" aby dostać wynik prawda.

Ponieważ w tym przykładzie my jako ludzie rozumiemy kontekst tego, że pozycja spalona nie może być aby gol został uznany. Program niestety tego nie rozumie tak jak my, wiec musimy dokonać negacji aby każdy warunek był prawdziwy.

Instrukcja warunkowa inaczej IF


Jest to wykorzystanie operatorów logicznych do kierowania przepływem programu. 
Jest to zapytanie logiczne,

    jeżeli piłka wpadła do bramki oraz piłkarz nie był na pozycji spalonej to uznaj, że jest gol

Tak można odczytać instrukcję warunkową w najprostszym przykładzie. 

Instrukcja warunkowa ma następującą budowę

if  - jeżeli - oznacza, że tutaj zaczyna się instrukcja
warunek - musimy określić co sprawdzamy 
polecenie co dalej jeżeli warunek jest poprawny

przykład instrukcji warunkowej dla języka Python

login = "admin"
password = "admin"

if login == "admin" and password == "admin":
    print("Zalogowałeś się")
else:
    print("Błąd")

Sprawdzamy czy login oraz hasło spełniają warunek, jeżeli tak wyświetli się wiadomość, że się zalogowaliśmy.  W przeciwnym wypadku jest błąd.

Możemy jednak ten przykład rozbudować 
if - jeżeli ...
else - w przeciwnym razie ... czyli jak instrukcja warunkowa nie zostanie wykonana. 

Jednak pomiędzy if oraz else możemy dodać inne zapytania. Wykorzystam tutaj przykład z wiekiem oraz biletem na koncert.

age = 18
ticket = True 

if age >= 18 and ticket == True:
    print("Możesz wejść na koncert")
    
elif age >= 18 and ticket == False:
    print("Niestety, ale nie posiadasz biletu")

elif age < 18 and ticket == True:
    print("Niestety, ale nie masz 18 lat")
    
else:
    print("Niestety, ale nie masz ani 18 lat ani biletu")

Przypominam, że jest to kod w Pythonie. W innych językach instrukcja warunkowa może wyglądać inaczej. 

elif - to alternatywne zapytanie, sprawdzane wówczas, gdy if da odpowiedź negatywną.

Możemy również zapisać to tak:

if age >= 18 and ticket == True:
    print("Możesz wejść na koncert")
    
elif age >= 18 and not(ticket == True):
    print("Niestety, ale nie posiadasz biletu")

elif not(age >= 18) and ticket == True:
    print("Niestety, ale nie masz 18 lat")
    
else:
    print("Niestety, ale nie masz ani 18 lat ani biletu")

Widzimy tutaj koniunkcję, gdyż oba warunki muszą być spełnione oraz negację.

Przykładowy kod można odpalić tutaj

Jeżeli age jest większy lub równy 18 oraz posiadamy bilet (daje nam wartość True) możemy wejść na koncert. Jednak jeżeli age lub ticket da wartość inną niż True czyli wiek będzie mniejszy niż 18 lub bilet nie da wartości True nastąpi coś innego. 

Wartość True

Operator logiczny oraz instrukcja warunkowa zwracają 2 wartości
Prawda - True - 1
Fałsz - False - 0

Można spytać w jakim celu tworzyć takiego tasiemca możemy spytać
jeżeli .... możesz wejść
w przeciwnym razie nie możesz wejść

Jednak wyobraźmy sobie grę RPG.

exp = 0

item_1 = 1
item_2 = 1
item_3 = 0 

if item_1 == True and item_2 == True and item_3 == True:
    exp += 500
elif item_1 == True and item_2 == True and item_3 == False:
    exp += 200
elif item_1 == True and item_2 == False and item_3 == False:
    exp += 100
else:
    print("nie możesz dostać exp")

print(exp)

Chcemy nagrodzić gracza za dostarczenie 3 przedmiotów, ale jeżeli gracz dostarczy zamiast 3 np. 2 powinien dostać mniej punktów doświadczenia, analogicznie za 2 mniej za 1 jeszcze mniej. Jednak zakładamy, że item_1 musi dostarczyć. 

Również warto zauważyć, że wartość True jest równa wartości 1 oraz False odpowiada 0. 

Wpis jest dosyć długi, ale chciałem pokazać jak najdokładniej jak działają operatory logiczne oraz instrukcje warunkowe. 

W telegraficznym skrócie

Operator logiczny sprawdza jakie warunki muszą zajść, aby coś mogło się wydarzyć. 
Instrukcja warunkowa bazuje na operatorach logicznych i instruuje co dalej. Po spełnieniu warunków.


Instrukcje warunkowe mogą być też zagnieżdżone w sobie, czyli:
if ...
    if...
        if ...

Jeżeli coś jest prawdą sprawdź kolejny poziom i tak dalej i dalej.
Przykładowo gra FPS.
Chcemy oddać strzał, trafić w przeciwnika i go pokonać.
Jeżeli mamy amunicję możemy oddać strzał, jeżeli strzeliliśmy to jak trafiliśmy w przeciwnika to wówczas możemy sprawdzić czy ten strzał go pokonał i tak dalej. Konstrukcja taka niczym się nie różni od zwykłej instrukcji warunkowej. 

Innym przykładem może być panel logowania i dostęp do panelu administratora
Jeżeli login i hasło były poprawne, wówczas następuje zalogowanie. Teraz sprawdzamy poziom uprawnień, jeżeli jest odpowiedni, wyświetlamy takiemu użytkownikowi panel administratora. 

Inaczej mówiąc


Operator logiczny:
Login i hasło muszą się zgadzać

Instrukcja warunkowa:
Login i hasło muszą się zgadzać -> przejdź do panelu
W przeciwnym wypadku -> pokaż komunikat o błędnym loginie i haśle

Istnieją jeszcze inne operatory logiczne jednak, jeżeli już z jakimś się spotkasz to będzie pewnie:

Alternatywa rozłączna inaczej ekskluzja albo XOR jest to jak alternatywa z tą różnicą, że prawda jest tylko i wyłączni wtedy, kiedy co najmniej jeden argument jest prawdziwy oraz nie mniej niż jeden argument jest fałszywy. Natomiast fałszywa, gdy wszystkie argumenty są prawdziwe lub dają fałsz.

Równoważność inaczej ekwiwalencja wówczas prawdą jest tylko wtedy, kiedy każdy argument jest prawdziwy lub każdy fałszywy

Kończąc

Operatory logiczne nie kończą się tylko na instrukcji warunkowej, spotkamy się z nimi np. przy budowaniu pętli czy tworzeniu rozbudowanych funkcji.

Operatory logiczne oraz instrukcje warunkowe w rzeczywistości nie są tak straszne i skomplikowane jak wyglądają. Jest to przykład sytuacji, w której teoria jest bardziej rozbudowana i skomplikowana, jednak należy ją poznać, aby swobodnie budować instrukcje w swoich programach.

Np. wyobraża sobie ktoś sytuacje, kiedy login i hasło sprawdzany jest nie przez wymuszenie poprawnego loginu i hasła a przez alternatywę? Kiedy login lub hasło musi być poprawne? Wtedy znając czyjś login można by się zalogować. 

Ewentualnie w grze strategicznej, kiedy chcemy wybudować budynek i z wymaganych 4 surowców mamy tylko 3? Wówczas może możemy wybudować, ale tylko do pewnego stopnia, później musimy i tak uzupełnić brakujące surowce albo możemy go wybudować (zacząć budowę) tylko i wyłącznie wtedy, kiedy mamy wszystko co jest potrzebne.