Dzi kuj za uwag! Spotkania z Pythonem. Cz ± 3 - wyra»enia lambda, generatory, dekoratory, operacje na plikach. Michaª Alichniewicz.

Podobne dokumenty
Dzi kuj za uwag! Spotkania z Pythonem. Cz ± 1 - podstawy - rozwi zania zada« Michaª Alichniewicz. Gda«sk Studenckie Koªo Automatyków SKALP

P tle. Rozdziaª Wst p. 4.2 P tle P tla for(...);

Listy Inne przykªady Rozwi zywanie problemów. Listy w Mathematice. Marcin Karcz. Wydziaª Matematyki, Fizyki i Informatyki.

Lekcja 12 - POMOCNICY

Programowanie i struktury danych

Lab. 02: Algorytm Schrage

1. Wprowadzenie do C/C++

1 Klasy. 1.1 Denicja klasy. 1.2 Skªadniki klasy.

1 Strumienie. 2 Pliki. 2.1 Zapis do pliku tekstowego. Programowanie w j zyku C - Adam Krechowicz, Daniel Kaczmarski

Model obiektu w JavaScript

1. Wprowadzenie do C/C++

Zaawansowany kurs języka Python

Lekcja 9 - LICZBY LOSOWE, ZMIENNE

Programowanie i struktury danych 1 / 44

Lekcja 8 - ANIMACJA. 1 Polecenia. 2 Typy animacji. 3 Pierwsza animacja - Mrugaj ca twarz

Programowanie funkcyjne w Pythonie

Przetwarzanie sygnaªów

19. Obiektowo± 1 Kacze typowanie. 2 Klasy

x y x y x y x + y x y

Lekcja 9 Liczby losowe, zmienne, staªe

Dzi kuj za uwag! Spotkania z Pythonem. Cz ± 2 - organizacja projektu i obiektowo± Michaª Alichniewicz. Gda«sk Studenckie Koªo Automatyków SKALP

ANALIZA NUMERYCZNA. Grzegorz Szkibiel. Wiosna 2014/15

Bash i algorytmy. Elwira Wachowicz. 20 lutego

Vincent Van GOGH: M»czyzna pij cy li»ank kawy. Radosªaw Klimek. J zyk programowania Java

A = n. 2. Ka»dy podzbiór zbioru sko«czonego jest zbiorem sko«czonym. Dowody tych twierdze«(elementarne, lecz nieco nu» ce) pominiemy.

Wska¹niki, tablice dynamiczne wielowymiarowe

Programowanie wspóªbie»ne

Algorytmy zwiazane z gramatykami bezkontekstowymi

Metody dowodzenia twierdze«

Programowanie funkcyjne. Wykªad 13

Programowanie obiektowe w C++ Wykªad 4

JAO - J zyki, Automaty i Obliczenia - Wykªad 1. JAO - J zyki, Automaty i Obliczenia - Wykªad 1

Podstawy JavaScript. Dawid Poªap. Dawid Poªap Technologia informacyjna Grudzie«, / 13

Programowanie wspóªbie»ne

Lekcja 5 Programowanie - Nowicjusz

ARYTMETYKA MODULARNA. Grzegorz Szkibiel. Wiosna 2014/15

Programowanie wspóªbie»ne

Dekoratora używa się wstawiając linijkę zaczynającą się przed definicją dekorowanego obiektu (klasy czy funkcji).

Logika dla matematyków i informatyków Wykªad 1

Lekcja 6 Programowanie - Zaawansowane

Bazy danych, 4. wiczenia

Wzorce projektowe strukturalne cz. 1

i, lub, nie Cegieªki buduj ce wspóªczesne procesory. Piotr Fulma«ski 5 kwietnia 2017

Rozwi zania klasycznych problemów w Rendezvous

Metodydowodzenia twierdzeń

Rzut oka na zagadnienia zwi zane z projektowaniem list rozkazów

ARYTMETYKA MODULARNA. Grzegorz Szkibiel. Wiosna 2014/15

Lekcja 2 - BUDUJEMY I CZARUJEMY

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

ARYTMETYKA MODULARNA. Grzegorz Szkibiel. Wiosna 2014/15

WST P DO TEORII INFORMACJI I KODOWANIA. Grzegorz Szkibiel. Wiosna 2013/14

Dzi kuj za uwag! Spotkania z Pythonem. Cz ± 1 - podstawy. Michaª Alichniewicz. Gda«sk Studenckie Koªo Automatyków SKALP

Listy i operacje pytania

WST P DO TEORII INFORMACJI I KODOWANIA. Grzegorz Szkibiel. Wiosna 2013/14

Ćwiczenie 5. Python 3: Programowanie obiektowe i dziedziczenie

1 Bª dy i arytmetyka zmiennopozycyjna

Wst p do informatyki. Systemy liczbowe. Piotr Fulma«ski. 21 pa¹dziernika Wydziaª Matematyki i Informatyki, Uniwersytet Šódzki, Polska

wiczenie 1 Podstawy j zyka Java. Instrukcje warunkowe

Przewodnik u»ytkownika

Nazwa implementacji: Nauka języka Python pętla for. Autor: Piotr Fiorek

2 Skªadnia polece«w pliku

Spis treści. Dekoratory. 1 Dekoratory 1.1 Zadanie Zadanie Zadanie Zadanie 4

Rekurencyjne struktury danych

ARYTMETYKA MODULARNA. Grzegorz Szkibiel. Wiosna 2014/15

Ciaªa i wielomiany. 1 Denicja ciaªa. Ciaªa i wielomiany 1

MiASI. Modelowanie systemów informatycznych. Piotr Fulma«ski. 18 stycznia Wydziaª Matematyki i Informatyki, Uniwersytet Šódzki, Polska

Relacj binarn okre±lon w zbiorze X nazywamy podzbiór ϱ X X.

Programowanie wspóªbie»ne

7.3 Tablice jednowymiarowe dynamiczne

PRZYPOMNIENIE Ka»d przestrze«wektorow V, o wymiarze dim V = n < nad ciaªem F mo»na jednoznacznie odwzorowa na przestrze«f n n-ek uporz dkowanych:

EPI: Interfejs Graczny 2009/2010 Podstawy Rubiego

O pewnym zadaniu olimpijskim

Spis treści. Funkcje. 1 Funkcje 1.1 Zadanie Zadanie Zadanie Zadanie Zadanie Zadanie Zadanie 7

Środowisko programisty

Interfejsy, klasy wewn trzne jako szczególny rodzaj obiektów

Przykªadowe tematy z JiMP

Uczenie Wielowarstwowych Sieci Neuronów o

Programowanie w Sieci Internet. Python: Operacje z plikami oraz obsługa wyjątków

Optymalizacja R dlaczego warto przesi ± si na Linuxa?

WYMAGANIA EDUKACYJNE I KRYTERIA OCENIANIA Z PRZEDMIOTU PROGRAMOWANIE APLIKACJI INTERNETOWYCH

Lekcja 3 - BANKI I NOWE PRZEDMIOTY

Arytmetyka zmiennopozycyjna

ˆ tablice statyczne (o staªej ilo±ci elementów) ˆ tablice dynamiczne (o zmiennej ilo±ci elementów) 7.1 Tablice jednowymiarowe statyczne

XVII Warmi«sko-Mazurskie Zawody Matematyczne

Wykresy i interfejsy użytkownika

PROE wykład 7 kontenery tablicowe, listy. dr inż. Jacek Naruniec

Indeksowane rodziny zbiorów

Subversion - jak dziaªa

ARYTMETYKA MODULARNA. Grzegorz Szkibiel. Wiosna 2014/15

Podstawy Pythona. Krzysztof Gdawiec. Instytut Informatyki Uniwersytet Śląski

Kompilowanie programów

Podstawy modelowania w j zyku UML

Biblioteka graczna XPCE

Wykªad 7. Ekstrema lokalne funkcji dwóch zmiennych.

Programowanie wspóªbie»ne

Android. Podstawy tworzenia aplikacji. Piotr Fulma«ski. March 4, 2015

KLASYCZNE ZDANIA KATEGORYCZNE. ogólne - orzekaj co± o wszystkich desygnatach podmiotu szczegóªowe - orzekaj co± o niektórych desygnatach podmiotu

Lekcja 3 Banki i nowe przedmioty

Informacje pomocnicze

Transkrypt:

Spotkania z Pythonem Cz ± 3 - wyra»enia lambda, generatory, dekoratory, operacje na plikach Michaª Alichniewicz Studenckie Koªo Automatyków SKALP Gda«sk 2014 Dzi kuj za uwag! Na licencji Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License. M. Alichniewicz (SKALP) Python vol. 3 2014 1 / 66

Wyra»enia lambda M. Alichniewicz (SKALP) Python vol. 3 2014 2 / 66

Wyra»enia lambda - co to jest? Zacznijmy od tego, czym jest wyra»enie lambda. Z denicji, jest to anonimowa funkcja (czyli - nie ma nazwy; ale jest równie» obiektem, wi c mo»emy j sobie gdzie± przypisa ), która przyjmuje zadane argumenty, a nast pnie u»ywa ich w tzw. wyra»eniu. Wynik wyra»enia jest warto±ci która taka funkcja zwraca. Najprostsz analogi która mo»e uªatwi zrozumienie funkcji lambda jest zwyczajna funkcja matematyczna. Przyjmuje ona jakie± argumenty, które nast pnie s cz ±ci skªadow jakiego± matematycznego wyra»enia, dla przykªadu f(x) = 5x 2 + x + 0.5 1 x M. Alichniewicz (SKALP) Python vol. 3 2014 3 / 66

Wyra»enia lambda - co to jest? Dlaczego akurat analogia do matematyki? Otó», w takiej prostej funkcji nie wyst puje logika, caªa funkcja jest tylko i wyª cznie pojedy«czym wyra»eniem. Druga cecha która powoduje»e funkcja matematyczna jest dobra do przedstawienia jako analogia funkcji lambda jest fakt,»e w matematyce wszystkie zmienne i nazwy funkcji s arbitralne. Czyli mo»emy mie funkcj f(x), ale równie dobrze mo»e to by g(a), czy inne litery alfabetu. To, co jest tu niezmienne, to wyra»enie. M. Alichniewicz (SKALP) Python vol. 3 2014 4 / 66

Wyra»enia lambda - co to jest? Zaªó»my,»e chcieli by±my zdeniowa w Pythonie tak funkcj jak ta opisana wzorem z poprzednich slajdów. W klasyczny sposób, by to wygl daªo tak: def nasza_funkcja(x): # Oblicz i zwroc return 5*x**2 + x + 0.5-1/x Jak widzicie, nie ma tutaj ciaªa funkcji - wszystko co funkcja robi to zwraca warto±. M. Alichniewicz (SKALP) Python vol. 3 2014 5 / 66

Wyra»enia lambda - denicja Poniewa» ciaªa funkcji jako takiej nie ma, to mo»na to skróci do wspomnianego wyra»enia lambda. Wyra»enia lambda deniuje si nast puj co: lambda arg1, arg2,...: wyrazenie arg1, arg2, etc. to argumenty funkcji lambda, za± wyra»enie jest naszym... wyra»eniem, którego wynik jest warto±ci jakie nasza funkcja lambda zwraca. Oczywi±cie funkcje lambda tak jak tradycyjne funkcje w Pythonie, mog przyjmowa domy±lne warto±ci argumentów, mo»emy podawa argumenty przez nazw przy wywoªywaniu funkcji, tak samo jak mo»emy zdeniowa zmienn liczb argumentów. M. Alichniewicz (SKALP) Python vol. 3 2014 6 / 66

Wyra»enia lambda - denicja Poniewa» sama funkcja lambda nie ma identykatora, trzeba j gdzie± przypisa : f = lambda arg1, arg2,...: wyrazenie Skoro i tak trzeba t funkcj gdzie± przypisa, to po co jej u»ywa? Czy ma to sens, skoro mo»emy sobie tak funkcj zdeniowa tradycyjnie? A no... nie ma. Zastosowanie funkcji lambda ma sens dopiero z innymi funkcjami, jak dla przykªadu reduce, lter oraz map. Wszystkie wymienione funkcje przetwarzaj w pewien sposób list podan przez u»ytkownika. A w jaki sposób? Równie» w pewien sposób zdeniowany przez u»ytkownika - jako pierwszy argument przyjmuj funkcje która operuje na elementach. Funkcje mo»emy albo zdeniowa normalnie - co poniek d za±mieca kod, bo mamy jak ± dziwn funkcj nie wiadomo po co, albo wªa±nie u»y wyra»enia lambda. M. Alichniewicz (SKALP) Python vol. 3 2014 7 / 66

Wyra»enia lambda - funkcja reduce Funkcja reduce przyjmuje dwa argumenty - drugi to lista, z kolei pierwszy jest funkcj dwóch parametrów. Jej dziaªanie opiera si na zredukowaniu listy do pojedynczego wyniku w sposób zdeniowany przez u»ytkownika, na zasadzie: y = f (f (f (f (f (x 1, x 2 ), x 3 ), x 4 ), x 5 )...) Co mo»na z tym zrobi? Np. zsumowa argumenty listy (mo»na to zrobi normaln p tl for, ale po co?). W takim wypadku, nasza funkcja to po prostu: f(x, y) = x + y M. Alichniewicz (SKALP) Python vol. 3 2014 8 / 66

Wyra»enia lambda - funkcja reduce A jak to wygl da w praktyce? Nasz funkcj redukuj c mo»emy zdeniowa jako wyra»enie lambda: lambda x,y: x + y Nie musimy jej nigdzie przypisywa - mo»emy je poda wprost jako argument funkcji. Mamy wtedy: reduce(lambda x, y: x+y, nasza_lista) Sprawd¹my wi c dziaªanie: # Zwroci 21 reduce(lambda x, y: x + y, [1,2,3,4,5,6]) M. Alichniewicz (SKALP) Python vol. 3 2014 9 / 66

Wyra»enia lambda - funkcja reduce Korzystaj c z funkcji reduce, mo»emy bardzo ªatwo policzy silni - jak pami tamy z matematyki, to iloczyn kolejnych liczb od 1 do docelowej. W takim przypadku, funkcja lambda b dzie wygl da nast puj co: lambda x,y: x * y # Mnoymy ssiednie elementy W poª czeniu z funkcj range, która deniuje nam list, mo»emy zdeniowa ko«cow funkcj n!: reduce(lambda x, y: x * y, range(1,n)) Sprawd¹my wi c dziaªanie: # Zwroci 120 reduce(lambda x, y: x * y, range(1,6)) M. Alichniewicz (SKALP) Python vol. 3 2014 10 / 66

Wyra»enia lambda - funkcja lter Drug funkcj z kolekcji jest lter. Ta funkcja dla odmiany zwraca list, która skªada si z elementów listy któr podajemy jako drugi argument, dla których wynik funkcji podanej w pierwszym argumencie jest prawd. Do czego to mo»na wykorzysta? A no na przykªad do stworzenia listy kolejnych liczb parzystych. Jak to zrobi? Zaªó»my,»e nasza funkcja to to prostu dzielenie modulo 2. Dla liczb parzystych - otrzymamy 1; dla liczb nieparzystych, otrzymamy 0, co jest interpretowane jako faªsz. Neguj c wynik otrzymamy prawd dla liczby parzystej i faªsz dla liczby nieparzystej. Oczywi±cie najlepiej to zobrazuje przykªad: # Zwroci [2,4,6,8] filter(lambda x: not x % 2, range(1,10)) M. Alichniewicz (SKALP) Python vol. 3 2014 11 / 66

Wyra»enia lambda - funkcja map Ostatnia funkcja z kolekcji to map. Tak jak poprzednia zwraca list, tylko»e dla odmiany tutaj dostajemy wynik w postaci tych samych elementów, ale po przetworzeniu przez podan przez nas funkcj (ilo± jest ta sama, nic nam nie ubywa). Funkcja jest wywoªywana dla ka»dego elementu oddzielnie. Za pomoc tego mo»emy np. podnie± liczby z listy do kwadratu lub np. zamieni wszystkie teksty z listy na pisane wielkimi literami. Przykªad: # Zwroci ['A', 'B', 'C', 'D', 'SKALP'] map(lambda x: x.upper(), ['a', 'b', 'c', 'd', 'Skalp']) M. Alichniewicz (SKALP) Python vol. 3 2014 12 / 66

Skrócone instrukcje warunkowe M. Alichniewicz (SKALP) Python vol. 3 2014 13 / 66

Skrócone instrukcje warunkowe Rozwa»my dwa zdania: Je»eli warunek jest speªniony, zwró A, w przeciwnym razie zwró B oraz Zwró A je»eli warunek jest speªniony, w przeciwnym razie zwró B Oba zdania maj oczywi±cie logiczny sens. M. Alichniewicz (SKALP) Python vol. 3 2014 14 / 66

Skrócone instrukcje warunkowe Oba zdania reprezentuj opisowo skrócon instrukcj warunkow, przy czym pierwsza jest dosªownym tªumaczeniem instrukcji znanej z C, a druga jest jej odpowiednikiem w Pythonie. Dla przypomnienia, w C to wygl da tak: warunek? wartosc_1 : wartosc_2 W Pythonie, to ma nieco inn posta : wartosc_1 if warunek else wartosc_2 Pierwsza ró»nica - zamiast nie do ko«ca czytelnych znaków? oraz :, mamy czytelne if i else. Druga to nieco inna konstrukcja warunku - najpierw podajemy warto± któr zwracamy je»eli warunek jest speªniony, pó¹niej instrukcj warunkow a dopiero na ko«cu warto± dla faªszu. M. Alichniewicz (SKALP) Python vol. 3 2014 15 / 66

Generatory M. Alichniewicz (SKALP) Python vol. 3 2014 16 / 66

Generatory W Pythonie istnieje mo»liwo± zdeniowania funkcji, b d¹ klasy, po której mo»emy iterowa - czyli wykorzysta je jako ¹ródªo danych dla p tli for. W Pythonie jest jedna taka funkcja: xrange. Je»eli sprawdzimy, co nam zwróci ta funkcja bezpo±rednio: print xrange(0,10) To co najwy»ej wy±wietli si nam xrange(10). Z kolei je»eli umie±cimy t instrukcj w p tli: for item in xrange(0,10): print item, To p tla wy±wietli nam 0 1 2 3 4 5 6 7 8 9. Tak samo zadziaªa jakby±my podali zamiast xrange podali range. Z tym»e je»eli wy±wietlimy co zwraca druga funkcja, to dostaniemy list. Jaka jest ró»nica? M. Alichniewicz (SKALP) Python vol. 3 2014 17 / 66

Generatory Stwórzmy odpowiednik funkcji range we wªasnym zakresie: def my_range(start, end, step = 1): return_ = [] while start < end: # Wpisz akutalna wartosc na liste # Metoda ``append'' na liscie pozwala # na dopisanie elementu na koniec listy return_.append(start) start += step return return_ Dziaªanie tej funkcji jest dokªadnie takie jak dziaªanie funkcji range. Tworzymy list z kolejnymi elementami z zakresu. M. Alichniewicz (SKALP) Python vol. 3 2014 18 / 66

Generatory W celu uªatwienia zrozumienia tego jak dziaªa generator, zróbmy sobie odpowiednik p tli for: for item in set_of_data: # Zrob cos z ``item'' # TUTAJ KOD DO WYKONANIA W PETLI pass Za pomoc p tli while. M. Alichniewicz (SKALP) Python vol. 3 2014 19 / 66

Generatory Jedna z mo»liwych wariacji tego kodu, która bardzo dobrze oddaje dziaªanie p tli for: # Pobierz obiekt iteratora z naszego # obiektu po jakim chcemy wykonywac petle iterator = set_of_data. iter () # (1) # Zacznijmy petle while True: try: # Wez kolejny element # z iteratora item = iterator.next() # (2) # Zrob cos z ``item'' # TUTAJ KOD DO WYKONANIA W PETLI except StopIteration: # (3) break M. Alichniewicz (SKALP) Python vol. 3 2014 20 / 66

Generatory Jak ten kod dziaªa? Przede wszystkim trzeba zwróci uwag»e nie u»ywamy tutaj indeksowania elementów. Ka»dy obiekt który mo»emy poda do p tli for, musi mie zaimplementowan metod iter. Zwraca ona obiekt, po którym bezpo±rednio mo»na iterowa (1) - a wymogiem takiego iterowalnego obiektu jest posiadanie zaimplementowanej metody next, która zwraca kolejny element z zestawu danych (2), albo rzuca wyj tkim StopIteration w przeciwnym wypadku (3). Oczywi±cie obiekt który podajemy na wej±cie p tli i obiekt który jest zwrócony przez jego metod iter mo»e by tym samym obiektem - wymagane jest jednak posiadanie odpowiednich metod. M. Alichniewicz (SKALP) Python vol. 3 2014 21 / 66

Generatory Stwórzmy sobie tak przykªadow klas : class my_range_class(object): def init (self, start, end, step = 1): self.start = start self.end = end self.step = step def iter (self): return self def next(self): if self.start < self.end: return_value = self.start self.start += self.step return return_value else: raise StopIteration() M. Alichniewicz (SKALP) Python vol. 3 2014 22 / 66

Generatory Jak wida, w tym kodzie nigdzie nie tworzymy listy elementów! Zwracamy je na bie» co, je»eli p tla (albo my) - o to poprosi poprzez wywoªanie metody next. Ma to t zalet,»e przede wszystkim nie generujemy dªugiej listy w pami ci. Je»eli generujemy liczby, to problemu nie ma - no chyba»e s to bardzo dªugie liczby - ale dla innych obiektów mo»e si okaza»e nasz program zu»ycie pami ci ma niczym Firefox w czasach ±wietno±ci (z caªym szacunkiem dla przegl darki Mozilli). Powy»szy kod bezproblemowo zadziaªa w bloku for, i jego dziaªanie b dzie zgodne z oczekiwaniami. M. Alichniewicz (SKALP) Python vol. 3 2014 23 / 66

Generatory Jak ju» si przekonali±my wielokrotnie, du»o dªugich instrukcji ma w Pythonie swoje krótsze odpowiedniki. Tak te» jest w przypadku generatorów - zamiast peªnej klasy mo»emy zdeniowa po prostu odpowiedni funkcj. Pisz c generator w postaci funkcji, informujemy Pythona»e wªa±nie zwracamy do p tli jak ± warto± (ale nie ko«czymy funkcji!) za pomoc sªowa kluczowego yield (jest to odpowiednik return: w tym momencie wychodzimy z funkcji, ale funkcja b dzie wznowiona od tego miejsca w przypadku pro±by o kolejny argument). M. Alichniewicz (SKALP) Python vol. 3 2014 24 / 66

Generatory Najlepiej to zobrazuje fragment kodu (funkcje print sªu» do pokazania dziaªania kodu): def my_range_generator(start, end, step = 1): print 'Wejscie do funkcji' while start < end: print 'Zwrocenie wartosci %d' % start # "Wyrzuc" nowa wartosc yield start print 'Wznowienie funkcji' start += step print 'Wyjscie z funkcji' Przeanalizujmy dziaªanie tego w praktyce. M. Alichniewicz (SKALP) Python vol. 3 2014 25 / 66

Generatory Zacznijmy od utworzenia obiektu i sprawdzenia co dostali±my: x = my_range_generator(0, 10, 2) print repr(x) # Dostaniemy na ekranie cos podobnego do # <generator object my_range_generator at...> Jak ju» wiemy, ka»dy obiekt po którym mo»emy chodzi p tl for musi mie zaimplementowan metod iter - sprawd¹my wi c czy nasza funkcja tak posiada, i co nam zwróci: x_iter = x. iter () print repr(x_iter) # Dostaniemy na ekranie cos podobnego do # <generator object my_range_generator at...> Mo»emy zauwa»y,»e oba polecenia repr zwróciªy nam to samo - czyli to jest taka sama sytuacja jak dla naszej klasy zdeniowanej wcze±niej. M. Alichniewicz (SKALP) Python vol. 3 2014 26 / 66

Generatory Skoro ju» wiemy»e nasze x jest iteratorem, mo»emy go poprosi o pierwszy element: item = x.next() # W ``item'' bedzie wartosc 0 - a na ekranie # zobaczymy: # # Wejscie do funkcji # Zwrocenie wartosci 0 Wy±wietlanie tych danych pozwala na wyci gni cie dwóch wa»nych wniosków: 1 wej±cie do funkcji jest wykonywanie dopiero przy pierwszym wywoªaniu next, 2 funkcja zako«czyªa swoje dziaªanie w miejscu wyst pienia yield. M. Alichniewicz (SKALP) Python vol. 3 2014 27 / 66

Generatory Wykonajmy wi c po raz kolejny ten sam kod: item = x.next() # W ``item'' bedzie wartosc 2 - a na ekranie # zobaczymy: # # Wznowienie funkcji # Zwrocenie wartosci 2 Jak wida, funkcja zostaªa wznowiona (a wi c nie mo»emy mówi o wyj±ciu z funkcji, a jedynie o wstrzymaniu - warto± wszystkich zmiennych jest zachowana!) od miejsca w którym wyszli±my z niej poprzez sªowo kluczowe yield, a nast pnie znów wstrzymana przy kolejnym wyst pieniu tego sªowa. M. Alichniewicz (SKALP) Python vol. 3 2014 28 / 66

Generatory Mo»emy kontynuowa wywoªywanie next do uzyskania wszystkich elementów (uda sie to nam jeszcze 3 razy). Za czwartym razem wynik wywoªania b dzie nieco inny: item = x.next() # Wartosc zmiennej ``item'' sie nie zmieni, # a na ekranie zobaczymy: # # Wznowienie funkcji # Wyjscie z funkcji # Traceback (most recent call last): # File "<stdin>", line 1, in <module> # StopIteration Wznowili±my dziaªanie, ale te» wyszli±my z p tli, a wi c nie napotkali±my na yield. Funkcja w naszym przypadku si sko«czyªa, co potwierdza wypisanie na ekranie ci gu Wyjscie z funkcji. Wida równie»»e Python rzuciª znanym ju» wyj tkiem StopIteration. M. Alichniewicz (SKALP) Python vol. 3 2014 29 / 66

Generatory - forma skrócona Podobnie jak dla instrukcji warunkowych, dla generatorów równie» istnieje denicja skrócona. Wygl da to tak: (przetworz_element for element in lista) przetworz_element to oczywi±cie wyra»enie które co± z naszym elementem (nazwanym przez nas element) robi. Jak wida, jest to konstrukcja b d ca odpowiednikiem zwini tej konstrukcji warunkowej dla p tli for. Przykªad takiego generatora: a = (item**2 for item in lista) print repr(a) # <generator object <genexpr> at 0x7f8e5df83c30> M. Alichniewicz (SKALP) Python vol. 3 2014 30 / 66

Generatory - forma skrócona Tak stworzony obiekt oczywi±cie ma wszystkie potrzebne generatorom metody - iter i next. Problem z takim generatorem jest jeden - jest to objekt JEDNOKROTNEGO u»ytku. Czyli jak raz co± z nim zrobimy (np., u»yjemy w p tli for), to drugi raz ju» to nie zadziaªa. W praktyce takie generatory najcz ±ciej dziaªaj jako skrócona wersja p tli for, i ich celem jest stworzenie specycznej listy. Robi si to umieszczaj c generator w parze nawiasów kwadratowych albo przekazuj c do konstruktora klasy list: a = [item**2 for item in list] # albo, zamiennie a = list(item**2 for item in list) M. Alichniewicz (SKALP) Python vol. 3 2014 31 / 66

Generatory - forma skrócona z instrukcj warunkow Póki co mo»liwo±ci generatorów s w zasadzie identyczne jak funkcji map, czyli przeprowad¹ operacj na ka»dym elemencie. Ciekawsze mo»liwo±ci daje poª czenie generatorów ze skrócon instrukcj warunkow. Skªadnia takiego generatora wygl da w ten sposób (mo»na to oczywi±cie zwin w jedn lini ): (przetworz_element for element in lista\ if warunek_elementu) Jak widzimy, na ko«cu pojawiªa si instrukcja if. Jest to warunek wykonywany dla ka»dego elementu z caªych danych wej±ciowych. M. Alichniewicz (SKALP) Python vol. 3 2014 32 / 66

Generatory - forma skrócona z instrukcj warunkow Prostym przykªadem wykorzystania jest np. znalezienie elementów wspólnych dla dwóch list: a = [1, 2, 3, 4, 5] b = [3, 4, 5, 6, 7] wspolne = [item for item in a if item in b] # [3, 4, 5] Innym praktycznym przykªadem jest konwersja ci gu znaków (np. odczytanych z UART'a) na ich heksadecymentaln reprezentacj : wejscie = 'SKALP' wyjscie = ''.join('\\x%02x' % ord(char) \ for char in wejscie) print wyjscie # \x53\x4b\x41\x4c\x50 M. Alichniewicz (SKALP) Python vol. 3 2014 33 / 66

Dekoratory M. Alichniewicz (SKALP) Python vol. 3 2014 34 / 66

Dekoratory Cz sto, tworz c bardziej skomplikowany kod, tramy na przypadek gdzie np. dla du»ej cz ±ci metod w klasie pocz tkowy kod jest dokªadnie ten sam - czyli dla przykªadu, jaka± inicjalizacja, sprawdzenie uprawnie«, etc. Zgodnie z reguªami KISS oraz DRY, warto to gdzie± przenie± na zewn trz. Jednym ze sposobów jest zwyczajne zawarcie tego w jakiej± dodatkowej metodzie i wywoªywanie na pocz tku ka»dej funkcji. To samo mo»emy zrobi z kodem wywoªywanym na ko«cu. Tak by to wygl daªo w ka»dym j zyku programowania. W Pythonie jednak mo»emy to zrobi nieco inaczej - tworz c dekoratory funkcji. M. Alichniewicz (SKALP) Python vol. 3 2014 35 / 66

Dekoratory Przez dekorowanie funkcji rozumiemy wykonanie jakiegos kodu przed i po wykonaniu zasadniczej tre±ci funkcji. Z kolei sam dekorator jest deniowany jako specyczna funkcja: przyjmuj ca jako parametr funkcj, i zwracaj ca now, udekorowan funkcj. Zaraz zaraz, jak to przyjmuj ca/zwracaj ca funkcj? Pami tajmy: w Pythonie wszystko jest obiektem. Tak wi c funkcja te», i mo»emy spokojnie j przypisa do jakiej± zmiennej - lub te» przekaza do funcji lub z funkcji. Druga sprawa - w Pythonie mo»emy deniowa funkcje lub klasy wewn trzne, czyli widoczne tylko wewn trz funkcji/klasy gdzie zostaªy zdeniowane. M. Alichniewicz (SKALP) Python vol. 3 2014 36 / 66

Dekoratory Na pocz tek zdeniujmy sobie prost funkcj któr b dziemy chcieli udekorowa : def hello(): for i in range(0,10000000): # Male opoznienie nie zaszkodzi pass print "Hello world!" Funkcja nie jest specjalnie skomplikowana, ale te» dla celów pokazowych jest jak najbardziej wystarczaj ca. M. Alichniewicz (SKALP) Python vol. 3 2014 37 / 66

Dekoratory Zaªó»my»e np chcieliby±my przed p tl opó¹niaj c wy±wietli tekst wejscie, a po wy±wietleniu Hello world! dorzuci jeszcze tekst wyj±cie, jednocze±nie nie modykuj c oryginalnej funkcji (celem zachowania czytelno±ci kodu - funkcja hello ma wy±wietla hello world, a nie dla przykªadu informowa»e do funkcji weszli±my). Mo»emy sobie stworzy now funkcj, która wywoªa t oryginaln : def hello_decorated(): print 'wejscie' hello() print 'wyjscie' Jest to jedno z mo»liwych rozwi za«, ale musimy pami ta o wywoªaniu hello_decorated zamiast hello. M. Alichniewicz (SKALP) Python vol. 3 2014 38 / 66

Dekoratory Na etapie pisania kodu to nie problem. Ciekawiej natomiast zaczyna si je»eli jest to zmiana tymczasowa - np. jako element debuggowania programu, i docelowo jej nie b dzie w ko«cowym programie. Trzeba b dzie wtedy pami ta»eby zmieni X wywoªa«z powrotem na hello. Inny ciekawy przypadek to sytuacja gdy to nie dotyczy jednej funkcji, a kilkunastu - wtedy w ogóle mo»emy si pogubi. Teoretycznie - mo»emy zmieni nazw funkcji pierwotnej, np. na _hello, a jako hello zdeniowa nasz udekorowan funkcj. Ponownie schody si zaczn dla kilkunastu funkcji. Krokiem który to uªatwi, jest stworzenie nowej funkcji, która generuje now, udekorowan funkcj (czyli, jej argumentem b dzie stara funkcja), a zwróci wersj ze zmianami. M. Alichniewicz (SKALP) Python vol. 3 2014 39 / 66

Dekoratory Stwórzmy wi c tak funkcj : def decorator(original_fcn): """ Dekoruje funkcje. Jako argument przyjmuje funkcje oryginalna. """ def decorated_fcn(*args, **kwargs): """ Funkcja udekorowana. Nie znamy argumentow, wiec *args i **kwargs. """ print 'wejscie' # Wywolanie oryginalu original_fcn(*args, **kwargs) print 'wyjscie' return decorated_fcn # Zwroc nowa funkcje M. Alichniewicz (SKALP) Python vol. 3 2014 40 / 66

Dekoratory Je»eli wywoªamy tak funkcj dekoruj c jako argument podaj c wªa±nie nasze hello (ale bez nawiasów, czyli nie wywoªujemy jej!), w efekcie dostaniemy now funkcj : hello_decorated = decorator(hello) print repr(hello_decorated) # Dostaniemy cos podobnego do # <function decorated_fcn at 0x7fbcf45f0938> Wywoªanie otrzymanego hello_decorated da nam oczekiwany efekt. Dalej jednak mamy problem, bo trzeba to gdzie± przypisa, czyli na chwil obecn dalej potrzebujemy sztuczki ze zmian nazwy. M. Alichniewicz (SKALP) Python vol. 3 2014 41 / 66

Dekoratory Python i na to ma rozwi zanie. Zdeniowana przez nas funkcja decorator jest faktycznie dekoratorem, i Python posiada mechanizm który umo»liwia automatyczne dekorowanie funkcji na etapie jej denicji. Maj c taki dekorator, mo»emy sobie przedeniowa nasz funkcj hello: @decorator # Podaj dekorator def hello(): for i in range(0,10000000): # Male opoznienie nie zaszkodzi pass print "Hello world!" Dekorator podaje przed denicj funkcji lini zaczynaj c si od znaku @, a nast pnie podajemy nazw dekoratora (nie jego wywoªanie) - po maªpie podajemy po prostu obiekt. M. Alichniewicz (SKALP) Python vol. 3 2014 42 / 66

Dekoratory A co je»eli chcieliby±my mie dekorator, który przyjmuje jaki± dodatkowy parametr, w naszym przypadku np. tekst jaki chcemy wy±wietli przed wej±ciem do funkcji? Z racji tego,»e po @ Python oczekuje na obiekt który jest funkcj (dekoratorem), mo»emy zastosowa sztuczk : stworzy funkcj, która przyjmuje jakis parametr, a nast pnie zwraca odpowiednio sparametryzowany dekorator (po maªpie musi by obiekt - ale nigdzie nie jest powiedziane,»e ma by podany bezpo±rednio.) M. Alichniewicz (SKALP) Python vol. 3 2014 43 / 66

Dekoratory Stwórzmy wi c tak funkcj generuj c dekorator (docstring-i pomini te ze wzgl du na orgraniczone miejsce na slajdzie): def decorator_verbose(text): """ Zwraca dekorator, ktory wyswietla na wejsciu do funkcji podany tekst. """ def decorator(original_fcn): def decorated_fcn(*args, **kwargs): print text # Wywolanie oryginalu original_fcn(*args, **kwargs) print 'wyjscie' return decorated_fcn # Zwroc nowa funkcje return decorator M. Alichniewicz (SKALP) Python vol. 3 2014 44 / 66

Dekoratory Oczywi±cie warto sprawdzi jej dziaªanie w praktyce: @decorator_verbose('begin execution') def hello(): for i in range(0,10000000): # Male opoznienie nie zaszkodzi pass print "Hello world!" hello() # Wyswietli: # # Begin execution # Hello world! # wyjscie M. Alichniewicz (SKALP) Python vol. 3 2014 45 / 66

Dekoratory Dekoratory mo»na równie» ze sob ª czy - wtedy funkcja jest bezpo±rednio udekorowana przez dekorator podany jako ostatni (ten bezpo±rednio przed denicj funkcji), pó¹niej to co dostaniemy jest dekorowane przez kolejny dekorator etc. Dorzu my wi c kolejny dekorator: def tictoc(fcn): def decorated(*args, **kwargs): tic = time.time() fcn(*args, **kwargs) # Policz czas wykonywania toc = time.time() print "Time elapsed: %f" % (toc - tic) return decorated M. Alichniewicz (SKALP) Python vol. 3 2014 46 / 66

Dekoratory Czas na przedeniowanie naszego hello: @tictoc @decorator_verbose('begin execution') def hello(): for i in range(0,10000000): # Male opoznienie nie zaszkodzi pass print "Hello world!" hello() # Wyswietli: (czas przykladowy) # # Begin execution # Hello world! # wyjscie # Time elapsed: 0.380634 M. Alichniewicz (SKALP) Python vol. 3 2014 47 / 66

Manager kontekstu M. Alichniewicz (SKALP) Python vol. 3 2014 48 / 66

Uruchamianie kodu z managerem kontekstu Manager kontekstu. Brzmi dosy nietypowo, a wi c co to jest? Cz ± kodu, nawet nie±wiadomie, uruchmiamy w pewnym kontek±cie. Mo»e to by np. operowanie na pliku - wszystkie operacje wykonujemy w kontek±cie tego pliku. To, co taki blok charakteryzuje to to,»e musimy jakie± operacje wykona wchodz c do tego kontekstu (np. otwarcie wspomnianego pliku), tak samo jak musimy wykona pewne operacje wychodz c z tego kontekstu (tutaj - zamkni cie pliku). M. Alichniewicz (SKALP) Python vol. 3 2014 49 / 66

Manager kontekstu - denicja W ogólnym rozrachunku, to naszym managerem kontekstu jest - jak wszystko w Pythonie - nic innego jak specyczny obiekt, posiadaj cy odpowiednie metody. Dla managera kontekstu s to metody dosy intuicyjne - pierwsza to enter (nie przyjmuj ca zewn trznych argumentów) zwracaj ca obiekt kontekstu (mo»na samego siebie), druga z kolei to równie intuicyjne exit, które z kolei przyjmuje 3 argumenty - deniuj one dlaczego zostaªo zako«czone wykonanie bloku z naszym kontekstem (dla poprawnego wykonania, wszystkie trzy elementy b d miaªy warto± None, dla wyj tku b d tu dane wyj tku). Je»eli wszystko poszªo OK, ta metoda powinna zwróci True. M. Alichniewicz (SKALP) Python vol. 3 2014 50 / 66

Manager kontekstu - denicja Zróbmy wi c przykªadowy kod. W naszym przykªadzie manager i kontekst to b d dwa ró»ne obiekty. class ManagerKontekstu(): """ Klasa managera kontekstu """ class Kontekst(): """ Klasa kontekstu """ def init (self): """ Konstruktor kontekstu """ print 'Utworzenie kontekstu' self.counter = 1 def init (self): """ Konstruktor managera kontekstu """ print 'Utworzenie managera' # pozostaly kod na nastepnym slajdzie M. Alichniewicz (SKALP) Python vol. 3 2014 51 / 66

Manager kontekstu - denicja def enter (self): """ Wejscie / utworzenie kontekstu """ print 'Wejscie do kontekstu' self.ctx = ManagerKontekstu.Kontekst() self.ctx.counter += 1 return self.ctx def exit (self, *args): """ Wyjscie z kontekstu (sprzatanie) """ print 'Wyjscie z kontekstu' self.ctx.counter += 1 Zmienna counter jest zdeniowana»eby pokaza dziaªanie oraz rozdzielenie kontekstu i managera. M. Alichniewicz (SKALP) Python vol. 3 2014 52 / 66

Manager kontekstu - wywoªanie W Pythonie blok kontekstu jest deniowany nast puj co: with ManagerKontekstu() as kontekst: # zrob cos z kontekstem # albo wpisz pass W naszym zdeniowanym poprzednio kontek±cie mamy wtedy: if name == " main ": with ManagerKontekstu() as kontekst: print '>>> Zwiekszam kontekst' kontekst.counter += 1 print 'Counter wynosi: %d' % kontekst.counter M. Alichniewicz (SKALP) Python vol. 3 2014 53 / 66

Manager kontekstu - wywoªanie Je»eli wykonamy nasz kod - dostaniemy na ekranie Counter wynosi: 4. Zmienna counter nale»y do kontekstu, ale zwi kszamy j równie» przy wchodzeniu do tego kontekstu przez wywoªanie odpowiedniej metody managera. Przygotujmy sobie bardziej praktyczny przykªad managera kontekstu (docsting'i pomi te ze wzgl du na oszcz dno± miejsca): import time class TicToc(): def enter (self): self.tic = time.time() return self def exit (self, *args): self.toc = time.time() self.elapsed = self.toc - self.tic M. Alichniewicz (SKALP) Python vol. 3 2014 54 / 66

Manager kontekstu - wywoªanie Sprawd¹my wi c jak to dziaªa: with TicToc() as timer: # jakies akcje time.sleep(5) # przerwa na 5 sekund # jakies dalsze akcje print 'Czas wykonywania: %f' % timer.elapsed W efekcie na ekranie powinni±my zobaczy ci g podobny do Czas wykonywania: 5.00281691551 (czas mo»e si ró»ni - ale powinien by wi kszy od 5 w naszym przypadku) M. Alichniewicz (SKALP) Python vol. 3 2014 55 / 66

Operacje na plikach M. Alichniewicz (SKALP) Python vol. 3 2014 56 / 66

Operacje na plikach Python, jak zdecydowana wi kszo± j zyków programowania, umo»liwia dziaªania na plikach. Do otwarcia pliku sªu»y - dosy logicznie nazwana - funkcja open: fp = open('nazwa_pliku', 'tryb') Generalnie, mamy 3 tryby otwarcia pliku: r - otwarcie do odczytu - ustawia wska¹nik na pocz tek pliku (domy±lny tryb) w - otwarcie do zapisu i skasowanie aktualnej zawarto±ci pliku - ustawia wska¹nik na pocz tek pliku (je»eli plik nie istnieje, to go tworzy) a - otwarcie do zapisu - ustawia wska¹nik na koniec pliku (je»eli plik nie istnieje, to go tworzy) M. Alichniewicz (SKALP) Python vol. 3 2014 57 / 66

Operacje na plikach Tryby te mo»na dodatkowo rozbudowywa poprzez dodatkowe modykatory: b - otwiera plik w trybie binarnym (dla systemów gdzie jest rozró»nienie plik tekstowy / plik binarny) U - otwiera plik tekstowy w trybie universal newlines - czyli jako znak nowej linii na równi jest traktowany \n, \r oraz \r\n (tryb domy±lny) + - otwiera plik do zapisu (je»eli plik nie istnieje, to go tworzy) M. Alichniewicz (SKALP) Python vol. 3 2014 58 / 66

Operacje na plikach Funkcja open, w przypadku Pythona zwraca obiekt typu le, zamiast uchwtu o pliku przekazywanego do funkcji odpowiedzialnych za odczyt i zapis jak w przypadku wi kszo±ci j zyków programowania. Obiekt typu le ma szereg przydatnych do tego metod, zaczynaj c od podstawowych: close() - zamyka plik write(str) - zapisuje ci g znaków do pliku. Nale»y pami ta»e wywoªanie tej metody nie zawsze powoduje natychmiastowy zapis zycznie do pliku, czasami jest to tylko zapis do bufora read(n) - odczytuje n bajtów z pliku. Je»eli rozmiar nie jest podany, odczytuje caªy plik (uwaga przy du»ych plikach!) readline(n) - je»eli nie podano n, odczytuje caª lini. Je»eli podane jest n, to jest to maksymalna liczba bajtów jaka mo»e by odczytana (w efekcie mo»emy odczyta niekompletn lini ). M. Alichniewicz (SKALP) Python vol. 3 2014 59 / 66

Operacje na plikach Ko«cz c na tych rzadziej wykorzystywanych: ush() - wymusza od±wie»enie bufora, tj. zapis jego zawarto±ci zycznie na dysk readlines() - odczytuje wszystkie linie z pliku i tworzy z nich list (odczyt zaczyna od aktualnego wska¹nika) seek(pointer) - ustawia wska¹nik wewn trz pliku (miejsce z którego b dziemy czyta / do którego pisa ) tell() - zwraca aktualn warto± wska¹nika writelines(list) - zapisuje do pliku wszystkie elementy z listy, b d¹ innego iterowalnego argumentu podanego w argumencie (czyli mo»e to np. by generator). Metoda nie dodaje znaków ko«ca linii! M. Alichniewicz (SKALP) Python vol. 3 2014 60 / 66

Operacje na plikach Jak plik otworzymy, to trzeba go pó¹niej zamkn (dajmy innym programom szans na dost p). Poniewa» obiekt typu le ma zaimplementowane metody enter oraz exit, jest wi c managerem kontekstu - a wi c mo»emy wykorzysta tutaj instrukcj with, która zamknie plik za nas: # Otworz plik i nie martw sie o zamkniecie with open('moj_plik', 'w') as fp: fp.write('ladna dzis pogoda!\n') fp.write('nieprawdaz?') print fp.closed # True - czyli plik zamkniety M. Alichniewicz (SKALP) Python vol. 3 2014 61 / 66

Zadanie M. Alichniewicz (SKALP) Python vol. 3 2014 62 / 66

Zadanie Napisa program, który odczyta od u»ytkownika wyra»enie matematyczne (zawieraj ce nawiasy, jednak ograniczone do operatorów matematycznych, bez funkcji - podane w tradycyjnej notacji) oraz obliczy jego warto±. Zadanie trzeba wykona bez wykorzystania funkcji eval! Podpowiedzi: Kluczem do rozwi zania jest Odwrotna Notacja Polska (w skrócie - ONP, albo RPN z angielskiego Rerverse Polish Notation) Wbudowane w Pythona listy mog sªu»y zarówno jako bufor FIFO, albo jako FILO - czyli stos Program zbuduj w taki sposób,»eby mo»na byªo go wykorzystywa bez modykacji w innych projektach (mile widziane obudowanie logiki w klas - uniwersalno± tej klasy, wliczaj c w to sposób podania danych - mile widziane). Mo»na poczyni dodatkowe zaªo»enia przy wprowadzaniu danych, jak np. biaªe znaki w tre±ci wyra»enia, jednak nale»y pami ta»e ko«cowy u»ytkownik nie ma obycia w Pythonie. M. Alichniewicz (SKALP) Python vol. 3 2014 63 / 66

Materiaªy M. Alichniewicz (SKALP) Python vol. 3 2014 64 / 66

Materiaªy Dokumentacja j zyka Python https://docs.python.org/2/ Forum StackOverow http://stackoverflow.com/ Improve Your Python: 'yield' and Generators Explained http://www.jeffknupp.com/blog/2013/04/07/ improve-your-python-yield-and-generators-explained/ Understanding Python Decorators in 12 Easy Steps! http://simeonfranklin.com/blog/2012/jul/1/ python-decorators-in-12-steps/ Understanding Python's with statement http://effbot.org/zone/python-with-statement.htm M. Alichniewicz (SKALP) Python vol. 3 2014 65 / 66

Spotkania z Pythonem Cz ± 3 - wyra»enia lambda, generatory, dekoratory, operacje na plikach Michaª Alichniewicz Studenckie Koªo Automatyków SKALP Gda«sk 2014 Dzi kuj za uwag! Na licencji Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License. M. Alichniewicz (SKALP) Python vol. 3 2014 66 / 66