Do tej pory widzieliśmy zaledwie bardzo proste warunki, sprawdzające wartość tylko jednej zmiennej na raz. Czasem to za mało!
Jak zachować się w sytuacji, gdy chcielibyśmy wykonać akcję tylko jeśli jednocześnie DWA warunki są spełnione? Na przykład, gdy piszemy zasady działania platformy społecznościowej:
and, or, not). Wykonują one operacje na wartościach logicznych (True/False) – podobnie jak plus i minus działają na liczbach!
Aby dobrze zrozumieć operatory logiczne, przytoczę historię małego Jasia. Chciał on pograć na komputerze, więc poszedł do mamy prosić o pozwolenie. Ta jednak powiedziała:
Widzimy tu zmienne finished_homework i cleaned_room, reprezentujące kolejno ukończenie zadań domowych i posprzątanie pokoju (są to wartości True lub False). Pomiędzy nimi znajduje się potężny operator and.
Operator and ("i") sprawia, że CAŁE wyrażenie jest równe True TYLKO WTEDY, gdy OBYDWIE jego strony są równe True. Spójrzmy na tabelę:
| Warunek A | Warunek B | Wynik A and B |
|---|---|---|
| True | True | True |
| True | False | False |
| False | True | False |
| False | False | False |
Spójrz na poniższy kod określający, czy Jasiowi uda się namówić rodziców na szczeniaka. W tym celu musi mieć czas wolny ORAZ być odpowiedzialnym. Jaki będzie wynik (True/False)?
Wynik to oczywiście False. Mimo posiadania czasu, brak odpowiedzialności (False z lewej strony and) psuje cały plan!
Częstym, praktycznym wykorzystaniem tego operatora w programowaniu jest sprawdzenie, czy liczba znajduje się w jakimś konkretnym przedziale: czyli czy jest większa od minimum I zarazem mniejsza niż maksimum.
percent będzie miał wartość z zakresu od 0 do 100, to zostanie wyświetlona "Poprawna wartość". W przeciwnym wypadku (np. ktoś wpisał -5 albo 105), warunek ten w ogóle się nie spełni.
Niestety, we wcześniejszej historyjce Jasio nie odrobił lekcji, zatem nie mógł pograć na komputerze. Wtedy jednak zadzwonili do niego znajomi i zaprosili go do kina. Jasio poszedł do mamy i poprosił o pieniądze na wyjście.
Operator or (po polsku "lub") reprezentuje alternatywę. Całe wyrażenie zwraca True, gdy spełnione jest albo jedno, albo drugie, albo nawet oba warunki jednocześnie! Wystarczy mu choć odrobina prawdy.
| Warunek A | Warunek B | Wynik A or B |
|---|---|---|
| True | True | True |
| True | False | True |
| False | True | True |
| False | False | False |
Wracając do naszej historii: Jasio tak się zapalił do pracy, że zarówno posprzątał garaż, jak i umył samochód! Zdziwiona mama powiedziała: "Chciałam, byś zrobił JEDNO albo DRUGIE, a nie obydwa".
Jasio jednak znał się na programowaniu i odpowiedział:
or w programowaniu".
True or True rzuca na koniec radosne True! Jasio był cwany, a mama zaakceptowała wyjaśnienie programistyczne. Jasio poszedł z kolegami do kina.
Ostatnim operatorem logicznym, który powinniśmy poznać, jest zaprzeczenie, czyli not stawiane PRZED wartością logiczną.
not przed wartością logiczną zamienia ją na przeciwną. Z True robi False, a z False robi True.
| Warunek (cond) | not cond |
|---|---|
| True | False |
| False | True |
Zazwyczaj nie dajemy `not` przed pojedynczą zmienną. Znacznie częściej kładziemy to słowo przed wielkim, skomplikowanym warunkiem, zamkniętym w nawiasach, żeby odwrócić JEGO CAŁKOWITY WYNIK.
Kolejna rozmowa mamy z Jasiem:
-(10 + 5) daje -15. Cały fragment obłożony nawiasami rozwiązuje się najpierw (np. dając False), a potem przylepia się do niego not zamieniając wynik na True.
Czy zastanawiałeś się, co się stanie, gdy napiszesz "nie, nie zjadłem tego ciastka"? Programowanie w 100% akceptuje podwójne zaprzeczenie!
print(-negative) dające cyfrę 1).
Aby nie pogubić się w zawiłych warunkach, warto wyrobić w sobie nawyk czytania wyrażeń logicznych na głos. Spróbuj stosować te tłumaczenia:
and czytaj jako i.or czytaj jako lub.not przed zmienną czytaj jako nie.not (...) przed całym NAWIASEM czytaj jako: nie jest tak, że...Poćwiczmy to! Załóżmy takie znaczenie naszych pudełek:
is_grounded jako "ma szlaban"cleaned_room jako "posprzątał pokój"passed_test jako "zaliczył sprawdzian"Przeczytaj w głowie poniższe zdania w języku Python, a następnie sprawdź tłumaczenie obok:
Jeśli masz ogromne problemy z rozszyfrowaniem wielokrotnych zaprzeczeń jak z ostatniego przykładu... możesz użyć sztuczek znanych jako prawa De Morgana, ale często łatwiej przepisać warunek od nowa w czytelniejszy sposób!
Spójrz na poniższe zmienne i odpowiedz, co wypiszą na ekranie wszystkie 3 printy? Bądź dokładny jak interpreter Pythona!
Zapisz odpowiedzi w głowie, na następnym slajdzie znajdziesz rozwiązanie.
print(has_computer and passed_test)print(passed_test or is_grounded)print(has_computer and not passed_test)not passed_test (czyli not False, co daje True). Razem mamy True AND True!Wszystko, o czym się do tej pory uczyliśmy w tym rozdziale (obliczanie, kiedy pojawia się Prawda, a kiedy Fałsz) dążyło do jednego celu. Przekazania tego wyniku do instrukcji decyzyjnej!
if ("jeśli"). Zaczynamy od tego słowa kluczowego, po nim umieszczamy nasz "warunek" (który zamieni się w True lub False), a na końcu obowiązkowo stawiamy dwukropek :.
Linia z tekstem "Promowany" wcięta niżej, jest nazywana Ciałem Warunku (Body). Ten kod wykona się TYLKO jeśli odpowiedź z zapytania po słowie if wyniosła True.
Wcięcia, czyli dodatkowe spacje lub tabulatory przed instrukcjami, są BARDZO ważne w języku Python. Popatrz na poniższy kod:
Co powinno zostać wypisane? Odpowiedź to tylko B, ponieważ print("A") znajduje się w ciele instrukcji if, której warunek to False (czyli się nie wykona). Skąd jednak wiemy, że literka B nie jest w tym ciele?
Oczywiście – jest dociśnięta do lewej krawędzi (nie posiada wcięcia). Dzięki wcięciom Python jest w stanie odróżnić odcięte fragmenty "zawartości if" od reszty zwykłego, głównego kodu.
Skoro wcięcia w Pythonie oznaczają dosłownie, czy kod należy do bloku warunkowego czy nie, to jak najlepiej je robić klawiaturą?
Zestaw reguł określających formatowanie kodu w Pythonie (np. znany dokument PEP 8) zaleca twardo: Większość projektów stosuje wcięcia na dokładnie CZTERY SPACJE. Profesjonalne edytory, jak PyCharm, potrafią sprytnie zamieniać jedno wciśnięcie klawisza Tab od razu w 4 spacje!
Czasem projektujemy architekturę i wiemy, że potrzebujemy w tym miejscu warunku, ale nie mamy jeszcze czasu napisać do niego kodu. Jeśli zostawisz wcięte miejsce całkiem puste, Python wyrzuci "IndentationError".
Ciało w instrukcji if wykona się tylko w przypadku spełnienia warunku. Ale co zrobimy, jeśli chcielibyśmy odpalić też akcję awaryjną na wypadek fałszu?
Sytuacja w której mówimy "Zrób to, a w przeciwnym razie zrób tamto" jest tak częsta, że wprowadzono słowo uzupełniające: else.
else: nie przyjmuje żadnego własnego warunku do sprawdzania! Musi on zawsze stać na tej samej linii marginesu (w lewo) co zaprzyjaźniony z nim if, do którego się odnosi.
Co natomiast, gdy mamy nie dwie ("tak" lub "nie"), ale więcej opcji do wyboru? Używamy dodatkowych szczebli w naszej decyzji, czyli słowa elif (skrót od "else if", czyli "w przeciwnym wypadku, jeśli...").
elif reprezentujących alternatywne wybory może być pod sobą nieskończenie wiele!
Ponieważ komputer przerywa działanie `if-elif` na pierwszym sukcesie (pierwszej znalezionej prawdzie), łatwo tu o kolosalny błąd podczas sprawdzania liczb (np. ocen za procenty testu).
elif zawsze zaczynamy pisać od warunków najbardziej wymagających / wąskich (np. czy ma >= 95%), schodząc powoli w dół aż do tych wyłapujących największą resztę (>= 50%). W przeciwnym razie pierwszy łagodny warunek na górze (np. 100 jest przecież > 50) złapie wszystko i pożre program!
Napisz kod, który realizuje poniższe wymagania dla serwowania napojów w oparciu o zmienną logiczną coffee_finished (czy dopił już kawę?) i liczbową days_until_deadline (ile dni do terminu?).
coffee_finished to False ➔ Wypisz "Piję kawę".Zastanów się: Czy połączyć dwa pierwsze polecenia w jeden wspólny łańcuch `if` - `elif`? Czy może rozbić to na dwa odrębne, wolnostojące ify?
W treści zadania ukryto pułapkę słowną. Skoro użyto opcji "w przeciwnym wypadku", musimy użyć łańcucha powiązanego wspólnym planem ratunkowym (else).
coffee_finished = False i zarazem days_until_deadline = 1.elif, kod wypisze tylko "Piję kawę" (i wyłączy strukturę). Gdybyś użył dwóch wolnostojących `if`ów jeden pod drugim, programista robiłby dwie rzeczy na raz: "Piję kawę", oraz "Pracuję"!
Zrozumiałeś, jak komputer nawiguje swoim własnym losem w ułamku sekundy, łącząc pętle, ify oraz logikę wykrzykników.
Gratulacje po przetrwaniu tej intensywnej przeprawy przez dokumentacje języka Python. Jesteś gotów zbudować swój własny, w pełni decyzyjny kod EduQuesta!