Adam Inglot
Adiunkt w Katedrze Geodezji
Wydział Inżynierii Lądowej i Środowiska, Politechnika Gdańska
adam.inglot@pg.edu.pl
2022-10-11, 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).W drugiej części wprowadzenia do Pythona zapoznamy się z definiowaniem własnej funkcji, trzema modułami z podstawowych bibliotek Pythona: os, datetime i random. Przyglądniemy się też podstawowemu sposobowi obsługiwania plików, na przykładzie i zastosowaniu do pliku tekstowego.
def
Budując własną funkcję w języku Python możemy utworzyć jedną z czterech rodzajów funkcji: globalną, lokalną, lambda lub metodę. My na potrzeby kursu ograniczymy się do używania, tworzenia funkcji globalnych. Ogólna składnia funkcji def
:
1def nazwa_funkcji(pierwszyParametr...):2pakiet
Parametry które możemy podać są opcjonalne, możemy je podać jako sekwencję identyfikatorów oddzielonych przecinkami lub jako sekwencja par identyfikator=wartość
. Podczas użycia funkcji należy wprowadzić dokładnie tyle parametrów ile jest wymaganych (podanych w nawiasie okrągłym), w przeciwnym razie zwrócony zostanie błąd w wyniku działania funkcji. Sprawdźmy na przykładzie jak zastosować funkcję def
:
1def suma_trzech_parametrow(pierwszyParametr, drugiParametr, trzeciParametr):2sumaParametrow = pierwszyParametr + drugiParametr + trzeciParametr3return sumaParametrow45print(suma_trzech_parametrow(1, 2, 3)
Wynik działania skryptu:
Run:6 Process finished
W powyższym przykładzie zostały zastosowane argumenty pozycyjne
, czyli wykonując funkcję podajemy na konkretnej pozycji wartość jaką ma przyjmować dany parametr. Możemy argument pozycyjny zamienić na argument z wartością domyślną, wtedy nie musimy podawać argumenty a funkcja zostanie wykonana z wprowadzoną wartością domyślną.
1def suma_trzech_parametrow(pierwszyParametr, drugiParametr, trzeciParametr=3):2sumaParametrow = pierwszyParametr + drugiParametr + trzeciParametr3return sumaParametrow45print(suma_trzech_parametrow(1, 2)
Wynik działania skryptu z wartością domyślną:
Run:6 Process finished
Przy zastosowaniu wartości domyślnej możemy pozostawić tę wartość jak w kodzie powyżej lub wprowadzić na ostatnią pozycję wartość dla której chcemy przeprowadzić działanie:
1def suma_trzech_parametrow(pierwszyParametr, drugiParametr, trzeciParametr=3):2sumaParametrow = pierwszyParametr + drugiParametr + trzeciParametr3return sumaParametrow45print(suma_trzech_parametrow(1, 2, 10)
Wynik działania skryptu gdzie wartość domyślna została zastąpiona:
Run:13 Process finished
Podczas projektowania własnej funkcji z wartością domyślną, należy pamiętać że w pierwszej kolejności należy wprowadzić argumenty pozycyjne
a po nich, argumenty z wartością domyślną.
os
Do czego może nam się przydać moduł os
? Najprościej można odpowiedzieć że na potrzeby dostępu do plików i folderów. Dzięki metodom z tego modułu możemy np. wylistować pliki i foldery z podanej lokalizacji, usunąć lub skopiować plik, wyodrębnić nazwę pliku czy rozszerzenia.
Dla podanych metod sposób importu biblioteki os
wygląda w taki sposób: import os
.
składnia | opis |
---|---|
os.listdir(path) | zwraca w formie listy zawartość podanego folderu |
os.remove(file) | usuwa plik z podanej lokalizacji |
os.rename(oldFile, newFile) | zmienia nazwę pliku, podajemy dwa argumenty, pierwszy to istniejący plik z ścieżką, drugi nowa nazwa pliku z miejscem docelowym |
os.replace(oldFile, newFile) | zmienia miejsce i nazwę pliku |
os.path.abspath(path) | metoda ta podaje pełną ścieżkę do pliku |
os.path.dirname(file) | wydziela samą ścieżkę |
os.path.exists(file) | zwraca wartość True w przypadku gdy plik istnieje |
os.path.getatime(file) | zwraca datę i czas w formie liczby typu float założenia pliku |
os.path.getmtime(file) | zwraca datę i czas w formie liczby typu float modyfikacji pliku |
os.path.getsize(file) | zwraca rozmiar pliku mierzony w bajtach |
os.path.join(path, name.r) | łączy ścieżki lub ścieżkę i nazwę pliku |
os.path.split(path) | dzieli ścieżkę na dwie części i zapisuje do krotki, dzieli ścieżkę na ostatni składnik i resztę, jeżeli mamy ścieżkę do pliku to podzieli nam na ścieżkę i nazwę pliku z rozszerzeniem |
os.path.splitext(name.r) | rozdziela nazwę pliku z rozszerzeniem w postaci krotki gdzie mamy wydzieloną nazwę i rozszerzenie |
Dokumentacja modułu os
jest dostępna na stronach internetowych python.org moduł os.
os
Na potrzeby przykładu posłużymy się folderem który zawiera kilka plików:
Wyświetlmy jakie pliki zawiera podany folder:
Można użyć pętli for
do bardziej czytelnej formy prezentacji listy plików:
Sprawdźmy parametry plików takie jak, czas założenia pliku i rozmiar:
Format czasu podany w tej formie, jest niejasny dla człowieka, nie jesteśmy w stanie określić roku, dnia czy godziny. W kolejnym module poznamy metody dzięki którym będziemy w stanie zamienić liczbę na datę i czas.
datetime
Dla podanych metod sposób importu biblioteki datetime
wygląda w taki sposób: import datetime as dt
.
składnia | opis |
---|---|
dt.datetime.now() | wywołanie aktualnej daty i czasu z dokładnością do 6 miejsc po przecinku dal sekund, w lokalnej strefie czasowej |
dt.timedelta.total_seconds() | |
dt.datetime.utcnow() | wywołanie aktualnej daty i czasu z dokładnością do 6 miejsc po przecinku dal sekund, dla strefy 0 UTC |
dt.datetime(y, m, d, H=0, M=0, S=0, MS=0, tzinfo=None, *, fold=0) | konwertuje podane wartości na obiekt datetime , wymaga minimum trzech argumentów, y=rok, m=miesiąc, d=dzień |
t.isoformat() | konwertuje obiekt datetime na typ string w formacie iso, np. '2022-10-15T14:31:53' |
dt.datetime.fromisoformat(datetime_iso_string) | konwertuje date i czas zapisany w formacie iso na obiekt datetime , np. '2022-10-15T14:31:53' |
t.strftime(format) | konwertuje obiekt datetime do string używając kombinacji parametrów z tabeli poniżej |
dt.datetime.fromtimestamp(datetime_float) | konwertuje liczbę zmiennoprzecinkową na obiekt datetime |
Kolejna tabela przedstawia oznaczenia formatu konwersji daty i czasu z obiektu datetime do string. Dzięki tym parametrom jesteśmy w stanie skomponować formę zapisu daty i czasu do ciąg znaków w dowolnej kombinacji.
oznaczenie | znaczenie | przykład, wynik |
---|---|---|
`%y` | zwraca dwucyfrową liczbę reprezentującą rok w obrębie jednego wieku | 01, 02, ..., 99 |
`%Y` | zwraca czterocyfrową liczbę reprezentującą rok | 0001, 0002, ..., 2022, 2023, ..., 9998, 9999 |
`%m` | zwraca dwucyfrową liczbę reprezentującą miesiąc | 01, 02, ..., 12 |
`%b` | zwraca trzy literowy ciąg znaków reprezentującą miesiąc | Jan, Feb, ..., Dec (en_US); |
`%B` | zwraca pełną nazwę miesiąca | January, February, ..., December (en_US); |
`%d` | zwraca dwucyfrową liczbę reprezentującą dzień w obrębie miesiąca | 01, 02, ..., 31 |
`%H` | zwraca dwucyfrową liczbę reprezentującą godzinę do 24h | 01, 02, ..., 24 |
`%I` | zwraca dwucyfrową liczbę reprezentującą godzinę do 12h | 01, 02, ..., 12 |
`%p` | oznaczenie pory dnia, przed południem czy popołudniu | AM, PM (en_US); |
`%M` | zwraca dwucyfrową liczbę reprezentującą minuty | 00, 01, 02, ..., 59 |
`%S` | zwraca dwucyfrową liczbę reprezentującą sekundy | 00, 01, 02, ..., 59 |
`%f` | zwraca sześciocyfrową liczbę reprezentującą mikrosekundy | 00, 01, 02, ..., 59 |
`%j` | zwraca trzycyfrową liczbę reprezentującą dzień liczony od początku roku | 001, 002, 003, ..., 366 |
Obie tabele zostały przygotowane na podstawie dokumentacji przedstawionej na stronie python.org moduł datetime.
datetime
Zacznijmy od niedokończonego zadania z modułu os
, odczytaliśmy informację o założeniu pliku ale w formie liczby, która jest trudna przez człowieka do interpretacji. Zamieńmy te liczby na czas w konwencjonalnej formie. Użyjemy do tego na początek metody fromtimestamp
.
Uwzględniając lokalny czas, za pomocą metody dt.timezone.utc
random
składnia | opis |
---|---|
random.randint(a, b) | zwraca liczbę całkowitą n z zakresu a ≤ n ≤ b , podobną metodą jest random.randrange() |
random.choice(sekwencja) | zwraca jeden element z wskazanej sekwencji, sekwencją może być lista, krotka czy też ciąg znaków |
random.random() | zwraca liczbę zmiennoprzecinkową z zakresu [0.0, 1.0) |
random.uniform(a, b) | zwraca liczbę zmiennoprzecinkową n z zakresu a ≤ n ≤ b |
random.sample(listValues, counts=countValue, k=countSample) | zwraca listę wartości wybranych z listValues , parametr countValue odpowiada liczebnością liście listValues i służy do zwielokrotnienia występowania danej wartości na tych samych pozycjach, parametrcountSample to liczba naturalna określająca ile ma się znajdować wartości w liście wynikowej, przy czym countSample ≤ len(listValues) lub kombinacji list listValues i countValue |
random
Moduł generujący liczby pseudolosowe głównie może nam się przydać do wprowadzenia danych testowych, sztucznie wygenerowanych współrzędnych lub z puli danych przygotować część losowo wybranych obiektów.
Przyglądnijmy się jak wygenerować listę 30 liczb całkowitych w przedziale (100, 200) - nie uwzględniając liczb 100 i 200:
1import random2listaDanych = []3for i in range(30):4listaDanych.append(random.randint(101, 199))
Sprawdź wynik działania skryptu w Python.
Teraz sprawdźmy czy w naszej liście są takie liczby które występują więcej niż 1 raz, skorzystajmy z metody count
którą możemy zliczyć wystąpienia w liście:
W takim razie zastosujmy metodę sample do wygenerowania liczb unikalnych w obrębie zakresu danych, możemy to wykonać podając zakres wartości z jakiego ma metoda pobierać wartości:
Po sprawdzeniu czy występują jakieś powielone liczby z podanego zakresu, program nie wykazuje nam żadnych powieleń.
Zapis i odczyt pliku tekstowego jest stosunkowo prostą operacją, komplikuje się w momencie pozyskiwania informacji z ciągu znaków. Inaczej mówiąc, gdy projektujemy sposób zapisu danych do liku tekstowego, musimy tak przygotować, zaprogramować zapis danych aby w łatwy sposób te dane ponownie wprowadzić do pierwotnej formy. Co może stanowić problem. Rozważmy zapis współrzędnych do pliku tekstowego, wiemy że część całkowita od części dziesiętnej jest separowana kropką .
, jeżeli jako separator wybierzemy kropkę a nie przecinek czy średnik, to przy odczytywaniu danych będziemy mieli więcej pracy.
Odczytywanie pliku tekstowego jest obsługiwane przez metodę open
, natomiast czytanie linii po linii w pliku tekstowym wykonuje się za pomocą pętli for
z metodą file.readlines()
. Zapisywanie danych do pliku tekstowego również odbywa się z wykorzystaniem metodę open
a poszczególne elementy wprowadzamy za pomocą metody file.write(<i>tekst</i>)
. Zobaczmy ogólną składnie z dodatkowymi elementami:
Odczytywanie informacji zawartych z pliku txt:
1inFile = open('NameFile.txt', "r", encoding="utf8")2for line in inFile.readlines():3line.split("")4...5inFile.colse()
Zapisywanie danych do pliku txt:
1outFile = open('NameFile.txt', "w", encoding="utf8")2outFile.write(tekst)3outFile.colse()
Pobierzmy dane badawcze udostępnione na portalu Most Danych, dane te udostępnione są w formie pliku txt zawierającym współrzędne przestrzenne (x, y, z) w lokalnym systemie współrzędnych. Odczytajmy te dane za pomocą powyższych składni, obliczmy ile jest punktów w pliku.
1inFile = open(r"D:\GIS\Dane\silo.txt", "r", encoding="utf8")2sumLine = 03for xyz in inFile.readlines():4sumLine += 15print(sumLine)
Wynik działania skryptu:
Run:447693 Process finished
Zmodyfikujmy plik w taki sposób żeby w pierwszej linijce podana była informacja o nazwie kolumn: x y z
1inFile = open(r"D:\GIS\Dane\silo.txt", "r", encoding="utf8")2outFile = open(r"D:\GIS\Dane\new_silo.txt", "w", encoding="utf8")34newText = 'x y z \n'5for xyz in inFile.readlines():6newText += xyz78outFile.write(newText)
[1] Mark Summerfield, Python 3 - kompletne wprowadzenie do programowania. Helion, wydanie 2, ISBN: 978-83-246-2642-7, 2010.
[2] Dokumentacja Python. https://docs.python.org/3/, (data dostępu 10.10.2022).