Zaawansowane Metody Geoinformatyczne

Adam Inglot
Adiunkt w Katedrze Geodezji
Wydział Inżynierii Lądowej i Środowiska, Politechnika Gdańska
adam.inglot@pg.edu.pl

2022-10-13, aktualizacja 2022-10-17

© ainglot.pl, 2022. Udostępnianie i wykorzystanie zgodnie z licencją Creative Commons Attribution 4.0 International license (CC BY 4.0).
Projekt strony zapożyczony za zgodą autora - Paulo Raposo

CC By 4.0

Podstawy pracy w Python

W tej części kursu zapoznamy się lub przypomnimy podstawowe działania, funkcje, moduły, operatory czy metody które są nam dostępne w podstawowej wersji Python. Podczas budowania kursu wybrane zostały zagadnienia które będą nam potrzebne do obsługi danych, wykonania własnego narzędzia przetwarzającego dane, wykorzystania silnika jakim jest Python do swobodnego przeprowadzania zaawansowanych procesów geoinformacyjnych.

Wersja Pythona jaką będziemy się posługiwać to z pewnością Python 3.x.x, co ważne, podczas kursu nie będziemy instalować dodatkowych źródeł Pythona jako osobnych środowisk, skorzystamy z tych które dostarczają nam podczas instalacji ArcGIS i QGIS.

image

Zmienna, odniesienie do obiektu

Zmienna w programowaniu służy do przechowywania danych i wyników wykonywanych operacji. Wartością zmiennej może być liczba, ciąg znaków, tablica, obiekt. Zmienna musi posiadać nazwę, przez którą można odwoływać się do niej w skrypcie. Nazwa może być dowolna, ale musi spełniać następujące warunki [1]:

Python nie posiada zmiennych jako takich, ale ma odniesienie do obiektów. W przypadku niezmiennych obiektów, np typu str lub int, nie ma żadnej widocznej różnicy między zmienną i odniesieniem do obiektu. Natomiast w przypadku obiektów zmiennych taka różnica występuje, choć w praktyce rzadko ma znaczenie [2].

Zwrócenie uwagi przez Marka Sumerfielda na to że Python właściwie nie posiada zmiennych ale odniesienie do obiektu wykażemy przy omawianiu operatora tożsamości. Pomimo tego, najczęściej będziemy określać odniesienie do obiektu jako zmienną. Po tym wprowadzeniu, zobaczmy w praktyce jak wygląda przypisanie wartości do zmiennej. Przypiszmy do zmiennej a tekst (ciąg znaków) Programowanie w PYTHON.

>>> a = 'Programowanie w PYTHON'

W podobny sposób możemy przypisać do zmiennej liczby, w Python najczęściej wykorzystujemy int - liczby całkowite, oraz float - liczby zmiennoprzecinkowe.

>>> b = 628
>>> c = 384.62

Operatory logiczne

Python oferuje cztery różne zestawy operacji logicznych. Możemy zainicjować operatory: tożsamości, porównania, przynależności i logiczne. Przejdziemy do przeglądu tych operatorów.

Operator tożsamości

Jak już zostało wspomniane, w Python zmienne przechowują odwołanie do obiektu operator tożsamości będzie sprawdzał czy odwołujemy się do tego samego obiektu, a nie czy odwołujemy się do tych samych wartości w zmiennych. Zobaczmy to na przykładzie.

>>> a = ['Zaawansowane metody geoinformatyczne', 2023]
>>> b = ['Zaawansowane metody geoinformatyczne', 2023]
>>> a is b
False
>>> a = b
>>> a is b
True

Przeprowadzając powyższe doświadczenie w konsoli Python dostaniemy efekt widoczny na poniższej grafice. Te dwie formy prezentacji kodu i konsoli, w postaci teksty w html lub grafiki skopiowanej z konsoli, będą przewijały się przez kurs.

image

Gdy do operatora is dodamy negacje w formie is not, dostaniemy zaprzeczenie powyższego testu.

>>> a = ['Zaawansowane metody geoinformatyczne', 2023]
>>> b = ['Zaawansowane metody geoinformatyczne', 2023]
>>> a is not b
True
>>> a = b
>>> a is not b
False

Używanie operatora is wiąże się z dużą szybkością wykonywania zapytania, jednak jak widać na przykładzie powyżej, trudno wyobrazić sobie efektywne zastosowanie tego operatora. Najczęściej stosowaną sytuacją w której wykorzystuje się operator is to porównanie do wbudowanego obiektu None.

image

Operator porównania

Mamy dostępne standardowy zestaw operatorów porównania: < mniejsze, <= mniejsze kub równe, == równe, => większe lub równe, > większe i na końcu operator różne - !=. Operatory porównania stosowane są bardzo często, same oznaczenia są dość intuicyjne i stosowane w wielu językach programowania jak i zarówno w matematyce. Odpowiedzią na wykonanie operatora porównania jest wartość boolowska: True lub False.

>>> a = 2
>>> b = 4
>>> c = 6
>>> a < b
True
>>> a == b
False
>>> b = 2
>>> a == b
True

Sprawdźmy teraz przykład z operatora is, czy w tym wypadku operator porównania zachowa się podobnie?

>>> a = ['Zaawansowane metody geoinformatyczne', 2023]
>>> b = ['Zaawansowane metody geoinformatyczne', 2023]
>>> a == b
True
>>> a = b
>>> a == b
True

Operator przynależności

Najlepiej sprawdza się stosowanie operatora przynależności do list, krotek czy ciągów znaków. Co ten operator wnosi? Sprawdza czy badany element znajduje się w danych. Działanie to wykonujemy poprzez zastosowanie formuły in lub dla negacji, not in czyli sprawdzenie czy dany obiekt nie występuje w danych. Sprawdźmy to na przykładzie.

>>> a = [1, 2, 3, 4]
>>> 2 in a
True
>>> 5 in a
False
>>> b = ['Zaawansowane', 'metody', 'geoinformatyczne', 2023]
>>> 'Zaawansowane' in b
True
>>> z = "Zaawansowane"
>>> 'a' in z
True
print(True)

Operatory logiczne

Do ostatniej grupy operatorów należą: and, or i not. Dwa pierwsze operatory (and, or) używają logiki warunkowej i zwracają w wyniku operand. Gdy zastosujemy jako łącznik pomiędzy liczbami zwracana jest jedna z wartości.

>>> a = 2
>>> b = 3
>>> a and b
3
>>> b and a
2

Najczęściej operatory te stosowane są z funkcją warunkową do łączenia warunków, wtedy wynikiem działania zdania logicznego jest odpowiedź True lub False. Możemy też sprawdzić jakie są odpowiedzi w ramach operatorów przy wartościach boolowskich.

>>> True and True
True
>>> True and False
False
>>> False and False
False
>>> True or True
True
>>> True or False
True
>>> False or False
False

Podstawowe typy danych

Do podstawowych typów danych zaliczmy trzy rodzaje danych: liczby całkowite - int, liczby rzeczywiste - float oraz ciąg znaków - str. Na potrzeby zadań przedstawianych w skryptach wymienione typy danych są wystarczające. Oprócz nich dostępne są liczby zespolone, liczby rzeczywiste w module Decimal. Sprawdźmy jak można przypisać liczbę całkowitą i rzeczywistą do zmiennej. Możemy zadeklarować poprzez przypisanie wartości, co już wykonywaliśmy:

>>> a = 2
>>> b = 1.2

Zmienna a przechowuje liczbę całkowitą a zmienna b przechowuje liczbę rzeczywistą. Czy istnieje jakaś metoda która pozwoli nam to zweryfikować? Tak, możemy to sprawdzić poprzez metodę type(), dostarczamy do tej metody jeden argument - czyli jedną zmienną\wartość.

image

Innym sposobem zadeklarowania liczby jest użycie metody int() lub float(). Dzięki tym metodom nie tylko możemy zadeklarować zmienne, możemy również wykonać konwersję:

>>> float(a)
2.0

Jeszcze w tej części został nam do omówienia typ string -str(), również i ten typ zmiennej deklarowaliśmy powyżej wykorzystując znak cudzysłowu przed i po ciągu znaków. Sposób zapisu jest nieco bardziej rozbudowany, możemy zadeklarować zmienną typu string używają pojedynczego cudzysłowu ', podwójnego " lub potrójnego ''' czy """, oraz mamy do dyspozycji metodę str(). Podczas zapisu, czy przypisywania ciągu znaków do zmiennej możemy napotkać na różnego rodzaj problemy. Związane są one z używaniem specjalnych znaków, pierwsze znaki już poznaliśmy w zdaniu poprzednim, tak, cudzysłów jest znakiem specjalnym który trzeba odpowiednio wstawić czy zakodować w zmiennej. Zapiszmy do zmiennej tekst: Lubię film "Milczenie owiec". Najprostszym sposobem jest użycie pojedynczego cudzysłowowa:

>>> a = 'Lubię film "Milczenie owiec".'

Wprowadźmy teraz jedną z podstawowych metod wbudowanych w Python która jest niezmiernie potrzebna podczas testowania kody - metoda print(). Metoda ta wydrukuje nam, czy to w terminalu, czy w oknie Run lub w 'Python Console' wartość zmiennej.

>>> print(a)
Lubię film "Milczenie owiec".

Jak tak dobrze nam idzie, wprowadźmy jeszcze kolejną metodą, niezwykle ważną, niezwykle użyteczną, metodę do obliczenia długości sekwencji, czy to ciągu znaków czy listy, krotki. Metoda ta to len(), jest to metoda jednoargumentowa, do której wprowadzamy obiekt poddający się iteracji.

>>> print(len(a))
29

Wróćmy jeszcze do sposobu deklarowania ciągu znaków. Innym sposobem uwzględnienia cudzysłowów w zmiennej jest wykorzystanie lewego slash (lewy ukośnik) - \:

>>> b = "Lubię film \"Milczenie owiec\"."
>>> print(b)
Lubię film "Milczenie owiec".

Znaczącą różnicą pomiędzy użyciem pojedynczego znaku a potrójnego jest wprowadzanie znaków specjalnych, rozpatrzmy to na przykładzie przejścia do następnej linii (w potocznej mowie 'enter'). Przypiszmy do zmiennej tekst:
Imię: Adam
Nazwisko: Inglot
Używając potrójnego cudzysłowu wystarczy wstawić przejście do następnej linii (w Python Console używamy Shift+Enter)

image

W przypadku pojedynczego cudzysłowu konieczne jest użycie znaku specjalnego \n który reprezentuje przejście do następnej linii.

image

Co się stanie gdy w podwójnym cudzysłowie zastosujemy przejście do kolejnej linii \n, zostanie ono wykonane, czyli program nie wydrukuje nam wartości lewy slash a następnie litera n, tylko podzieli nam na dwie linie tekstu. Ta uwaga ma znaczenie przy używaniu specjalnych znaków. To znaczy, gdy chcemy wprowadzić wartość a nie konwertować ją w danym znaczeniu. Możemy użyć niezmodyfikowanych ciągów znaków przy użyciu litery r poprzedzającej pierwszy cudzysłów.

>>> a = '\u20AC'
>>> b = r'\u20AC'
>>> print(a)

>>> print(b)
'\u20AC'

Podczas kursu, niezmodyfikowany ciąg znaków będzie nam najczęściej służył do podania ścieżki do plików lub katalogów. Kopiując ścieżkę możemy wstawić i z literą r będzie on zachowany zgodnie z wprowadzonymi znakami:

image

Operatory arytmetyczne

Python zawiera pełną paletę operatorów arytmetycznych, między innymi: dodawanie, odejmowanie, mnożenie i dzielenie. Oprócz tego wiele typów danych może być używanych z rozszerzeniem operatora przypisania.

operatoroperator przypisaniaopis
++=operator dwuargumentowy, dodaje wartości liczbowe a dla stringów łączy ciągi znaków ze sobą
--=operator jednoargumentowy i dwuargumentowy, jako operator jednoargumentowy przeprowadza negację wartości, jako dwuargumentowy jest to działanie odejmowania, nie dotyczy ciągu znaków
**=operator dwuargumentowy, mnożenie wartości liczbowych, nie dotyczy ciągu znaków
//=operator dwuargumentowy, dzielenie wartości liczbowych, nie dotyczy ciągu znaków

W tej części sprawdźmy jak działają te cztery podstawowe operatory arytmetyczne (z rozszerzeniem na operator przypisania), w części omawiania danych typu liczbowego rozszerzymy operatory dla działań na liczbach. Operator przypisania składa się z dwóch znaków, znaku = który poprzedzony jest operatorem arytmetycznym. Operator ten dodaje już do istniejącej zmiennej wskazaną wartość.

>>> a = 'Programowanie w PYTHON'
>>> a += ', programowanie w GIS.'
>>> print(a)
'Programowanie w PYTHON, programowanie w GIS.'

Wykorzystanie operatorów do danych liczbowych:

>>> a = 2
>>> b = 10
>>> print(a + b)
12
>>> a += a
>>> print(a + b)
14
>>> print(a)
4
>>> c = 1.2
>>> print(a - c)
2.8
>>> print(a)
4
>>> a -= c
>>> print(a)
2.8
>>> d = b / c
>>> print(d)
8.333333333333334

Co nam pokazuje powyższy przykład: (1) na liczbach typu int (całkowitych) jak i float (rzeczywistych) możemy wykonywać podstawowe działania matematyczne z użyciem operatorów arytmetycznych, (2) gdy wykonamy działanie w metodzie print, działanie zostanie wykonane, wynik zostanie wyświetlony ale nie zapisany będzie do żadnej zmiennej, nie zostanie zachowany, (3) działanie z operatorem przypisania nadpisuje wartość w zmiennej. Zaobserwowaliśmy, że typ int i float można poddać działaniu operatorom arytmetycznym, bez przeprowadzania konwersji. Stanowi to zaletę jak i wadę przyjętej architektury programowania w Python, jednak nie będziemy rozszerzać tej tematyki. Pozostaje jednak pytanie czy możemy wykonać działanie dodawania + na liczbie i ciągu tekstowym - NIE, chyba że wykonamy konwersji, ale wtedy już nie wykonujemy działania liczba + string.

To teraz przejdźmy jeszcze do zagadnienia konwersji tekstu na liczbę i liczby na tekst. Zacznijmy od pierwszego przypadku. Jeżeli w ciągu tekstowym mamy zapisaną liczbę - bez dodatkowych znaków - możemy wykonać konwersję za pomocą dostępnych metod int() lub float(), następnie wykonać działanie matematyczne:

>>> a = 2
>>> b = '10'
>>> print(a + int(b)
12

Przypadek brak konwersji powoduje wywołanie błędu w konsoli Python (Python Console), informacja o błędzie wskazuje jednoznacznie że nie można wykonać łączenia obiektu typu int z obiektem str.

image

Drugi przypadek, gdy chcemy połączyć tekst z liczbą, a w wyniku łączenia chcemy zachować obiekt typu string. Wykonujemy konwersje liczby za pomocą metody str():

>>> a = 2
>>> b = '10'
>>> print(str(a) + b)
210
>>> print(b + str(a))
102

image

Metody dla podstawowych typów danych

W tej części przeglądniemy metody, funkcje i operatory dla podstawowych trzech typów danych które poznaliśmy powyżej: int, float i str. Poniższe metody nie tylko odnoszą się do tych typów danych ponieważ np, segmentacja ciągu odnosi się to ciągu tekstowego jak i listy, krotki czy tablicy. Na podstawowych typach danych będzie nam łatwiej przyswoić sposób funkcjonowania tych operatorów.

Działania na liczbach - int, float

Na temat pojemności zapisu liczb jest tyle dostępnych materiałów, że aż nie wypadu tutaj przypominać o tym. Śmiało można zaglądnąć choćby do pozycji literatury przywołanej na końcu kursu. W tej części przeglądniemy dostępne operatory z poziomu podstawowego Python (wbudowane operatory). Poniższa tabelka zaczerpnięta jest z książki - Marka Summerfielda [2], pominięte zostały operatory arytmetyczne (+ - * /)

składniaopis
x // ydzieli liczbę x przez liczbę y, odrzucając część dziesiętną i zapisując wynik w postali liczby całkowitej - int
x % yoblicza resztę z dzielenia liczby x przez liczbę y
x ** ypodnosi liczbę x do potęgi y
-xnegacja x
abs(x)funkcja zwracająca wartość bezwzględną liczby x
pow(x, y)funkcja zwraca liczbę x podniesioną do potęgi y, działa tak samo jak x ** y
round(x, n)funkcja zwraca liczbę x zaokrągloną do n cyfr po przecinku, można stosować ujemne wartości lub dodatnie, typ liczby jest ten sam jak liczby zaokrąglanej, liczby x. Ujemna wartość liczby n, zaokrągla część całkowitą, gdy n jest dodatnie, zaokrąglana jest część po przecinku (a w nomenklaturze Python po kropce).

Sprawdźmy na przykładach jak funkcjonują przywołane funkcje i operatory. W szczególności wielokrotnie będziemy stosowań funkcję dwuargumentową round(). Zacznijmy od końca, czyli właśnie od tej funkcji:

image

Działania na ciągu znaków, tekście

W tej części, zapoznamy się z obsługą ciągu znaków. Niektóre z przedstawionych tu metod mają znaczenie nie tylko do tekstu, ale również do innych typów danych. Szczególną uwagę należy zwrócić na część 'Segmentacja ciągu tekstowego', opisane tam metody odnoszą się również do listy, krotki czy tablicy, które będą podczas kursu wykorzystywane wielokrotnie.

Segmentacja ciągu tekstowego

Jak już wiemy, ciąg znaków składa się z szeregu znaków. Wykonaliśmy kilka zmiennych przechowujących tego rodzaju dane. Teraz zapoznamy się z segmentacją, wydzielaniem części lub pojedynczego znaku. Zacznijmy od pojedynczego znaku, możemy wykonać za pomocą podania nazwy zmiennej a następnie w nawiasie kwadratowym pozycji znaku który chcemy wyodrębnić. Ale jeszcze, zanim to wykonamy, przyglądnijmy się jak określone, indeksowane znaki w zmiennej typu string.

image

Na rysunku ukazany jest sposób indeksowania w Python. Wynika z tego że mamy indeksowanie w dwóch kierunkach: od początku do końca ciągu znaków - rozpoczynamy "liczenie" od indeksu 0, oraz mamy też indeksowanie od końca do początku ciągu znaków - rozpoczynamy od indeksu -1 i kierując się ku początkowi "liczymy" kolejne znaki. Sprawdźmy jak to działa:

>>> a = 'Programowanie w PYTHON'
>>> print(a[5])
a

Podanie jednej liczby, jednego argumentu w nawiasie kwadratowym powoduje wybranie jednej wartości z ciągu znaków. Jeżeli chcemy wybrać część z ciągu znaków musimy podać początek i koniec. Niech p i k będą liczbami naturalnymi, gdzie p < k to odpowiednio liczba początku i końca podciągu z ciągu znaków. Wykonamy to podając: sekwencja[p:k], separatorem pomiędzy podanymi liczbami jest dwukropek. Sprawdźmy to na przykładzie:

>>> a = 'Programowanie w PYTHON'
>>> print(a[7:13])
owanie

Na końcu dodajmy jeszcze że w przypadku stosowania operatora [] do sekwencji, możemy podawać od jednej do trzech argumentów, tj. początek:koniec:krok. Podczas pracy nad ciągiem znaków wartość krok rzadko jest podawana, częściej wykorzystuje się ją w pracy na listach czy tablicach. Podsumowując, na podstawie sekwencji, ciągu można wykonać podciąg za pomocą składni:
sekwencja[początek]
sekwencja[początek:koniec]
sekwencja[początek:koniec:krok]

Porównywanie ciągu tekstowego

Operatory które obsługują porównanie ciągów tekstowych bazują na porównaniu wartości w pamięci, czyli tekst porównywany jest jako liczba. Po tym wprowadzeniu już mniej może dziwić, że do porównywania ciągu znaków wykorzystywane są operatory: <, <=, ==, =>, >, !=. Wykonywaniu porównań tekstu towarzyszą błędy związane z sortowaniem list ciągu znaków oraz powielone odniesienie do znaków w Unicode. Szerzej o tych problemach można dowiedzieć się z literatury fachowej, podczas tego kursu nie będziemy rozwijać tego wątku.

Operatory, funkcje i metody dla ciągu tekstowego

składniaopis
t.capitalizepierwsza litera w ciągu tekstowym $t$ zamienia na duża literę
t.count(x, początek, koniec)liczy wystąpienie wartości $x$ w zmiennej $t$, lub gdy zostaną podane parametry początku i końca, to liczy te wystąpienia do podciągu zmiennej $t$, obie zmienne są typu string
t.find(x, początek, koniec)zwraca pierwsze wystąpienie ciągu tekstowego $x$, jeżeli wartości zmiennej $x$ nie występuje w ciągu $t$ wynikiem jest wartość $-1$, wartości początku i końca są opcjonalne i mają zastosowanie analogiczne jak w funkcji count
t.isnumeric()zwraca wartość True gdy każdy znak w zmiennej `t` jest liczbą całkowitą lub zmiennoprzecinkową
t.lower()zwraca kopie ciągu tekstowego $t$ zamieniając duże litery na małe
t.partition(x)rozcina ciąg tekstowy na trzy części, zapisując wynik do krotki, pierwszy element to część ciągu $t$ przed wystąpieniem $x$, drugi element to $x$ a trzeci ostatni element to część ciągu $t$ po wystąpieniu $x$
t.replace(x, y, z)w wyniku działania otrzymujemy kopię ciągu znaków $t$, gdzie każde wystąpienie wartości $x$ zostało zastąpione wartością $y$, zmienna $z$ to liczba naturalna określająca limit wykonanych zmian w ciągu $t$, wartość $z$ opcjonalna
t.split(x, y)zwraca listę w której ciąg znaków $t$ jest rozdzielony wartością zmiennej $y$
t.splitlines()zwraca listę wierszy uzyskanych w wyniku podziału ciągu znaków $t$ w miejscu zakończenia linii
t.strip(z)usunie z początku lub końca zmiennej $t$, podobne zastosowanie ma funkcja lstrip i rstrip
t.upper()zwraca kopię ciągu znaków $t$ w którym wszystkie znaki zostały zamienione na duże
t.zfill(x)zwraca kopie $t$, jeżeli jest mniejszy od $x$ to zostaje uzupełniony zerami

Kolekcje danych

Dane które nauczyliśmy się wprowadzać to liczby, teks i wartość boolowska, te podstawowe typy danych możemy zbierać, agregować w formie kolekcji danych. W Python mamy do dyspozycji kilka kolekcji danych: krotka, lista, zbiór i słownik. Ze względu na ograniczenia dotyczące kursu, omówimy jedynie część dotyczącą list.

Listy

Listę możemy zadeklarować poprzez metodę list() lub []. Ale zacznijmy od początku. Lista jest to uporządkowana sekwencja zera lub większej liczby odniesień do obiektów. Obsługa segmentacji listy jest analogiczna do segmentacji tekstu, z uwzględnieniem poziomu zagnieżdżenia lity (co nie występuje podczas pracy nad ciągiem znaków). W przeciwieństwie do krotki i ciągu znaków, listę możemy modyfikować - tutaj zastanówmy się nad tym szerzej. Listę faktycznie można modyfikować, czyli usunąć lub dodać do listy elementy i ta lista zostają 'tą samą' listą. W przypadku krotki czy tekstu, również możemy wykonać modyfikacje ale konieczne jest nadpisanie tego typu danych. Co może przechowywać lista, w zasadzie wszystkie poznane typy danych - liczby, tekst, listę, krotki.

image

Operatory, funkcje i metody dla lity

składniaopis
L.append(x)dołącza element $x$ na końcu listy $L$
L.count(x)zwraca liczbę wystąpień elementu $x$ w liście $L$
L.extend(x)wszystkie elementy które poddają się iteracji są dołączone na koniec listy $L$
L += x
L.index(x, początek, koniec)zwraca pozycję w liście $L$ pierwszego wystąpienia elementu $x$
L.insert(i, x)wstawia element $x$ na pozycji $i$ w liście $L$
L.pop(i)zwraca ostatni element listy $L$, lub na podanej pozycji $i$
L.remove(x)usuwa ostatnie wystąpienie elementu $x$, gdy nie znajdzie, wywołany jest wyjątek ValueError
L.reverse()odwraca listę $L$
L.sort(...)sortuje listę $L$, metoda przyjmuje więcej argumentów - link do dokumentacji

Podstawowe funkcje, funkcja warunkowa, iteracja

Jednym z głównych celów używania języka programowania w GIS jest wielokrotne wykonanie jakiejś czynności oraz przygotowanie narzędzia wykonującego czynność której nie jesteśmy w stanie przeprowadzić w oprogramowaniu GIS. Poniższe funkcje, czy polecenia będziemy wykorzystywać wielokrotnie podczas kursu do ułożenia kodu w celu efektywnego wykonania zadania.

Funkcja warunkowa if

W poleceniu potocznie nazywanym if, poleceniu warunkowym, możemy użyć trzech wyrażeń: if, elif oraz else. Jak łatwo się domyśleć, polecenie if nie może zaistnieć bez rozpoczęcia całej instrukcji od zwrotu if. Klauzule elif i else są jedynie opcjonalne. Jak wygląda ogólna składnia if w Python:

1if wyrażenieBoolowskie:
2pakiet
3elif wyrażenieBoolowskie:
4pakiet
5...
6elif wyrażenieBoolowskie:
7pakiet
8else:
9pakiet

Sprawdźmy jak można stosować polecenie warunkowe. Przeprowadźmy to na prostym przykładzie. Niech funkcja if sprawdza czy zmienna jest większa od liczby 10, jeżeli tak, to niech wydrukuje w konsoli tekst: 'większe niż 10'.

image

Co możemy zauważyć w powyższym przykładzie, zadeklarowaliśmy zmienną typu int, o wartości a = 11, następnie wprowadziliśmy instrukcję if, wyrażeniem boolowskim to a > 10 i postawiliśmy na końcu dwukropek. To co ma zostać przetworzone oznacza - jeżeli zmienna a jest większa od liczby 10 to, w naszym przypadku faktycznie zmienna a jest większa od 10, dlatego zostanie wykonany pakiet po dwukropku. To wyrażenie również można zapisać w jednej linii:

image

Sprawdźmy teraz co się stanie gdy wartość zmiennej a będzie mniejsza niż 10.

image

Wartość wyrażenia boolowskiego jest równa False ze względu na logikę wyrażenie - 9 nie jest większe niż 10. To znaczy że pakiet if nie zostanie wykonany a klauzuli elif lub else nie mamy podanej. Uzupełnijmy o klauzule else, niech podaje komunikat 'mniejsze niż 10':

image

Zostaje nam jeszcze sprawdzić co z wartością 10.

image

Jak widzimy na grafice powyżej, według naszego rozwiązaniu można wyciągnąć fałszywe wnioski że liczba 10 jest mniejsza niż 10. Brakuje nam klauzuli elif dla wartości 10. Zwróćmy uwagę gdzie znajduje się klauzula elif, jest pomiędzy if a else, przy czym klauzula else nie jest konieczna. Dodajmy jeszcze uwagę na koniec że elif wymaga wyrażenia boolowskiego a else nie.

image

Funkcja for ... in

Pętla for będzie często wykorzystywana w naszych rozwiązaniach podczas kursu, składnia samej funkcji jest krótka i wygląda tak:

1for zmienna in iteracja:
2pakiet

Do zmiennej zostaje przypisana kolejna wartość z obiektu iteracja, a obiekt iteracja może być dowolnym typem danych który można iterować, czyli element po elemencie "przejść" po zawartości. Oznacza to że iterować można ciągi tekstowe, listy, krotki oraz inne kolekcje danych.

>>> for t in 'Programowanie w PYTHON':
...print(t)
P
r
o
g
r
a
m
o
w
a
n
i
e

w

P
Y
T
H
O
N

Dla listy prosty przykład użycia pętli for może wyglądać tak:

>>> for n in [1, 2, 3, 4, 5, 6]:
...print(n)
1
2
3
4
5
6

Podczas wykonywania pakietu w pętli for możemy wykonać działanie matematyczne, czy choćby użyć funkcji warunkowej:

>>> for n in [1, 2, 3, 4, 5, 6]:
... if n > 3:
...print(n + 10)
... else:
...print(n + 100)
101
102
103
14
15
16

Na koniec dodajmy jeszcze że pętla for obsługuje polecenia continue i break, a także opcjonalną klauzule else. Omówmy, na dwóch prostych przykładach działanie polecenia continue i break. Sprawdźmy to na działaniu pętli for z listą zawierającą liczby. Gdy wykorzystujemy polecenie continue w warunku jaki postawiliśmy - n przyjmuje wartość 3, przerywane jest wykonywanie dalszej części pakietu for a następnie przechodzimy do kolejnej wartości z pętli.

image

W zastosowaniu polecenia break, przerywane jest dalsze działanie pętli for.

image

Funkcja while

Pętla while uruchamiamy do wykonania pakietu, zadania dowolną liczbę razy. Pakiet zadań który jest podany w funkcji while jest wykonywany do puki wyrażenie boolowska nie przyjmie wartości True. Trzeba też zwrócić uwagę że podczas pierwszego uruchomienia pętli wyrażenie boolowskie nie przyjmuje wartości True, pakiet nie zostanie wykonany. Ogólna składnia to:

1while wyrażenieBoolowskie:
2pakiet_while
3else:
4pakiet_else

Tak jak w przypadku funkcji warunkowej if, klauzula else jest opcjonalna, równie dobrze pętla while może składać się z pierwszych dwóch linii. Do polecenia while, w pakiet_while można dołączać polecenie continue lub break, działające analogicznie jak to zostało opisane w pętli for.

Moduł math

Do podstawowej wersji Python, którą możemy zainstalować ze strony internetowej python.org, dołączone są moduły, biblioteki obsługujące dane, kolekcje danych jak i specjalne obiekty w Python. Moduły te wymagają dodatkowego zaimportowania, należy wykonać to zanim zaczniemy korzystać z danej biblioteki. Poniższa tabela przedstawia najpopularniejsze lub przydatne podczas kursu metody do obliczeń. Moduł math posiada wszystkie dostępne funkcje trygonometryczne, wystarczy przejść do strony dokumentacji Python i wyszukać pożądanej przez nas funkcji.

składniaopis
math.acos(x)zwraca wartość arcus cosinus w radianach dla argumentu x
math.ceil(x)zwraca najmniejszą liczbę całkowitą większą lub równą x, zaokrąglanie w górę
math.copysign(x, y)zwraca wartość argumentu x ze znakiem (+-) argumentu y
math.degrees(r)konwertuje wartość wyrażoną w radianach na stopnie
math.estała $e$
math.fabs(x)zwraca wartość bezwzględną i zapisuje do liczby float
math.factorial(x)zwraca x!
math.floor(x)zwraca największą liczbę całkowitą mniejszą lub równą x
math.fmod(x, y)zwraca resztę z dzielenia liczby x przez y, wynik jest lepszy dla liczb rzeczywistych - float
math.fsum(i)zwraca sumę dla sekwencji w formie liczby typu float
math.hypot(x, y)zwraca wartość dla wyrażenia $\sqrt{x^2+y^2}$
math.modf(x)zwraca dwie liczby typu float, jedna to część całkowita a druga to część dziesiętna liczby zmiennoprzecinkowej x
math.pizwraca przybliżoną wartość liczby $\pi$
math.pow(x, y)zwraca liczbę x podniesioną do potęgi y
math.radians(x)konwersja liczby x stopni na radiany
math.sqrt(x)zwraca pierwiastek kwadratowy liczby x

[1] Informatyka - materiały do nauki. http://informatyka2.orawskie.pl/, (data dostępu 28.09.2022).
[2] Mark Summerfield, Python 3 - kompletne wprowadzenie do programowania. Helion, wydanie 2, ISBN: 978-83-246-2642-7, 2010.

ZADANIA

1. Korzystając z listy ['Rozpoczynam', 'naukę', 'Python', 'do', 'rozwiązywania', 'zadań', 'GISowych', '.'] wydrukuj na ekranie jako zdanie - Rozpoczynam naukę Python do rozwiązywania zadań GISowych.

2. Korzystając z pętli while wypisz na ekranie kolejne wartości ciągu geometrycznego $1, 3, 5, 7 ...$ do puki wartość zmiennej nie osiągnie liczby 50.

3. Wydrukuj na ekranie w której ćwiartce znajduje się punkt gdy zmienna przechowuje wartość kąta w stopniach. Niech komunikat będzie miał formę X: -, Y: +.

image

4. Wprowadź dwie zmienne jako listy ze współrzędnymi [x, y], oblicz długość pomiędzy tymi punktami.

5. Przekształć ciąg znaków '30.46 75.91, 55.97 17.18, 19.66 89.76, 47.87 68.2, 70.55 11.0, 53.99 33.45, 11.6 5.17, 49.71 15.08, 35.85 0.9, 31.94 0.24' w listę przechowującą liczby float w strukturze [[$x_1$, $y_1$], [$x_2$, $y_2$], ..., [$x_n$, $y_n$]].