TI/Wykonanie warunkowe

Z Brain-wiki

Wprowadzenie

W programach, które widzieliśmy dotychczas, zawsze występowały ciągi wyrażeń, które Python wiernie odtwarzał w podanej kolejności. Co zrobić, gdy chcemy zmienić tę kolejność? Na przykład chcemy, żeby program podejmował decyzje i robił różne rzeczy, zależnie od sytuacji, jak na przykład wypisywał „Dzień dobry” albo „Dobry wieczór” zależnie od pory dnia.

Uzyskuje się to kontrolując przepływ programu za pomocą wyrażeń, które powodują przeskok i wykonanie instrukcji w innej kolejności niż ta, w której są napisane. Najważniejsze z takich wyrażeń to if (wykonanie warunkowe, przedstawione poniżej) oraz for i while (wykonanie w pętli, przedstawione w następnym rozdziale).

Konstrukcja if

Składnia

Konstrukcja if jest używana do wyboru jednego z dwóch bloków w zależności od pewnego warunku. Poniżej przedstawiamy składnię tej konstrukcji najpierw w dwóch szczególnych, ale często występujących przypadkac, a na końcu w pełnej wersji. Proszę zwrócić uwagę na dwukropki i wcięcia. Fragment kodu o wyróżniony jednakowym wcięciem nazywamy blokiem.

  • Przypadek I: wykonanie warunkowe bloku kodu:
if warunek:
    blok kodu,
    który ma być wykonany
    jeśli warunek jest prawdziwy
  • Przypadek II: wykonanie warunkowe jednego z dwóch bloków kodu:
if warunek:
    blok kodu,
    który ma być wykonany
    jeśli warunek jest prawdziwy
else:
    blok kodu,
    który ma być wykonany
    jeśli warunek jest fałszywy
  • Przypadek ogólny: kaskada warunków
if warunek1:
    blok kodu,
    który ma być wykonany
    jeśli warunek1 jest prawdziwy
elif warunek2:
    blok kodu,
    który ma być wykonany
    jeśli warunek2 jest prawdziwy
else:
    blok kodu,
    który ma być wykonany
    jeśli każdy z powyższych warunków jest fałszywy

Przykład 1

Chcemy napisać program realizujący następujący algorytm:

  1. ustal zmienną temperatura na pewną wartość np. 11
  2. Jeśli temperatura jest dodatnia wypisz komunikat: "jest ciepło!"

Algorytm ten można w pythonie zaimplementować następująco:

#!/usr/bin/python
# -*- coding: utf-8 -*-
temperatura = 11

if temperatura > 0:
   print "jest ciepło!"

Python wykonuje wyrażenie będące warunkiem (temperatura > 0). Ponieważ warunek jest prawdziwy, uruchamiamy blok operacji bezpośrednio pod if.

Przykład 2

Zmodyfikujmy nieco nasz algorytm:

  1. ustal zmienną temperatura na pewną wartość np. 11
  2. Jeśli temperatura jest dodatnia wypisz komunikat: "jest ciepło!"
  3. W przeciwnym razie wypisz komunikat: "uwaga, przymrozek!"

Algorytm ten można zaimplementować w następujący sposób:

#!/usr/bin/python
# -*- coding: utf-8 -*-
temperatura = 11

if temperatura > 0:
   print "jest ciepło!"
else:
   print "uwaga, przymrozek!"

Program został wzbogacony o nowy blok poprzedzony instrukcją else. Jeśli zmienilibyśmy wartość przypisaną do zmiennej temperatura i warunek był fałszywy, wykonałby się właśnie ten blok (pod else).

Sekcja else jest opcjonalna — jeśli jej nie ma, a warunek jest fałszywy, to cała konstrukcja if nie powoduje wykonania żadnych instrukcji (poza wykonaniem warunku).

Zadanie

Proszę napisać program realizujący algorytm:

  1. poproś użytkownika po podanie temperatury
  2. przypisz podaną przez użytkownika wartość do zmiennej temperatura
  3. Jeśli temperatura jest powyżej 30 wypisz komunikat: "upał"
  4. jeśli jest powyżej 15 dodatnia wypisz komunikat: "jest ciepło!"
  5. W przeciwnym razie wypisz komunikat: "uwaga, chłodno!"

Uwaga 1: proszę przeanalizować sekwencję warunków

Uwaga: W tym i kolejnym zadaniu przydać się może funkcja raw_input. Dla przypomnieinia: ta funkcja wczytuje jedną linijkę „z klawiatury“ Wywołujemy funkcję raw_input przekazując jej jako argument napis, który zostaje wypisany na ekran jako zachęta dla użytkownika. Po tym jak użytkownik wpisze coś i naciśnie Enter, funkcja raw_input zwraca to, co zostało wpisane, jako napis. Przetwarzamy go na liczbę całkowitą za pomocą int, a następnie zapisujemy w zmiennej. Podsumowując:

liczba_wprowadzona =  int(raw_input('Podaj liczbę: ' ) )

Zadanie: Zagadka

Algorytm zagadki jest następujący:

  1. przypisz do zmiennej liczba wartość 23
  2. pobierz od użytkownika liczbę całkowitą i przypisz ja do zmiennej strzal
  3. Jeśli wartości zmiennych liczba i strzal są równe to wypisz gratulacje
  4. jeśli wartość zmiennej liczba jest większa niż wartość zmiennej strzal to wypisz informację "Nie, szukana liczba jest większa od podanej"
  5. jeśli wartość zmiennej liczba jest mniejsza niż wartość zmiennej strzal to wypisz informację "Nie, szukana liczba jest mniejsza od podanej"

Zwróćmy uwagę na fakt, że jeżeli pierwszy i drugi warunek nie jest spełniony (jest fałszywy) to warunek ostatni jest jedyną możliwością i nie musimy go już sprawdzać.

Proszę zaimplementować powyższy algorytm.

Możliwe rozwiązanie (ukryte):

Wartości logiczne

Jak wiadomo, logika rządzi się swoimi prawami. Pozwalają one na ścisłe wyliczanie wartości logicznej zdań — czyli po prostu określenie, czy zdanie złożone z prostszych zdań jest prawdziwe czy też fałszywe. Ponieważ występują tylko dwie wartości i można dla nich pisać równania, to zasady logiki nazywamy algebrą dwuwartościową, lub częściej algebrą Boole'a, od nazwiska osoby która pierwsza sformalizowała ten rachunek.

Dwie wartości, prawdę i fałsz, oznaczamy często jako 1 i 0. W Pythonie jako wartość oznaczającą prawdę można użyć liczby 1 albo specjalnego obiektu True, natomiast fałsz — liczby 0 lub obiektu False. Te specjalne obiekty nazywane są po angielsku booleans, co należy rozumieć jako wartości Boole'a. Nie są niezbędne i zostały wprowadzone po to, by podkreślić kiedy używamy algebry dwuwartościowej, a kiedy zwykłej.

Operacje logiczne

Koniunkcja

Jeśli mamy dwa zdania a oraz b, ich koniunkcją nazywamy wyrażenie, które jest prawdziwe gdy obywa zdania są prawdziwe. W matematyce oznacza się to przez [math]a \wedge b[/math]. W Pythonie operatorem koniunkcji jest and.

Możemy wypisać działanie operatora na każdą możliwą parę wartości logicznych:

wartości zdań wartość ich koniunkcji
a b a and b
True True True
True False False
False True False
False False False

Koniunkcję nazywa się często iloczynem logicznym, bo jeśli oznaczymy prawdę i fałsz przez 1 i 0, to zwykłe mnożenie tych dwóch liczb daje taki sam wynik jak koniunkcja.

Alternatywa

Jeśli mamy dwa zdania a oraz b, ich alternatywą nazywamy wyrażenie, które jest prawdziwe gdy przynajmniej jedno z tych zdań jest prawdziwe. W matematyce oznacza się to przez [math]a \vee b[/math]. W Pythonie operatorem alternatywy jest or.

Ponownie, najłatwiej przedstawić działanie operatora w tabelce ze wszystkimi możliwymi parami wartości logicznych:

wartości zdań wartość ich alternatywy
a b a or b
True True True
True False True
False True True
False False False

Alternatywę nazywa się często sumą logiczną, bo jeśli ponownie oznaczymy prawdę i fałsz przez 1 i 0, to zwykłe dodawanie tych dwóch liczb daje taki sam wynik jak koniunkcja, za wyjątkiem 1 + 1. W wypadku sumy logicznej dwóch zdań prawdziwych wynik i tak jest 1, bo w algebrze Boole'a po prostu nie ma większej liczby.

Zaprzeczenie

Jeśli mamy zdanie a, jego zaprzeczeniem nazywamy wyrażenie, które jest prawdziwe tylko gdy to zdanie jest fałszywe.

Tutaj tabelka możliwości jest krótsza, bo mamy tylko jedno zdanie:

wartość zdania wartość jego zaprzeczenia
a not a
True False
False True

Wartość logiczna wyrażeń w Pythonie

Kiedy używamy operatorów przyrównania (==, !=, <=, >=, <, >), w wyniku otrzymujemy jedną z dwóch wartości logicznych True / False. Większość innych wyrażeń nie jest prawdziwa lub fałszywa w sensie matematycznym. Na przykład napis "Hello, World" nie ma wartości logicznej w sensie matematycznym. Niemniej w Pythonie, jak też w wielu innych językach programowania, wszystkie obiekty mają wartość logiczną określaną zgodnie z pewnymi ustalonymi regułami. Pozwala to wykorzystać dowolne wyrażenie jako warunek w poleceniu sterujących wykonaniem programu, jak if czy while, bo każde wyrażenie zwraca jakiś obiekt.

W przypadku obiektów które nie są po prostu True ani False, to czy dany obiekt zostanie zinterpretowany jako prawdziwy, czy też jako fałszywy, rządzi się paroma prostymi regułami:

  1. w przypadku liczb, liczba 0 jest fałszywa, wszystkie pozostałe są prawdziwe
  2. w przypadku sekwencji (np. napisów) i innych kolekcji, tylko te puste, o długości 0, są fałszywe
  3. pozostałe obiekty są prawdziwe (o ile ich twórca nie podjął specjalnych działań by mogły mieć różne wartości logiczne)

TO DO: http://Link?

Przykład

Kiedy piszemy if temperatura > 0:... to jest jasne, jak należy rozumieć warunek — jest on spełniony jeśli temperatura jest dodatnia. Wartością wyrażenia stanowiącego ten warunek, tak samo jak każdego wyrażenia z dowolnym z operatorów przyrównania, jest wartość logiczna True lub False. Jeśli jako warunek napiszemy po prostu temperatura, to to wyrażenie daje w wyniku wartość zmiennej temperatura, czyli zapewne liczbę. Na podstawie podanych powyżej reguł możemy określić, że taki warunek jest równoważny warunkowi temperatura != 0.


Jeśli chcemy sprawdzić wartość logiczną, możemy konwersję na wartość logiczną wykonać explicite. Robimy to za pomocą wyrażenia bool(coś).

$ python
>>> bool("Hello, World")
True
>>> bool("")
False

>>> bool(1)
True
>>> bool(120)
True
>>> bool(-120)
True
>>> bool(0.5)
True

>>> bool(0)
False
>>> bool(0.0)
False

>>> bool(True)
True
>>> bool(False)
False

Obliczanie wartości wyrażeń logicznych w Pythonie

Jeśli napiszemy wyrażenie zawierające operatory and lub or, często możemy określić wartość logiczną całego wyrażenia bez znajomości wartości logicznej drugiego operandu. Pozwala to na pominięcie części obliczeń, tzw. wykonanie warunkowe (ang. short-circuiting). Mówiąc bardziej konkretnie,

  • w przypadku operatora and, jeśli pierwszy wyraz jest fałszywy, to drugi nie jest obliczany bo wiadomo, że całe wyrażenie jest fałszywe,
  • w przypadku operatora or, jeśli pierwszy wyraz jest prawdziwy, to drugi nie jest obliczany, bo wiadomo, że całe wyrażenie jest prawdziwe.

W przedstawionych powyżej tabelkach przedstawiającej działanie operatorów and lub or na wartości logiczne True i False argumentami były wszystkie możliwe kombinacje tych dwóch wartości. Później zostały przedstawione reguły pozwalająca na nadanie wartości logicznej każdemu wyrażeniu. W przypadku gdy jako argumentu w koniunkcji lub alternatywie użyje się obiektu, który nie jest wartością logiczną True albo False, to wynik wyrażenia logicznego też może nie być wartością logiczną.

Tabelki działania operatorów pozostają w mocy, ale aby uwzględnić działanie na nie-booleans i wykonanie warunkowe, do wykonywania operatorów logicznych używa się następujących reguł:

x and y — jeżeli x jest fałszem, zwraca x, w przeciwnym wypadku zwraca y
x or y — jeżeli x jest prawdą, zwraca x, w przeciwnym wypadku zwraca y

Wyniki działania tych reguł dla wartości True i False dają to co powinny. Natomiast w innych przypadkach pozwalają na budowanie pseudo-zdań logicznych. Np. jeśli prosimy użytkownika o wpisanie pewnego napisu, ale w przypadku gdy wpisał napis pusty chcemy użyć wartości domyślnej, możemy wykorzystać alternatywę:

print (napis or "(podałeś pusty napis)")
# napis o długości 0 jest fałszywy,
#     w takim wypadku zostanie użyty drugi operand

Przedstawione powyżej reguły obliczania koniunkcji i alternatywy są równoważne następującemu przepisowi:

  1. Zaczynamy od obliczenia wartości lewego operandu.
  2. Jeśli wartość logiczna lewego operandu nie pozwala na rozstrzygnięcie wartości logicznej całego wyrażenia, obliczamy wartość prawego operandu.
  3. Jako wynik zwracamy ostatni obliczony operand, czyli ten który rozstrzyga o wartości logicznej całego wyrażenia.



Zadanie

Proszę napisać program do rozwiązywania równania kwadratowego.

[math]y = a x^2 + b x + c[/math]
[math]\Delta = b^2 - 4 a c[/math]
[math]x_{1,2} = \frac{-b \pm \sqrt{\Delta}}{2 a}[/math]