Inżynieria oprogramowania - Moodle

advertisement
Inżynieria oprogramowania
Ćwiczenia
26 lutego 2014
Cele przedmiotu
1
nabycie praktycznych umiejętności związanych z
wytwarzaniem oprogramowania
2
opanowanie języka Python
Treści
Programowanie w języku Python
Wprowadzenie do programowania proceduralnego
Typy danych
Funkcje i struktury kontrolne
Moduły
Wprowadzenie do programowania obiektowego
Obsługa plików
Zaawansowane techniki; programowanie funkcjonalne
Programowanie wielowątkowe
Programowanie sieci
Wykorzystanie wyrażeń regularnych
Techniki usuwania błędów
Praca z repozytorium kodu
Automatyzacja procesu budowania projektu
...
Literatura
1
http:
//openbookproject.net/thinkcs/python/english2e/
2
http://docs.python.org/tutorial/
3
Mark Summerfield, Python 3.
4
... dowolna inna pozycja do Pythona.
Zasady zaliczenia
Regulamin studiów
Zaliczenie ćwiczeń:
na każdych zajęciach oprócz ostatnich punkty za kodowanie
zadań; 14 zajęć, zawsze do zdobycia 5-6 punktów (w sumie
min. 75 punktów)
każde zadanie będzie można dokończyć w domu (termin
zawsze podany na zajęciach)
quiz na 25 punktów
w sumie można będzie zdobyć 100 punktów (lub nieco ponad)
Praca niesamodzielna
Minus 10 punktów na koniec za każdy wykryty przypadek
niesamodzielnej pracy, brak punktów za zadanie.
Zasady zaliczenia
Progi PUNKTOWE:
0.00 – 59.99
60.00 – 69.99
70.00 – 79.99
80.00 – 89.99
90.00 – 94.99
95.00 – 100
powyżej 100
ndst
dst
dst pl
db
db pl
bdb
cel
brak wystarczającej liczby puntków = poprawka we wrześniu
formuła poprawki: quiz + do napisania zadanie
programistyczne
Quiz
quiz na moodle
test wyboru
Termin
Kolokwium odbędzie się na ostatnich zajęciach.
Nieobecności
usprawiedliwienia przynosimy na najbliższych zajęciach po
powrocie na uczelnię
po tym terminie brak możliwości usprawiedliwienia zajęć
do 2 nieusprawiedliwionych nieobecności – nie odejmujemy
punktów
każda kolejna nieobecność to –3 punkty
frekwencja poniżej 50% – brak klasyfikacji
reguły dotyczące obecności nie dotyczą studentów z IOZ
wykonywanie zadań nie wymaga obecności na zajęciach
Coursera
możliwość zdobycia dodatkowych 10 punktów - ukończenie
kursu z Pythona na Courserze
Link do kursu
https://www.coursera.org/course/interactivepython
Start kursu: 24 marca
IOZ
Podpisujemy zgodę na IOZ, ale zasady zaliczenia się nie
zmieniają. Wszystkich studentów, bez względu na to, czy uzyskali
IOZ, czy nie, obowiązują takie same reguły zdobywania punktów.
Wyjątkiem jest frekwencja, co reguluje regulamin studiów.
Reguły ogólne
W przypadkach spornych głównymi obowiązujacymi regułami jest
regulamin studiów i zasady zaliczenia obowiązujące w KIE: http:
//www.kie.ue.poznan.pl/pl/content/zasady-zaliczania
Rejestracja na przedmiot
Hasło: ...
Rejestracja do sprawdzarki
http://150.254.36.78/judge/sharifjudge/index.php/
register
Wprowadzenie do programowania w języku Python
Uniwersytet Ekonomiczny w Poznaniu
26 lutego 2014
Wprowadzenie do programowania w języku Python
Język Python
Definicja (Wikipedia)
Język programowania wysokiego poziomu ogólnego przeznaczenia i
rozbudowanym pakiecie bibliotek standardowych, którego ideą
przewodnią jest czytelność i klarowność kodu źródłowego. Jego składnia
cechuje się przejrzystością i zwięzłością.
Wprowadzenie do programowania w języku Python
Hello world w javie
public class HelloWorld {
public static void main ( String [] args ) {
System . out . println ( " Hello , world ! " );
}
}
./hello world.java
Wprowadzenie do programowania w języku Python
1
2
3
4
5
Hello world w Pythonie
print ( " Hello world ! " )
1
./hello.py
Wprowadzenie do programowania w języku Python
Wybór języka programowania
Język
C
C++
Fortran 95
Java
Perl
Python
Smalltalk
Microsoft Visual Basic
Poziom w stosunku do C
1
2.5
2
2.5
6
6
6
4.5
Tabela:
Poziomy języka w stosunku do C. Źródło: Code Complete 2 - Steve McConnell, za “Estimating Software Costs” (Jones
1998), “Software Cost Estimation with Cocomo II” (Boehm 2000), “An Empirical Comparison of Seven Programming Languages”
(Prechelt 2000).
Wprowadzenie do programowania w języku Python
Wersje Pythona
Ciągle wykorzystywane są dwie wersje:
Python 2 (ostatnia wersja: Python 2.7)
Python 3
Wersje te nie są ze sobą w pełni zgodne!
My na zajęciach korzystamy z wersji trzeciej.
Wprowadzenie do programowania w języku Python
Python – różne implementacje
Różne implementacje języka Python:
CPython (Python) – główna implementacja, najczęściej stosowana,
także podczas tych zajęć.
Jython – uruchamia programy w Pythonie na wirtualnej maszynie
Java.
Iron Python – uruchamia programy w Pythonie w środowsku .NET.
PyPy – szybsze działanie, ale brak kompatybilności z niektórymi
elementami języka.
Różnią się m. in.:
szybkością wykonywania konkretnych operacji
dostępnymi bibliotekami
Wprowadzenie do programowania w języku Python
Co można zrobić za pomocą Pythona?
Przykładowe biblioteki:
django – web application framework
scipy – obliczenia naukowe
nltk – przetwarzanie języka naturalnego
pyQT – aplikacje okienkowe
Przykłady programów napisanych w pythonie:
BitTorrent
OpenERP
Dropbox
Ubuntu software center
Wprowadzenie do programowania w języku Python
Korzystanie z Pythona
korzystanie z interpretera na bieżąco
pisanie kodu w pliku
Wprowadzenie do programowania w języku Python
Tworzenie i uruchamianie programów
Dowolny edytor tekstowy
Standardowo kodowanie - UTF-8, może być ASCII
pliki z rozszerzeniem .py lub .pyw (aplikacje okienkowe)
Uruchamianie: w konsoli - python hello.py lub tylko nazwa pliku w
przypadku zawarcia w pliku linii shebang
# !/ usr / bin / python
print ( " Hello world ! " )
1
2
./hello shebang.py
Wprowadzenie do programowania w języku Python
Programowanie na zajęciach
na zajęciach korzystamy z systemu Linux
edytor: zalecany gedit
podczas pracy w domu, w przypadku korzystania z systemu
Windows, polecamy notepad++
Ważne!
kodowanie znaków: UTF-8
wcięcia: każdy tabulator to cztery spacje
Wprowadzenie do programowania w języku Python
Standard ASCII
Przewiduje użycie jednego bajtu na znak
Poszczególne liczby, które można wpisać w bajt są interpretowane
jako znaki
Obsługuje podstawowy zestaw znaków (litery, cyfry, podstawowe
znaki matematyczne itp.)
Nie obsługuje alfabetów niełacińskich lub zawierających dodatkowe
znaki (polski, hiszpański, chiński itp.)
Wprowadzenie do programowania w języku Python
Problem stron kodowych
Możliwy do użycia w ramach jednego bajtu zakres liczb podzielono
na dwa podzakresy - 0-127 i 128-255
Liczbom z drugiego podzakresu można przyporządkować znaki z
alfabetów np. polskiego (ogonki) czy niemieckiego (umlauty)
Każde takie przyporządkowanie to inna strona kodowa. Powstało ich
wiele (dla Polski np. windows-1250 i iso-8859-2)
problem chińskiego i podobnych nie rozwiązany
Wprowadzenie do programowania w języku Python
Unicode
Przedsięwzięcie skatalogowania wszystkich (!) znaków używanych w
jakimkolwiek języku w jakimkolwiek czasie i różnych innych znaków
użytych w piśmie
Każdy symbol ma przyporządkowany identyfikator - to obejmuje
Unicode (tabela ok 100 tys. symboli)
Identyfikatory trzeba przetłumaczyć na zapis w bajtach - zakodować
Różne kodowania: UTF-7,UTF-8,UTF-16,UTF-32 różnią się ilością
bajtów przewidzianych do reprezentacji pojedynczego znaku
Wprowadzenie do programowania w języku Python
Uwagi o kodowaniu plików
Strona kodowa użyta do kodowania plików nie jest oznaczana w
jakikolwiek sposób w pliku tekstowym!
Edytor (notepad i inne) używa ustawień domyślnych - dla MS
Windows - windows-1250 (cp1250) dla j. polskiego, Linux - iso lub
UTF-8 (częstsze)
Zalecane - UTF-8! Zawsze i do wszystkich zastosowań na wszystkich
systemach. Windows (od Vista) wewnętrznie pracuje na UTF-8 i
obsługuje je bez problemów.
Używać edytora tekstowego który umożliwia ustalenie kodowania
pliku!
Wprowadzenie do programowania w języku Python
Typy danych
Liczby całkowite - int
Nieograniczonej długości (długie wolniej działają) - pamięć granicą
Ciągi tekstowe - str
Unicode - dowolne znaki
Ujęte w cudzysłów podwójny lub pojedynczy
Wprowadzenie do programowania w języku Python
Dostęp do elementów ciągu tekstowego
‘‘Trudne czasy’’[7]
‘‘muflon’’[0]
‘‘Trudne czasy’’[0:4]
działa dla każdej sekwencji
Wprowadzenie do programowania w języku Python
Konwersje
int(‘‘45’’)
int(‘‘ 45 ’’) - toleruje spacje
str(912)
w przypadku niemożności konwersji - wyjątek
można zaprojektować własny typ danych, który będzie obsługiwał
konwersję
Wprowadzenie do programowania w języku Python
Identyfikatory
Identyfikator - nazwa referencji (“zmienna”)
Reguły
bez spacji
zaczyna się literą lub podkreśleniem (uwaga - podkreślenia raczej
zastrzeżone do specjalnych zadań)
może zawierać cyfry
wielkość liter ma znaczenie
Wprowadzenie do programowania w języku Python
Dynamiczna kontrola typu
Python ustala typ obiektu w trakcie wykonania programu, nie trzeba
go deklarować. Ten typ jest niezmienny.
Referencja do obiektu akceptuje obiekt dowolnego typu i można w
każdym momencie przypisać jej obiekt innego typu.
a = 7
a = a + 1
a = " kura "
1
2
3
funkcja type() zwraca typ obiektu
print (a , type ( a ))
1
Wprowadzenie do programowania w języku Python
Standardowe wejście
print ( " Jak masz na imie ? " )
imie = input ()
print ( " Czesc " , imie )
1
2
3
./input.py
Wprowadzenie do programowania w języku Python
Zadanie na rozgrzewkę – formularz
Program zadaje kolejno następujące pytania (w nawiasach znajdują się
nazwy zmiennych):
1
Podaj imię: (imie)
2
Podaj nazwisko: (nazwisko)
3
Rok studiów: (rok)
4
Specjalność: (specjalnosc)
5
Miasto rodzinne: (miasto)
Zainteresowania: (zainteresowania)
6
Wypisanie na ekranie frazy:
Student nazywa się (imie) (nazwisko) i jest na (rok) roku studiów, na
specjalności (specjalnosc). Jego miasto rodzinne to (miasto), a jego
zainteresowania obracają się wokół takich tematów jak: (zainteresowania).
Wprowadzenie do programowania w języku Python
Warunek
Najprostszy warunek w Pythonie
if 5 > 0:
print ( " Piec jest wieksze od zera " )
print ( " Koniec programu " )
./if.py
Na co zwracamy uwagę:
dwukropek po warunku
wcięcie w linijkach po warunku sygnalizuje zasięg warunku (który
fragment kodu będzie wywołany warunkowo)
Wprowadzenie do programowania w języku Python
1
2
3
Prosta pętla
Pętla for:
for i in range (0 ,6):
print ( i )
1
2
./for.py
Na co zwracamy uwagę:
dwukropek po definicji pętli
wcięcie w linijkach wskazuje który fragment kodu wykonywany jest w
pętli
proszę przetestować: co robi funkcja range?
Wprowadzenie do programowania w języku Python
Zadanie 1 – licznik
użytkownik wprowadza 5 wyrazów (po każdym wciska Enter)
cel: liczymy, ile z tych wyrazów zaczynało się od wielkiej litery
Przykładowe wejście:
OJEJKU
Jacek
bINGO
Ciastko
czkawka
1
2
3
4
5
./zad1 input.txt
Przykładowe wyjście:
3
1
./zad1 output.txt
Podpowiedź na kolejnej stronie :)
Wprowadzenie do programowania w języku Python
Zadanie 1 – podpowiedź
Przeanalizuj co robią następujące linie:
print ( str . lower ( " Aaa " ))
print ( str . lower ( " AAA " ))
print ( str . lower ( " aaa " ))
1
2
3
./lower.py
Przy rozwiązaniu zadania wykorzystaj:
funkcję str.lower()
dostęp do elementu sekwencji
pętlę
warunek
Wprowadzenie do programowania w języku Python
Zadanie 2 – Weryfikacja numeru PESEL
1
użytkownik wprowadza numer PESEL
2
sprawdzamy, czy zgadza się ostatnia cyfra
3
jeśli ostatnia cyfra jest prawidłowa program ma zwrócić 1
4
jeśli nie - program ma zwrócić 0
Zakładamy, że numer ma prawidłową długość (11 znaków).
Regułę poprawności numeru proszę odszukać w Sieci.
Przykładowe wejście:
97082123152
1
Przykładowe wyjście:
0
1
Wprowadzenie do programowania w języku Python
Wprowadzenie do programowania w języku Python
(wyjątki, funkcje, rekurencja)
Uniwersytet Ekonomiczny w Poznaniu
11 marca 2014
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
Obsługa wyjątku
polecenia objęte pakietem try zostaną wykonane
jeżeli w czasie ich wykonania nastąpi błąd rodzaju wskazanego przez
jedną z klauzul except to:
nastąpi przerwanie wykonania programu w linii, która spowodowała
błąd
kontrola zostanie przekazana do właściwego pakietu obsługi
pozostałe polecenia w pakiecie try nie zostaną wykonane
jeżeli nie nastąpi błąd, bloki except zostaną pominięte
jeżeli nastąpi błąd w pakiecie except lub powstanie błąd nie
obsługiwany przez żaden z except to:
interpreter przekazuje wyjątek do zewnętrznego zasięgu (funkcji
wywołującej daną funkcję)
przekazywanie postępuje “w górę” aż do złapania wyjątku lub
opuszczenia programu
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
Przykład
# !/ usr / bin / env python3
try :
text = " test5 "
i = int ( text )
print ( " i wynosi " ,i )
except ValueError as ex1 :
print ( " konwersja " , text , " do i sie nie powiodla " )
1
2
3
4
5
6
7
./wyjatek.py
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
EAFP: Easier to ask for forgiveness than permission.
Zalecany styl kodowania w Pythonie (ale np. w Javie już
nie. . . dlaczego?).
Lepiej tak:
try :
1
el = elements [ key ]
# do sth
except IndexError as e :
# do sth else
2
3
4
5
A nie tak:
if len ( elements ) > key :
el = elements [ key ]
# do sth
else :
# do sth else
1
2
3
4
5
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
Operatory arytmetyczne
Standardowe: +,-,*,/
dzielenie daje liczbę z przecinkiem!
Operatory rozszerzone: +=,-=,*=,/=
Uwaga: liczby w Pythonie to obiekty niezmienne, zatem a=a-1
utworzy nowy obiekt i przypisze go do a
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
Przeciążone operatory dla list
Operator + i += są przeciążone dla ciągów znaków (str)
imie = " Jan "
imie += " Kowalski "
1
2
Uwaga - powstaje nowy ciąg znaków (str jest niezmienny)
Dla list + powoduje dodanie do listy
ziarna =[ " sezam " ," slonecznik " ]
ziarna +=[ " dynia " ]
1
2
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
Przeciążone operatory - uwagi
Operand po prawej stronie += musi być iterowalny (w przypadku
list)
ziarna +=5
# error !
ziarna +=[5] # OK
1
2
Można dodawać do siebie listy
ziarna +=[3 ,4 ,6 , " mak " ]
1
Uwaga: ciąg znaków jest iterowalny więc dodanie go może przynieść
nieoczekiwany efekt:
ziarna += " siemie "
1
[ ’ sezam ’ , ’ slonecznik ’ , ’ dynia ’ ,5 ,3 ,4 ,6 , ’ mak ’ , ’s ’ , ’i
2 ’ , ’e ’ ,
ziarna +=[ " siemie " ]
3
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
Tworzenie i wywoływanie funkcji
bloki instrukcji można ujmować w funkcje
def nazwaFunkcji ( argument , argument2 ):
pakiet
1
2
argumenty są opcjonalne
wartość zwracana domyślnie to None, chyba że funkcja zwróci
wartość przy pomocy polecenia return
def działa jak operator przypisania - powoduje utworzenie obiektu
funkcji i przypisanie go do referencji o wskazanej nazwie
funkcje jako obiekty mogą być przechowywane w kolekcjach,
przekazywane jako argumenty do innych funkcji
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
Przykład funkcji
def pobierzLiczbe ( msg ):
while True :
try :
line = input ( msg )
i = int ( line )
return i
except ValueError as err :
print ( err )
1
2
3
4
5
6
7
8
funkcja pobiera liczbę
jeżeli błąd to wraca do ponownego wykonania pętli, jeżeli bez
błędów - zwraca liczbę
wywołanie:
wiek = pobierzLiczbe ( " Podaj swoj wiek " )
1
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
Zadanie na rozgrzewkę. . .
Zaimplementuj funkcję policz, która przyjmuje na wejściu dwa
argumenty:
lista, zawierający listę elementów, które zostaną policzone,
dzialanie, zawierający funkcję obliczającą wartość na podstawie
dwóch elementów.
Przykładowym wynikiem wywołania funkcji policz dla listy trzech
elementów powina być wartość, którą można przedstawić jako
dzialanie(dzialanie(lista[0], lista[1]), lista[2]) .
Inny przykład: dla definicji funkcji def suma(a, b): return a+b,
wynikiem wywołania policz([1,2,3,4,5,6], suma) powinna być
suma wszystkich elementów (1+2+3+4+5+6).
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
Zadanie na rozgrzewkę. . . c.d.
Zaimplementuj działanie na mnożenie, zastosuj je w wywołaniu
funkcji policz.
Zaimplementuj sumę w taki sposób, żeby w liście mogły znaleźć się
dowolne wartości, a te, które nie będą liczbami, będą ignorowane.
Przykładowo wywołanie dzialanie([1,‘‘a’’,-3,‘‘ 2 ’’],
suma ignorowanie) powinno zwrócić 0.
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
Rekurencja
Przykład: definicja ciągu arytmetycznego:
1
a0 = 10
2
b=7
3
an+1 = an + b
czyli w Pythonie:
def a ( n ):
if n == 0:
return 10
else :
return 7 + a ( n - 1)
1
2
3
4
5
albo:
def a ( n ): return 10 if n == 0 else 7 + a ( n - 1)
1
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
Zadanie na rozgrzewkę. . . c.d.
Zaimplementuj funkcję zliczającą n wyrazów ciągu arytmetycznego.
Dlaczego w tym wypadku zastosowanie funkcji rekurencyjnej na n-ty
wyraz ciągu jest niewskazane?
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
Moduły
Moduł to plik Pythona zawierający klasy i funkcje
Można zaimportować moduł aby używać funkcji (dostęp przy
pomocy kropki)
import sys
print ( sys . argv )
1
2
Python posiada bogatą bibliotekę gotowych modułów
Przykład:
import random
x = random . randint (1 ,16)
y = random . choice ([ " jablko " ," gruszka " ," banan " ])
1
2
3
moduły standardowe zaczynają się małymi literami, własne można
nazywać dużymi (dla odróżnienia)
konwencja: importy na początku pliku
sugerowana kolejność importowania: standardowe, zewn., własne
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
Zadanie 1
n
Oblicz symbol Newtona, zdefiniowany jako k
=
n!
k!(n−k)!
Na wejściu dwie liczby oddzielone spacją (n i k), np.:
6 4
1
Na wyjściu obliczony symbol Newtona, np.:
15
1
Uwaga! Proszę zwrócić uwagę, czy na wyjściu zwracana jest liczba
całkowita, tj. np. 15, a nie 15.0. W drugim przypadku może być błąd
przy sprawdzaniu.
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
Zadanie 2
Oblicz, na ile sposobów można rozmienić określoną kwotę pieniędzy,
mając do dyspozycji określone nominały.
Przykładowo dla nominałów [1, 2] kwotę 4 można rozmienić na 3
sposoby:
1+1+1+1
1+1+2
2+2
Wskazówka: warto użyć rekurencji.
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
Zadanie 2 c.d.
Wejście:
W pierwszej linii podana jest kwota.
W drugiej linii podane są nominały (jako liczby oddzielone
spacjami). Nominały są zawsze posortowane rosnąco (!).
Przykładowe wejście:
6
1 2 3
1
2
Wyjście:
Liczba reprezentująca, ile jest sposobów rozmienienia pieniędzy.
Przykładowe wyjście:
7
1
Wprowadzenie do programowania w języku Python (wyjątki, funkcje, rekure
Listy składane
Zbiory
Słowniki
Uniwersytet Ekonomiczny w Poznaniu
18 marca 2014
Listy składaneZbiorySłowniki
Listy składane
tworzenie listy pętlą for
przestepne =[]
for rok in range (1900 ,1940):
if ( rok % 4 ==0 and
rok % 100 !=0) or ( rok % 400 == 0):
przestepne . append ( rok )
1
2
3
4
5
lista składana - [element for element in iteracja]
lata = [ y for y in range (1900 ,1940)]
1
lista składana z warunkiem
przestepne = [ rok for rok in range (1900 ,1940)
if ( rok % 4 ==0 and rok % 100 !=0)
or ( rok % 400 == 0)]
Listy składaneZbiorySłowniki
1
2
3
Przykłady list składanych
W matematyce często opisujemy zbiory w taki sposób:
S = {x 2 |x ∈ {0, ..., 9}}
V = {2i |i ∈< 0, 13) ∧ i ∈ N}
M = {x|x ∈ S ∧ x parzyste}
W Pythonie w naturalny sposób można wyrazić to tak:
S = [ x **2 for x in range (10)]
V = [2** i for i in range (13)]
M = [ x for x in S if x % 2 == 0]
Listy składaneZbiorySłowniki
1
2
3
Przykłady list składanych
Liczby pierwsze to takie,... które nie są niepierwsze (nie są
wielokrotnością innej liczby niż 1)
npr =[ j for i in range (2 ,8) for j in range ( i *2 ,50 , i )] 1
pr = [ x for x in range (2 , 50) if x not in npr ]
2
Listy składaneZbiorySłowniki
Przykłady list składanych
Przykład ze słowami:
words = ’ The quick brown fox jumps ’. split ()
stuff =[[ w . upper () , w . lower () , len ( w )] for w in words ]
Listy składaneZbiorySłowniki
1
2
Zbiór - set
obsługuje in, len, iterację
zbiory modyfikowalne - set, niemutowalne - frozenset
dodane do zbioru mogą być tylko typy które dają hash tzn.
float,frozenset,int,str,tuple
typy mutowalne nie mogą być dodawane do zbioru bo ich hash byłby
zmienny (dict,list,set)
S = {7 , ‘ ‘ welon ’ ’ ,( ‘ ‘ a ’ ’ ,1) , frozenset ({3 ,6 ,8})}
1
pusty zbiór - tylko przez funkcję set()
zbiory nie przechowują duplikatów. Trick na usunięcie duplikatów z
listy
x = list ( set ( x ))
1
Listy składaneZbiorySłowniki
Operatory i funkcje dla zbiorów
suma
set ( ‘ ‘ pecan ’ ’) | set ( ‘ ‘ pie ’ ’)
1
iloczyn
set ( ‘ ‘ pecan ’ ’) & set ( ‘ ‘ pie ’ ’)
1
różnica
set ( ‘ ‘ pecan ’ ’) - set ( ‘ ‘ pie ’ ’)
1
różnica symetryczna
set ( ‘ ‘ pecan ’ ’) ^ set ( ‘ ‘ pie ’ ’)
Listy składaneZbiorySłowniki
1
Operatory i funkcje dla zbiorów
powyższe operatory i funkcje aktualizujące im odpowiadające tworzą
kopie. Są wersje aktualizujące lewy argument
funkcje isdisjoint, pop, remove, update, add, clear, copy
zbiory można tworzyć przez zbiór składany
Listy składaneZbiorySłowniki
Frozenset
tworzenie - tylko przez funkcję frozenset()
obsługuje z API zbioru tylko funkcje nie zmieniające zbioru
Listy składaneZbiorySłowniki
Słownik
Słownik albo mapa (dictionary, map) to kolekcja par klucz - wartość
obsługuje in, len() oraz iterację
w Pythonie 3.0 jest dict oraz collections.defaultdict - słownik z
wartościami domyślnymi
słownik jest kolekcją nieuporządkowaną tak jak zbiór
jako klucze mogą służyć tylko wartości hashowalne (tak jak przy
zbiorach - float, frozenset, int, str, tuple)
wartości mogą być dowolne
słownik jest modyfikowalny
można porównywać słowniki operatorami == i !=
Listy składaneZbiorySłowniki
Słownik - tworzenie
d = dict ({ ’ id ’ :1948 , ’ nazwa ’: ’ Zmywarka ’ ,
1
’ rozmiar ’ :3})
2
d2 = dict ([( ’ id ’ ,1948) , ( ’ nazwa ’ , ’ Zmywarka ’) ,
3
( ’ rozmiar ’ ,3)])
4
d3 = dict ( zip (( ’ id ’ , ’ nazwa ’ , ’ rozmiar ’) ,
5
(1948 , ’ Zmywarka ’ ,3)))
6
d4 = { ’ id ’ :1948 , ’ nazwa ’: ’ Zmywarka ’ , ’ rozmiar ’ :3}7
d2 tworzy słownik z kolekcji par
d3 używa funkcji zip która zwraca listę krotek odpowiednio
sparowanych
Listy składaneZbiorySłowniki
Słownik - wykorzystanie
można odwoływać się do elementów słownika po kluczu
d1 [ ’ nazwa ’]
1
jeżeli nie ma klucza to wyjątek KeyError
można wstawiać do słownika
d [ ’x ’ ]=234
1
usuwanie - del - uwaga na wyjątek KeyError
del d [ ’x ’]
1
słownik obsługuje funkcje clear, copy, fromkeys, get, items, k eys,
pop, popitem, setdefault, update, values
Listy składaneZbiorySłowniki
Iteracja po słowniku - po parach
for klucz , wartosc in d . items ():
print ( klucz , wartosc )
1
for element in d . items ():
print ( element [0] , element [1])
1
Listy składaneZbiorySłowniki
2
2
Iteracja po kluczach i wartościach
for klucz in d :
print ( klucz )
1
for klucz in d . keys ():
print ( klucz )
1
for w in d . values ():
print ( w )
1
2
2
2
Listy składaneZbiorySłowniki
Widoki
keys, values, items to widoki na słownik
widok to niemutowalna sekwencja umożliwiająca iterację
widok zostanie zaktualizowany w przypadku aktualizacji słownika
na widokach można wykonywać operacje jak na zbiorach - suma,
iloczyn, różnica, różnica symetryczna
d . fromkeys ( ’ ABCD ’ ,3)
s = set ( ’ ACX ’)
dopasowania = d . keys () & s
Listy składaneZbiorySłowniki
1
2
3
Słowniki składane
Słownik obsługuje podobnie jak lista i zbiór składanie
{ klucz : wartosc for klucz , wartosc in iteracja if warunek
1
}
wielkosci = { nazwa : os . path . getsize ( nazwa ) for nazwa
2
in
os . listdir ( ’. ’) if os . path . isfile ( nazwa )}
3
odwracanie słownika - uwaga na TypeError przy mutowalnych
wartościach
odwrocony = { v : k for k , v in d . items ()}
Listy składaneZbiorySłowniki
1
Słownik domyślny
Słownik domyślny nigdy nie zgłasza KeyError
jeżeli nie ma klucza, który jest wykorzystany w danej linii to zostanie
wygenerowany wpis w słowniku z pustą lub domyślną wartością
przy tworzeniu słownika domyślnego podaje się funkcję fabryczną funkcję , która zwraca obiekt domyślny określonego typu
words = collections . defaultdict ( int )
1
uwaga - tutaj int jest referencją do funkcji! (funkcja jest w Pythonie
obiektem)
words [ word ]+=1
1
powyższy kod nie zgłosi wyjątku nawet jeżeli klucz word nie istnieje zostanie utworzony wpis o wartości 0 i zwiększony o 1
Listy składaneZbiorySłowniki
Zadanie 1 – konkurs jedzenia pączków
Konkurs w tłusty czwartek: kto zje najwięcej pączków w 10 minut? Na
wejściu po kolei:
unikalne imiona uczestników (w jednej linii)
pojedyncza linia złożona z imion uczestników w takiej kolejności w
jakiej kończyli jeść kolejne pączki
Na wyjściu:
Lista krotek (imię uczestnika, liczba zjedzonych pączków)
posortowana malejąco po liczbie zjedzonych pączków
Upraszczające założenie: każdy z uczestników zjadł inną liczbę pączków
Listy składaneZbiorySłowniki
Zadanie 1 – przykładowe wejście i wyjście
Przykładowe wejście:
pawel kasia lukasz
1
pawel kasia lukasz kasia pawel lukasz pawel kasia pawel
2
Przykładowe wyjście:
[( ’ pawel ’ , 4) , ( ’ kasia ’ , 3) , ( ’ lukasz ’ , 2)]
Listy składaneZbiorySłowniki
1
Zadanie 2 – Indeksowanie
Wejście (w kolejnych linijkach):
liczba dokumentów do przetworzenia (n)
n linijek z wielowyrazowymi dokumentami (1 dokument na linijkę)
liczba zapytań do przetworzenia (m)
m linijek z jednowyrazowymi zapytaniami
Wyjście:
m linijek (jedna na każde zapytanie)
w każdej linijce lista zawierająca numery (indeksy) dokumentów, w
których wystąpił wyraz z danego zapytania
każda lista posortowana według częstości wystąpienia wyrazu z
zapytania w danym dokumencie
przy równej częstości powinna być zachowana kolejność wczytywania
dokumentów
Listy składaneZbiorySłowniki
Zadanie 2 – przykład
3
Your care set up , do not pluck my care down .
My care is loss of care with old care done .
Your care is gain of care when new care is won .
2
care
is
1
[1 , 2 , 0]
[2 , 1]
1
2
3
4
5
6
7
2
Listy składaneZbiorySłowniki
Zadanie 2 – dodatkowe założenia
zapytania formułowane są małymi literami, ale odpowiedź powinna
uwzględniać wyrazy, które w dokumentach zapisane są różną
wielkością liter, np.:
dokument: A Rose is a rose is a roSE
zapytanie: rose
występowanie: 3 razy
wyrazy powinny zawierać tylko znaki alfanumeryczne (bez
interpunkcyjnych), tzn. wystąpienie znaku interpunkcyjnego lub
spacji, tabulatora itp. powoduje podział ciągu znaków na oddzielne
wyrazy,
jeśli zapytanie nie zwraca rezultatów jako wynik na zapytanie
powinna być wypisana pusta lista.
Listy składaneZbiorySłowniki
Zadania – podpowiedź
# !/ usr / bin / python3
1
2
import string
3
4
l = " aaa bbb ccc " . split () # [" aaa " ," bbb " ," ccc "]
j = " ," . join ( l ) # " aaa , bbb , ccc "
5
6
7
p = string . punctuation # ciag wszystkich
# znakow interpunkcyjnych
s = string . whitespace # ciag wszystkich
# znakow bialych
8
9
10
11
12
# jak posortowac slownik po wartosciach ?
import operator
test_dict = dict ({ ’a ’:1 , ’c ’ :50 , ’f ’ :17})
wynik = sorted ( test_dict . items () ,
key = operator . itemgetter (1))
Listy składaneZbiorySłowniki
13
14
15
16
17
Zadania – podpowiedź
Jak posortować słownik malejąco po wartościach i rosnąco po kluczach?
Sortujemy dwa razy:
najpierw po kluczach rosnąco (w pierwszej linijce)
następnie malejąco po wartościach (w drugiej linijce)
Odpowiednia kolejność w kluczach zostanie zachowana.
Listy składaneZbiorySłowniki
Klasy
Obiekty
Uniwersytet Ekonomiczny w Poznaniu
24 marca 2014
KlasyObiekty
Problemy programowania proceduralnego
Brak możliwości nazywania elementów przy tworzeniu bardziej
złożonych struktur danych, np. okrąg, punkt, itd.
Przy wykorzystaniu krotki (nawet nazwanej) - brak możliwości
zmiany elementu składowego.
Przy wykorzystaniu listy lub słownika - brak możliwości
kontrolowania wartości (np. podanie ujemnego promienia okręgu).
KlasyObiekty
Python, a programowanie obiektowe
Python pozwala tworzyć programy proceduralne, obiektowe i
funkcyjne oraz mieszać te style zależnie od potrzeb.
Programy proceduralne mogą wykorzystywać obiekty, ale dopiero
program tworzący klasy można nazwać obiektowym.
Python jest całkowicie zorientowany obiektowo: można definiować własne
klasy, dziedziczyć z własnych lub wbudowanych klas, a także tworzyć
instancje zdefiniowanych przez siebie klas.
KlasyObiekty
Podstawowe pojęcia
Klasa, typ, typ danych - synonimy, oznaczają zbiór obiektów, ich
rodzaj, stanowią ”wzorzec” dla tworzenia obiektów w pamięci.
s = str ( ’ abc ’)
type ( s )
1
2
Instancja, egzemplarz, obiekt - synonimy, oznaczają pojedyncze
wystąpienia, obiekty danej klasy występujące w pamięci.
Enkapsulacja - obiekty zawierają w sobie dane (atrybuty)
definiowane przez klasy; klasy definiują funkcje (metody), które
można wykonywać na obiektach.
Hermetyzacja - dostęp do atrybutów obiektu powinien być pośredni
(przez metody), a nie bezpośredni.
Właściwości - atrybuty dostępne pozornie bezpośrednio, ale w istocie
obsługiwane przez metody.
KlasyObiekty
Konwencje i reguły dotyczące tworzenia klas
Nazwy klas w Pythonie zaczynamy dużą literą.
Metody specjalne __add__() lub __len__() umieszczone w klasie
pozwalają obsługiwać operator + i funkcję len() dla obiektów tej
klasy.
Wszystkie metody specjalne zaczynają się i kończą __.
Zwykłe metody zaczynają się od małej litery.
Nazwa modułu nie musi być taka sama jak nazwa klasy.
KlasyObiekty
Tworzenie własnej klasy
class NazwaKlasy :
blok_instrukcji
1
2
blok_instrukcji może być pusty - wtedy pass.
Polecenie class podobnie jak def umożliwia dynamiczne tworzenie
klas.
Metody tworzy się przy użyciu def, z tym że do każdej metody
trzeba przekazać jawnie instancję obiektu - przez referencję self.
KlasyObiekty
Tworzenie obiektu
Tworzenie (obiektu) instancji - poprzez wywołanie klasy tak jak
funkcji:
n = NazwaKlasy ()
1
Obiekty biorą swoje zmienne i funkcje z klas.
Klasy są podstawowym schematem, według których tworzone są
obiekty.
KlasyObiekty
Zmienne w metodach 1
Atrybuty obiektu - dostępne po odwołaniu się do instancji self.x.
Zmienne lokalne - dostęp po nazwie.
Zmienne klasy (statyczne) - dostęp po nazwie klasy.
Zmienne globalne (modułu) - dostęp po nazwie.
modulowa = ’a ’
class Testowa :
z =0
def __init__ ( self , x =1):
self . x = x
def test ( self ):
print ( self . x )
y =7
print ( y )
print ( Testowa . z )
print ( modulowa )
1
2
3
4
5
6
7
8
9
10
11
KlasyObiekty
Zmienne w metodach 2
Atrybuty obiektu - dostępne po odwołaniu się do instancji self.x.
Zmienne lokalne - dostęp po nazwie.
Zmienne klasy (statyczne) - dostęp po nazwie klasy.
Zmienne globalne (modułu) - dostęp po nazwie.
t1 = Testowa ()
t1 . test ()
1
2
3
t2 = Testowa (3)
t2 . test ()
4
5
KlasyObiekty
Przykład
class MojaKlasa :
1
zmienna =2
2
def __init__ ( self , wartosc =1):
3
self . wartosc = wartosc
4
def mojaFunkcja ( self ):
5
wynik1 = self . wartosc ** self . zmienna
6
wynik2 = self . wartosc ** MojaKlasa . zmienna
7
print ( self . wartosc , ’ podniesiona do potegi : ’ , 8
self . zmienna , ’ daje wynik : ’ , wynik1 )
9
print ( self . wartosc , ’ podniesiona do potegi : ’ , 10
MojaKlasa . zmienna , ’ daje wynik : ’ , wynik2 ) 11
12
liczba1 = MojaKlasa ()
liczba1 . mojaFunkcja ()
13
14
15
liczba1 . zmienna = 4
liczba1 . mojaFunkcja ()
16
17
18
liczba2 = MojaKlasa (3)
liczba2 . mojaFunkcja ()
19
20
KlasyObiekty
Zadanie na rozgrzewkę
Utworzyć klasę obiektów Statek
Każdy obiekt powinien mieć następujące cechy: model, ładowność,
liczba masztów, wielkość.
Liczba masztów powinna być podana jako liczba (int)
Ładowność powinna być wyliczana z funkcji na podstawie wielkości:
jeśli ’duzy’ - ładowność: 50
jeśli ’maly’ - ładowność: 10
Utworzyć trzy nowe obiekty: statek1, statek2 i statek3.
KlasyObiekty
Zadanie 1 - wynagrodzenie
Obliczyć wynagrodzenie pracowników.
Obliczyć wysokość składek pracodawcy (na pracownika).
Obliczyć łączny koszt dla pracodawcy na pracownika.
Założenia:
każdy pracownik powinien być obiektem klasy pracowników,
program przyjmuje pierwszą wartość: liczbę pracowników (i),
dla liczby pracowników (i) wczytuje imię pracownika i wynagrodzenie
brutto (int) (oddzielone spacją),
każdy pracownik jest wprowadzany w nowej linii,
w wyniku wypisać: imię pracownika, wynagrodzenie netto (float),
składki pracodawcy (float), łączny koszt na pracownika (float),
każdy pracownik wypisywany jest w nowej linii,
w ostatniej linii wypisać łączny koszt dla pracodawcy (wszyscy
pracownicy).
KlasyObiekty
Zadanie 1 - wynagrodzenie
Przykładowe wejście:
2
Bartek 2580
Marek 1680
1
2
3
Przykładowe wyjście:
Bartek 1863.91 535.09 3115.09
Marek 1237.20 348.43 2028.43
5143.52
KlasyObiekty
1
2
3
Zadanie 1 - podpowiedzi
round (i , n ) # zaokraglanie
1
2
’ %.3 f ’ % 1.29003 # daje 1.290
Poszukać sposobu obliczania wynagrodzenia od 01.01.2014
Za koszty uzyskania przychodu przyjąć zawsze: 111.25
Każdy wynik pośredni powinien być zaokrąglany do 2 miejsc po
przecinku
Wypisywane wyniki powinny być sformatowane do 2. miejsca po
przecinku
KlasyObiekty
3
Zadanie 2 - figury
Obliczyć sumę pól figur geometrycznych.
Założenia:
program przyjmuje pierwszą wartość: liczbę figur (i),
dla liczby figur (i) wczytuje liczby (oddzielone spacją),
każda figura jest wprowadzona w nowej linii; jeśli linia zawiera:
jedną liczbę - jest to promień koła,
dwie liczby - boki prostokąta,
trzy liczby - boki trójkąta,
w wyniku wypisać sumę pól wprowadzonych figur (zaokrągloną do 2
miejsc po przecinku).
Dla każdej figury geometrycznej (koło, prostokąt, trójkąt) utwórz
oddzielną klasę.
KlasyObiekty
Zadanie 2 - figury
Przykładowe wejście:
5
2
4 6
3 3.5 4
8 2.1
4.14
1
2
3
4
5
6
Przykładowe wyjście:
112.3
1
KlasyObiekty
Klasy
Obiekty
część II
Uniwersytet Ekonomiczny w Poznaniu
1 kwietnia 2014
KlasyObiektyczęść II
Dziedziczenie
KlasyObiektyczęść II
Dziedziczenie c.d.
class Konto :
def __init__ ( self , numer , roczna_stopa ):
self . numer = numer
self . roczna_stopa = roczna_stopa
self . kwota = 0.0
def wplac ( self , kwota ):
self . kwota += kwota
1
2
3
4
5
6
7
8
9
class KontoKapRoczna ( Konto ):
def __init__ ( self , numer , roczna_stopa ):
super (). __init__ ( numer , roczna_stopa )
KlasyObiektyczęść II
10
11
12
Prywatne atrybuty
class Konto :
1
2
numer = 2
__numer = 1
3
4
5
def __init__ ( self , roczna_stopa ):
self . numer = Konto . __numer
Konto . __numer += 1
self . roczna_stopa = roczna_stopa
self . kwota = 0.0
6
7
8
9
10
11
def _ _prywa tna_metoda ( self ):
print ( " Nie mozna jej wywolac spoza klasy " )
KlasyObiektyczęść II
12
13
Zadanie na rozgrzewkę
Zaimplementuj system bankowy zgodnie z diagramem.
KlasyObiektyczęść II
Zadanie na rozgrzewkę c.d.
Bank:
W banku zapisane są wszystkie konta.
Metoda pobierz konto, to metoda prywatna, która pozwala
odwołać się do obiektu konta po jego numerze.
Metoda zaloz konto pozwala na założenie konta. Podana jest
roczna stopa procentowa jako float (np. 0.036) oraz typ kapitalizacji
(możliwe wartości: "miesieczna", "dzienna").
Metoda zwraca numer nowego konta.
Metoda wplac pozwala na wpłacenie pieniędzy na konto.
Metoda nastepny miesiac powoduje zaksięgowanie miesięcznych
odsetek na wszystkich kontach.
Metoda przelej pozwala przelać określoną kwotę z jednego konta
na inne.
KlasyObiektyczęść II
Zadanie na rozgrzewkę c.d.
Konto, KontoKapDzienna, KontoKapMiesieczna:
Każde konto posiada numer, który jest generowany automatycznie.
Każde konto posiada kwotę – początkowa kwota, to 0.00.
Każde konto ma zdefiniowaną roczną stopę procentową.
Metoda wplac pozwala na dokonanie wpłaty na konto. Wypłata z
konta to podanie kwoty jako wartości ujemnej.
KlasyObiektyczęść II
Zadanie na rozgrzewkę c.d.
Konto, KontoKapDzienna, KontoKapMiesieczna:
Każde konto ma metodę nastepny miesiac, jednak implementacja
tej metody różni się w zależności od tego, czy mamy do czynienia z
KontoKapMiesieczna, czy z KontoKapDzienna.
Metoda nastepny miesiac w klasie KontoKapMiesieczna
powoduje naliczenie odsetek dla kwoty konta z wykorzystaniem
kapitalizacji miesiecznej. Końcowa kwota zaokrąglana jest do 2
miejsca po przecinku.
Metoda nastepny miesiac w klasie KontoKapDzienna powoduje
naliczenie odsetek dla kwoty konta za cały miesiąc z wykorzystaniem
kapitalizacji dziennej. Po każdym dniu kwota zaokrąglana jest do
drugiego miejsca po przecinku. Przyjmujemy, że miesiąc ma 30 dni.
KlasyObiektyczęść II
Zadanie na rozgrzewkę c.d.
bank = Bank ()
k1 = bank . zaloz_konto (0.02 , " dzienna " )
k2 = bank . zaloz_konto (0.02 , " miesieczna " )
print ( bank )
1
2
3
4
5
bank . wplac ( k1 , 1000)
bank . wplac ( k2 , 1000)
print ( bank )
6
7
8
9
bank . nastepny_miesiac ()
print ( bank )
10
11
12
bank . przelej ( k1 , k2 , 100)
print ( bank )
13
14
KlasyObiektyczęść II
Zadania domowe
KlasyObiektyczęść II
Zadanie 1
Zaimplementuj dodawanie książek do biblioteki (metoda
dodaj egzemplarz ksiazki)
W tej metodzie do biblioteki powinien być dodawany nowy
Egzemplarz oraz (jeśli to konieczne) nowa Ksiazka.
Na wejściu w pierwszej linijce podana jest liczba egzemplarzy książek
do dodania (n), a następnie w kolejnych n linijkach egzemplarze
książek podane jako ("tytul", "autor", 2014).
Wskazówka: aby wczytać krotkę z egzemplarzem, użyj:
eval(input()).
Na wyjściu w kolejnych linijkach wypisana lista książek wraz z liczbą
egzemplarzy, też w postaci krotek (posortowana po tytułach).
KlasyObiektyczęść II
Zadanie 1 c.d.
Przykładowe wejście:
5
1
( " Chatka Puchatka " , " Alan Alexander Milne " , 2014)2
( " Quo Vadis " , " Henryk Sienkiewicz " , 2010)
3
( " Chatka Puchatka " , " Alan Alexander Milne " , 1998)4
( " Pan Tadeusz " , " Adam Mickiewicz " , 2003)
5
( " Quo Vadis " , " Henryk Sienkiewicz " , 2010)
6
Przykładowe wyjście:
( ’ Chatka Puchatka ’ , ’ Alan Alexander Milne ’ , 2)
( ’ Pan Tadeusz ’ , ’ Adam Mickiewicz ’ , 1)
( ’ Quo Vadis ’ , ’ Henryk Sienkiewicz ’ , 2)
KlasyObiektyczęść II
1
2
3
Zadanie 2
Zaimplementuj wypożyczanie książek przez czytelnika.
KlasyObiektyczęść II
Zadanie 2 – wejście
Na wejściu w pierwszej linijce podana jest liczba akcji (n).
W kolejnych linijkach podane są akcje:
dodaj – oznacza dodanie książki do biblioteki, zapisane np. jako:
("dodaj", "Pan Tadeusz", "Adam Mickiewicz", 2000)
wypozycz – oznacza wypożyczenie egzemplarza ksiazki przez
czytelnika (można wypożyczyć tylko jeden egzemplarz tej samej
książki; przyjmij też, że domyślnie można wypożyczyć maksymalnie 3
egzemplarze różnych książek). Akcja może być zapisana jako:
("wypozycz", "Jakub Dzikowski", "Quo Vadis")
oddaj – oznacza zwrócenie konkretnego egzemplarza książki do
biblioteki. Może być zapisane jako:
("oddaj", "Jakub Dzikowski", "Quo Vadis")
KlasyObiektyczęść II
Zadanie 2 – wyjście
Na wyjściu w kolejnych linijkach wypisane wartości logiczne True
lub False, oznaczające powodzenie lub niepowodzenie wykonania
konkretnej akcji.
dodaj – akcja zawsze powinna kończyć się powodzeniem.
wypozycz – może się skończyć niepowodzeniem, jeśli czytelnik
wypożyczył za dużo egzemplarzy książki lub chciał wypożyczyć drugi
egzemplarz tej samej książki, lub nie było już dostępnych
egzemplarzy książki.
oddaj – może się skończyć niepowodzeniem, jeśli czytelnik nie ma
takiej książki.
KlasyObiektyczęść II
Zadanie 2 – przykładowe wejście
12
1
( " dodaj " , " Pan Tadeusz " , " Adam Mickiewicz " , 2000)
2
( " dodaj " , " Quo Vadis " , " Henryk Sienkiewicz " , 2010) 3
( " dodaj " , " Chatka Puchatka " , " Alan Alexander Milne " , 4 1998)
( " dodaj " , " Pan Tadeusz " , " Adam Mickiewicz " , 2000)
5
( " dodaj " , " Chatka Puchatka " , " Alan Alexander Milne " , 6 2014)
( " wypozycz " , " Bartek Perkowski " , " Pan Tadeusz " )
7
( " wypozycz " , " Bartek Perkowski " , " Pan Tadeusz " )
8
( " wypozycz " , " Jacek Malyszko " , " Quo Vadis " )
9
( " wypozycz " , " Bartek Perkowski " , " Quo Vadis " )
10
( " oddaj " , " Jacek Malyszko " , " Quo Vadis " )
11
( " wypozycz " , " Bartek Perkowski " , " Quo Vadis " )
12
( " oddaj " , " Jacek Malyszko " , " Quo Vadis " )
13
KlasyObiektyczęść II
Zadanie 2 – przykładowe wyjście
True
True
True
True
True
True
False
True
False
True
True
False
1
2
3
4
5
6
7
8
9
10
11
12
KlasyObiektyczęść II
Zadanie 2 – wskazówki
Warto, aby Biblioteka zapamiętywała obiekty czytelników (podobnie
jak książki). Można w tym celu napisać metodę prywatną, która
będzie pobierać czytelnika o podanym nazwisku (jeśli istnieje już
zapisany taki obiekt czytelnika), a jeśli nie istnieje, to dodawać nowy
obiekt czytelnika i zwracać ten obikt.
Warto, żeby w obiekcie czytelnika były zapamiętane obiekty
wypożyczonych egzemplarzy i sprawdzanie części poprawnych
warunków na wypożyczenie i oddanie było oddelegowane na obiekty
czytelnika.
Pamiętaj, że zgodnie z podejściem Pythona, często „Easier to ask
for forgiveness than permission” (EAFP). Korzystaj z try: ...
except KeyError: ....
KlasyObiektyczęść II
Dokumentacja kodu
Tworzenie modułów
Uniwersytet Ekonomiczny w Poznaniu
9 kwietnia 2014
Dokumentacja kodu Tworzenie modułów
Adnotacje funkcji
Można opatrzyć sygnaturę funkcji adnotacjami korzystając ze
składni:
def nazwa_funkcji ( arg1 : ad1 , arg2 : ad2 ) -> ad3 :
pass
1
2
Python dodaje te adnotacje do atrybutu __annotations__, który jest
słownikiem - atrybutem w funkcji
jako adnotację możemy użyć:
stringa
typu danych (w tym zdefiniowanych klas)
Sam Python nie przywiązuje żadnej roli do tych adnotacji, ale można
je wykorzystać wprost, np. do kontroli typów
Dokumentacja kodu Tworzenie modułów
Adnotacje funkcji
Jak działa poniższa funkcja?
def mnozenie ( a : int , b : int ) -> int :
1
print ( mnozenie . __annotations__ )
2
anns = mnozenie . __annotations__
3
if type ( a ) != anns [ ’a ’] or type ( b ) != anns [ ’b ’ ]: 4
raise Exception ( ’ Bledne typy parametrow ! ’) 5
else :
6
return a * b
7
8
print ( mnozenie ( ’ ojej ’ ,2))
9
Dokumentacja kodu Tworzenie modułów
Adnotacje funkcji
w miejsce adnotacji można wstawić po prostu łańcuchy znaków
opisujące co ma się znaleźć w danym parametrze
class Biblioteka :
def wypozycz ( self , nazw : ’ nazwisko czytelnika ’ ,
tyt : ’ tytul ksiazki ’ ):
pass
Dokumentacja kodu Tworzenie modułów
1
2
3
4
Ciągi dokumentujące (docstrings)
Ciągi dokumentujące są to łańcuchy znaków umieszczane na
początku dokumentowanej struktury programistycznej:
modułu
klasy
funkcji
umieszczane są w specjalnym atrybucie __doc__
zainstancjonowanego obiektu
istnieją secjalne formaty do przygotowywania ciągów
dokumentujących, np. reStructuredText, z których można korzystać
w większych projektach
Dokumentacja kodu Tworzenie modułów
Ciągi dokumentujące – funkcje
aby dołączyć dokumentację do funkcji wystarczy po linii definicji
umieścić ją w komentarzu wielolinijkowym
dokumentacja funkcji może mieć np. następującą strukturę:
krótki opis w jednej linii
linię odstępu
dłuższy opis
opis parametrów funkcji
przykłady wykorzystania - w trybie interaktywnym interpretera
Dokumentacja kodu Tworzenie modułów
Ciągi dokumentujące + tworzenie modułów
Stwórz plik o następującej zawartości:
import math
1
2
def heron (a ,b , c ):
""" Oblicza pole trojkata wg wzoru Herona
3
4
5
a ,b , c dlugosci bokow trojkata
>> heron (3 ,4 ,5)
6.0
"""
s = ( a + b + c )/2
return math . sqrt ( s * (s -1) * (s - b ) * (s - c ))
6
7
8
9
10
11
12
if __name__ == ’ __main__ ’:
print ( heron . __doc__ )
print ( heron (3 ,4 ,5))
13
14
15
Dokumentacja kodu Tworzenie modułów
Ciągi dokumentujące + tworzenie modułów
zapisz plik na dysku (np. pod nazwą heron_modul.py)
otwórz interpreter pythona
zaimportuj go jako moduł (import heron_modul)
wykonaj na module funkcję help()
oblicz pole trójkąta o bokach za pomocą funkcji zdefiniowanej w
module
Co robi następująca linijka?
if __name__ == ’__main__’:
Dokumentacja kodu Tworzenie modułów
Zadanie – odległość węzłów w drzewie
w zadaniu operujemy na drzewie, czyli strukturze reprezentującej
hierarchię danych:
drzewo składa się z węzłów i krawędzi
każdy węzeł ma nad sobą dokładnie jeden inny węzeł, za wyjątkiem
węzła – korzenia (który nie ma nad sobą węzłów)
każdy węzeł może mieć dowolną liczbę pod-węzłów
na moodle znajduje się plik 07_zad_szkielet.py z dokumentacją,
która może pomóc w rozwiązaniu zadania
Dokumentacja kodu Tworzenie modułów
Dokumentacja kodu Tworzenie modułów
Zadanie 1 – wejście i wyjście
Na wejściu otrzymujemy:
Listę krotek, gdzie każda krotka składa się z dwóch elementów:
nad-węzła i pod-węzła. W liście może być wiele takich krotek i
reprezentują one nasze drzewo. Kolejność krotek w liście nie
powinna mieć znaczenia.
Listę wybranych wierzchołków drzewa.
Na wyjściu, dla każdego zadanego wierzchołka w osobnym wierszu
wypisujemy jego wszystkie nad-węzły aż do korzenia drzewa,
rozpoczynając od zadanego węzła (nad-węzeł stopnia zerowego).
Dokumentacja kodu Tworzenie modułów
Zadanie 1 – przykładowe wejście i wyjście
Wejście:
[( ’F ’ , ’B ’) , ( ’B ’ , ’A ’) , ( ’B ’ , ’D ’) , ( ’D ’ , ’C ’) ,
( ’D ’ , ’E ’) , ( ’F ’ , ’G ’) , ( ’G ’ , ’I ’) , ( ’I ’ , ’H ’ )]
[ ’B ’ , ’F ’ , ’C ’]
1
2
3
Wyjście:
[ ’B ’ , ’F ’]
[ ’F ’]
[ ’C ’ , ’D ’ , ’B ’ , ’F ’]
1
2
3
Dane odpowiadają drzewu przedstawionemu na ilustracji na
wcześniejszych slajdach
Dokumentacja kodu Tworzenie modułów
Zadanie 2 – odległość węzłów w drzewie (miara prosta)
Zdefiniujemy miarę prostą liczenia odległości pomiędzy węzłami w
drzewie jako liczbę krawędzi, które trzeba pokonać, aby dojść od
jednego do drugiego węzła
Możemy ją obliczyć poprzez znalezienie najniższego wspólnego
nadwęzła dla obu wierzchołków, a następnie określenia i zsumowania
jego odległości od ich obu
Poniżej, odległość między węzłami A i C wynosi 3 (najnizszym
wspólnym nadwęzłem jest B, jego odległość od A wynosi 1 a od C
wynosi 2)
Dokumentacja kodu Tworzenie modułów
Zadanie 2 – wejście i wyjście
Na wejściu otrzymujemy:
Listę krotek reprezentującej drzewo, analogicznie do zad. 1.
Listę krotek, reprezentujących zapytania; każda krotka składa się z
trzech elementów: dwóch nazw wierzchołków i nazwy metryki
wykorzystywanej do mierzenia odległości:
prosta – miara prosta, opisana na poprzednim slajdzie
potęgowa – opisana w komentarzu do metody licz odleglosc klasy
MiaraPotegowa
Mamy za zadanie obliczyć odległość pomiędzy wierzchołkami za pomocą
zadanej miary. Na wyjściu wypisujemy listę liczb, które reprezentują
odległości pomiędzy węzłami.
Dokumentacja kodu Tworzenie modułów
Zadanie 2 – przykładowe wejście i wyjście
Dane odpowiadają rysunkowi drzewa na wcześniejszych zlajdach.
Przykładowe wejście
[( ’F ’ , ’B ’) , ( ’B ’ , ’A ’) , ( ’B ’ , ’D ’) , ( ’D ’ , ’C ’) ,
( ’D ’ , ’E ’) , ( ’F ’ , ’G ’) , ( ’G ’ , ’I ’) , ( ’I ’ , ’H ’ )]
[( ’ prosta ’ , ’C ’ , ’G ’) , ( ’ prosta ’ , ’G ’ , ’C ’) ,
( ’ potegowa ’ , ’G ’ , ’C ’ )]
1
2
3
4
Przykładowe wyjście
[4 , 4 , 8]
1
Dokumentacja kodu Tworzenie modułów
Wczytywanie danych
Praca z CSV
Uniwersytet Ekonomiczny w Poznaniu
23 kwietnia 2014
Wczytywanie danych Praca z CSV
Wczytywanie danych
input()
pobiera dane wprowadzone z klawiatury
można przekazywać dane wejściowe bez ręcznego wpisywania
przygotowanie plików wejściowych zastępujących dane wprowadzane
ręcznie
Wczytywanie danych Praca z CSV
Wczytywanie danych c.d.
input()
Plik input.txt
( " Chatka Puchatka " , " Alan Alexander Milne " , 1998)1
( " Pan Tadeusz " , " Adam Mickiewicz " , 2003)
2
( " Quo Vadis " , " Henryk Sienkiewicz " , 2010)
3
Plik jako dane wejściowe
python3 moj_skrypt.py < input.txt
Wczytywanie danych Praca z CSV
Parsowanie argumentów
import sys
1
2
for arg in sys . argv :
print ( arg )
3
4
argumenty linii poleceń przekazywane są do programu
sys.argv jest listą elementów
pierwszy element - nazwa uruchomionego skryptu
Wczytywanie danych Praca z CSV
Parsowanie argumentów c.d.
getopt(arg, short, long)
Funkcja przyjmuje trzy parametry:
arg - listę argumentów
short - ciąg znaków zawierający jedno-znakowe flagi
long - listę dłuższych flag, będących odpowiednikami krótszych
Wczytywanie danych Praca z CSV
Parsowanie argumentów - przykład
import getopt , sys
1
2
try :
3
opts , args = getopt . getopt ( sys . argv [1:] ,
" ho : " , [ " help " , " output = " ])
except getopt . GetoptError as err :
print ( err )
4
5
6
7
8
for op , ar in opts :
if op in ( ’ -h ’ , ’ -- help ’ ):
print ( help ())
elif op in ( ’ -o ’ , ’ -- output ’ ):
print ( ar )
python3 moj_skrypt.py -h
python3 moj_skrypt.py -o tekst
Wczytywanie danych Praca z CSV
9
10
11
12
13
Moduł CSV
moduł csv umożliwia odczyt oraz zapis do liku CSV
CSV - pliki przechowujące tabele z danymi, zawierające rekordy
podzielone na pola
brak ogólnego standardu co do separatorów pól
Wczytywanie danych Praca z CSV
Odczyt pliku CSV
import csv
1
2
plik_csv = open ( nazwa_pliku , tryb )
csv . reader ( plik_csv , dialect = ’ ’ , format_params )
open() otwiera plik
nazwa_pliku - wskazuje nazwę pliku do otwarcia
tryb - definiuje jak będzie używany plik (read mode, write mode,
append mode)
reader() tworzy nowy obiekt o podanych parametrach:
plik_csv - wskazuje na plik
dialect - określa format pliku CSV (opcjonalnie)
format_params - określa specyficzne parametry formatowania
Wczytywanie danych Praca z CSV
3
4
Praca z plikiem CSV
import csv
1
2
plik_csv = open ( ’ sample . csv ’ , ’r ’)
czytaj = csv . reader ( plik_csv )
3
4
5
for i , rekord in enumerate ( czytaj ):
if i == 0:
naglowek = rekord
else :
for j , pole in enumerate ( rekord ):
print ( naglowek [ j ] , ’: ’ , pole )
print ( ’ ’)
6
7
8
9
10
11
12
13
plik_csv . close ()
14
Wczytywanie danych Praca z CSV
Zapis do CSV
import csv
1
2
plik_csv = open ( ’ output . csv ’ , ’w ’ , encoding = ’utf -8 ’) 3
zapisz = csv . writer ( plik_csv , dialect = ’ unix ’)
4
5
dane = [
( ’ Imie ’ , ’ Nazwisko ’ , ’ Firma ’ , ’ Stanowisko ’) ,
( ’ Bartek ’ , ’ Perkowski ’ , ’ UEP ’ , ’ Informatyk ’) ,
( ’ Jan ’ , ’ Nowak ’ , ’ ABC ’ , ’ Sprzedawca ’) ,
( ’ Jakub ’ , ’ Dzikowski ’ , ’ UEP ’ , ’ Administrator ’) ,
( ’ Jacek ’ , ’ Malyszko ’ , ’ UEP ’ , ’ Administrator ’) ,
( ’ Marek ’ , ’ Kowalski ’ , ’ ABC ’ , ’ Informatyk ’)
]
6
7
8
9
10
11
12
13
14
for element in dane :
zapisz . writerow ( element )
15
16
17
plik_csv . close ()
18
Wczytywanie danych Praca z CSV
Zapis do CSV c.d.
zapisz = csv.writer(plik_csv,delimiter=’|’)
zapisz = csv.writer(plik_csv,delimiter=’\t’)
zapisz = csv.writer(plik_csv,dialect=’excel’)
zapisz = csv.writer(plik_csv,dialect=’unix’)
Wczytywanie danych Praca z CSV
CSV - tworzenie dialektu
import csv
csv . register_dialect ( ’ mojDialekt ’ , delimiter = ’| ’ ,
quoting = csv . QUOTE_ALL )
1
2
3
4
plik_csv = open ( ’ output . csv ’ , ’w ’)
zapisz = csv . writer ( plik_csv , dialect = ’ mojDialekt ’)
5
6
7
dane = [
( ’ Imie ’ , ’ Nazwisko ’ , ’ Firma ’ , ’ Stanowisko ’) ,
( ’ Bartek ’ , ’ Perkowski ’ , ’ UEP ’ , ’ Informatyk ’)
]
8
9
10
11
12
for element in dane :
zapisz . writerow ( element )
13
14
15
plik_csv . close ()
16
Wczytywanie danych Praca z CSV
Wstęp do zadań
W pliku CSV posiadamy dane dotyczące połączeń telefonicznych. Każdy
wiersz opisuje jedno połączenie (pierwszy wiersz w pliku jest
nagłówkiem). W każdym wierszu znajdują się kolejno:
Nadawca (From) - unikalny identyfikator liczbowy
Odbiorca (To) - unikalna identyfikator liczbowy
Data i godzina (Datetime) - w postaci RRRRMMDD HHMM
Czas trwania (Duration(seconds)) - liczba sekund
Nadajnik (Cell Tower) - unikalny identyfikator liczbowy
Nadawca i odbiorca jest reprezentowany przez ten sam identyfikator.
Wczytywanie danych Praca z CSV
Zadanie 1 - połączenia
W pliku wejściowym podane są następujące informacje:
w pierwszej linii znak oddzielający kolejne pola w rekordzie, np. ;
w drugiej linii ścieżka dostępu do pliku zwierającego dane o
połączeniach.
Na wyjściu powinna znajdować się informacja:
w pierwszym wierszu identyfikator użytkownika, który wykonał
największą liczbę połączeń, oraz łączny czas tych połączeń
w drugim wierszu identyfikator użytkownika, który odebrał
największą liczbę połączeń, oraz łączny czas tych połączeń
w przypadku równej liczby połączeń, powinien zostać wypisany
użytkownik o niższym identyfikatorze
Wczytywanie danych Praca z CSV
Zadanie 1 - połączenia
Przykładowe wejście:
,
./ phoneCalls . csv
1
2
Przykładowe wyjście:
226: 5387
5: 16797
1
2
Na moodle przykładowy plik do testowania: phoneCalls.csv
Wczytywanie danych Praca z CSV
Zadanie 2 - statystyki
Plik wejściowy taki sam jak w Zadaniu 1. Do Zadania 2. wykorzystaj
skrypt z Zadania 1. Wynikiem zadania powinno być:
w pierwszym wierszu lista 10 identyfikatorów najczęściej dzwoniących
w drugim wierszu lista 10 identyfikatorów najczęściej odbierających
w trzecim wierszu najczęściej używany nadajnik wraz łączną liczbą
połączeń, do których został użyty
w czwartym wierszu dla najczęściej dzwoniącego wypisać jego
atrybuty: średni czas połączenia wychodzącego (zaokrąglony do 2
miejsc po przecinku) oraz średnia liczba połączeń wychodzących
(zaokrąglona do 2 miejsca po przecinku)
identyfikatory powinny być posortowane malejąco wg liczby
połączeń, a w przypadku równej liczby połączeń od najniższego
Wczytywanie danych Praca z CSV
Zadanie 2 - statystyki
Przykładowe wyjście:
[ ’ 226 ’ , ’ 47 ’ , ’ 75 ’ , ’ 152 ’ , ’ 158 ’ , ’ 176 ’ , ’ 297 ’ ,
’ 359 ’ , ’ 363 ’ , ’ 375 ’]
[ ’5 ’ , ’0 ’ , ’2 ’ , ’ 13 ’ , ’ 172 ’ , ’1 ’ , ’ 15 ’ , ’ 32 ’ ,
’ 23 ’ , ’ 42 ’]
( ’ 15 ’ , 54)
1077.4 0.71
Wczytywanie danych Praca z CSV
1
2
3
4
5
6
Biblioteka
część II
Uniwersytet Ekonomiczny w Poznaniu
25 kwietnia 2014
Bibliotekaczęść II
Zadanie
Dla podanej wcześniej definicji biblioteki, zaimplementuj
1
Dodawanie historii przeprowadzania akcji na egzemplarzach:
dodania
wypożyczenia
oddania
2
Naliczanie kar bibliotecznych.
Na Moodle dostępne jest rozwiązanie poprzedniego zadania z biblioteki,
które można zmodyfikować zgodnie z instrukcjami do tego zadania.
Bibliotekaczęść II
Zadanie 1
Podczas dodawania egzemplarzy książki, podawana jest także data
jego dodania do biblioteki, jako krotka, np. (2013, 12, 23).
Wyświetl zestawienie egzemplarzy książek, które zostały dodane
później, niż podana data (czyli zestawienie nowszych egzemplarzy).
Wejście:
W pierwszej linijce podawana liczba książek do dodania (n).
W kolejnych n linijkach podane egzemplarze książki.
W ostatniej linijce podana data (jako krotka).
Wyjście: analogiczne zestawienie, jak w poprzednim zadaniu
z biblioteki.
Bibliotekaczęść II
Zadanie 1 c.d.
Przykładowe wejście:
5
1
( " Chatka Puchatka " , " Alan A . Milne " , 2014 , (2014 , 4 , 10)) 2
( " Quo Vadis " , " Henryk Sienkiewicz " , 2010 , (2014 , 1 , 15)) 3
( " Chatka Puchatka " , " Alan A . Milne " , 1998 , (2013 , 12 , 31))4
( " Pan Tadeusz " , " Adam Mickiewicz " , 2003 , (2012 , 1 , 1))
5
( " Quo Vadis " , " Henryk Sienkiewicz " , 2010 , (2014 , 1 , 15)) 6
(2013 , 12 , 31)
7
Przykładowe wyjście:
( ’ Chatka Puchatka ’ , ’ Alan A . Milne ’ , 1)
( ’ Quo Vadis ’ , ’ Henryk Sienkiewicz ’ , 2)
Bibliotekaczęść II
1
2
Zadanie 2
Zaimplementuj naliczanie kar bibliotecznych.
Reguły naliczania kar:
Każdy egzemplarz ma limit wypożyczenia 7 dni.
Za każdy dzień przekroczenia limitu naliczana jest kara w wysokości
50 groszy.
Wszystkie kary sumują się.
Na wejściu podane są akcje z datami ich wykonania; w ostatniej
linijce bieżąca (końcowa) data. Akcje podane są chronologicznie.
Na wyjściu:
Najpierw wyświetlone są wartości logiczne, opisujące poprawność
wykonania operacji (analogicznie do poprzedniego zadania
z biblioteki).
Następnie wyświetlone jest zestawienie kar wszystkich czytelników
(czytelnicy sortowani są rosnąco po nazwiskach). Jeśli czytelnik nie
ma kar, nie jest wyświetlany. Nie trzeba zaokrąglać kar, ani
wyświetlać ich w specjalny sposób. Krotki z karami wyświetlane są
jedna pod drugą, podobnie jak w przypadku wyświetlania zestawienia
egzemplarzy.
Bibliotekaczęść II
Zadanie 2 c.d.
Przykładowe wejście
11
( " dodaj " ," Pan Tadeusz " ," A . Mickiewicz " ,2000 ,(2014 ,1 ,1))
( " dodaj " ," Quo Vadis " ," H . Sienkiewicz " ,2010 ,(2014 ,1 ,1))
( " dodaj " ," Chatka Puchatka " ," A . A . Milne " ,1998 ,(2014 ,1 ,1))
( " dodaj " ," Pan Tadeusz " ," A . Mickiewicz " ,2000 ,(2014 ,1 ,1))
( " dodaj " ," Chatka Puchatka " ," A . A . Milne " ,2014 ,(2014 ,1 ,1))
( " wypozycz " ," Bartek Perkowski " ," Pan Tadeusz " ,(2014 ,1 ,25))
( " wypozycz " ," Bartek Perkowski " ," Pan Tadeusz " ,(2014 ,2 ,2))
( " wypozycz " ," Jacek Malyszko " ," Quo Vadis " ,(2014 ,2 ,12))
( " oddaj " ," Jacek Malyszko " ," Quo Vadis " ,(2014 ,2 ,17))
( " oddaj " ," Bartek Perkowski " ," Pan Tadeusz " ,(2014 ,2 ,25))
( " wypozycz " ," Bartek Perkowski " ," Quo Vadis " ,(2014 ,3 ,5))
(2014 ,3 ,13)
Bibliotekaczęść II
1
2
3
4
5
6
7
8
9
10
11
12
13
Zadanie 2 c.d.
Przykładowe wyjście:
True
True
True
True
True
True
False
True
True
True
True
( ’ Bartek Perkowski ’ , 12.5)
1
2
3
4
5
6
7
8
9
10
11
12
Bibliotekaczęść II
Wskazówki
Warto wykorzystać bibliotekę do obsługi dat.
Dokumentacja:
https://docs.python.org/3.0/library/datetime.html
Tutorial: http://pymotw.com/2/datetime/ (tutorial jest dla
Pythona 2, ale moduł działa podobnie dla Pythona 3)
Przykład wykorzystania w konsoli Pythona 3:
1
>>> import datetime
>>> d1 = datetime . date (2008 , 3 , 12)
>>> print ( d1 )
2008 -03 -12
>>> d2 = datetime . date (2009 , 1 , 21)
>>> ( d1 - d2 ). days
-315
Bibliotekaczęść II
2
3
4
5
6
7
8
Sposób rozwiązania zadania 1
Ponieważ w trzech grupach zadanie pierwsze rozwiązywane było podczas
zajęć, na kilku kolejnych slajdach zaprezentowano krok po kroku
przykładowy sposób rozwiązania tego zadania. Opis powinien być bardzo
przydatny studentom, którzy nie mieli tych zajęć (godziny rektorskie)
oraz dla tych, którzy nie zrobili tego podczas zajęć.
Bibliotekaczęść II
Krok 1. Wczytywanie danych
W pliku z rozwiązaniem poprzedniego zadania, który znajduje się na
Moodle, są następujące linijki:
biblioteka = Biblioteka ()
1
for i in range ( int ( input ())):
2
t = eval ( input ())
3
if t [0] == " dodaj " :
4
print ( biblioteka . d o d a j _ e g z e m p l a r z _ k s i a z k i ( t [1] , t [2]
5
, t [3]
elif t [0] == " wypozycz " :
6
print ( biblioteka . wypozycz ( t [1] , t [2]))
7
elif t [0] == " oddaj " :
8
print ( biblioteka . oddaj ( t [1] , t [2]))
9
Kod ten jest przystosowany do zadania nr. 2 z poprzedniej biblioteki.
Najpierw tworzona jest instancja biblioteki, a następnie wczytywane są
wszystkie krotki z opisywanymi akcjami, po czym określone akcje są
wykonywane i wyświetlany jest ich rezultat (czy się powiodły, czy nie).
Bibliotekaczęść II
Krok 1. Wczytywanie danych
Linie od 4 do 9 z poprzedniego slajdu najlepiej zakomentować. Przydadzą
się później w zadaniu z naliczaniem kar bibliotecznych (najlepiej
wykorzystać działający kod z zadania 1 w zadaniu 2 – tam też będzie
ważne zapisywanie egzemplarzy z datą dodania).
Natomiast po liniach 1 – 3 należy:
1
2
3
dodać egzemplarz książki z datą dodania,
wczytać datę, dla której generowany będzie raport,
wyświetlić raport nowszych egzemplarzy, niż podana data.
Zostanie to szczegółowo omówione na kolejnych slajdach.
Bibliotekaczęść II
Krok 2. Dodawanie egzemplarza książki
Za dodanie egzemplarza do biblioteki służy metoda:
d o d a j _ e g z e m p l a r z _ k s i a z k i ( self , tytul , autor , rok_wydania )
1
Najlepiej rozszerzyć tę metodę o nowy parametr z datą:
d o d a j _ e g z e m p l a r z _ k s i a z k i ( self , tytul , autor , rok_wydania , 1data )
Zatem dodanie egzemplarza książki na podstawie krotki t mogłoby
wyglądać w następujący sposób (podane są dwie alternatywne formy):
biblioteka . d o d a j _ e g z e m p l a r z _ k s i a z k i ( t [0] , t [1] , t [2] , t [3])
1
biblioteka . d o d a j _ e g z e m p l a r z _ k s i a z k i (* t )
2
Gwiazdka przed krotką powoduje „rozpakowanie” krotki, czyli
w przypadku powyższego wywołania, jeśli krotka t ma cztery elementy,
to wywołanie *t w metodzie dodaj egzemplarz ksiazki spowoduje
podanie tych czterech kolejnych elementów jako cztery kolejne argumenty
w metodzie.
Bibliotekaczęść II
Krok 2a. Modyfikacja dodaj egzemplarz ksiazki
Istniejąca metoda dodaj egzemplarz ksiazki działa w następujący
sposób:
1
Do zmiennej ksiazka przypisywana jest książka, która wcześniej
została dodana do „bazy” – słownika z książkami.
2
Jeśli ta instrukcja się nie powiedzie – czyli jeśli nie można odnaleźć
książki o tym tytule w „bazie”, to znaczy, że należy dodać nową
książkę. Zatem w kolejnych krokach tworzony jest nowy obiekt
książki i przypisywany do zmiennej ksiazka. Następnie ten obiekt
jest dodawany do „bazy”.
3
Każda książka posiada listę egzemplarzy. W kolejnej linijce do takiej
listy dodawany jest nowy, utworzony obiekt egzemplarza książki.
4
Zwracane jest True, oznaczające, że akcja się powiodła.
W tym wypadku modyfikacja powinna polegać na dodaniu parametru
data do deklaracji metody oraz na przekazaniu tego parametru do
konstruktora egzemplarza. Zatem utworzenie obiektu egzemplarza
powinno wyglądać następująco:
Egzemplarz ( rok_wydania , ksiazka , data )
Bibliotekaczęść II
1
Krok 2b. Modyfikacja konstruktora egzemplarza
W konstruktorze egzemplarza należy dodać nowy parametr: data
i przypisać go jako atrybut nowego obiektu. To jest też dobre miejsce,
żeby skorzystać z rekomendowanej biblioteki do obsługi dat. Zatem na
początku pliku należy zaimportować odpowiedni moduł:
import datetime
1
Z kolei samo utworzenie atrybutu i przypisanie daty mogłoby wyglądać
następująco:
self . data_dodania = datetime . date (* data )
1
Ponieważ data występuje jako krotka z trzema elementami, np. (2013,
4, 23), to użycie gwiazdki przed datą spowoduje, że zostanie wywołane
coś podobnego do: datetime.date(2013, 4, 23). Czyli krotka
zostanie „rozpakowana”.
Po wykonaniu tych kroków nasza biblioteka będzie zapamiętywać daty
dodania egzemplarza.
Bibliotekaczęść II
Krok 3. Wczytanie daty
Aby wczytać datę, wystarczy wywołać np.:
data = eval ( input ())
1
Data ta następnie zostanie użyta przy wyświetleniu raportu nowszych
książek.
Bibliotekaczęść II
Krok 4. Wyświetlenie raportu nowszych egzemplarzy
Aktualnie w bibliotece znajduje się metoda raport ksiazek:
def raport_ ksiazek ( self ):
1
lista = []
2
for k in self . __ksiazki . values ():
3
lista . append (( k . tytul , k . autor , len ( k . egzemplarze )))
4
return sorted ( lista , key = lambda t : t [0])
5
W tej metodzie najpierw tworzona jest pusta lista, a następnie do tej listy
dodawane są krotki zawierające tytuł książki, autora książki i liczbę
egzemplarzy. Na końcu zwracana lest lista krotek posortowana po
pierwszych elementach krotek (czyli po tytułach).
Dobrym sposobem byłoby zmodyfikowanie tej metody, żeby zwrcała
raport nie wszystkich egzemplarzy, ale raport egzemplarzy nowszych niż
określona data.
Bibliotekaczęść II
Krok 4a. Modyfikacja metody raport ksiazek
Aby zmodyfikować metodę raport ksiazek należy:
1
Dodać nowy argument do metody, reprezentujący datę o nazwie,
przykładowo, data.
2
Zamiast liczby wszystkich egzemplarzy interesuje nas liczba
wszystkich egzemplarzy nowszych niż określona data. Zatem
najlepiej zamiast wywołania k.egzemplarze, wywołać nową metodę
(którą oczywiście należy dopisać do klasy Ksiazka). Warto także
wynik wywołania tej metody zapisać w nowej zmiennej, np.:
nowsze = k . e g z e m p l a r z e _ n o w s z e _ n i z ( data )
3
1
Dodatkowo, jeśli liczba egzemplarzy nowszych wyniesie 0, nie
umieszczamy tej pozycji w raporcie, zatem do zmiennej lista krotki
powinny być dodawane tylko wtedy, gdy len(nowsze) > 0
Bibliotekaczęść II
Krok 4b. Dodanie metody egzemplarze nowsze niz
Do klasy Ksiazka powinna zostać dodana metoda
egzemplarze nowsze niz o następującej deklaracji:
def e g z e m p l a r z e _ n o w s z e _ n i z ( self , data ):
1
Metoda powinna zwracać tylko te egzemplarze, które są nowsze niż
podana data, co można osiągnąć w dwóch linijkach, stosując listy
składane:
data = datetime . date (* data )
1
return [ e for e in self . egzemplarze if e . data_dodania > data
2
]
Tym samym metoda raport ksiazek jest już w stanie generować
zestawienie egzemplarzy książek nowszych niż podana data. Ostatnim
krokiem jest ich prawidłowe wyświetlenie.
Bibliotekaczęść II
Krok 4c. Wyświetlenie krotek z raportu
Metoda raport ksiazek zwracała posortowaną listę krotek. Na wyjściu
jednak nie jest oczekiwane wyświetlenie całej listy w jednej linijce, lecz
wyświetlenie kolejnych krotek w nowych linijkach. Tym samym należy
przeiterować wszystkie krotki z tej listy wyświetlić je w kolejnych
wywołaniach funkcji print:
for x in biblioteka . raport_ ksiazek ( data ):
print ( x )
Po wykonaniu tych kroków zgodnie z instrukcjami pierwsze zadanie
powinno przejść testy na sprawdzarce.
Bibliotekaczęść II
1
2
Obiektowość cz. 3.
Generatory
Uniwersytet Ekonomiczny w Poznaniu
12 maja 2014
Obiektowość cz. 3. Generatory
Uwagi o pamięci, wskaźnikach, referencjach i zmiennych
Rzut okiem na pamięć (przykłady w języku C)
Zmienna - nazwane miejsce w pamięci
Wskaźnik - specyficzna zmienna, która przechowuje adres; adres do
innych danych; w językach Pascal, C, C++ odróżnia się od
zmiennych zachowaniem i wyglądem
Referencja - prawie to samo co wskaźnik (robi to samo, ale wygląda
tak samo jak zmienna), nie może być pusta (nie wskazywać na coś)
Nazwa referencji to inaczej identyfikator
Obiektowość cz. 3. Generatory
Zmienne, referencje
Python nie posiada zmiennych - tylko referencje
Zmienna - nazwane miejsce w pamięci, komórka w której można
zmieniać wartość
Referencja - odniesienie do miejsca w pamięci, komórka w pamięci w
której jest adres innego obszaru pamięci
Referencje i zmienne mogą być zmieniane
x = " niebieski "
y = " zielony "
z = x
1
2
3
Operator = łączy obiekt z referencją
Obiektowość cz. 3. Generatory
Atrybuty obiektów
atrybuty obiektu znajdują się w specjalnym słowniku __dict__
atrybuty można dodawać do obiektu w dowolnym momencie
class A :
def __init__ ( self ):
self . atr1 = 1
1
2
3
4
obiekt_a = A ()
obiekt_a . atr2 = 15
print ( obiekt_a . __dict__ )
obiekt_a . __dict__ [ ’ atr3 ’] = 8
print ( obiekt_a . atr3 )
./atrybuty.py
Obiektowość cz. 3. Generatory
5
6
7
8
9
Atrybuty obiektów 2
Aby uniemożliwić dodawanie / usuwanie atrybutów trzeba założyć
klasę z krotką o nazwie __slots__ zawierającą nazwy wszystkich
atrybutów
>>> class P :
...
__slots__ = ( " x " )
...
def __init__ ( self ):
...
self . x =10
...
1
2
3
4
5
słownik __dict__ nie jest wtedy tworzony i nie można dodawać ani
usuwać atrybutów
obiekty ze slots działają szybciej niż z dict (nieznacznie)
Obiektowość cz. 3. Generatory
Abstrakcyjne klasy bazowe
AKB to klasa, która nie może być użyta do tworzenia obiektów
AKB zawiera przynajmniej jedną właściwość lub metodę
abstrakcyjną (bez implementacji)
AKB używa się aby z nich dziedziczyć
AKB zwykle “obiecują” wsparcie dla pewnych metod w klasach
potomnych i grupują klasy potomne w abstrakcyjne koncepcje
AKB musi mieć metaklasę abc.ABCMeta
Obiektowość cz. 3. Generatory
Metaklasy
Metaklasa jest dla klasy tym czym klasa dla instancji
Klasa służy jako szablon do tworzenia instancji
Metaklasa służy jako szablon do tworzenia klas
Metaklasa musi dziedziczyć po metaklasie bazowej (type) lub jednej
z jej podklas
Metaklasa może ingerować w skład klasy
Zastosowania: wyjątkowe sytuacje, np. tworzenie frameworków
(Django itd.)
Do przeczytania dla chętnych
http://stackoverflow.com/a/6581949
Obiektowość cz. 3. Generatory
AKB – zdefiniowanie klasy abstrakcyjnej
import abc
1
2
class PluginBase ( metaclass = abc . ABCMeta ):
3
4
@abc . abstractmethod
def load ( self , input ):
""" Pobiera dane . """
return
5
6
7
8
9
@abc . abstractmethod
def save ( self , output , data ):
""" Zapisuje dane . """
return
./akb1.py
Źródło: http://pymotw.com/2/abc/
Obiektowość cz. 3. Generatory
10
11
12
13
AKB – klasa implementująca
class S u b c l a s s I m p le men ta ti on ( PluginBase ):
1
2
def load ( self , input ):
return input . read ()
3
4
5
def save ( self , output , data ):
return output . write ( data )
6
7
8
if __name__ == ’ __main__ ’:
9
print ( ’ Podklasa : ’ ,
10
issubclass ( SubclassImplementation , PluginBase
11
))
akb2.py
Źródło: http://pymotw.com/2/abc/
Obiektowość cz. 3. Generatory
Wartościowanie leniwe
Definicja
Wartościowanie leniwe (ang. lazy evaluation) to strategia wyznaczania
wartości wyrażenia tylko wtedy, kiedy jest to potrzebne (na żądanie).
Obiektowość cz. 3. Generatory
Generatory
Funkcja generatora to funkcja z wyrażeniem yield zamiast return
Wartością zwrotną jest iterator
Z iteratora pozyskiwane są kolejno wartości przy pomocy wywołania
niejawnego funkcji __next__() na iteratorze
podczas każdego wywołania __next__() zwracana jest wartość
wygenerowana przez yield
działanie generatora kończy użycie return lub normalne zakończenie
funkcji
przykład: chcemy przejść przez litery od podanej początkowej do
końcowej. Można to zrobić albo tworząc ich listę albo używając
generatora
d = listaLiter ( ’a ’ , ’m ’)
for litera in litery ( ’a ’ , ’m ’ ):
print ( litera )
Obiektowość cz. 3. Generatory
1
2
3
Funkcja generatora a zwykła funkcja
# buduje i zwraca liste
def litery (a , z ):
wynik = []
while ord ( a ) < ord ( z ):
wynik . append ( a )
a = chr ( ord ( a ) + 1)
return wynik
1
# zwraca kazda wartosc na zadanie
def litery (a , z ):
while ord ( a ) < ord ( z ):
yield a
a = chr ( ord ( a ) + 1)
1
2
3
4
5
6
7
Obiektowość cz. 3. Generatory
2
3
4
5
yield
Jak zrozumieć funkcję z poleceniem yield?
1
dodaj linijkę result = [] na początku funkcji,
2
zamień yield expr na result.append(expr),
3
wstaw linię return result na końcu funkcji.
Otrzymamy analogiczny wynik (choć nie w postaci generatora), jednak
program w wielu przypadkach będzie wymagał więcej pamięci i będzie
działał wolniej.
Obiektowość cz. 3. Generatory
Generatory
Znane nam przykłady generatorów to:
range
csv.reader
Obiektowość cz. 3. Generatory
Generatory c.d.
Jeżeli chcemy uzyskać wszystkie elementy z generatora to można
przekazać go do funkcji list() lub tuple()
wszystkie = list ( litery ( ’a ’ , ’m ’ ))
1
generator wykonuje działanie kiedy jest potrzebna następna wartość,
a nie “z góry”
generator może generować nieskończoną sekwencję wartości
def cwiartki ( nastepna_cwiartka =0.0):
while True :
yield nastepna_cwiartka
nas tepna_cwiartka += 0.25
wynik =[]
for x in cw ():
wynik . append ( x )
if x >=2.0:
break
Obiektowość cz. 3. Generatory
1
2
3
4
5
6
7
8
9
Korzyści z generatorów – funkcja range
Porównanie pamięci zużytej do obliczenia sumy liczb.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
import resource
mem_usg = resource . getrusage
m0 = mem_usg ( resource . RUSAGE_SELF ). ru_maxrss
a = sum ( range (10000000))
m1 = mem_usg ( resource . RUSAGE_SELF ). ru_maxrss
b = sum ( list ( range (10000000)))
m2 = mem_usg ( resource . RUSAGE_SELF ). ru_maxrss
print ( m1 / m0 )
print ( m2 / m1 )
Wnioski?
Obiektowość cz. 3. Generatory
1
2
3
4
5
6
7
8
9
Wyrażenia generatora
Zamiast funkcji generatora można użyć wyrażenia generatora
Wyrażenie takie to pętla for, ujęta w nawias okrągły (podobne do
list składanych, różni się nawiasem)
Wyrażenie takie daje iterator, podobnie jak funkcja generatora
def ele m e n t y _ p o s o rtowane ( d ):
for klucz in sorted ( d ):
yield klucz , d [ klucz ]
1
2
3
# wyrazenie generatora
1
def ele m e n t y _ p o s o rtowane ( d ):
2
return (( klucz , d [ klucz ]) for klucz in sorted ( d )) 3
Obiektowość cz. 3. Generatory
Zadanie 1
Napisz własną implementację funkcji range (o innej nazwie, np.
my_range). Funkcja ma otrzymywać na wejściu zawsze dokładnie dwa
argumenty:
początek sekwencji
koniec sekwencji
Krokiem jest zawsze 1.
Uwaga
Wykorzystanie wbudowanej funkcji range będzie traktowane jako plagiat.
Przygotowanie rozwiązania bez wykorzystania generatora to 0 punktów.
Obiektowość cz. 3. Generatory
Zadanie 1 c.d.
Na wejściu otrzymujemy:
n – w pierwszej linijce liczbę mówiącą o tym ile wierszy będziemy
przetwarzać
n krotek, gdzie zerowym elementem jest początek sekwencji, a
pierwszym koniec sekwencji
Wyjściem jest n linijek, gdzie każda linijka ma być sumą liczb z
odpowiedniej sekwencji.
Obiektowość cz. 3. Generatory
Zadanie 1 c.d.
Przykładowe wejście:
2
(0 , 1000000)
(717 , 18000)
1
2
3
Przykładowe wyjście:
499999500000
161734314
1
2
Uwaga!
Test będzie sprawdzał pamięć wykorzystaną przez program. Jeśli program
przekroczy zdefiniowany limit, sprawdzarka zwróci błąd.
Obiektowość cz. 3. Generatory
Zadanie 2
Napisz własną funkcję odpowiedzialną za przetwarzanie plików CSV
korzystając z generatora i instrukcji yield.
Uwaga!
Wykorzystanie wbudowanego modułu csv będzie traktowane jako plagiat.
Brak wykorzystania generatora i instrukcji yield – brak punktów za
zadanie.
Obiektowość cz. 3. Generatory
Zadanie 2 c.d.
Wejście jest analogiczne do zadań z Tematu 9 na moodle.
Wyjściem ma być suma sekund wszystkich połączeń w pliku.
Obiektowość cz. 3. Generatory
Zadanie 2
Przykładowe wejście:
|
./ phoneCalls . csv
1
2
./zad1 in.txt
Przykładowe wyjście:
449242
Plik CSV taki sam jak w zajęciach Temat 9 na moodle.
Obiektowość cz. 3. Generatory
Systemy kontroli wersji
Git
Uniwersytet Ekonomiczny w Poznaniu
13 maja 2014
Systemy kontroli wersji Git
Wstęp
System kontroli wersji
pozwala na śledzenie zmian, np. w kodzie źródłowym
umożliwia łączenie zmian dokonywanych w wielku plikach, przez
wiele osób, w różnym czasie.
Podział systemów kontroli wersji wg:
architektury oprogramowania
licencjonowania oprogramowania
sposobu oceny zmian
Systemy kontroli wersji Git
Rodzaje systemów wg architektury
lokalne - zapis danych jedynie na komputerze lokalnym (np. Revision
Control System)
scentralizowane - wykorzystujące architekturę klient-serwer (np.
Subversion)
rozproszone - wykorzystujące architekturę Peer-to-Peer (np. Git)
Systemy kontroli wersji Git
Git
rozproszony system kontroli wersji
twórca: Linus Torvalds
po co Git?
Umożliwia pracę wielu osób nad jednym projektem, niezależnie od
siebie. Przechowuje wszystkie wersje modyfikowanych plików,
wspiera proces scalania plików bez utraty danych oraz umożliwia
przywracanie wcześniejszych wersji plików.
wybrane projekty korzystające z Gita:
jądro Linuksa, GNOME, KDE, GIMP, Wine...
a także... Facebook
Systemy kontroli wersji Git
Git - podstawowe pojęcia
Terminal (Command line) - program służący do wykonywania
poleceń Gita.
Repozytorium (Repository) - miejsce / katalog, w którym
przechowywane są projekty (skrypty, pliki tekstowe, obrazki...). Może
być umieszczone na komputerze lokalnym lub online, np. na
GitHubie.
Kontrola wersji (Version control) - podstawowy cel Gita.
Przechowuje wszystkie wersje modyfikowanych plików (tzw.
”snapshot”), dzięki czemu żadne elementy nie zostają utracone ani
nadpisane.
Przekazanie (Commit) - podstawowe polecenie, które tworzy
”snapshot” wprowadzanych zmian. Przesłanie informacji o zmianach
do lokalnego repozytorium.
Gałąź (Branch) - praca wielu osób nad tym samym projektem jest
możliwa dzięki tworzeniu gałęzi, w których znajdują się tylko zmiany
dokonane przez daną osobę. Gałęzie są następnie scalane z głównym
katalogiem projektu.
Systemy kontroli wersji Git
Schemat działań Gita
Źródło: http: // pl. wikibooks. org/ wiki/ Plik:
Git_ data_ flow_ simplified. svg
Systemy kontroli wersji Git
Git - polecenia
Każde polecenie Git zaczynamy od wyrazu ”git”
git init - inicjuje nowe repozytorium Gita
git config - służy do konfiguracji
git help - lista poleceń; można też wywołać dla wybranego
polecenia, np. git help init
git status - pozwala sprawdzić stan repozytorium, zawartych
plików, wprowadzonych zmian
git add - nie dodaje plików do repozytorium, wskazuje co ma
zostać uwzględnione przy przekazaniu
git commit - polecenie tworzące ”snapshot” w lokalnym
repozytorium
Systemy kontroli wersji Git
Git - polecenia c.d.
Każde polecenie Git zaczynamy od wyrazu ”git”
git branch - przy pracy z wieloma osobami, tworzenie własnej
gałęzi do wprowadzania tylko swoich zmian
git checkout - umożliwia przejście w repozytorium do wybranej
gałęzi
git merge - scalenie zmian wprowadzanych w danej gałęzi z
głównym repozytorium widocznym dla wszystkich
git push - pracując na repozytorium lokalnym, ładuje wszystkie
zmiany na repozytorium online
git pull - pobiera aktualną wersję repozytorium online do
lokalnego repozytorium
Systemy kontroli wersji Git
GitHub
Jedno z największych miejsc w sieci, umożliwiające przechowywanie
projektów i równoczesną pracę wielu użytkowników przy jednym
projekcie.
Działa podobnie jak sieć społecznościowa.
W przeciwieństwie do wielu sieci społecznościowych / miejsc
udostępnianych online: wszystkie załadowane dane pozostają
własnością użytkownika.
Dostarcza graficzny interfejs do zarządzania Gitem.
https://github.com
Systemy kontroli wersji Git
Git - zadanie
Zadanie obejmuje wszystkie polecenia wykonywane podczas zajęć.
Maksymalna liczba punktów: 5.
Link do własnego repozytorium GitHub proszę wprowadzić na
Moodle w temacie 11, np.
https://github.com/bartekperkowski/IOrepo
Systemy kontroli wersji Git
Początek pracy
Założenie konta na https://github.com
Instalacja Gita na komputerze lokalnym (dostępne pod Linux,
Windows, MacOS)
dla Windows i MacOS: http://git-scm.com/downloads
dla Linux (np. Ubuntu): sudo apt-get install git
Systemy kontroli wersji Git
Początek pracy c.d.
Polecenie 1
Utwórz konto na stronie GitHub:
https://github.com
Systemy kontroli wersji Git
Wstępne ustawienia
Ustawienie domyślnej nazwy użytkownika; dowolna nazwa
informująca kto dokonywał zmian w projekcie:
git config --global user.name "Twoje imię"
Ustawienie domyślnego adresu e-mail:
git config --global user.email "Twój adres e-mail"
Uwaga: Powyższe kroki umożliwiają skonfigurowanie konta
globalnego, niezależnego od repozytorium. W celu ustawienia innego
użytkownika dla wybranego repozytorium, należy przejść do
wybranego katalogu i wywołać te same polecenia bez argumentu
”–global”.
Systemy kontroli wersji Git
Wstępne ustawienia c.d.
Polecenie 2
Z wykorzystaniem Terminala (Wiersza poleceń), ustaw w systemie konto
globalne z wybraną nazwą użytkownika oraz adresem e-mail
wykorzystanym przy zakładaniu konta na GitHub.
Systemy kontroli wersji Git
Zakładanie repozytorium
https://github.com/new
Systemy kontroli wersji Git
Zakładanie repozytorium c.d.
Polecenie 3
W systemie GitHub stwórz nowe repozytorium dla swojego projektu:
https://github.com/new
Systemy kontroli wersji Git
Utworzenie lokalnego repozytorium
Utworzenie katalogu:
mkdir "Nazwa katalogu"
Przejście do nowo utworzonego katalogu
Zainicjowanie lokalnego repozytorium Git:
git init
Utworzenie pustego pliku README: touch README.txt lub cd. >
README.txt
Systemy kontroli wersji Git
Utworzenie lokalnego repozytorium c.d.
Polecenie 4
W Dokumentach utwórz nowy katalog o tej samej nazwie co
repozytorium na GitHub.
Zainicjuj nowy katalog jako repozytorium lokalne Git i stwórz pusty plik:
README.txt.
Systemy kontroli wersji Git
Dodawanie i zatwierdzanie zmian
Sprawdzenie stanu lokalnego repozytorium:
git status
Co możemy zaobserwować?
Systemy kontroli wersji Git
Dodawanie i zatwierdzanie zmian
Sprawdzenie stanu lokalnego repozytorium:
git status
Co możemy zaobserwować?
Aby plik był ”śledzony”:
git add README.txt
Aby utworzyć ”snapshot” działań, czyli przesłać plik do
repozytorium lokalnego:
git commit -m "Mój komentarz"
Systemy kontroli wersji Git
Dodawanie i zatwierdzanie zmian c.d.
Polecenie 5
Przyjrzyj się aktualnemu statusowi repozytorium lokalnego i wprowadź
odpowiednie zmiany, aby nowo utworzony plik znalazł się w repozytorium
lokalnym.
Systemy kontroli wersji Git
Podłączanie repozytorium GitHub
Ścieżka do repozytorium GitHub:
https://github.com/bartekperkowski/IOrepo
Dodanie zdalnego adresu: git remote add mojeRepo
https://github.com/bartekperkowski/IOrepo.git
mojeRepo - nazwa odnosząca się do repozytorium na GitHub
remote - wskazuje, że mojeRepo znajduje się poza komputerem
lokalnym
Systemy kontroli wersji Git
Podłączanie repozytorium GitHub c.d.
Polecenie 6
Podłącz swoje repozytorium GitHub pod wybraną nazwą.
Sprawdzenie czy do danego repozytorium lokalnego jest podłączone
repozytorium online:
git remote -v
Systemy kontroli wersji Git
Zatwierdzanie zmian w repozytorium GitHub
Wysyłanie zmian do zdalnego repozytorium:
git push lub git push mojeRepo master
Polecenie 7
Przekaż wszystkie zmiany do zdalnego repozytorium utworzonego na
GitHub.
Systemy kontroli wersji Git
Działanie na gałęziach - wstęp
Polecenie 8
Utwórz plik kalkulator.py zawierający dowolną funkcję (można skopiować
z wcześniejszych zajęć) oraz prześlij go do repozytorium na GitHub.
Pracujesz nad plikiem kalkulator.py, w którym wprowadzasz własne
zmiany.
W trakcie pracy nad plikiem nastąpiła konieczność zmodyfikowania
funkcji istniejącej w tym pliku.
Utworzysz nową gałąź związaną tylko z wprowadzaną poprawką,
dokonasz zmian i wrzucisz zmiany do repozytorium.
Powrócisz do wcześniej wprowadzanych zmian.
Systemy kontroli wersji Git
Działanie na gałęziach
Tworzenie i przechodzenie do nowej gałęzi:
git checkout -b "Nowa gałąź"
Wersja alternatywna:
git branch "Nowa gałąź"
git checkout "Nowa gałąź"
Edycja pliku kalkulator.py
Zatwierdzenie zmian w nowej gałęzi:
git commit -a -m "Nowy komentarz"
Parametr -a pomija polecenie git add
Systemy kontroli wersji Git
Działanie na gałęziach
Polecenie 9
Napisz fragment nowej funkcji w pliku kalkulator.py i zatwierdź zmiany.
Systemy kontroli wersji Git
Działanie na gałęziach
Przełączanie do głównej gałęzi:
git checkout master
Tworzenie nowej gałęzi na potrzeby wprowadzenia poprawki:
git checkout -b "poprawka1"
Edycja pliku kalkulator.py
Zatwierdzenie zmian w nowej gałęzi:
git commit -a -m "Poprawka funkcji"
Systemy kontroli wersji Git
Działanie na gałęziach
Polecenie 10
Utwórz nową gałąź w repozytorium, dokonaj zmian w pliku kalkulator.py
(dopisz nową, działającą funkcję) i zatwierdź zmiany.
Systemy kontroli wersji Git
Scalenie gałęzi
Aby scalić nową gałąź z gałęzią master:
git checkout master
git merge poprawka1
Jaka wersja jest teraz w repozytorium na GitHub?
Systemy kontroli wersji Git
Scalenie gałęzi
Aby scalić nową gałąź z gałęzią master:
git checkout master
git merge poprawka1
Jaka wersja jest teraz w repozytorium na GitHub?
Konieczne przesłanie do repozytorium!
Systemy kontroli wersji Git
Usuwanie gałęzi
Po scaleniu gałęzi, ”poprawka1” może zostać usunięta, jako że
wskazuje na dokładnie to samo co ”master”.
Aby usunąć gałąź z lokalnego repozytorium:
git branch -d poprawka1
Systemy kontroli wersji Git
Scalenie i usuwanie gałęzi
Polecenie 11
Scal gałąź zawierającą poprawkę z gałęzią master, prześlij zmiany do
repozytorium na GitHub i usuń gałąź z poprawką.
Systemy kontroli wersji Git
Scalanie gałęzi c.d.
Po dokonaniu poprawek można powrócić do wcześniejszych zadań.
Powrót do gałęzi wcześniej utworzonej.
Edycja pliku kalkulator.py
Zatwierdzenie zmian w nowej gałęzi.
Scalenie gałęzi z gałęzią ”master”.
Systemy kontroli wersji Git
Scalenie całej pracy
Polecenie 12
Dokonaj zmian w poprzedniej gałęzi, zatwierdź, scal z gałęzią ”master” i
rezultat prześlij do repozytorium na GitHub.
Systemy kontroli wersji Git
Praca z gałęziami - przebieg procesu
master
V1
V2
Systemy kontroli wersji Git
Praca z gałęziami - przebieg procesu
master
V1
V2
V3
nowa
Systemy kontroli wersji Git
Praca z gałęziami - przebieg procesu
V1
master
popr
V2
V4
V3
nowa
Systemy kontroli wersji Git
Praca z gałęziami - przebieg procesu
master
popr
V1
V2
V4
V3
nowa
Systemy kontroli wersji Git
Praca z gałęziami - przebieg procesu
master
V1
V2
V4
V3
V5
nowa
Systemy kontroli wersji Git
Praca z gałęziami - przebieg procesu
master
V1
V2
V4
V3
V6
V5
nowa
Systemy kontroli wersji Git
Usuwanie plików
Usunięcie pliku z katalogu nie powoduje usunięcia z repozytorium!
Aby wskazać plik do usunięcia:
git rm "Przykładowy plik"
Konieczne zatwierdzenie zmian w repozytorium lokalnym.
Przesłanie informacji do repozytorium na GitHub
Systemy kontroli wersji Git
Usuwanie plików c.d.
Polecenie 13
Usuń utworzony na początku zajęć plik README.txt i zatwierdź zmiany
w repozytorium na GitHub.
Systemy kontroli wersji Git
Konflikty przy scalaniu
Co to są konflikty?
<<<<<<< HEAD : README . txt
cos
=======
cos nowego
przykladowy tekst
>>>>>>> nowa_galaz : README . txt
1
2
3
4
5
6
Należy dokonać zmiany poprzez usunięcie niewłaściwych elementów
ręcznie.
Po dokonany zmianach:
git add README.txt
Można wykorzystać narzędzie graficzne do rozwiązywania konfliktów:
git mergetool
Systemy kontroli wersji Git
Praca z gałęziami - ciekawostki
Wypisanie wszystkich istniejących gałęzi:
git branch
* oznacza aktywną gałąź
Ostatni zatwierdzony zestaw zmian:
git branch -v
Wyświetlanie gałęzi, które zostały lub nie zostały scalone:
git branch --merged oraz git branch --no-merged
Usuwanie gałęzi (nie pozwoli na usunięcie jeśli zmiany nie zostały
scalone):
git branch -d "gałąź"
Systemy kontroli wersji Git
Wielowątkowość
Uniwersytet Ekonomiczny w Poznaniu
20 maja 2014
Wielowątkowość
Pobieranie treści URL
Problem: pod określonym adresem URL znajduje się treść, którą chcemy
pobrać.
Rozwiązanie: korzystamy z modułu urllib.request i funkcji urlopen
Przykład:
from urllib . request import urlopen
content = urlopen ( ’ http :// example . com ’ ). read ()
print ( content . decode ( ’utf -8 ’ ))
Wielowątkowość
1
2
3
Pobieranie treści URL c.d.
execute typical instruction
fetch from L1 cache memory
branch misprediction
fetch from L2 cache memory
Mutex lock/unlock
fetch from main memory
send 2K bytes over 1Gbps network
read 1MB sequentially from memory
fetch from new disk location (seek)
read 1MB sequentially from disk
send packet US to Europe and back
1/1,000,000,000 sec = 1
0.5
5
7
25
100
20,000
250,000
8,000,000
20,000,000
150 ms = 150,000,000
Źródło: http://norvig.com/21-days.html#answers
Wielowątkowość
ns
ns
ns
ns
ns
ns
ns
ns
ns
ns
ns
Pobieranie treści URL c.d.
Pobieranie treści przez HTTP zazwyczaj zajmuje sporo czasu...
Może nie ma to dużego znaczenia przy pobieraniu jednego linka, ale
jeśli jest ich kilka:
from urllib . request import urlopen
for i in range (10):
content = urlopen ( ’ http :// example . com ’ ). read ()
print ( ’ Pobrano URL nr ’ , i )
Wielowątkowość
1
2
3
4
Pobieranie treści URL c.d.
Limit czasu wywołania:
from urllib . request import urlopen
1
2
linki = [
3
’ http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / a ’ ,
4
’ http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / b ’ ,
5
’ http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / c ’ ,
6
’ http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / d ’ ,
7
]
8
for link in linki :
9
try :
10
x = urlopen ( link , timeout =0.8). read ()
11
print ( ’ Pobrano ’ , x . decode ( ’utf -8 ’) , ’z ’ , link 12
)
except Exception as e :
13
print ( ’ Nie udalo sie pobrac ’ , link )
14
Wielowątkowość
Konstrukcja with ... as ...
plik1 = open ( ’ ala . txt ’ , ’w ’ , encoding = ’utf -8 ’)
plik1 . write ( ’ Ala ma kota ’)
1
2
3
plik2 = open ( ’ ala . txt ’ , ’r ’)
print ( plik2 . readlines ())
4
5
Gdzie w tym przykładzie jest błąd?
Wielowątkowość
Konstrukcja with ... as ... (c.d.)
with open ( ’ ala . txt ’ , ’w ’ , encoding = ’utf -8 ’) as plik1 :
plik1 . write ( ’ Ala ma kota ’)
1
2
3
with open ( ’ ala . txt ’ , ’r ’) as plik2 :
print ( plik2 . readlines ())
Wielowątkowość
4
5
Konstrukcja with ... as ... (c.d.)
Domyślnie „zamyka” różnego rodzaju zasoby.
Dzięki niej kod może być bardziej czytelny.
Przydatne w korzystaniu z plików, połączeń z bazą danych,
korzystaniem z wielowątkowości...
Wielowątkowość
Obliczenia wielowątkowe
Co to są wątki?
Kiedy wielowątkowe wykonywanie programu jest użyteczne?
Wielowątkowość
Przykład na rozgrzewkę – sleepsort
Na wejściu podane w jednej linii liczby, np.:
3 2 6 4 1 8
1
Na wyjściu podane jedna pod drugą posortowane liczby, np.:
1
2
3
4
6
8
1
2
3
4
5
6
Wykorzystaj funkcję time.sleep oraz wielowątkowość
Wielowątkowość
Przykład na rozgrzewkę – sleepsort
import threading
import time
1
2
3
def wyswietl ( x ):
time . sleep ( x )
print ( x )
4
5
6
7
liczby = [ int ( x ) for x in input (). split ()]
8
9
for x in liczby :
t = threading . Thread ( target = wyswietl , args =[ x ])
t . start ()
Wielowątkowość
10
11
12
Zadanie na rozgrzewkę
Rozszerz sleepsort tak, aby na końcu wyświetlała się suma wszystkich
liczb.
Wielowątkowość
Problemy w tym podejściu
Trzeba w jakiś sposób przechwycić rezultat wywołania.
Czy wyswietl może zwracać rezultat?
A może zapisywać liczby w jakimś słowniku?
Trzeba wprost napisać kod, który „poczeka”, aż wątki zakończą
pracę.
Wątek ma metodę join, która powoduje czekanie, aż wątek skończy
pracę, ale czy powinniśmy się tym zajmować? Czy powinny nas
interesować takie niskopoziomowe rzeczy?
Te problemy są na tyle złożone w przedstawionym podejściu do
wielowątkowości, że nie będziemy ich rozwiązywać. Zamiast tego
pokażemy, jak je obejść, bo od Pythona 3.2 jest na to prosty sposób:
moduł concurrent.futures.
https://docs.python.org/3/library/concurrent.futures.html
Wielowątkowość
Sleepsort 2
from concurrent . futures import T h r e a d P o o l E x e c u t o r
import time
1
2
3
def wyswietl ( x ):
time . sleep ( x )
print ( x )
4
5
6
7
liczby = [ int ( x ) for x in input (). split ()]
8
9
with T hr e a d P o o l E x e c u t o r ( max_workers = len ( liczby )) as e :
for x in liczby :
e . submit ( wyswietl , x )
Wielowątkowość
10
11
12
Rozwiązanie zadania na rozgrzewkę
from concurrent . futures import T h r e a d P o o l E x e c u t o r
from concurrent . futures import as_completed
import time
1
2
3
4
def wyswietl ( x ):
time . sleep ( x )
return x
5
6
7
8
liczby = [ int ( x ) for x in input (). split ()]
9
10
with T hr e a d P o o l E x e c u t o r ( max_workers = len ( liczby )) as e :
futures = { e . submit ( wyswietl , x ) for x in liczby }
suma = 0
for f in as_completed ( futures ):
print ( f . result ())
suma += f . result ()
print ( suma )
Wielowątkowość
11
12
13
14
15
16
17
Zadanie 1
Na wejściu w pierwszej linijce znajduje się liczba (n), a w kolejnych n
linijkach podane są adresy URL.
Na wyjściu powinny być wyświetlone wszystkie adresy URL zgodnie
z kolejnością ich wczytania. Adresy URL, których wczytywanie zajęło
zbyt dużo czasu powinny zostać pominięte (przyjmij timeout jako
1.5 sekundy).
Jeśli zadanie nie zostanie wykonane wielowątkowo, przekroczony
zostanie dopuszczalny czas na sprawdzarce.
Wielowątkowość
Zadanie 1 (c.d.)
Przykładowe wejście:
8
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / a
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / b
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / c
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / d
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / e
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / f
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / g
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / h
1
2
3
4
5
6
7
8
9
Przykładowe wyjście:
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / b
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / h
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / g
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / a
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / d
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / e
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / c
Wielowątkowość
1
2
3
4
5
6
7
Zadanie 2
Na wejściu w pierwszej linijce znajduje się liczba (n), a w kolejnych n
linijkach podane są adresy URL.
Na wyjściu powinna być wyświetlona suma wszystkich liczb, które
znajdują się pod podanymi adresami URL. Adresy URL, których
wczytywanie zajęło zbyt dużo czasu powinny zostać pominięte
(przyjmij timeout jako 1.5 sekundy).
Jeśli zadanie nie zostanie wykonane wielowątkowo, przekroczony
zostanie dopuszczalny czas na sprawdzarce.
Wielowątkowość
Zadanie 2 (c.d.)
Przykładowe wejście:
8
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / a
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / b
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / c
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / d
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / e
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / f
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / g
http : / / 1 5 0 . 2 5 4 . 3 6 . 7 8 / inzynieria / h
1
2
3
4
5
6
7
8
9
Przykładowe wyjście:
74
1
Wielowątkowość
Komunikacja z bazami danych (MySQL)
Graficzne interfejsy użytkownika (Tkinter)
Uniwersytet Ekonomiczny w Poznaniu
28 maja 2014
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Python i graficzny interfejs użytkownika
Programowanie GUI może odbywać się za pomocą różnych bibliotek:
GTK
Qt
wxWidgets
TkInter
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
TkInter – Prosty program
from tkinter import *
from tkinter import ttk
1
2
3
def pressed ():
print ( ’ Wykonuje funkcje ... ’)
4
5
6
root = Tk ()
button = Button ( root ,
text = ’ Kliknij na mnie ! ’ , command = pressed )
button . pack ( pady =20 , padx = 20)
root . mainloop ()
7
8
9
10
11
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Prosty program 2
from tkinter import *
from tkinter import ttk
1
2
3
def pressed ():
print ( z a w a r t o s c _ p o l a _ t e k s t o w e g o . get ())
4
5
6
root = Tk ()
7
8
z a w a r t o s c _ p o l a _ t e k s t o w e g o = StringVar ()
pole_tekstowe = ttk . Entry ( root , width =7 ,
textvariable = z a w a r t o s c _ p o l a _ t e k s t o w e g o )
button = Button ( root ,
text = ’ Kliknij na mnie ! ’ , command = pressed )
pole_tekstowe . pack ( pady =20 , padx = 20)
button . pack ( pady =20 , padx = 20)
root . mainloop ()
9
10
11
12
13
14
15
16
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
TkInter – Przechowywanie wartości
Wartości, które są pobierane lub wyświetlane w widgetach TkInter mają
specjalne typy, np.:
IntVar
StringVar
Powód: domyślne proste typy w Pythonie są niemutowalne.
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Praktyczny przykład
Patrz plik jednostki.py na moodle
W pliku znajduje się dużo dokumentacji, dokładnie wyjaśniającej
działanie programu.
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Zadanie na rozgrzewkę
Zmień program jednostki.py tak, aby :
otrzymane cale były zaokrąglane do jedności
w zależności od tego, jaki wyszedł wynik, ma się zmieniać etykieta
przy wyniku (ta, która teraz zawsze ma wartość ”cali”), czyli:
jeśli cyfra dziesiątek jest inna niż 1, a cyfra jedności to 2,3 lub 4,
etykietą ma być ”cale”
w przeciwnym wypadku, etykieta ma mieć wartość ”cali”
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Komunikacja z bazami danych
Python Database API Specification v2.0
http://legacy.python.org/dev/peps/pep-0249/
specyfikacja API, zgodnie z którą powinny być przygotowywane
biblioteki do komunikacji z bazami danych
łatwe przejście pomiędzy różnymi bibliotekami i różnymi bazami
danych
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
MySQL
relacyjny system zarządzania bazami danych (RDBMS),
dostępny na licencji wolnego oprogramowania GNU General Public
Licence,
rozwijany przez firmę Oracle,
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
PhpMyAdmin
http://ego.kie.ue.poznan.pl/mysql-admin/
user: inz opr
hasło: inz opr
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Biblioteki do komunikacji z MySQL
Mysql Connector
MySQLdb (na razie tylko Python 2)
pymysql
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
pymysql - prosty przykład
import pymysql
1
2
connection = pymysql . connect ( host = ’ ego . kie . ue . poznan . pl ’ ,
port = 8080 , user = ’ inz_opr ’ , passwd = ’ inz_opr ’ ,
database = ’ i n z y n i e r i a _ o p r o g r a m o w a n i a ’)
cursor = connection . cursor ()
cursor . execute ( ’ select * from polaczenia ; ’)
for i in cursor :
print ( i )
3
4
5
6
7
8
9
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Kursor
Kursor jest to kontrolna struktura pośrednicząca w wykonywaniu zapytań
i pozwalająca na iterowanie po ich wynikach.
dla jednego połączenia z bazą możemy stworzyć wiele kursorów
dzięki temu do jednego połączenia z bazą możemy wysyłać wiele
różnych zapytań i łatwo operować na różnych kolekcjach
otrzymanych wyników
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Dłuższy przykład – ładowanie danych do bazy
Patrz plik data_upload.py
za pomocą tego skryptu załadowano do bazy dane do zadania
domowego
UWAGA: ze względu na ustawienia bazy danych skrypt zwróci błąd
(brak uprawnień użytkownika do zapisu)
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Zmiany w bazie i zatwierdzanie wyników
podobnie jak w przypadku zapisywania do pliku, wprowadzanie
danych do bazy powinno być zakończone faktycznym
potwierdzeniem wprowadzenia zmian
aby to zrobić:
na obiekcie połączenia używamy funkcji commit
używamy menedżera kontekstu with... as...
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Wstęp do zadań
w bazie danych przechowywane są analogiczne dane co w zajęciach z
CSV
zadanie polega na odpytywaniu bazy zgodnie z zadanymi kryteriami
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Zadanie 1
Wejściem są linijki odpowiedzialne za podłączenie się do bazy
danych:
1
2
3
4
5
host
port
użytkownik
hasło
baza danych
Baza danych ma strukturę analogiczną do bazy
inzynieria_oprogramowania, dostępną na serwerze
ego.kie.ue.poznan.pl
Wyjściem ma być suma czasów trwania wszystkich połączeń (w
sekundach)
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Zadanie 1
Przykładowe wejście
ego . kie . ue . poznan . pl
8080
inz_opr
inz_opr
inzynieria_oprogramowania
1
2
3
4
5
Przykładowe wyjście
104956
1
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Zadanie 2
wejście analogiczne do zadania 1 + dodatkowe dwie krotki:
krotka z identyfikatorami nadawców
krotka z identyfikatorami odbiorców
na wyjściu mają być zwrócone dwie krotki, gdzie pierwsza to suma
sekund połączeń dla poszczególnych nadawców podanych w krotce
wyjściowej, a druga to czas ostatniego połączenia odebranego przez
odbiorców z drugiej krotki (w formacie ISO, skorzystaj z metody
datetime.isoformat())
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Zadanie 2
Przykładowe wejście
ego . kie . ue . poznan . pl
8080
inz_opr
inz_opr
inzynieria_oprogramowania
(47 , 209 , 392)
(5 , 42)
1
2
3
4
5
6
7
Przykładowe wyjście
(2099 , 2073 , 2058)
( ’ 2006 -06 -01 T05 :16:00 ’ , ’ 2006 -06 -01 T07 :34:00 ’)
1
2
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Testy jednostkowe
Uniwersytet Ekonomiczny w Poznaniu
3 czerwca 2014
Testy jednostkowe
Testowanie
W praktyce oznacza napisanie kodu (niezależnie od kodu aplikacji), który
uruchamia testy umożliwiające wykrycie ewentualnych błędów.
Przykładowe rodzaje błędów wykrywanych podczas testowania:
Syntax errors - niezamierzone błędy językowe.
Logical errors - błędy w implementowanych algorytmach, np.
pobieranie niewłaściwego indeksu z listy.
Większe, czy systematycznie występujące błędy - np. zawieszanie się
aplikacji przy konkretnych danych wejściowych.
Testy jednostkowe
Testowanie jednostkowe
Wychwycenie każdego z błędów jest możliwe poprzez właściwe
przygotowanie procedur testowych.
Testowanie jednostkowe polega na sprawdzeniu wybranego fragmentu
kodu w wyizolowanym środowisku. Dzięki temu inne operacje w kodzie
aplikacji nie mają wpływu na testowany fragment. Testy jednostkowy
pozwalają sprawdzać:
całe moduły
pojedyncze klasy
funkcje
Testy jednostkowe
Moduł unittest
Do przeprowadzania testów jednostkowych wykorzystywany jest
moduł unittest.
Moduł ten dostarcza zestaw narzędzi wspomagających budowę i
przeprowadzanie testów.
Nazwa każdej metody w teście poprzedzona test_
Metoda setUp() wywoływana jest przed każdym testem i pozwala na
wykonanie określonych operacji przed uruchomieniem testu, np.
ustawienie zmiennych
unittest.main()
uruchamia testy
Testy jednostkowe
Przykładowy plik
def czy_pierwsza ( liczba ):
for element in range ( liczba ):
if liczba % element == 0:
return False
return True
1
2
3
4
5
6
def n a s t e p n a _ p i e r w s z a ( liczba ):
index = liczba
while True :
index += 1
if czy_pierwsza ( index ):
print ( index )
7
8
9
10
11
12
Testy jednostkowe
Przykładowy test
import unittest
from pierwsze import czy_pierwsza
1
2
3
class Tes tPierws zych ( unittest . TestCase ):
4
5
def test_czy_piec ( self ):
self . assertTrue ( czy_pierwsza (5))
6
7
8
if __name__ == ’ __main__ ’:
unittest . main ()
9
10
Testy jednostkowe
Przykładowy test
Dlaczego test wyrzuca taki błąd?
Testy jednostkowe
Przykładowy plik poprawiony
def czy_pierwsza ( liczba ):
for element in range (2 , liczba ):
if liczba % element == 0:
return False
1
2
3
4
5
return True
6
7
def n a s t e p n a _ p i e r w s z a ( liczba ):
index = liczba
while True :
index += 1
if czy_pierwsza ( index ):
print ( index )
8
9
10
11
12
13
Testy jednostkowe
Przykładowy test 2
import unittest
from pierwsze import czy_pierwsza
1
2
3
class Tes tPierws zych ( unittest . TestCase ):
4
5
def test_czy_piec ( self ):
self . assertTrue ( czy_pierwsza (5))
6
7
8
def t es t_ c zy _c zt e ry ( self ):
self . assertFalse ( czy_pierwsza (4) , msg = ’4 nie
jest liczba pierwsza ! ’)
9
10
11
12
if __name__ == ’ __main__ ’:
unittest . main ()
13
14
Testy jednostkowe
Metody weryfikujące wartości
assertEqual(a,b) - porównanie
assertEqual(1+1,2)
assertTrue()
wartości ’a’ z oczekiwaną ’b’, np.
- sprawdzenie czy prawda
assertFalse()
- sprawdzenie czy fałsz
Więcej: https://docs.python.org/3.3/library/unittest.html
Testy jednostkowe
Zadanie
Na Moodle znajduje się plik z metodami, które mają testować
poprawność Biblioteki (wypożyczanie książek - biblioteka 1).
Należy zaimplementować te metody zgodnie z komentarzami w
pliku.
Przygotowany plik testowy należy wykorzystać przy zadaniach
dostępnych w quizie na Moodle:
W pytaniach zawarte są pliki, na których mają zostać
przeprowadzone testy.
Dla każdego pliku (pytania) należy zaznaczyć te odpowiedzi, dla
których testy zakończyły się pozytywnie.
Za poprawnie rozwiązane zadania jest do zdobycia maksymalnie 6
punktów.
Testy jednostkowe
http://www.tutorialspoint.com/python/python_classes_objects.htm
PROGRAMY:
1.
Nawiasy
a=str(input())
alista=list(a)
o='('
c=')'
ileo=alista.count(o)
ilec=alista.count(c)
2.
3.
if ileo==ilec:
po=alista.index(o)
pc=alista.index(c)
if po<pc:
alista.reverse()
ko=alista.index(o)
kc=alista.index(c)
if kc<ko:
print("True")
else:
print("False")
else:
print("False")
else:
print("False")
Pesel
pesel=input()
sk=(pesel[0]*1)+(pesel[1]*3)+(pesel[2]*7)+(pesel[3]*9)+(pesel[4]*1)+(pesel[5]*3)+(pesel[6]*7)+(pesel[7
]*9)+(pesel[8]*1)+(pesel[9]*3)
dm=sk%10
kontrolna=(10-dm)%10
if kontrolna==pesel[10]:
check="1"
else:
check="0"
print(check)
2.1 anagram
wyraz_wzorcowy=input()
wyraz1=input()
wyraz2=input()
wyraz3=input()
wyraz4=input()
wyraz5=input()
w_w=sorted(wyraz_wzorcowy)
l=[wyraz1,wyraz2,wyraz3,wyraz4,wyraz5]
l2=[]
for i in l:
if w_w == sorted(i):
l2.append(i)
print(sorted(l2))
4.
3.1 silnia/newton
from math import factorial
nk=input().split()
n=int(nk[0])
k=int(nk[1])
newton=int((factorial(n)/(factorial(k)*factorial(n-k))))
print(newton)
5.
3.2 monety
kwota = int(input())
n = input().split()
nominaly=[]
for i in n:
z=int(i)
nominaly.append(z)
p=[1]
j=kwota*[0]
sposoby = p+j
for i in nominaly:
for j in range(i,kwota+1):
sposoby[j]=sposoby[j]+sposoby[j-i]
d=sposoby[kwota]
print(d)
6.
4.1 pączki
a. Kasi
osoby = input().split()
imiona = input().split()
n=[]
for i in osoby:
a=(imiona.count(i))
print(a)
n.append((i,a))
n.sort(key=lambda x:x[1],reverse=True)
print(n)
b.
Moje
names=input()
doughnuts=input()
names=names.split()
doughnuts=doughnuts.split()
count=[]
z=[]
for i in range(0,len(names)):
count.append(doughnuts.count(names[i]))
z.append([count[i],names[i]])
z.sort()
z.reverse()
result=[]
for j in range(0,len(z)):
z[j].reverse()
z[j]=tuple(z[j])
result.append(z[j])
print(result)
7.
5.1 figury
import math
class Kolo:
suma1=0
def __init__(self,promien):
self.promien=promien
def polekola(self):
pole1=round(math.pi*self.promien**2,2)
self.suma1=self.suma1+pole1
class Prostokat:
suma2=0
def __init__(self,dlugosc,szerokosc):
self.dlugosc=dlugosc
self.szerokosc=szerokosc
def poleprostokata(self):
pole2=round(self.dlugosc*self.szerokosc,2)
self.suma2=self.suma2+pole2
class Trojkat:
suma3=0
def __init__(self,ramie1,ramie2,ramie3):
self.ramie1=ramie1
self.ramie2=ramie2
self.ramie3=ramie3
def poletrojkata(self):
p=(self.ramie1+self.ramie2+self.ramie3)/2
pole3=round(math.sqrt((p*(p-self.ramie1)*(p-self.ramie2)*(p-self.ramie3))),2)
self.suma3=self.suma3+pole3
iloscfigur=float(input())
listafigur = []
a=0
b=0
c=0
for i in range(int(iloscfigur)):
figura = input().split()
if len(figura)is 1:
liczba1=Kolo(float(figura[0]))
liczba1.polekola()
a=round(a+liczba1.suma1,2)
elif len(figura)is 2:
liczba2=Prostokat(float(figura[0]),float(figura[1]))
liczba2.poleprostokata()
b=round(b+liczba2.suma2,2)
elif len(figura) is 3:
liczba3=Trojkat(float(figura[0]),float(figura[1]),float(figura[2]))
liczba3.poletrojkata()
c=round(c+liczba3.suma3,2)
8.
suma=round((a+b+c),2)
print(suma)
5.2 wynagrodzenie
class Wynagrodzenie:
suma=0
def __init__(self,imie,brutto):
self.imie=imie
self.brutto=int(brutto)
def wynagrodzenienetto(self):
if self.brutto > 1599:
sus=round(round(self.brutto*0.0976,2)+round(self.brutto*0.015,2)+round(self.brutto*0.0245,2),2)
podswymskl=round(self.brutto-sus,2)
sklubezzdr=round(podswymskl*0.09,2)
dop=round(podswymskl*0.0775,2)
poz=round(self.brutto-139.25-sus,0)
zpdpo=round((poz*0.18)-46.33,2)
zpddp=round(zpdpo-dop,0)
n=round(self.brutto-sus-sklubezzdr-zpddp,2)
netto='%.2f' %n
skp=round(self.brutto*0.0976,2)+round(self.brutto*0.065,2)+round(self.brutto*0.0193,2)+round(self.br
utto*0.0245,2)+round(self.brutto*0.001,2)
kp=round(self.brutto+skp,2)
sklobciazprac='%.2f' %skp
kosztypracodawcy='%.2f' %kp
self.suma=self.suma+kp
print(self.imie,netto,sklobciazprac,kosztypracodawcy)
else:
print(self.imie,0)
9.
iloscpracownikow=int(input())
k=[]
for i in range(iloscpracownikow):
pracownik=input().split()
k.append(pracownik)
s=0
for j in k:
liczba1=Wynagrodzenie(j[0],int(j[1]))
liczba1.wynagrodzenienetto()
s=(s+liczba1.suma)
su='%.2f' %s
print(su)
6.1 dodawanie książki
class Ksiazka:
def __init__(self,lista):
self.lista=lista
def dodaj_egzemplarz_ksiazki(self):
pojedynczalista=set(self.lista)
informacjaoksiazce=[]
for i in pojedynczalista:
tytul=i[0]
autor=i[1]
liczbaegzemplarzy=self.lista.count(i)
informacjaoksiazce.append((tytul,autor,liczbaegzemplarzy))
informacjaoksiazce.sort(key=lambda x:x[0],reverse=False)
for j in informacjaoksiazce:
print (j)
liczbaksiazek=int(input())
listaksiazek=[]
for a in range(liczbaksiazek):
ksiazka=eval(input())
tytulksiazki=ksiazka[0]
autorksiazki=ksiazka[1]
listaksiazek.append((tytulksiazki,autorksiazki))
ksiazka1=Ksiazka(listaksiazek)
ksiazka1.dodaj_egzemplarz_ksiazki()
10. 6.2 Biblioteka
"""class Ksiazka:
def __init__(self, tytul, autor):
pass
class Egzemplarz:
def __init__(self, rok_wydania, ksiazka):
pass"""
class Biblioteka:
dostepne_ksiazki=[]
def __init__(self):
self.ksiazka=dict()
def dodaj_egzemplarz_ksiazki(self, tytul, autor, rok_wydania):
self.dostepne_ksiazki.append(tytul)
return True
def __pobierz_czytelnika(self, nazwisko):
czytelnik=Czytelnik()
def wypozycz(self, nazwisko, tytul):
czytelnik=Czytelnik()
return czytelnik.wypozycz(nazwisko,tytul)
def oddaj(self, nazwisko, tytul):
czytelnik=Czytelnik()
return czytelnik.oddaj(nazwisko,tytul)
class Czytelnik(Biblioteka):
limit = 3
wypozyczone_ksiazki=[]
lista_wypozyczonych_ksiazek=[]
oddane=[]
def __init__(self):
self.nazwisko=dict()
def wypozycz(self, nazwisko,tytul):
self.wypozyczone_ksiazki.append(nazwisko)
self.lista_wypozyczonych_ksiazek.append((nazwisko,tytul))
lista_nazwisk=set(self.wypozyczone_ksiazki)
lista_nazwiska_tytul=set(self.lista_wypozyczonych_ksiazek)
if tytul in self.dostepne_ksiazki:
for l in lista_nazwisk:
if (self.wypozyczone_ksiazki.count(l) <= self.limit):
for m in lista_nazwiska_tytul:
if self.lista_wypozyczonych_ksiazek.count(m)<2:
self.dostepne_ksiazki.remove(tytul)
return True
else:
self.wypozyczone_ksiazki.remove(l)
self.lista_wypozyczonych_ksiazek.remove(m)
return False
else:
self.wypozyczone_ksiazki.remove(l)
self.lista_wypozyczonych_ksiazek.pop()
return False
else:
self.wypozyczone_ksiazki.pop()
self.lista_wypozyczonych_ksiazek.pop()
return False
def oddaj(self, nazwisko, tytul):
self.oddane.append((nazwisko,tytul))
for n in self.oddane:
if n in self.lista_wypozyczonych_ksiazek:
self.wypozyczone_ksiazki.remove(nazwisko)
self.lista_wypozyczonych_ksiazek.remove(n)
self.oddane.remove(n)
self.dostepne_ksiazki.append(tytul)
return True
else:
return False
biblioteka = Biblioteka()
czytelnik = Czytelnik()
for i in range(int(input())):
t = eval(input())
if t[0] == "dodaj":
print(biblioteka.dodaj_egzemplarz_ksiazki(t[1], t[2], t[3]))
elif t[0] == "wypozycz":
print(biblioteka.wypozycz(t[1], t[2]))
elif t[0] == "oddaj":
print(biblioteka.oddaj(t[1], t[2]))
11. 7.1 drzewo
class Drzewo:
lista_wynikow=[]
lista_usuwanych=[]
def __init__(self, lista_krotek: list):
self.lista_krotek=lista_krotek
def pobierz_nadkoncepty(self, wierzcholek: str) -> list:
for i in wierzcholek:
self.lista_wynikow.append(i)
for j in self.lista_krotek:
if i==j[1]:
self.lista_wynikow.append(j[0])
self.lista_usuwanych.append(j[0])
drzewo.petla_nieskonczona(i)
print(self.lista_wynikow,self.lista_usuwanych)
self.lista_wynikow=[]
self.lista_usuwanych=[]
def petla_nieskonczona(self,wierzcholek):
for m in self.lista_krotek:
if m[1] in self.lista_usuwanych:
self.lista_wynikow.append(m[0])
self.lista_usuwanych.pop()
self.lista_usuwanych.append(m[0])
drzewo.petla_nieskonczona(wierzcholek)
else:
pass
drzewo_input = eval(input())
drzewo = Drzewo(drzewo_input)
zapytania = drzewo.pobierz_nadkoncepty(eval(input()))
12. 7.2 odleglosc drzewo
class Drzewo:
lista_wynikow=[]
lista_usuwanych=[]
nadwezly1=[]
nadwezly2=[]
lista_miar=[]
lista_miar_prostych=[]
lista_miar_potegowych=[]
def __init__(self, lista_krotek: list):
self.lista_krotek=lista_krotek
def pobierz_nadkoncepty1(self, wierzcholek1:str)->list:
self.nadwezly1=[]
self.nadwezly1.append(wierzcholek1)
for j in self.lista_krotek:
if wierzcholek1==j[1]:
self.nadwezly1.append(j[0])
self.lista_usuwanych.append(j[0])
drzewo.petla_nieskonczona1(wierzcholek1)
self.lista_usuwanych=[]
def pobierz_nadkoncepty2(self, wierzcholek2:str)->list:
self.nadwezly2=[]
self.nadwezly2.append(wierzcholek2)
for l in self.lista_krotek:
if wierzcholek2==l[1]:
self.nadwezly2.append(l[0])
self.lista_usuwanych.append(l[0])
drzewo.petla_nieskonczona2(wierzcholek2)
self.lista_usuwanych=[]
def petla_nieskonczona1(self,wierzcholek):
for m in self.lista_krotek:
if m[1] in self.lista_usuwanych:
self.nadwezly1.append(m[0])
self.lista_usuwanych.pop()
self.lista_usuwanych.append(m[0])
drzewo.petla_nieskonczona1(wierzcholek)
else:
pass
def petla_nieskonczona2(self,wierzcholek: list)->list:
for m in self.lista_krotek:
if m[1] in self.lista_usuwanych:
self.nadwezly2.append(m[0])
self.lista_usuwanych.pop()
self.lista_usuwanych.append(m[0])
drzewo.petla_nieskonczona2(wierzcholek)
else:
pass
def oblicz_odleglosc(self, lista_zapytan: list) -> list:
for k in lista_zapytan:
miara=k[0]
wierzcholek1=k[1]
wierzcholek2=k[2]
drzewo.pobierz_nadkoncepty1(wierzcholek1)
drzewo.pobierz_nadkoncepty2(wierzcholek2)
if miara=='prosta':
drzewo.miara_prosta_licz_odleglosc(self.nadwezly1,self.nadwezly2)
elif miara=='potegowa':
drzewo.miara_potegowa_licz_odleglosc(self.nadwezly1,self.nadwezly2)
else:
pass
return self.lista_miar
def miara_prosta_licz_odleglosc(self, nadwezly1:list, nadwezly2:list) -> int:
miara_prosta=0
self.lista_miar_prostych=[]
for o in nadwezly1:
for p in nadwezly2:
if o == p:
odleglosc1_mpr=nadwezly1.index(o)
odleglosc2_mpr=nadwezly2.index(p)
miara_prosta=int(odleglosc1_mpr+odleglosc2_mpr)
self.lista_miar_prostych.append(miara_prosta)
if len(self.lista_miar_prostych)==1:
self.lista_miar.append(miara_prosta)
else:
pass
else:
pass
def miara_potegowa_licz_odleglosc(self, nadwezly1:list, nadwezly2:list) -> int:
miara_potegowa=0
self.lista_miar_potegowych=[]
for q in nadwezly1:
for r in nadwezly2:
if q == r:
odleglosc1_mpg=((2**nadwezly1.index(q))-1)
odleglosc2_mpg=((2**nadwezly2.index(r))-1)
miara_potegowa=int(odleglosc1_mpg+odleglosc2_mpg)
self.lista_miar_potegowych.append(miara_potegowa)
if len(self.lista_miar_potegowych)==1:
self.lista_miar.append(miara_potegowa)
else:
pass
else:
pass
drzewo_input = eval(input())
drzewo = Drzewo(drzewo_input)
zapytania =print(drzewo.oblicz_odleglosc(eval(input())))
13. 8.1 biblioteka 1
import datetime
class Ksiazka:
lista_nowych=[]
informacjaoksiazce=[]
def __init__(self,lista,data_graniczna):
self.lista=lista
self.data_graniczna=data_graniczna
def dodaj_egzemplarz_ksiazki(self):
format_daty_granicznej=datetime.date(data_graniczna[0],data_graniczna[1],data_graniczna[2])
for i in self.lista:
tytul=i[0]
autor=i[1]
data_wprowadzenia=i[3]
data_dodania=datetime.date(data_wprowadzenia[0],data_wprowadzenia[1],data_wprowadzenia[2])
if data_dodania>format_daty_granicznej:
self.lista_nowych.append((i[0],i[1]))
else:
pass
bez_powtorzen=set(self.lista_nowych)
for j in bez_powtorzen:
tyt=j[0]
aut=j[1]
liczbaegzemplarzy=self.lista_nowych.count(j)
self.informacjaoksiazce.append((tyt,aut,liczbaegzemplarzy))
for k in self.informacjaoksiazce:
print(k)
liczbaksiazek=int(input())
listaksiazek=[]
for a in range(liczbaksiazek):
ksiazka=eval(input())
listaksiazek.append(ksiazka)
data_graniczna=eval(input())
ksiazka1=Ksiazka(listaksiazek,data_graniczna)
ksiazka1.dodaj_egzemplarz_ksiazki()
14. 8.2 biblioteka 2
import datetime
class Ksiazka:
def __init__(self, tytul, autor):
self.tytul = tytul
self.autor = autor
self.egzemplarze = []
class Egzemplarz:
def __init__(self, rok_wydania, ksiazka,data_dodania):
self.rok_wydania = rok_wydania
self.ksiazka = ksiazka
self.data_dodania=data_dodania
self.wypozyczony = False
class Czytelnik:
limit = 3
kara_za_nieoddanie=0
kara_za_przetrzymanie=0
lista_dat=[]
def __init__(self, nazwisko,data_wypozyczenia,data_zapytania):
self.nazwisko = nazwisko
self.data_wypozyczenia=data_wypozyczenia
self.data_zapytania=data_zapytania
self.wypozyczone = {}
def wypozycz(self, egzemplarz,data_wypozyczenia,data_zapytania):
tytul = egzemplarz.ksiazka.tytul
kara_za_nieoddanie=0
if Czytelnik.limit > len(self.wypozyczone) and tytul not in self.wypozyczone.keys():
egzemplarz.wypozyczony = True
self.wypozyczone[tytul] = egzemplarz
self.lista_dat.append((self.nazwisko,tytul,data_wypozyczenia))
self.kara_za_nieoddanie=0.5*((self.data_zapytania-data_wypozyczenia).days-7)
return True
else:
return False
def oddaj(self, tytul,data_oddania):
try:
kara_za_przetrzymanie=0
self.wypozyczone.pop(tytul).wypozyczony = False
for x in self.lista_dat:
if (x[0],x[1])==(self.nazwisko,tytul):
self.kara_za_przetrzymanie=0.5*((data_oddania-x[2]).days-7)
return True
except KeyError:
return False
class Biblioteka:
def __init__(self):
self.__ksiazki = {}
self.__czytelnicy = {}
self.lista_kar_za_przetrzymanie=[]
self.lista_kar_za_nieoddanie=[]
def dodaj_egzemplarz_ksiazki(self, tytul, autor, rok_wydania,data_dodania):
try:
ksiazka = self.__ksiazki[tytul]
except KeyError:
ksiazka = Ksiazka(tytul, autor)
self.__ksiazki[tytul] = ksiazka
ksiazka.egzemplarze.append(Egzemplarz(rok_wydania, ksiazka,data_dodania))
return True
def raport_ksiazek(self):
lista = []
for k in self.__ksiazki.values():
lista.append((k.tytul, k.autor, len(k.egzemplarze)))
return sorted(lista, key = lambda t: t[0])
def dostepne_egz(self, tytul):
try:
return [ egz for egz in self.__ksiazki[tytul].egzemplarze if not egz.wypozyczony ]
except KeyError:
return []
def __pobierz_czytelnika(self, nazwisko,data_wypozyczenia,data_zapytania):
try:
return self.__czytelnicy[nazwisko]
except KeyError:
nowy = Czytelnik(nazwisko,data_wypozyczenia,data_zapytania)
self.__czytelnicy[nazwisko] = nowy
return nowy
def wypozycz(self, nazwisko, tytul,data_wypozyczenia,data_zapytania):
try:
egzemplarz = self.dostepne_egz(tytul)[0]
czytelnik = self.__pobierz_czytelnika(nazwisko,data_wypozyczenia,data_zapytania)
a= (czytelnik.wypozycz(egzemplarz,data_wypozyczenia,data_zapytania))
print(a)
if (czytelnik.kara_za_nieoddanie>0) and (a==True):
self.lista_kar_za_nieoddanie.append((nazwisko,tytul,czytelnik.kara_za_nieoddanie))
except IndexError:
return False
def oddaj(self, nazwisko, tytul,data_oddania,data_zapytania):
czytelnik = self.__pobierz_czytelnika(nazwisko,data_oddania,data_zapytania)
b=czytelnik.oddaj(tytul,data_oddania)
print(b)
if (b==True):
self.lista_kar_za_przetrzymanie.append((nazwisko,tytul,czytelnik.kara_za_przetrzymanie))
def kary(self):
lista=[]
lista_kar_n=[]
lista_kar_p=[]
for n in self.lista_kar_za_przetrzymanie:
for m in self.lista_kar_za_nieoddanie:
if (m[0],m[1]) == (n[0],n[1]):
self.lista_kar_za_nieoddanie.remove(m)
for o in self.lista_kar_za_nieoddanie:
if o[2] > 0:
lista_kar_n.append((o[0],o[2]))
for p in self.lista_kar_za_przetrzymanie:
if p[2] > 0:
lista_kar_p.append((p[0],p[2]))
lista=lista_kar_n+lista_kar_p
lista_nazwisk=[]
for z in lista:
lista_nazwisk.append(z[0])
pojedyncza_lista_nazwisk=set(lista_nazwisk)
ostatczna_lista=[]
for d in pojedyncza_lista_nazwisk:
kara=0
for e in lista:
if d ==e[0]:
kara+=e[1]
ostatczna_lista.append((d,(kara)))
ostatczna_lista.sort()
for r in ostatczna_lista:
print(r)
biblioteka = Biblioteka()
lista_czynnosci=[]
for t in range(int(input())):
lista_czynnosci.append(eval(input()))
data_zapytania_krotka=eval(input())
data_zapytania =
datetime.date(data_zapytania_krotka[0],data_zapytania_krotka[1],data_zapytania_krotka[2])
for i in lista_czynnosci:
if i[0] == "dodaj":
print(biblioteka.dodaj_egzemplarz_ksiazki(i[1], i[2], i[3],i[4]))
elif i[0] == "wypozycz":
datawyp = datetime.date(i[3][0],i[3][1],i[3][2])
biblioteka.wypozycz(i[1], i[2],datawyp,data_zapytania)
elif i[0] == "oddaj":
dataoddaj=datetime.date(i[3][0],i[3][1],i[3][2])
biblioteka.oddaj(i[1], i[2],dataoddaj,data_zapytania)
biblioteka.kary()
15. 9.1
import csv
import operator
separator=input()
wejscie=input()
plik_csv = open(wejscie, 'r')
czytaj = csv.reader(plik_csv, delimiter=separator)
liczba_polaczen_nadawca=dict()
liczba_polaczen_odbiorca=dict()
for i, rekord in enumerate(czytaj):
if i==0:
naglowek=rekord
else:
if rekord[0] in liczba_polaczen_nadawca.keys():
liczba_polaczen_nadawca[rekord[0]]+=1
else:
liczba_polaczen_nadawca[rekord[0]]=1
if rekord[1] in liczba_polaczen_odbiorca.keys():
liczba_polaczen_odbiorca[rekord[1]]+=1
else:
liczba_polaczen_odbiorca[rekord[1]]=1
lista_krotek_nadawca= [(int(i[0]),i[1]) for i in liczba_polaczen_nadawca.items()]
lista_krotek_odbiorca= [(int(i[0]),i[1]) for i in liczba_polaczen_odbiorca.items()]
posortowana_liczba_nadawcow_po_kluczach=sorted(lista_krotek_nadawca,
key=operator.itemgetter(0))
posortowana_liczba_nadawcow_po_wartosciach=sorted(posortowana_liczba_nadawcow_po_kluczach,
key=operator.itemgetter(1),reverse=True)
posortowana_liczba_odbiorcow_po_kluczach=sorted(lista_krotek_odbiorca,
key=operator.itemgetter(0))
posortowana_liczba_odbiorcow_po_wartosciach=sorted(posortowana_liczba_odbiorcow_po_kluczach,
key=operator.itemgetter(1),reverse=True)
max_nadawca=str(posortowana_liczba_nadawcow_po_wartosciach[0][0])
max_nadawca_sekund=0
max_odbiorca=str(posortowana_liczba_odbiorcow_po_wartosciach[0][0])
max_odbiorca_sekund=0
plik_csv=open(wejscie,'r')
czytaj = csv.reader(plik_csv, delimiter=separator)
for rekord in czytaj:
if rekord[0]==max_nadawca:
max_nadawca_sekund +=int(rekord[3])
if rekord[1]==max_odbiorca:
max_odbiorca_sekund +=int(rekord[3])
print(max_nadawca+":", max_nadawca_sekund)
print(max_odbiorca+":", max_odbiorca_sekund)
16. 9.2
import csv
import operator
import datetime
separator=input()
wejscie=input()
plik_csv = open(wejscie, 'r')
czytaj = csv.reader(plik_csv, delimiter=separator)
liczba_polaczen_nadawca=dict()
liczba_polaczen_odbiorca=dict()
liczba_nadajnikow=dict()
liczba_dni=dict()
for i, rekord in enumerate(czytaj):
if i==0:
naglowek=rekord
else:
if rekord[0] in liczba_polaczen_nadawca.keys():
liczba_polaczen_nadawca[rekord[0]]+=1
else:
liczba_polaczen_nadawca[rekord[0]]=1
if rekord[1] in liczba_polaczen_odbiorca.keys():
liczba_polaczen_odbiorca[rekord[1]]+=1
else:
liczba_polaczen_odbiorca[rekord[1]]=1
if rekord[4] in liczba_nadajnikow.keys():
liczba_nadajnikow[rekord[4]]+=1
else:
liczba_nadajnikow[rekord[4]]=1
if rekord[2] in liczba_dni.keys():
liczba_dni[rekord[2]]+=1
else:
liczba_dni[rekord[2]]=1
lista_krotek_nadawca= [(int(i[0]),i[1]) for i in liczba_polaczen_nadawca.items()]
lista_krotek_odbiorca= [(int(i[0]),i[1]) for i in liczba_polaczen_odbiorca.items()]
lista_krotek_nadajniki= [(int(i[0]),i[1]) for i in liczba_nadajnikow.items()]
lista_krotek_dni= [(i[0]) for i in liczba_dni.items()]
day=[]
for k in lista_krotek_dni:
data=(datetime.datetime(int(k[0:4]),int(k[4:6]),int(k[6:9]),int(k[9:11]),int(k[11:13])))
day.append(data)
posortowana_liczba_nadawcow_po_kluczach=sorted(lista_krotek_nadawca,
key=operator.itemgetter(0))
posortowana_liczba_nadawcow_po_wartosciach=sorted(posortowana_liczba_nadawcow_po_kluczach,
key=operator.itemgetter(1),reverse=True)
posortowana_liczba_odbiorcow_po_kluczach=sorted(lista_krotek_odbiorca,
key=operator.itemgetter(0))
posortowana_liczba_odbiorcow_po_wartosciach=sorted(posortowana_liczba_odbiorcow_po_kluczach,
key=operator.itemgetter(1),reverse=True)
posortowana_liczba_nadajnikow_po_kluczach=sorted(lista_krotek_nadajniki,
key=operator.itemgetter(0))
posortowana_liczba_nadajnikow_po_wartosciach=sorted(posortowana_liczba_nadajnikow_po_kluczac
h, key=operator.itemgetter(1),reverse=True)
posortowana_liczba_dni=sorted(day)
max_nadawcy=[]
for a in posortowana_liczba_nadawcow_po_wartosciach:
max_nadawcy.append(str(a[0]))
if len(max_nadawcy)>9:
break
max_odbiorcy=[]
for b in posortowana_liczba_odbiorcow_po_wartosciach:
max_odbiorcy.append(str(b[0]))
if len(max_odbiorcy)>9:
break
max_nadajnik=str(posortowana_liczba_nadajnikow_po_wartosciach[0][0])
max_nadajnik_ilosc=(posortowana_liczba_nadajnikow_po_wartosciach[0][1])
plik_csv=open(wejscie,'r')
czytaj = csv.reader(plik_csv, delimiter=separator)
max_nadawca=str(posortowana_liczba_nadawcow_po_wartosciach[0][0])
max_nadawc=int(posortowana_liczba_nadawcow_po_wartosciach[0][1])
max_nadawca_sekund=0
lista_nadawcow=[]
for rekord in czytaj:
if rekord[0]==max_nadawca:
max_nadawca_sekund +=int(rekord[3])
srednie_polaczenia_wychodzace=round(max_nadawca_sekund/(posortowana_liczba_nadawcow_po_w
artosciach[0][1]),2)
ostatnia_wartosc=posortowana_liczba_dni.pop()
pierwsze=posortowana_liczba_dni[0]
dni=round((ostatnia_wartosc.day-pierwsze.day)+1,2)
srednia_liczba_polaczen=round((posortowana_liczba_nadawcow_po_wartosciach[0][1])/dni,2)
print(max_nadawcy)
print(max_odbiorcy)
print((max_nadajnik, max_nadajnik_ilosc))
print(srednie_polaczenia_wychodzace,srednia_liczba_polaczen)
17. 10.1
def my_range(poczatek,koniec):
while poczatek < koniec:
yield poczatek
poczatek+=1
wynik=[]
for i in range(int(input())):
poczatek_koniec=eval(input())
wejscie = my_range(poczatek_koniec[0],poczatek_koniec[1])
wynik.append(sum(wejscie))
for j in wynik:
print(j)
18. 10.2
import operator
separator=input()
wejscie=input()
plik = open(wejscie, 'r')
def csv(plik,separator):
for i in plik:
wiersz = i.split(separator)[3]
yield wiersz
wynik=[]
suma=0
zadanie=csv(plik,separator)
for j in zadanie:
wynik.append(j)
for k in(wynik[1:]):
suma+=int(k)
print(suma)
19. 12.1
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import as_completed
import time
from urllib.request import urlopen
ile_liczb=int(input())
lista_adresow=[]
for adres in range(ile_liczb):
adres=input()
lista_adresow.append(adres)
def wyswietl(x):
a = urlopen(x, timeout=1.5).read()
a.decode('utf-8')
return x
with ThreadPoolExecutor(max_workers = len(lista_adresow)) as e:
futures = {e.submit(wyswietl, x) for x in lista_adresow}
for f in as_completed(futures):
try:
print(f.result())
except:
pass
20. 12.2
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import as_completed
from urllib.request import urlopen
ile_liczb=int(input())
lista_adresow=[]
for adres in range(ile_liczb):
adres=input()
lista_adresow.append(adres)
def wyswietl(x):
a = urlopen(x, timeout=1.5).read()
return a.decode('utf-8')
suma=0
with ThreadPoolExecutor(max_workers = len(lista_adresow)) as e:
futures = {e.submit(wyswietl, x) for x in lista_adresow}
for f in as_completed(futures):
try:
suma+=int(f.result())
except:
pass
print(suma)
21. 13.1
import pymysql
connection = pymysql.connect(host=input(),
port = int(input()), user=input(), passwd=input(),
database=input())
cursor = connection.cursor()
cursor.execute('select * from polaczenia;')
suma=0
for i in cursor:
suma+=i[3]
print(suma)
22. 13.2
import pymysql
import datetime
connection = pymysql.connect(host=input(),
port = int(input()), user=input(), passwd=input(),
database=input())
id_nadawcy=eval(input())
id_odbiorcy=eval(input())
lista_nad=[]
max_odb=[]
cursor = connection.cursor()
for nadawca in id_nadawcy:
cursor.execute('select * from polaczenia;')
suma=0
for i in cursor:
if i[0]==nadawca:
suma+=i[3]
lista_nad.append(suma)
for odbiorca in id_odbiorcy:
cursor.execute('select * from polaczenia;')
lista_odb=[]
for i in cursor:
if i[1]==odbiorca:
lista_odb.append(i[2].isoformat())
max_odb.append(max(lista_odb))
suma_polaczen=tuple(lista_nad)
ostatnie_pol=tuple(max_odb)
print(suma_polaczen)
print(ostatnie_pol)
23. Zajecia zad1
import random
class Bank:
def __init__(self):
self.konta =dict()
def __pobierzkonto(self, nr_konta):
return self.konta[nr_konta]
def zaloz_konto(self, roczna_stopa, kapitalizacja):
numer = random.randint(10000000000000000000000000,99999999999999999999999999)
if kapitalizacja == 'dzienna':
konto = KontoKapDzienna(numer,0,roczna_stopa)
elif kapitalizacja == 'miesieczna':
konto = KontoKapMiesieczna(numer,0,roczna_stopa)
pass
else:
print('Jakas literowka')
return False
self.konta[numer]=konto
return numer
def wplac (self, nr_konta, kwota):
konto=self.__pobierzkonto(nr_konta)
konto.wplac(kwota)
def przelej (self, nr_konta_nad, nr_konta_odb, kwota):
konto_nad = self.__pobierzkonto(nr_konta_nad)
konto_nad.wplac(-kwota)
konto_odb = self.__pobierzkonto(nr_konta_odb)
konto_odb.wplac(kwota)
def nastepny_miesiac(self):
for nr_konta in self.konta:
self.konta[nr_konta].nastepny_miesiac()
def wypisz_stan_kont(self):
for nr_konta in self.konta:
print ('Konto o numerze',nr_konta, 'ma stan', self.konta[nr_konta].kwota)
print ('--------------')
class Konto:
def __init__(self, numer, kwota, roczna_stopa):
self.numer=numer
self.kwota=kwota
self.roczna_stopa=roczna_stopa
def nastepny_miesiac(self):
pass
def wplac (self,kwota):
self.kwota +=kwota
#te poniżej dziedziczą od KONTO !!!
class KontoKapDzienna(Konto):
def nastepny_miesiac(self):
for i in range(30):
self.kwota= round((1+self.roczna_stopa/360)*self.kwota,2)
class KontoKapMiesieczna(Konto):
def nastepny_miesiac(self):
self.kwota= round((1+self.roczna_stopa/12)*self.kwota,2)
bank = Bank ()
k1 = bank.zaloz_konto (0.02, "dzienna")
k2 = bank.zaloz_konto (0.02, "miesieczna")
bank.wypisz_stan_kont()
bank.wplac (k1, 1000)
bank.wplac (k2, 1000)
bank.wypisz_stan_kont()
bank.nastepny_miesiac ()
bank.wypisz_stan_kont()
bank.przelej (k1 , k2 , 100)
bank.wypisz_stan_kont()
## zad dom
##a = "("Quo vadis", "Henryk Sienkiewicz", 2011)
##krotka = eval(a)
# krotki przekształcamy na obiekty
#
24. Zajecia zad2
a. def wypisz(arg1:str) -> str:
return "wypisany str to " + arg1
b. 2
def mnozenie (a: int , b: int ) -> int :
"""
print( mnozenie.__annotations__ )
anns = mnozenie.__annotations__
if type (a) != anns ['a'] or type (b) != anns ['b']:
raise Exception (' Bledne typy parametrow ! ')
else:
"""
return a*b
try:
print( mnozenie ( 6 ,2))
except Exception as ex:
print(ex)
try:
print( mnozenie ( ' ojej ' ,2))
except Exception as ex:
pass
try:
print( mnozenie ( 6.0,2.0))
except Exception as ex:
pass
c. 3
import math
def heron(a ,b ,c ):
""" Oblicza pole trojkata wg wzoru Herona
a ,b ,c dlugosci bokow trojkata
>> heron (3 ,4 ,5)
6.0
"""
s = (a+b+c )/2
return math.sqrt (s*(s-a)*(s-b)*(s-c))
if __name__ == '__main__':
print(heron.__doc__ )
print(heron (3 ,4 ,5))
Komunikacja z bazami danych (MySQL)
Graficzne interfejsy użytkownika (Tkinter)
Uniwersytet Ekonomiczny w Poznaniu
28 maja 2014
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Python i graficzny interfejs użytkownika
Programowanie GUI może odbywać się za pomocą różnych bibliotek:
GTK
Qt
wxWidgets
TkInter
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
TkInter – Prosty program
from tkinter import *
from tkinter import ttk
1
2
3
def pressed ():
print ( ’ Wykonuje funkcje ... ’)
4
5
6
root = Tk ()
button = Button ( root ,
text = ’ Kliknij na mnie ! ’ , command = pressed )
button . pack ( pady =20 , padx = 20)
root . mainloop ()
7
8
9
10
11
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Prosty program 2
from tkinter import *
from tkinter import ttk
1
2
3
def pressed ():
print ( z a w a r t o s c _ p o l a _ t e k s t o w e g o . get ())
4
5
6
root = Tk ()
7
8
z a w a r t o s c _ p o l a _ t e k s t o w e g o = StringVar ()
pole_tekstowe = ttk . Entry ( root , width =7 ,
textvariable = z a w a r t o s c _ p o l a _ t e k s t o w e g o )
button = Button ( root ,
text = ’ Kliknij na mnie ! ’ , command = pressed )
pole_tekstowe . pack ( pady =20 , padx = 20)
button . pack ( pady =20 , padx = 20)
root . mainloop ()
9
10
11
12
13
14
15
16
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
TkInter – Przechowywanie wartości
Wartości, które są pobierane lub wyświetlane w widgetach TkInter mają
specjalne typy, np.:
IntVar
StringVar
Powód: domyślne proste typy w Pythonie są niemutowalne.
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Praktyczny przykład
Patrz plik jednostki.py na moodle
W pliku znajduje się dużo dokumentacji, dokładnie wyjaśniającej
działanie programu.
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Zadanie na rozgrzewkę
Zmień program jednostki.py tak, aby :
otrzymane cale były zaokrąglane do jedności
w zależności od tego, jaki wyszedł wynik, ma się zmieniać etykieta
przy wyniku (ta, która teraz zawsze ma wartość ”cali”), czyli:
jeśli cyfra dziesiątek jest inna niż 1, a cyfra jedności to 2,3 lub 4,
etykietą ma być ”cale”
w przeciwnym wypadku, etykieta ma mieć wartość ”cali”
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Komunikacja z bazami danych
Python Database API Specification v2.0
http://legacy.python.org/dev/peps/pep-0249/
specyfikacja API, zgodnie z którą powinny być przygotowywane
biblioteki do komunikacji z bazami danych
łatwe przejście pomiędzy różnymi bibliotekami i różnymi bazami
danych
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
MySQL
relacyjny system zarządzania bazami danych (RDBMS),
dostępny na licencji wolnego oprogramowania GNU General Public
Licence,
rozwijany przez firmę Oracle,
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
PhpMyAdmin
http://ego.kie.ue.poznan.pl/mysql-admin/
user: inz opr
hasło: inz opr
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Biblioteki do komunikacji z MySQL
Mysql Connector
MySQLdb (na razie tylko Python 2)
pymysql
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
pymysql - prosty przykład
import pymysql
1
2
connection = pymysql . connect ( host = ’ ego . kie . ue . poznan . pl ’ ,
port = 8080 , user = ’ inz_opr ’ , passwd = ’ inz_opr ’ ,
database = ’ i n z y n i e r i a _ o p r o g r a m o w a n i a ’)
cursor = connection . cursor ()
cursor . execute ( ’ select * from polaczenia ; ’)
for i in cursor :
print ( i )
3
4
5
6
7
8
9
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Kursor
Kursor jest to kontrolna struktura pośrednicząca w wykonywaniu zapytań
i pozwalająca na iterowanie po ich wynikach.
dla jednego połączenia z bazą możemy stworzyć wiele kursorów
dzięki temu do jednego połączenia z bazą możemy wysyłać wiele
różnych zapytań i łatwo operować na różnych kolekcjach
otrzymanych wyników
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Dłuższy przykład – ładowanie danych do bazy
Patrz plik data_upload.py
za pomocą tego skryptu załadowano do bazy dane do zadania
domowego
UWAGA: ze względu na ustawienia bazy danych skrypt zwróci błąd
(brak uprawnień użytkownika do zapisu)
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Zmiany w bazie i zatwierdzanie wyników
podobnie jak w przypadku zapisywania do pliku, wprowadzanie
danych do bazy powinno być zakończone faktycznym
potwierdzeniem wprowadzenia zmian
aby to zrobić:
na obiekcie połączenia używamy funkcji commit
używamy menedżera kontekstu with... as...
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Wstęp do zadań
w bazie danych przechowywane są analogiczne dane co w zajęciach z
CSV
zadanie polega na odpytywaniu bazy zgodnie z zadanymi kryteriami
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Zadanie 1
Wejściem są linijki odpowiedzialne za podłączenie się do bazy
danych:
1
2
3
4
5
host
port
użytkownik
hasło
baza danych
Baza danych ma strukturę analogiczną do bazy
inzynieria_oprogramowania, dostępną na serwerze
ego.kie.ue.poznan.pl
Wyjściem ma być suma czasów trwania wszystkich połączeń (w
sekundach)
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Zadanie 1
Przykładowe wejście
ego . kie . ue . poznan . pl
8080
inz_opr
inz_opr
inzynieria_oprogramowania
1
2
3
4
5
Przykładowe wyjście
104956
1
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Zadanie 2
wejście analogiczne do zadania 1 + dodatkowe dwie krotki:
krotka z identyfikatorami nadawców
krotka z identyfikatorami odbiorców
na wyjściu mają być zwrócone dwie krotki, gdzie pierwsza to suma
sekund połączeń dla poszczególnych nadawców podanych w krotce
wyjściowej, a druga to czas ostatniego połączenia odebranego przez
odbiorców z drugiej krotki (w formacie ISO, skorzystaj z metody
datetime.isoformat())
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Zadanie 2
Przykładowe wejście
ego . kie . ue . poznan . pl
8080
inz_opr
inz_opr
inzynieria_oprogramowania
(47 , 209 , 392)
(5 , 42)
1
2
3
4
5
6
7
Przykładowe wyjście
(2099 , 2073 , 2058)
( ’ 2006 -06 -01 T05 :16:00 ’ , ’ 2006 -06 -01 T07 :34:00 ’)
1
2
Komunikacja z bazami danych (MySQL) Graficzne interfejsy użytkownika (
Download