JĘZYK PYTHON - NARZĘDZIE DLA KAŻDEGO NAUKOWCA Marcin Lewandowski [ mlew@ippt.gov.pl ]
OPERACJE NA STRINGACH 2
Bit/Byte/Word Bit 0/1 Byte 8 bitów Word 2 bajty 16 bitów Long Word 4 bajty 32 bitów Long Long Word 8 bajty 64 bitów 3
Power of 2 4
ASCII American Standard Code for Information Interchange ustandaryzowany w 1963 Pierwsze zastosowanie: BELL teleprinter (TTY - TeleTYpe) Kodowanie znaków alfanumerycznych amerykaoskich, kontrolnych i ew. znaków międzynarodowych (tzw. strona kodowa) 5
ASCII-I 6
ASCII-II 7
UNICODE UNICODE - jest nowoczesnym sposobem kodowania obejmującym znaki używane na całym świecie (np. polskie ogonki, alfabet chioski, hieroglify, cyrylicę i wiele innych), symbole muzyczne, techniczne, fonetyczne i inne często spotykane. Unicode przypisuje każdemu znakowi unikalny numer (kod numeryczny, ang. code point), niezależny od używanego systemu operacyjnego, programu czy języka. Ważną cechą Unicode jest fakt, że pierwsze 128 znaków odpowiada kodom ASCII (zakres 00..7F). Więcej o Unicode na www.unicode.org. 8
UNICODE encoding UTF-8 an 8-bit variable-width encoding which maximizes compatibility with ASCII. UTF-16 a 16-bit, variable-width encoding UTF-32 a 32-bit, fixed-width encoding 9
UNICODE escape >>> 'm' 'm' >>> '\155' 'm' >>> '\x6d' 'm >>> u'\n{latin SMALL LETTER A} 'a' >>> u'\n{latin SMALL LETTER A WITH ACUTE} 'á' >>> u"\u0041" A >>> u"\u00000041" A 10
Składnia stringów stringliteral ::= [stringprefix](shortstring longstring) stringprefix ::= "r" "u" "ur" "R" "U" "UR" "Ur" "ur" shortstring ::= "'" shortstringitem* "'" '"' shortstringitem* '"' longstring ::= "'''" longstringitem* "'''" '"""' longstringitem* '"""' shortstringitem ::= shortstringchar escapeseq longstringitem ::= longstringchar escapeseq shortstringchar ::= <any source character except "\" or newline or the quote> longstringchar ::= <any source character except "\"> escapeseq ::= "\" <any ASCII character> 11
String escape sequence Raw string wyłączona interpretacja sekwencji escape! 12
Funkcje len(s) zwraca długośd sekwencji (liczbę elementów), działa dla obiektów typu: string, tuple, list, dictionary char(n) zwraca znak odpowiadający kodowi n ASCII ord(ch) zwraca kod ASCII danego znaku ch str(s) reprezentacja obiektu dla człowieka repr(s) reprezentacja obiektu dla interpretera W Python 3.0+ znaki są stringi/kodowane w UNICODE! 13
str() vs repr() >>> s = 'Hello, world.' >>> str(s) 'Hello, world.' >>> repr(s) "'Hello, world. >>> str(0.1) '0.1' >>> repr(0.1) '0.10000000000000001' 14
\ problem # Path on Windows >>> path = C:\\sample.txt >>> path = r C:\sample.txt >>> str(path) 'C:\\sample.txt' >>> repr(path) "'C:\\\\sample.txt >>> print path C:\sample.txt # Path on Unix/Linux >>> path = /tmp/sample.txt 15
Formatowanie stringów format_spec ::= [[fill]align][sign][#][0][width][.precision][type] fill ::= <a character other than '}'> align ::= "<" ">" "=" "^ sign ::= "+" "-" " " width ::= integer precision ::= integer type ::= "c" "d" "i" "o" "u" "e" "E" "f" "F" "g" "G" "x" "X" "r" "s" "%" 16
Formatowanie 17
Formatowanie: opcje dosuwania 18
Formatowanie: opcje znaku '#' dla całkowitoliczbowych jeśli występuję poprzedza liczbę '0b', '0o', or '0x w zależności od podstawy: binarnej, ósemkowej, hexadecymalnej 19
print ze słownika >>> print WITAMY %(imie)s %(nazwisko)s.' % \ { imie : Marcin", nazwisko": Lewandowski } WITAMY Marcin Lewandowski 20
Funkcje stringowe >>> dir( Hello Python! ) [' add ', ' class ', ' contains ', ' delattr ', ' doc ', ' eq ', ' format ', ' ge ', ' getattribute ', ' getitem ', ' getnewargs ', ' getslice ', ' gt ', ' hash ', ' init ', ' le ', ' len ', ' lt ', ' mod ', ' mul ', ' ne ', ' new ', ' reduce ', ' reduce_ex ', ' repr, ' rmod ', ' rmul ', ' setattr ', ' sizeof ', ' str ', ' subclasshook ', '_formatter_field_name_split', '_formatter_parser', 'capitalize, 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper, 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', strip', 'swapcase', 'title', 'translate', 'upper', 'zfill ] *** Przegląd funkcji stringowych w dokumentacji *** 21
Użycie help() >>> help( Hello.replace) Help on built-in function replace: replace(...) S.replace (old, new[, count]) -> str Return a copy of S with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. 22
Operacja na stringach I Operacja S = '' S = str() S = "spam's" S = 'spam\'s' S = '\thello\nworld \x21' S = """...ble, ble, ble""" S = r'\temp\spam' Interpretacja Pusty string Apostrof w stringu Sekwencje escape String wieloliniowy String raw S = u'spam' String Unicode tylko Python 2.6 S = b'spam' String bajtowy tylko Python 3.0+ S1 + S2 S * 3 S[i] S[i:j] Konkatenacja (łączenie) stringów Powielanie stringów Indeksowanie, przecinanie (slicing) 23
Operacja na stringach II Operacja len(s) "Type: %s has value %d" % (type, val) Interpretacja Długośd stringu Formatowanie stringu "a {0} parrot".format(kind) Funkcja formatowania S.find( spam') S.rstrip() S.replace('spam', 'ham') S.split(',') '+'.join(strlist) S.lower(), S.upper() S.startswith('spam'), S.endswith('spam') S.isdigit() Funkcja szukania w stringu Funkcja usuwania spacji Funkcja zamiany Funkcja dzielenia stringu na separatorze Funkcja łączenia listy w string z separatorem Zamiana znaków na małe/wielkie litery Test na zawartośd początku/kooca stringu Test czy string zawiera tylko cyfry S.encode('latin-1') Kodowanie w danej stronie kodowej 24
EX6 Konwersja/kodowanie ASCII Wyświetlanie całej tablicy znaków ASCII w formacie: kod hex, kod decymalny, znak ASCII Kodowanie/Dekodowanie stringu ASCII reprezentacji heksadecymalnej i binarnej 25
Encoding "Marcin".encode('hex') "3233343536". decode('hex') encodings/cp1252.py *** Codecs w dokumentacji *** 26
Encoding I >>> import sys >>> sys.version '2.6 (r26:66721, Oct 2 2008, 11:35:03) [MSC v.1500 32 bit (Intel)]' >>> S = 'A\xC4B\xE8C' # String of 8-bit bytes >>> print S # Some are non-ascii AÄBčC >>> S.decode('latin-1') # Decode byte to latin-1 Unicode u'a\xc4b\xe8c' >>> S.decode('utf-8') # Not formatted as utf-8 UnicodeDecodeError: 'utf8' codec can't decode bytes in position 1-2: invalid data >>> S.decode('ascii') # Outside ASCII range UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 1: ordinal not in range(128) 27
Moduł struct Pakowanie i rozpakowywanie struktur binarnych na podstawie definicji formatu danych Potrzebne przy konwersji, zapisie/odczycie binarnych plików i struktur danych 28
Moduł struct - funkcje exception struct.error wyjątek generowany dla niepoprawnych specyfikacji typów struct.pack(fmt, v1, v2,...) zwraca string zawierający spakowaną (binarną) strukturę w formacie fmt złożoną z wartości v1, v2,... (argumenty muszą pasowad do formatu wzorca!) struct.pack_into(fmt, buffer, offset, v1, v2,...) j.w. ale pakuje wynik do zapisywalnego bufora buffer zaczynając w miejscu offset struct.unpack(fmt, string) rozpakowuje strukturę binarną (string) zgodnie z formatem fmt; zwraca listę niemodyfikowalną wartości; Uwaga: len(string) == struct.calcsize(fmt) struct.unpack_from(fmt, buffer[, offset=0]) j.w. ale rozpakowuje z bufora buffer zaczynając od miejsca offset struct.calcsize(fmt) zwraca długośd struktury dla określonej specyfikacji formatu wzorca 29
Moduł struct typy I Format C Type Python x pad byte no value c char string of length 1 b signed char integer B unsigned char integer h short integer H unsigned short integer i int integer I unsigned int integer or long l long integer L unsigned long long q long long long 30
Moduł struct typy II Format C Type Python f float float d double float s char[] string p char[] string P void * long Wzorzec formatu Znaczenie 10s String o długości 10 4h <HLQ Liczba powtórzeo z wyjątkiem typu s (to samo co hhhh ) Pierwszy znak określa kolejnośd bajtów i wyrównanie w tym wypadku little-endian/standard 31
Moduł struct kolejnośd bajtów Znak Kolejnośd bajtów Rozmiar @ (domyślny) Natywny Natywny = Natywny Standard < little-endian Standard > big-endian Standard! network (= big-endian) Standard Natywny rozmiar i wyrównanie określa funkcje kompilatora C sizeof(). Standardowy rozmiar i wyrównanie = bez wyrównania, short = 2 bajty; int, long = 4 bajty; long long = 8 bajty; float = 4 bajty, double = 8 bajtów 32
EX6 Moduł struct - przykład BIN2TXT konwerter binarnych plików z danymi typu int do pliku tekstowego 33
WYRAŻENIA REGULARNE (REGEX) 34
Hmmm "Some people, when confronted with a problem, think 'I know, I'll use regular expressions.' Now they have two problems. Jamie Zawinski 35
Regex >>> import re >>> s = His name is Marcin Lewandowski and her is Merlin Monroe.' >>> print re.findall( ([A-Z]\w+)\s+([A-Z]\w+)', s) [('Marcin', 'Lewandowski'), ('Merlin', 'Monroe')] 36
Regex funkcje I re.compile(pattern[, flags]) kompilacja wyrażenie regularnego do obiektu, który będzie następnie używany do wywołania metod: match() i search(); flags opcjonalne, specyfikowane razem przy pomocy operatora OR ( ). prog = re.compile(pattern) result = prog.match(string) 37
Regex funkcje II RegexObj.match(string[, pos[, endpos]]) dopasowywanie obiektu regex do stringu. Jeśli zero lub więcej znaków na początku stringu pasuje do wzorca zwraca obiekt MatchObj, lub None w przeciwnym wypadku RegexObj.search(string[, pos[, endpos]]) przeszukuje string w celu dopasowania wzorca. Zwraca obiekt MatchObj w przypadku znalezienia dopasowania lub None w przeciwnym wypadku *** moduł re w dokumentacji *** 38
Regex flagi/opcje re.i, re.ignorecase włącza opcję case-insensitive re.l, re.locale włącza interpretację znaków \w, \W, \b, \B, \s, \S z wykorzystaniem aktualnego locale. re.m, re.multiline kiedy włączone znak '^' dopasowuje na początku stringu oraz każdej nowej linii tekstu; podobnie znak '$' na koocu stringu oraz na koocu każdej linii tekstu re.s, re.dotall włącza dopasowanie znaku '.' jako każdego znaku włącznie ze znakiem nowej linii re.u, re.unicode włącza interpretację znaków \w, \W, \b, \B, \d, \D, \s, \S zgodnie z UNICODE re.x, re.verbose umożliwia pisanie wyrażeo regularnych w bardziej czytelnej postaci wieloliniowej oraz ze spacjami, które są ignorowane, znaki po # są traktowane jak komentarz 39
match vs search import re regex = re.compile( he..o') if regex.match( hello!!!'): print match!' if regex.search( Python hello!'): print found!' 40
Regex I Znak Znaczenie ^ Dopasowuje początek napisu $ Dopasowuje koniec napisu \b Dopasowuje początek lub koniec słowa \d Dopasowuje dowolna cyfrę \D Dopasowuje dowolny znak, który nie jest cyfra \s Dopasowuje pustą przestrzeo odpowiednik: [ \t\n\r\f\v] \S Negacja do \s odpowiednik: [^ \t\n\r\f\v] \w Dopasowuje znak alfanumeryczny odpowiednik: [a-za-z0-9_] \W Negacja do \w odpowiednik: [^a-za-z0-9_] 41
Regex II Znak Znaczenie x? Dopasowuje wystąpienie x zero lub jedno raz x* Dopasowuje x zero lub więcej razy x+ Dopasowuje x jeden lub więcej razy x{n,m} (a b c) (x) Dopasowuje znak x co najmniej n razy, lecz nie więcej niż m razy Dopasowuje a albo b albo c Definicja grupy dopasowana wartośd dostępna za pomocą groups(), na obiekcie zwróconym przez re.search. Dopasowuje dowolny pojedynczy znak (z wyjątkiem nowej linii, o ile nie ustawiona flaga re.dotall) * + Dopasowuje zestaw lub zakres znaków (np. *abc], [a-za-z] *^ + Negacja do * + 42
Obiekt match m = re.search("a(b*)c", "_abbbbc_") Wyrażenie Wartośd Opis m.group(1) bbbb Dopasowany string pierwszej dopasowanej grupy m.start(1) 2 Indeks startu w stringu elementu pierwszej dopasowanej grupy m.end(1) 6 Indeks kooca w stringu elementu pierwszej dopasowanej grupy 43
Dekodowanie numerów telefonów EX7 Formaty numerów telefonów: 800-555-1212 800 555 1212 800.555.1212 (800) 555-1212 1-800-555-1212 800-555-1212-1234 800-555-1212x1234 800-555-1212 ext. 1234 work 1-(800) 555.1212 #1234 44
Regex narzędzia i linki http://www.regular-expressions.info dla Pythona i różnych innych języków http://www.pythonregex.com webowy tester Regex http://kodos.sourceforge.net narzędzie GUI do testowania Regex 45
OPERACJA NA PLIKACH 46
Co o plikach? Typy plików: Tekstowe (automatyczna obsługa znaków kooca linii) Binarne Pliki wirtualne urządzeo (znakowe/blokowe) Tryby dostępu Buforowany/niebuforowany Blokujący/nieblokujący Funkcje/Operacje na plikach i katalogach Moduły obsługi plików: os, os.path, fileinput, tempfile, shutil CSV, XML, ZIP, rekordy, DB 47
Moduł io open(filename[, mode[, bufsize]]) otwiera plik filename w trybie mode (domyślnie r ); bufsize określa tryb i wielkośd bufora close(file) zamyka plik file file.readline([limit]) czyta linię tekstu z pliku (max limit znaków) file.readlines([limit]) czyta linie z pliku i zwraca w formie listy (max limit znaków) file.seek(offset[, whence]) zmienia pozycję w pliku o offset względem (whence): 0 początku pliku (domyślnie); 1 pozycji aktualnej; 2 kooca pliku; zwraca bezwzględną pozycję aktualną file.tell() Return the current stream position file.read([n]) czyta i zwraca zadaną liczbę n bajtów z pliku file.readall() czyta zawartośd całego pliku file.write(buf) pisze bajty z bufora buf do pliku 48
open/read/close # open( C:\\path\\file, w+ ) # tekstowy, read/write # open( C:/path/file, rb ) # binarny, read >>> f = open(r C:\path\file ) >>> f.read(10) >>> print f.tell() >>> f.seek(10) >>> print f.tell() >>> f.close() 49
open() tryb otwarcia Wartośd Początkowa pozycja w pliku Odczyt? Zapis? r Początek (domyślnie) Tak Nie w Początek Nie Tak a Koniec Nie Tak r+ Początek Tak Nie w+ Początek Tak Tak a+ Koniec Tak Tak U Uniwersalna obsługa kooców linii: \n, \r, \r\n 50
Pliki zapis/odczyt # ZAPIS: fid = open( test.txt, w ) fid.write( Hello\nWorld ) fid.close() # ODCZYT: cały plik na raz! fid = open( test.txt, r ) s = fid.read() fid.close() # ODCZYT: linia po linii fid = open( test.txt, r ) for line in fid: print("line: " + line.strip()) fid.close() 51
CRLF/LF Linia tekstu zakooczona znakiem nowej linii: LF (0x0A) Unix CR LF (0x0D 0x0A) Windows print ord( \r ) # 13 print ord( \n ) # 10 print \n, # \x0d\x0a '\n' w plikach tekstowych zamieniane automatycznie na koniec linii dla danej platformy 52
Przetwarzanie pliku tekstowego def process(line): print line # Process file line-by-line file = open( plik1.txt ) for line in file: process(line) 53
Wyjątki obsługi plików try: # file operations except IOError, message: print( An IO error, message) except : else: print( Succes ) 54
EX8 Czytanie plików INI [View] WindowSize=1024,768 BackgroundColor=green7 WindowSize=1280,1024 [Print] BackgroundColor=green5 55
Moduł os os.chdir(path) zmienia katalog bieżący na path os.getcwd() zwraca string z katalogiem bieżącym os.listdir(path) zwraca listę nazw w katalogu path os.mkdir(path[, mode]) tworzy katalog path z prawami dostępu mode (domyślnie 0777) os.makedirs(path[, mode]) rekursywne tworzenie katalogów os.rmdir(path) usuwa katalog path os.remove(path) usuwa plik path os.stat(path) zwraca strukturę (tuple) stat z informacjami o pliku (rozmiar, czasy, etc.) moduł os patrz dokumentacja Pythona 56
Moduł os.path Na danej platformie import os.path Implementacja dla różnych systemów: posixpath dla UNIXowych ntpath dla Windows macpath dla starych MacOS os2emxpath dla OS/2 EMX 57
Moduł os.path funkcje os.path.dirname(path) zwraca katalog dla podanej ścieżki os.path.getsize(path) zwraca rozmiar pliku w bajtach (os.error gdy plik jest niedostępny lub nieistnieje) os.path.isfile(path) True gdy path jest istniejącym i regularnym plikiem os.path.isdir(path) True gdy path jest katalogiem os.path.join(path1[, path2[,...]]) inteligentnie łączy elementy ścieżki w jedną ścieżkę wynikową moduł os.path patrz dokumentacja Pythona 58
Moduł glob Znajduje nazwy plików wg. zadanego wzorca zgodnie z regułami stosowanymi w systemach powłok systemu UNIX Wildcard Dopasowuje Przykład * zero lub więcej znaków *.xls wszystkie pliki z rozszerzeniem xls? pojedynczy znak??? wszystkie pliki o nazwie składającej się dokładnie z 3 znaków [...] Pojedynczy znak z listy [ABC]* nazwy zaczynające się od liter A, B lub C [!...] Pojedynczy znak nie z listy *[!x] nazwy które nie kooczą się na literę x >>> import glob >>> for path in glob.glob( C:\\source\\*.bak ):... os.remove(path) 59
Pliki CSV moduł CSV csv.reader(csvfile[, dialect='excel'][, fmtparam]) zwraca obiekt typu reader dla pliku CSV. import csv cr = csv.reader(open('plik.csv'), delimiter=',', quotechar= ') for row in cr: print ':'.join(row) 60
CSV z obsługą błędów import csv, sys fn = "some.csv" reader = csv.reader(open(fn, "rb")) try: for row in reader: print row except csv.error, e: sys.exit('file %s, line %d: %s' % (filename, reader.line_num, e)) 61
Inne moduły fileinput otwiera i czyta pliki podane w linii poleceo, czyli sys.argv*1:+; domyślnie sys.stdin import fileinput for line in fileinput.input(): process(line) tempfile do tworzenia tymczasowych plików i katalogów shutil wysokopoziomowe operacja na plikach (np. copytree, rmtree) urllib pobieranie stron WWW 62
LINKI G. Wilson, Data Crunching - Solve Everyday Problems Using Java, Python, and More, PRAGMATIC, 2005 (polskie wydanie w HELION) http://gnosis.cx/tpip/ Text Processing in Python 63