In [1]:
# setup
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

Biblioteki

Podstawowa wersja każdego języka dostarcza jedynie podstawową funkcjonalność, niezbędą do wykonywania operacji dla których dany język został zaprojektoway. Wraz z rozwojem języka pojawia się duża liczba funkcji, ale indywidualny użytkownik korzysta jedynie z niewielkiego podzbioru związanego z zakresem jego aktywności. Ładowanie wszystkich istniejących funkcji danego języka do pamięci nie ma sensu, z tego powodu część funkjonalności języka jest wydzielana do zewnętrznych bibliotek, z których każda dotyczy innego zakresu zagadnień. Jeżeli taki zestaw bibilotek zewnętrznych jest rozwijany i dostarczany razem z językiem, nosi ona nazwa biblioteki standardowej języka. W przypadku, gdy jest rozwijana przez niezależnych developerów nosi nazwę biblioteki zewnętrznej. W biblioteki (moduły) możemy również organizować własne funkcje, zwrówno jeżeli chcemy daną bibliotekę rozpowszechniać niezależnie, jak również po to aby uprościć kod tworzonego programu.

Moduł jest zbiorem zmiennych, stałych oraz funkcji, które zostały pogrupowane w jeden plik. Zmienne i funkcje zawarte w module są zazwyczaj między sobą tematycznie i logicznie powiązane. Np. moduł math zawiera zmienne, np. pi oraz funkcje wykorzystywane do operacji matematycznych – np. funkcja sqrt()

Import zewnętrznego modułu

Aby otrzymać dostęp do zmiennych oraz funkcji zawartych w module, trzeba taki moduł zaimportować.

Python oferuje 4 tryby importu modułu:

  1. Import bezpośreni pod własną nazwą. Stosujemy dla jednolitych modułów o krótkiej nazwie np. math, os, sys
  2. Import modułów pod zmienioną nazwą (tzw. alias) stosujemy dla modułów o długiej nazwie np. numpy (np), pandas (pd)
  3. import wybranych funkcji z modułu
  4. Import wszystkich funkcji z modułu

Poniżej jako przykład wykorzystamy moduł math.

In [2]:
import math #1 import całego modułu
import math as m #2 import pod inną nazwą
from math import sqrt #3 import pojedynczej funkcji z modułu
from math import * #4 import całego modułu do standardowego zestawu nazw

Dwa pierwsze rozwiązania wymagają podania przedrostka biblioteki przy wywoływaniu funkcji (math.sqrt(), m.sqrt()). Dwa pozostałe nie wymagają w tym momencie przedrostka, ale mają inne ograniczenia. Wiele zewnętrznych modułów ma funkcje o takiej samej nazwie jak funkcje w bibliotece standardowej (nie dotyczy to metod obiektów!) w związku z tym wczytanie nowej funkcji nadpisuje inną funkcję już obecną w pamięci. O ile import pojedynczej funkcji jest bezpieczny o ile panujemy nad kodem o tyle import całej bibloteki (#4) nie jest już zalecany.

Założenia biblioteki standardowej

Biblioteka standardowa dostarcza ogromnej listy funkcji niezbędnych we współcznesnych językach programowania, które nie są dostępne w module wbudowanym, ale są niezbędne, albo przynajmniej ułatwiają pracę w zakresie podstawowych czynności wykonywanych w trakcie pracy z danymi. Znajomość wszystkich funkcji nie jest możliwa, przeciętny programista zna kilkadziesiąt, którymi się posługuje w codziennej pracy. Pozostałe funkcje najczęściej są wyszukiwane w razie potrzeby. Należy jednak znać ogólny schemat biblioteki, tak aby rozumieć jaka funkcjonalność jest dostarczona.

Moduł os

Moduł os dostarcza narzędzi do pracy z plikami, katalogami, ścieżkami (os.path). Przede wszystkim pozwala na sprawdzenie i zmianę bierzącego katalogu roboczego (miejsca gdzie domyślnie są zapisywane pliki), ustalenie ścieżki dostępu do otwieranego pliku, sprawdzenia czy plik istnieje i jest plikem (a nie katalogiem) itp. Opis wszystkich funkcji można znaleść w opisie modułu.

[https://docs.python.org/3/library/os.html]

Wybrane funkcje:

  • os.chdir(path) - Zmienia folder roboczy, wg. podanej ścieżki
  • os.listdir(path) - Zwraca listę zawierajcą nazwy folderów oraz plików w folderze zdefiniowanym za pomocą ścieżki. Kolejność w liście jest przypadkowa.
  • os.path.isfile(file), os.path.isdir(dir) - sprawdza czy dany obiekt jest plikiem lub katalogiem
  • os.path.exists(dir) - sprawdza czy obiekt istnieje
  • os.path.join() - łączy katalogi do ścieżki dostępu właściwej dla danego systemu operacyjnego
  • os.path.expanduser() - podaje katalog domowy wskazanego użytkownika
In [3]:
import os
current_path = os.getcwd()
print("current path: " + current_path)
os.path.expanduser("~")
new_path = os.path.join(os.path.expanduser("~"),"Documents")
print("new path: " + new_path)
os.chdir(new_path)
os.getcwd()
os.chdir(current_path)
os.getcwd()
current path: /home/jarekj/Dropbox/dydaktyka/programowanie1
Out[3]:
'/home/jarekj'
new path: /home/jarekj/Documents
Out[3]:
'/home/jarekj/Documents'
Out[3]:
'/home/jarekj/Dropbox/dydaktyka/programowanie1'

Moduły obsługi pracy kodu (runtime): sys, gc, copy

Dwa najważniejsze moduły w tej grupie to sys odpowiedzialne za obsługę skrytpów i pobieranie argumentów; copy pozwalający na głębokie i płytkie kopiowanie danych. Najważniejsze fukcje i stałe:

  • sys.argv - przechowuje listę argumentów skryptów
  • sys.exit() - pozwala na opuszczenie skryptu - udane lub z kodem błędu
  • gc.enable()/distable() - deaktywowanie/aktywowanie garbage collector
  • gc.collect() - ręczne uruchomienie garabge collektora
  • copy.copy() płytkie kopiowanie obiektu
  • copy.deepcopy() głębokie kopiowanie obiektu
  • pickle.pickle

Note: Zarządzanie pamięcią w Pythonie

Duże obiekty takie jak sekwencje (listy, tablice, krotki) ale też łańcuchy znaków a zwłaszcza listy zagnieżdżone są obszarem pamięci natomiast reprezentująca je zmienna jedynie wskazuje na ten obszar pamięci. Duże obiekty mogą zajmować rzeczywiście dużo pamęci a to oznacza że ich skopiowanie mogło by bardzo szybko wyczerpać dostępną pamięć. Dlatego skopiowanie obiektu nie kopiuje obiektu jako obszaru pamięci a jedynie zmiennej która wskazuje na ten sam obszar. W praktyce oznacza to że nie mamy dwóch niezależnych zbiorów danych a modyfikacja jednego z nich powoduje zmodyfikowanie drugiego. Funkcja copy.copy() kopiuje listę - ale tylko jej najwyższy poziom. Ewentualne zagnieżdzenia nadal są wskaźnikami do tych samych obszarów pamięci. Funkcja copy.deepcopy() kpiuje całą wewnętrzną strukturę obiektu.

Każde usunięcie zmiennej nie usuwa przypisanego do niej obszaru pamięci, bo może ob być przypisany również do innej zmiennej. Języki niskiego poziomu w takich sytuacjach wymagają ręcznego czyszczenia pamięci ale Python jak większość współczesnych języków nie wymaga stosowania ręcznego zarządzania pamięcią ale posiada wykonuje to automatycznie przy pomocy narzędzia zwanego garbage collector. GC usuwa z pamięci wszystkie obiekty, które nie są przypisane do żadnej zmiennej. Wadą tego rozwiązania jest że jest uruchamiane bardzo często powodując spowolenie działania skrytpu oraz niekiety mogą nie oczyścić pamieci całkowicie, co przy dużych zbiorach może powodować kłopoty. W sytuacji gdy czas obliczeń jest krytyczny możemy gc wyłączyć, w sytuacjach gdy pamięć jest krytyczna, możemy ręcznie analizować i oczyścić pamięć.

Poniższy przykład pokazuje jak działa proces kopiowania obiektów w Pythonie

In [4]:
lista = [0,1,2,3,4,[50,51,52,53,54],6]
nowa_lista = lista # zwłykłe kopiowanie
nowa_lista
nowa_lista[2] = 22 # zarowno nowa_lista jak i lista mają zmienioną wartość
'###'
nowa_lista
lista
Out[4]:
[0, 1, 2, 3, 4, [50, 51, 52, 53, 54], 6]
Out[4]:
'###'
Out[4]:
[0, 1, 22, 3, 4, [50, 51, 52, 53, 54], 6]
Out[4]:
[0, 1, 22, 3, 4, [50, 51, 52, 53, 54], 6]
In [5]:
# zastosowanie copy
import copy
lista = [0,1,2,3,4,[50,51,52,53,54],6]
nowa_lista = copy.copy(lista)
# kopiowanie nie działa na listę zagnieżodzą
nowa_lista[2] = 22
nowa_lista[5][1] = 510
nowa_lista
lista
Out[5]:
[0, 1, 22, 3, 4, [50, 510, 52, 53, 54], 6]
Out[5]:
[0, 1, 2, 3, 4, [50, 510, 52, 53, 54], 6]
In [6]:
# zastosowanie copy
import copy
lista = [0,1,2,3,4,[50,51,52,53,54],6]
nowa_lista = copy.deepcopy(lista)
# kopiowanie działa na listę zagnieżodzą
nowa_lista[2] = 22
nowa_lista[5][1] = 510
nowa_lista
lista
Out[6]:
[0, 1, 22, 3, 4, [50, 510, 52, 53, 54], 6]
Out[6]:
[0, 1, 2, 3, 4, [50, 51, 52, 53, 54], 6]

Dodatkowe typy danych daytime, calendar, enum, collections

Dodatkowe typy danych to przede wszystkim obsługa typu data/czas (time i calendar) oraz typ enum - czyli typ wyliczeniowy. Pozostałe typy danych - przede wszyskim związane z obliczeniami wprowadza zewnętrzna biblioteka numpy

Najważniejsze operacje

omówić kolekcje

Moduły wspomagające programowanie strukturalne: itertools, operator

Moduł itertools dostarczcza funkcje pozwalające tworzyć generatory/iteratory o większych możliwościach niż te oferowane przez sekwencję range(). Wiele funkcji z modułu itertools współpracuje z funkcjami z modułu operators dostarczającego wysokowydajnych funkcji zastępujących operatory języka do stosowania z generatorami/iteratorami

Wybrane funkcje z modułu itertools:

  • accumulate() - pozwala na akumulowanie wyników kolejnych iteracji. Podobna w działaniu do funkcji reduce()
  • count() - tworzy iterator od wskazanej liczby i działa do przerwania pętli przez polecenie break
  • cycle() - cyklicznie iterują bo krótkiej liście aż do przerwania pętli przez polecenie break
  • combinations() - tworzy kombinacje z elementów listy/krotki zawierające określoną elementów

Inne funkcjonalności modułu można znaleść w dokumentacji modułu [https://docs.python.org/3/library/itertools.html]

Narzędzia itertools ze względu na generowanie struktur o potencjalnie nieskończonej długości są niebezpieczne i powinny być stosowane przez doświadczonych użytkowników.

In [7]:
dane = [1,2,2,3,1,3,4,2,5,3,2,3,4,3,2,1,2,3,1,4,1,1,2]

import itertools
import operator

# akumulacja
accum = itertools.accumulate(dane,operator.add)
print(list(accum))
[1, 3, 5, 8, 9, 12, 16, 18, 23, 26, 28, 31, 35, 38, 40, 41, 43, 46, 47, 51, 52, 53, 55]
In [8]:
#nieskończony iterator
lista = itertools.count(10,2)
for r in lista:
    print(r)
    if(r>20):
        break
10
12
14
16
18
20
22
In [9]:
kolory = ['czerwone','zielone','niebieskie','zolte','fioletowe','pomaranczowe']
#kombinacje
comb = itertools.combinations(kolory,2)
list(comb)
Out[9]:
[('czerwone', 'zielone'),
 ('czerwone', 'niebieskie'),
 ('czerwone', 'zolte'),
 ('czerwone', 'fioletowe'),
 ('czerwone', 'pomaranczowe'),
 ('zielone', 'niebieskie'),
 ('zielone', 'zolte'),
 ('zielone', 'fioletowe'),
 ('zielone', 'pomaranczowe'),
 ('niebieskie', 'zolte'),
 ('niebieskie', 'fioletowe'),
 ('niebieskie', 'pomaranczowe'),
 ('zolte', 'fioletowe'),
 ('zolte', 'pomaranczowe'),
 ('fioletowe', 'pomaranczowe')]

Moduły matematyczno-statystyczne

Moduły matematyczno-statystyczne z biblioteki standardowej mają mniejsze znaczenie w związku z rozwojem biblioteki numpy i scipy, które ze względu na wydajność i stopień rozwoju całkowicie przejęły funkcjonalność modułów statystyczno-matematycznych. Obecnie są one wykorzystywane jedynie dla małych zbiorów danych, gdy uruchamianie dodatkowych narzędzi nie ma większego sensu.

Najważniejsze funkcje:

  • math.() - funkcje matematyczne takie jak: sqrt(), log(), exp(), sin(), cos() itp
  • math. funkcje zaokrąglające: ceil(), floor(), round()
  • math. funkcje sprawdzające poprawność wartości numerycznych: isfinite(), isnan(),
  • stats. median(), mode(), mean() itp. Niektóre funkcje statystyczne jak min lub max są częścią modułu build_in
  • random. randint(), random(), sample() itp. funkcje wykorzystujace generator liczb losowych do generowania liczb
In [10]:
import math
import random

liczba = random.random()
print(liczba)
arcus = math.atan(liczba)
print(arcus)
0.8451514476434062
0.7016724863190231

Inne moduły

Poza zainteresowaniem tego etapu kursu leżą biblioteki związane z obsługą komunikacji internetowej, przetwarzania doekumentów xml, przetwarzania równoległego, i zarządania systemami. Warto jednak zapoznać się z zawartością biblioteki standardowej w mierę postępów w uczeniu się języka Python. W dwóch osobnych częściach zostaną omówione moduły fukcje związane z czytaniem i zapisem danych zewnętrznych oraz wspmagającymi tworzenie niezależnie działających skryptów.

Biblioteki zewnętrzne

Potęgą języka Python jest duża liczba wysokiej jakości bibliotek zewnętrznych. Są wśród nich biblioteki ogólnego przeznaczenia zwiększające funkcjonalność języka (numpy, matplotlib), biblioteki naukowe (scikit-), specjalistyczne biblioteki programistyczne, w tym biblioteki obsługi danych geoprzestrzennych. Dalsze części kursu będą poświęcone zastosowaniu wybranych bibliotek w pracy z danymi geograficznymi (głównie geoprzestrzennymi). Do najważniejszych bibliotek z punktu widzenia geoinformacji zaliczamy:

  • numpy - biblioteka obsługi tablic wielowymiarowych. Podstawa algebry liniowej i wszystkich modułów obliczeniowych i analitycznych w Pythonie
  • matplotlib - niskopoziomowa biblioteka wizualizacji graficznych, podstawa systemu wizualizacji danych w Pythonie
  • scipy - biblioteka zaawansowanych obliczeń numerycznych
  • pandas - biblioteka wspomagająca przetwarzanie danych tabelarycznych i dostępu do baz danych
  • gdal - biblioteka dostępu do danych geoprzestrzennych
  • scikit-learn - biblioteka uczenia maszynowego i klasyfikacji danych
  • seaborn - biblioteka wysokopoziomowych wizualizacji graficznych
  • pyQt, wxPython - biblioteki tworzenia interface graficznych

Powyższe biblioteki będę omawiane w średnio- i zaawansowanej części kursu

Ćwiczenie

Utworzyć bibliotekę funkcji do przeliczania wybranych jednostek geograficznych