W dzisiejszym artykule skupimy się na jednym z najbardziej fundamentalnych aspektów programowania – logice, a dokładniej na typie danych boolean w Pythonie, i operatorach logicznych. Logika, będąca sercem informatyki i kluczowym elementem programowania, wywodzi się z matematyki, ale nie martw się – jej zrozumienie jest znacznie prostsze, niż może się wydawać.
Na początku warto zrozumieć, że sercem działania komputerów jest system binarny, opierający się na dwóch stanach: 0 (brak prądu) i 1 (prąd płynie). Te dwa stany są podstawą do budowy logiki komputerowej, w tym bramek logicznych, które są niezbędne do przetwarzania informacji.
Co z tego, że prąd płynie lub nie
W systemie binarnym, '1′ i '0′ nie są tylko reprezentacją prądu; są one również podstawą do tworzenia większych jednostek danych, takich jak liczby, znaki, a nawet złożone struktury danych. Każda kolejna pozycja w liczbie binarnej reprezentuje kolejną potęgę liczby dwa, co pozwala na kodowanie skomplikowanych informacji w prosty sposób.
Podsumowując; powstała więc koncepcja, że konkretna pozycja jedynki, na konkretnym miejscu oznacza konkretną potęgę liczby dwa – dlaczego dwa? Bo mamy dwie wartości – tak, bardzo skrótowo, doszliśmy do powstania systemu liczbowego, który u podstawy ma cyfrę dwa, tak jak ten „ludzki”, używany na codzień ma u podstawy liczbę 10. No, ale dziś nie o tym, to tylko taka dygresja.
Prawda i fałsz
W Pythonie, jak w wielu innych językach programowania, typ danych boolean reprezentuje wartości prawdy lub fałszu. Jest to odzwierciedlenie idei binarnych – '1′ dla prawdy (True) i '0′ dla fałszu (False). Te proste wartości mają ogromne znaczenie w tworzeniu logiki programów, pozwalając na kontrolowanie przepływu wykonania programu poprzez instrukcje warunkowe.
Zatem, mamy sytuacje następującą; cyfra jeden, reprezentuje nam prawdę, a cyfra zero – reprezentuje fałsz. I tu przechodzimy do wspomnianej na początku logiki – w logice przydatna możliwość to stwierdzenie czy dane zdanie jest prawdziwe czy fałszywe. W programowaniu takie stwierdzenia też są ważne, jak wspomnieliśmy już trochę przy okazji omawiania instrukcji warunkowych, dlaczego? Bo na tej podstawie komputer może decydować – czyli nasze kochane instrukcje warunkowe.
W programowaniu mamy do czynienia z tak zwaną algebrą Boolowską, więcej możesz o niej poczytać tutaj, my natomiast zajmiemy się tym, że od właśnie Boola, pochodzi nazwa zmiennej wykorzystywanej do przechowywania prawdy lub fałszu, a zmienna ta to boolean.
Boolean, w skrócie bool, to po prostu zmienna, która może przyjąć dwie wartości logiczne: true, albo false. I jest to zmienna, którą często wykorzystuje się w warunkach logicznych (instrukcjach warunkowych), a też często służy do ustawiania tak zwanych flag. Przykładowo; możemy mieć flagę „mówiącą” czy jest dzień. I jeśli flaga taka jest ustawiona na True, to znaczy, że jest dzień, a jeśli na False, to znaczy, że nie ma dnia (czyli pewnie jest noc). Zajrzyjmy do przykładowego kodu.
Czy jesteś w stanie przewidzieć działanie powyższego kodu? Kod ten, a w zasadzie instrukcja if , zawarta w nim, sprawdzi czy zmienna is_day jest prawdą, czyli czy jest równa True. Zmienna ta, zawiera wartość True, a jak wiemy jeśli warunek (tak pojedynacza zmienna też może spełniać rolę warunku) jest prawdziwy, to wykonują się instrukcje w pierwszym bloku. No więc finalnie, będziemy mieli na ekranie tekst „Jest dzień”.
Jeśli natomiast zmienilibyśmy wartość zmiennej is_day na wartośc przecwiną, czyli logiczny Fałsz, a dosadniej mówiąc po prostu na False, to spełniłby się nasz else, czyli każdy inny przypadek, gdy warunek nie jest spełniony – więc finalnie dostalibyśmy na ekran tekst o treści „Nie ma dnia” (trochę zabawnie to brzmi xd).
Możemy teraz sobie sprawdzić naszą zmienną is_day pod kątem przechowywanego typu, by dowiedzieć się…
…że nasza zmienna przechowuje typ danych, będący tzw. instancją klasy, a klasa ta nazywa się 'bool’. Czyli po prostu zmienna is_day, jest typu bool, a to oznacza wspomniany już boolean. Jest to po prostu właśnie wartość logiczna – logiczna prawda lub logiczny fałsz.
Dobrze, mamy więc naszą zmienną typu logicznego, możemy zatem przechowywać wyniki działań logicznych, które mogą być prawdą lub fałszem. Czas pomówić trochę o tych działaniach logicznych, czyli naszych „zdaniach logicznych”, bo to właśnie one będą mogły być prawdziwe lub fałszywe.
Operatory logiczne
Żeby móc wykonywać logiczne działania, potrzebujemy operatorów logicznych. Tak jak w zwykłych działaniach, mamy operatory takie jak plus, minus, podzielić itp., tak w działaniach logicznych także mamy operatory, ale tutaj nie operujemy na liczbach, a raczej na wartościach logicznych. O co chodzi?
Mamy powyższy obrazek, który ilustruje nam prosty kod wykonujący działanie logiczne. Mamy bowiem dwie zmienne. Zmienną a i zmienną b, obie przechowują wartość logiczną True (czyli jak wiemy prawdę). Poniżej, w kodzie, mamy sprawdzenie, które brzmi dosłownie „czy a i b”. No właśnie, między zmienne a i b wstawiliśmy słowo „and”, które tłumaczymy jako „i” – to właśnie jest nasz pierwszy operator logiczny.
Zauważmy więc, że operatorem logicznym, jest po prostu słowo and, które pozwala sprawdzić czy jednocześnie a i b jest prawdą, natomiast zmienne te zawierają wartość logiczną True, czyli „są prawdą”. Tak więc, naprawdę mamy coś takiego:
Czyli, jak widać powyżej, możemy sobie zastąpić nasze zmienne po prostu wartościami logicznymi (tak robi sobie Python), a więc mamy w naszym warunku zdanie „czy prawda i prawda”, a takie zdanie da nam dosłownie prawdę, bo chodzi nam o to, czy prawda i prawda, ta w wyniku prawdę, no i (nawet intuicyjnie) z algebry Boola, wynika, że prawda i prawda = prawda, tak więc warunek jest spełniony, a my na ekran dostaniemy filozoficzne stwierdzenie „wszystko jest prawdą” 😉
Mamy więc tutaj wyjaśnienie takiego działania jak koniunkcja, bo właśnie tym jest słówko „and”, czyli logiczne „i”, które po prostu zwraca prawdę, tylko wtedy, gdy jego obie strony są prawdziwe. Możemy sobie nawet zilustrować to w tabelce, by lepiej zrozumieć co tutaj w naszym kodzie Pythona się dzieje.
a | b | wynik |
0 | 0 | 0 |
1 | 0 | 0 |
0 | 1 | 0 |
1 | 1 | 1 |
W powyższej tabeli mamy zmienne a i b, a także wartości logiczne. Wartość logiczną prawdy reprezentuje jeden, a wartość logiczną fałszu, reprezentuje dwa. I tak widzimy, że tylko dla dwóch jedynek, otrzymujemy w wyniku również jeden, czyli prawda jest tylko, gdy po obu stronach mamy prawdę.
Z troszeczkę inną sytuacją mamy do czynienia, gdy na scenę wkracza nasz drugi operator, a mianowicie alternatywa. Alternatywa jest po prostu logicznym „lub”, a w takim przypadku, nieprawdę mamy tylko, gdy obie wartości brane pod uwagę są False. Zaprezentujmy sobie to może w taki oto sposób:
W kodzie Pythona, który widać na obrazku powyzej, mamy następującą sytuację. Mamy dwie zmienne, obie są typu logicznego, i obie przechowują wartość logiczną False – czyli fałsz. Następnie mamy warunek logiczny, w właściwie instrukcję warunkową sprawdzającą ten warunek, który używa operatora or. Operator or jest alternatywą logiczną, więc pyta „czy a lub b” (w tym wypadku).
Nasz warunek sprawdza, krótko mówiąc, czy przynajmniej jedna z wartości po jego lewej i prawej stronie, jest prawdą – jeśli jest, to zwraca prawdę w wyniku. W tym wypadku żadna ze zmiennych nie przechowuje wartości prawdziwej, zatem warunek nie będzie spełniony i wykona się blok kodu znajdujący się pod else, a na ekranie zobaczymy tekst „wszystko jest kłamstwem”.
Nie jest to jeszcze koniec, bo prócz koniunkcji i alternatywy, w języku Python mamy także operator logiczny jednoargumentowy, którym jest po prostu zaprzeczenie – jeśli mamy prawdę, operator ten zamieni ją na fałsz, a jeśli fałsz to zamieni go na prawdę. Można to ująć przykładowo jako „nieprawda, że prawda” lub „nieprawda, że fałsz”.
Operatorem negacji w języku Python, jest po prostu słowo not, czyli tłumacząc na polski „nie”, tak więc, otrzymać możemy zdanie „nie prawda” – „not True” lub „nie fałsz” – „not False”, a w kodzie będzie to wyglądało następująco:
No i właśnie. Na powyższym obrazku mamy dwie zmienne, ale tylko zmienna „a” będzie nas tutaj interesować – ona bowiem jest używana w warunku logicznym. Nasza zmienna przechowuje wartość False, a jak wiemy skądinąd, jest to wartość nieprawdy. Zatem mamy fałsz, który w warunku, zostaje zanegowany słówkiem „not” – tak więc otrzymujemy „nieprawda, że fałsz”, co oczywiście daje w efekcie prawdę, czyli wartość True. W wyniku zaprzeczenia fałszu, warunek nam się spełnia i otrzymujemy na ekran stringa „warunek spełniony”.
Podsumowując mamy do dyspozycji trzy operatory; and, or, not – które kolejno odpowiadają operacji koniunkcji, alternatywy i negacji. Natomiast w przykładach pokazywaliśmy tylko proste zmienne przechowujące wartości True lub False. Ciekawiej robi się natomiast gdy używamy jeszcze do tego operatorów porównania, czyli przykładowo, możemy sprawdzić czy jakaś zmienna jest w danym przedziale:
Na powyższym obrazku mamy zmienną o wartości 10, a następujący po niej, warunek, sprawdza nam czy zmienna tak jest większa lub równa zero i jednocześnie mniejsza lub równa dziesięć. Widzimy, że zmienna „a” spełnia te kryteria, zatem zostanie wyprintowany tekst „Zmienna a jest w przedziale domkniętym od 0 do 10”. Pod spodem dodam tylko, dla porządku, jeszcze tabelę prawdy dla alternatywy.
a | b | wynik |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
I na tym zakończymy naszą dzisiejszą przygodę z logiką, ale zachęcam do testowania, budowania własnych skomplikowanych warunków i patrzenia co też otrzymujemy w wyniku, bo mamy tutaj przykładowo także kolejność działań, jak w działaniach na liczbach. Zatem miłego testowania nowej wiedzy. I pamiętaj, że typ boolean w Pythonie, to bardzo ważny typ danych 🙂