Stałe i zmienne

Transkrypt

Stałe i zmienne
Spis treści
1 Stałe i zmienne
1.1 Stałe dosłowne (literalne)
1.1.1 Liczby
1.1.2 Napisy
1.2 Zmienne, czyli nazwy
1.2.1 Reguły tworzenia nazw
2 Wyrażenia
2.1 Arytmetyczne
2.1.1 Rozszerzone operatory przypisania
2.2 Logiczne
2.3 Napisowe
2.4 Inne wyrażenia
3 Ćwiczenia
Stałe i zmienne
Stałe dosłowne (literalne)
Stałe dosłowne to takie, których wartości wprost wpisano do pliku z kodem (lub w linii poleceń
interpretera). Mogą to być liczby (paru rodzajów) lub napisy, ale również różne złożone rodzaje
(typy) danych, z którymi zapoznamy się nieco później.
Zapamiętajmy od razu: liczba dla komputera to zupełnie co innego, niż napis składający się z cyfr.
Na napisie nie wykonamy operacji arytmetycznych - a na liczbie, operacji właściwych dla napisów
(takich jak np. wyjęcie z niego znaku stojącego na określonej pozycji).
Liczby
Dobrze jest pamiętać, że nieco odmiennie traktowane są liczby całkowite, a inaczej - liczby
ułamkowe, zwykle zwane zmiennoprzecinkowymi (po angielsku floating point, jako że Amerykanie
piszą kropkę dziesiętną a nie - jak my - przecinek, przez co i w Pythonie używa się w tym celu
kropki).
Liczby całkowite w zapisie dziesiętnym: 1024, , -666, ...
Liczby ułamkowe: 1.0, .99, 98.6, -37.43, ...
Liczby ułamkowe w zapisie wykładniczym: 1.024e3, 96.9E-12, ...
Notacja e3, E-12 itp. (wielka i mała litera e są tu równoważne) oznacza pomnożenie poprzedzającej
liczby przez odpowiednio 103, 10-12, ... i służy ułatwieniu zapisu liczb bardzo dużych lub bardzo
małych. Nie można tam wtrącać dodatkowych odstępów, podobnie jak pomiędzy cyframi.
Jeśli część całkowita (lub ułamkowa) liczby zmiennoprzecinkowej wynosi zero, to można to zero
pominąć. Oczywiście nie można pominąć obu, zapisując liczbę zero! (można napisać: 0. albo .0, ale
nie samotną kropkę).
Podstawowa różnica pomiędzy sposobem traktowania liczb całkowitych i zmiennoprzecinkowych
polega na tym, że:
liczby całkowite mogą być dowolnie duże, a rachunki całkowitoliczbowe wykonywane są
dokładnie,
liczby ułamkowe oraz wyniki rachunków na liczbach ułamkowych należy zawsze traktować
jako przybliżone (oczywiście dla szczególnych wartości zdarza się, że są one dokładne); zakres
wielkości liczb ułamkowych jest ograniczony.
Python zna też liczby zespolone oraz operacje na nich, ale tego zdaje się nie było w
szkole...
Liczby całkowite można pisać również w podstawach innych niż 10:
dwójkowe: 0b101 == 5
ósemkowe: 0o123 == 83
szesnastkowe: 0x1f == 31
(podwojony znak równości oznacza: lewa strona jest równa prawej; litery b, o, x mogą być zarówno
małe jak i wielkie).
W zapisie szesnastkowym, wymagającym 16 różnych cyfr, w roli "brakujących" cyfr oznaczających
liczby od 10 do 15 przyjmuje się początkowe litery alfabetu (a-f), można równoważnie używać liter
małych lub wielkich.
Napisy
Napis (ang. string) to po prostu ciąg znaków.
OK, nic nie jest tak proste, jak się wydaje. Pytanie: co to jest znak? Odpowiedzi dostarcza
standard Unicode, w skład którego chodzi m. in. katalog wszystkich znaków, używanych
przez systemy pisma wszystkich w zasadzie języków świata (języków żywych, i co
ważniejszych spośród martwych). Nie będziemy się w tej chwili zastanawiać nad tym, jak
dokładnie znaki te są reprezentowane w komputerze. Warto jednak pamiętać, że napisy
nie muszą ograniczać się do znaków znanych z zapisu języków europejskich.
Literalne stałe napisowe, czyli napisy "na twardo" wpisane do kodu, mogą być podane w paru
różnych postaciach:
napis1 = 'jedna z postaci napisu'
napis2 = "nieco inna postać napisu"
napis3 = '''tak też może wyglądać napis,
i w tej postaci może zawierać przejścia do nowego wiersza
(w poprzednich nie może)'''
napis4 = """zamiast apostrofów, mogą być cudzysłowy - wychodzi na to samo,
również w postaci takiej, jak napis1 i napis2 są one równoważne"""
napis5 = "korzyść z tego pojawia się np. gdy w treści napisu potrzebujemy
umieścić znak taki jak ' "
napis6 = 'w treści napisów można użyć kilku specjalnych sekwencji:\nTo
powoduje przejście do nowego wiersza..'
napis7 = 'jeśli dwa napisy (lub więcej) postawimy ' 'jeden obok drugiego '
'to zostaną połączone w jeden'
Zmienne, czyli nazwy
Programy oczywiście nie operują jedynie na stałych. Potrzebny jest w nich sposób odnoszenia się do
wartości, które nie są znane z góry (w chwili pisania programu) - albo dlatego, że zostaną
dostarczone dopiero przy uruchomieniu lub w trakcie pracy programu, jako dane wejściowe (później
zobaczymy, na jakie sposoby można tego dokonać), albo dlatego, że będą wynikiem obliczeń lub
przekształceń danych wykonywanych przez program.
Do tego w Pythonie służą zmienne - można je uważać za nazwy, z jakimi wiążemy pewne wartości
(liczby, napisy, itd.), poprzez instrukcję podstawienia. Do zapisu instrukcji podstawienia służy znak
równości (=), po jego lewej stronie stawiamy nazwę (zmiennej), po drugiej - wyrażenie, np. literalną
stałą, ale również może być to wyrażenie zbudowane ze stałych, operatorów (np. arytmetycznych),
nazw zmiennych (reprezentujących w wyrażeniu związane z nimi aktualnie wartości), i szereg innych
elementów które dopiero poznamy.
Do zapamiętania: pojedynczy znak równości = w Pythonie (i wielu innych językach programowania)
nie tworzy równania, czyli stwierdzenia, że lewa strona jest równa prawej; tylko podstawienie, a więc
operację powodującą, że z nazwą stojącą po stronie lewej zostaje związana obliczona wartość
wyrażenie stojącego po prawej. Zauważmy, że jest to operacja niesymetryczna (stron nie można
bezkarne zamienić miejscami):
i = # pierwsze użycie nazwy, w tym przypadku 'i', tworzy zmienną i wiąże z
nią wartość
i = i + 2 # to jest legalne, i oznacza, że wartość związana z 'i' rośnie o 2
i + 2 = i # to jest błędne, po lewej stronie nie może stać wyrażenie złożone
Pojawienie się w wyrażeniu stojącym po prawej stronie podstawienia tej samej nazwy, która stoi po
lewej stronie, nie tworzy jakiejkolwiek niejednoznaczności: zasadą jest, że wpierw obliczana jest
wartość wyrażenia z prawej strony, z wykorzystaniem aktualnych wartości zmiennych, a potem
następuje związanie nazwy zmiennej stojącej po lewej z wynikiem.
Zauważmy, że błędem byłoby użycie nazwy po raz pierwszy bez uprzedniego nadania jej wartości,
np. w wyrażeniu arytmetycznym.
Reguły tworzenia nazw
Aktualnie reguły określające, co jest poprawną nazwą w Pythonie, dopuszczają użycie całkiem
szerokiego podzbioru znaków Unicode i są dość trudne do opisania w zrozumiały sposób. Pomijając
jednak taką możliwość, że ktoś zechce użyć w nazwie zmiennej znaków pisma Kanji lub perskiego,
można w dużym uproszczeniu powiedzieć tak:
nazwy można budować z liter (wielkich i małych), cyfr, i znaku podkreślenia (_)
z zastrzeżeniem, że pierwszym znakiem nazwy nie może być cyfra
litery wielkie i małe są rozróżniane, tak więc nazwy różniące się jedynie wielkością liter są
różne
długość nazwy nie podlega ograniczeniu
zabronione jest użycie jako nazwy któregokolwiek z tzw. słów zastrzeżonych, które mają
specjalne znaczenie w składni języka Python.Tutaj można znaleźć ich wykaz.
W szczególności, nazwy (zmiennych i innych obiektów) mogą jak najbardziej zawierać litery
właściwe dla języka polskiego (oraz dla innych języków). Z rozmaitych względów nie jest to jednak
szczególnie rekomendowane, lepiej (przynajmniej na razie) ograniczyć się do liter podstawowego
alfabetu łacińskiego.
Oprócz twardych reguł zawartych w definicji języka, w tworzeniu nazw programiści trzymają się na
ogół pewnych konwencji - które nie są w żaden sposób egzekwowane przez interpreter, ale ułatwiają
czytanie kodu:
w nazwach zmiennych używamy małych liter (a nie wielkich)
wielkie litery rezerwujemy dla nazw oznaczających wartości stałe, które nie mają prawa się
zmienić w trakcie pracy programu
staramy się, by nazwy coś znaczyły i ułatwiały zrozumienie kodu programu
nie unikamy nazw składających się z dwóch lub nawet kilku słów; ponieważ spacja jako
składnik nazwy nie jest dozwolona, zastępujemy ją znakiem podkreślenia
unikamy jednak nazw przesadnie długich, a nazwy zmiennych, które są potrzebne jedynie
"chwilowo" mogą wręcz być jednoliterowe
nazwy zaczynające się od podkreślenia (_) mają pewne specjalne znaczenia i nie tworzymy
takich nazw, chyba że całkiem świadomie.
Wyrażenia
Arytmetyczne
Wyrażenia arytmetyczne tworzymy z udziałem znanych już operatorów arytmetycznych +, -, /,
*, **, //, %, ..., ale również wywołań funkcji zwracających wartości liczbowe (więcej o tym
dalej), z wykorzystaniem literalnych liczb i nazw oznaczających zmienne, których aktualne wartości
powinny być liczbami. Możemy również używać nawiasów (wyłącznie okrągłych!) do grupowania
podwyrażeń, aby wymusić określoną kolejność operacji. Każdy na ogół pamięta, że dzielenie i
mnożenie mają pierwszeństwo przed dodawaniem i odejmowaniem; potęgowanie ma jeszcze wyższy
priorytet. Gdy mamy do czynienia z operatorami o równym priorytecie, to operacje wykonywane są
zgodnie z kolejnością czytania, od lewej do prawej. Jeżeli mamy wątpliwości, to użycie nawiasów nie
będzie błędem. Przykłady:
a
a
a
a
a
a
+ b * c == a + (b * c)
/ b / c == (a / b) / c
* b ** c == a * (b ** c)
** b ** c == a ** (b ** c)
** - b == a ** (-b)
** b / c == (a ** b) / c
Zachowanie operatora potęgowania jest tu nieco szczególne, i zgadza się z umową przyjętą w
matematyce.
Operatory arytmetyczne znajdują również czasem zastosowanie do obiektów nie będących liczbami,
mają wtedy oczywiście nieco inne znaczenie. Np. suma dwóch napisów jest ich sklejeniem (mówi się
też: konkatenacją).
W przypadku, gdy będziemy mieszać w jednym wyrażeniu liczby całkowite i zmiennoprzecinkowe, to
wynik będzie liczbą zmiennoprzecinkową. Wyjątkiem jest dzielenie: a / b zawsze da w wyniku
liczbę zmiennoprzecinkową, natomiast a // b - całkowitą, jeśli oba argumenty są całkowite; w
przeciwnym razie, zmiennoprzecinkową (ale o zerowej części ułamkowej).
Rozszerzone operatory przypisania
Z dwuargumentowymi operatorami arytmetycznymi związane są tzw. rozszerzone operatory
przypisania, stanowiące drobne udogodnienie pozwalające w sposób bardziej zwięzły zapisać dość
często występujące operacje - takie, jak powiększenie aktualnej wartości x o 1 i zapamiętanie tej
nowej, powiększonej wartości pod nazwą x:
#
x
x
#
x
x
#
x
x
#
x
x
#
x
x
poniższe instrukcje są parami równoważne
= x + a
+= a
= x * a
*= a
= x - a
-= a
= x / a
/= a
**= a
= x**a
Wersja np. z potęgowaniem może jest niezbyt często przydatna, ale wprowadzono ją choćby po to, by
było konsekwentnie.
Logiczne
Wyrażenia logiczne mogą mieć jedną z dwu wartości: Prawda (True) lub Fałsz (False). Literalne
wartości True i False są też przykładami wyrażeń logicznych, choć dość mało przydatnymi.
Prawdziwe lub fałszywe mogą być np. porównania dwóch wartości, tworzone za pomocą operatorów
>, <, >=, <=, ==, != (to ostatnie, to sposób w jaki w Pythonie pisze się znak nierówności). Jak już
wspomniano, podwojony znak równości jest operatorem porównania (w odróżnieniu od pojedynczego
- przypisania). Porównywać można przede wszystkim liczby (a więc - dowolne wyrażenia o
wartościach liczbowych), ale również np. napisy - wówczas większy oznacza tyle, co dalszy w
porządku leksykograficznym. Porównania mają priorytet niższy, niż operatory arytmetyczne.
Przy bliższym przyjrzeniu okazuje się, że wartości True i False są tak naprawdę w
pewnym sensie liczbami: odpowiednio 1 i 0.
Z elementarnych wyrażeń logicznych (porównań) można tworzyć złożone wyrażenia logiczne za
pomocą operatorów (spójników) logicznych, pisanych and, or i not. Mają one następujące
właśności:
(a and b) == (b and a)
(False and False) == False
(False and True) == False
(True and True) == True
(a or b) == (b or a)
(False or False) == False
(False or True) == True
(True or True) == True
(not True) == False
(not False) == True
Spójniki logiczne mają priorytet jeszcze niższy, niż porównania - stąd nawiasy w powyższym. Wśród
nich najwyższy priorytet ma not, następnie and, na końcu or.
Wyrażenia logiczne mają tę szczególną własność, że wartość wyrażenia można często określić
obliczając jedynie część jego elementów. Np. a and b, jeżeli wartością a jest False, jest na pewno
False - niezależnie od wartości b. W takich przypadkach Python przerywa obliczanie (od prawej do
lewej, z uwzględnieniem nawiasów) gdy tylko wartość jest określona. Fakt ten czasami może mieć
znaczenie - jeżeli np. obliczenie któregoś z członów wyrażenia logicznego jest szczególnie
czasochłonne, lub ma tzw. skutki uboczne.
Wyrażenia logiczne znajdują zastosowanie przede wszystkim w instrukcji warunkowej - pozwalają
określić warunki, pod jakimi pewne operacje będą wykonane, lub nie - o tym dalej.
Napisowe
Wartością wyrażenia może być również napis. Na przykład, a + b, jeżeli a i b są napisami, jest
napisem utworzonym przez ich sklejenie (zauważmy, że w odróżnieniu od dodawania liczb nie jest to
operacja przemienna).
Wcześniej wspomniano, że dwa napisy literalne postawione obok siebie zostaną
automatycznie sklejone w jeden: np. 'abc' "123" jest równoważne 'abc123'. Nie
stosuje się to jednak np. do zmiennych o wartościach napisowych: napisanie dwóch nazw
obok siebie bez operatora pomiędzy nimi jest błędem składniowym. Jest tak, ponieważ
wspomniane sklejenie napisów literalnych ma miejsce na etapie kompilacji kodu - tzn.
wtedy, gdy interpreter analizuje zapis programu i przekłada go na instrukcje, jakie
zostaną wykonane w etapie uruchomienia - a wartości stojące za nazwami zmiennych nie
są na tym etapie jednoznacznie określone.
Bogatszy repertuar operacji tworzących wyrażenia o wartościach będących napisami poznamy dalej.
Inne wyrażenia
Oprócz liczb, napisów i wartości logicznych, Python posiada szereg dalszych, złożonych typów
danych, które również mogą być wartościami wyrażeń. Każdy typ obiektu w Pythonie może być
wartością odpowiednio zbudowanego wyrażenia. Gdy poznamy kolejne typy danych, wprowadzimy
również operacje tworzące takie wyrażenia.
Ćwiczenia
1. Które z następujących są poprawnymi nazwami według reguł Pythona:
nazwa1
9sił
dluga-nazwa
wykonaj_rachunki
_
to&owo
if
2. Wykazać, że poniższe równości są równoważnościami -- tzn. że zachodzą dla dowolnej kombinacji
wartości a i b:
not (a or b) == not a and not b
not (a and b) == not a or not b
a or not a == True
Wskazówka: stworzyć tabelki wartości wyrażeń po lewej i prawej stronie operatora porównania ==
dla wszystkich możliwych kombinacji wartości a i b.
3. Które z poniższych równości są tożsamościami, w wyniku działania reguł pierwszeństwa
operatorów?
a / b / c == a / (b / c)
a ** b / c == (a ** b) / c
-a ** b == (-a) ** b
CDN...
poprzednia | Strona główna | dalej
--RobertJB (dyskusja) 14:22, 21 cze 2016 (CEST)