- ... ?
- Bo można rozwiązywać własne problemy
- Bo można grzebać w open-source'owych aplikacjach
- Bo można złapać dobrą pracę w przyszłości
- Bo mozna być jeszcze większym nerdem niż się jest
Bo programowanie jest ciekawym i rozwijajacym zajęciem
- Bo jest prosty i elegancki
- Bo jest popularny
- Bo jest dobrze wpierany
- Bo jest do niego dużo bibliotek
- Linuksowy terminal i jakiś edytor tekstowy (np. gedit)
- Interpreter: python lub, lepiej, ipython
- Zintegrowane środowisko programistyczne: PyCharm <https://www.jetbrains.com/pycharm/>
Python 2 (2.7) vs Python 3 (3.2)
print("Hello world!")
Plik z programem:
- Stwórz gedit hello_world.py
print("Hello world!")- Uruchom przez interpreter: python hello_world.py lub python3 hello_world.py
Program jako plik wykonywalny:
- Stwórz (edytuj) plik: gedit hello_world.py
#!/usr/bin/env python3 print("Hello world!")- Nadaj prawa do wykonywania: chmod a+x hello_world.py
- Uruchom jako skrypt: ./hello_world.py
Programowanie jak matematyka:
2 + 2 2 - 2 2 * 2 2 / 2 2 % 2 2 ** 2
Programowanie jak matematyka:
2 + 2 # dodawanie 2 - 2 # odejmowanie 2 * 2 # mnożenie 2 / 2 # dzielenie 2 % 2 # reszta z dzielenia - dzielenie modulo 2 ** 2 # potęgowanie
Operatory dla napisów (string-ów)
"a" + "b" "x" * 10 "a %s c" % ("b")
Operatory dla napisów (string-ów)
"a" + "b" # konkatenacja "x" * 10 # zwielokrotnianie "a %s c" % ("b") # podstawianie - α-konwersja
- Utwórz plik z przykładowymi użyciami operatorów: gedit ops.py
#!/usr/bin/env python3 2 ** 10 "x" * 100- Nadaj prawa do uruchomienia i uruchom
- ... ?
A teraz?
#!/usr/bin/env python3 print(2 ** 10) print("x" * 100)
Przypisywanie wartości zmiennej:
x = 5 y = 2
Stosowanie zmiennej w wyrażeniach:
x + 1 3 * x ** 2 + y "x" * x
Przypisywanie zmiennej do innej zmiennej:
x = y
Inkrementacja (dodawanie 1 do zmiennej):
x = x + 1
Specjalny operator, który robi to samo:
x += 1
Podobne operatory:
x -= 1 # to samo co: x = x - 1 x *= 2 # to samo co: x = x * 2 x /= 3 # to samo co: x = x / 3 x %= 4 # to samo co: x = x % 4 s += "a" # to samo co: s = s + "a"
Mamy dane dwie zmienne: x i y o dowolnych wartościach. Np.
x = "sól" y = "pieprz"Napisz program który podmieni wartości tych zmiennych między sobą.
T.j. na wyjściu:
- x ma taką wartość jaką y miało na wejściu
- y ma taką wartość jaką x miało na wejściu
Wypisz na ekran zawartość x i y po podmienieniu.
x = "sól" y = "pieprz" tmp = x x = y y = tmp print("x =", x, "y =", y)
Zmienne całkowitoliczbowe (integer):
i = 5 type(i) # -> int
Zmienne napisowe (string):
s = "hello world" type(s) # -> str
Zmienne zmiennoprzecinkowe (floating-point):
f = 1.5 f = 1. f = .5 type(f) # -> float
Zmienne prawda/fałsz (algebra Boole'a, Boolean):
b = True b = False type(b) # -> bool
str(5) # -> "5" float(5) # -> 5.0 int(5.2) # -> 5 bool(5) # -> True
Dla jakiej wartości int-a, float-a, string-a typ bool przyjmuje wartość False?
Wyrażenie jeżeli (if statement)
if x == 5: print(x, "is 5")
Czemu operator ma dwa znaki a nie jeden?
A co jeśli nie? (else statement)
if x == 5: print(x, "is 5") else: print(x, "is not 5")
Dodatkowe warunki (else-if):
if x == 5: print(x, "is 5") elif x == 7: print(x, "is 7") else: print(x, "is neither 5 nor 7")
Więcej warunków...
if x == 5: print(x, "is 5") elif x == 7: print(x, "is 7") elif x == 9: print(x, "is 9") else: print(x, "is neither 5, 7 nor 9")
Zagnieżdżanie warunków:
if x == 5: print(x, "is 5") if y == 5: print (y, "is y") elif x == 7: print(x, "is 7") if y == 5: print (y, "is 7") elif x == 9: print(x, "is 9") if y == 9: print (y, "is 9") else: print(x, "is neither 5, 7 nor 9") print(y, "is some number")
Operatory logiczne:
x == y # x równe y x < y # x mniejsze niż y x > y # x większe niż y x <= y # x mniejsze lub równe y x >= y # x większe lub równe y x != y # x nierówne y
Czy operatory działają na napisach i bool-ach?
Złożone wyrażenia:
if x > 0 and y > 0: print("a") if x <= 0 or y <= 0: print("b")
Zaprzeczenie:
if not z % 10: print("c") if not z % 10 and not z % 3: print("d")
Mamy daną zmienną: x o typie int i dowolnej wartości, np.
- Napisz program który:
- wypisuje na ekran fizz jeśli x jest podzielne przez 3
- wypisuje na ekran buzz jeśli x jest podzielne przez 5
- (więc wypisuje na ekran fizzbuzz jeśli x jest podzielne przez 3 i 5)
- wypisuje na ekran x jeśli x nie jest podzielne przez 3 ani 5
(Czyli klasyczny fizzbuzz.)
output = "" if x % 3 == 0: output += "fizz" if x % 5 == 0: output += "buzz" if not x % 3 == 0 and not x % 5 == 0: output += str(x) print output
Powtarzanie bloku kodu:
x = 0 while x < 100: print(x) x += 1
Powtarzaj instrukcje:
print(x) x += 1
... tak długo, jak x < 100 jest prawdziwe.
Powtarzanie bloku kodu:
x = 0 while x < 100: print(x) x += 1
Zagnieżdżanie pętli:
x = 0 y = 0 while x < 10: while y < 10: print(".") y += 1 x += 1
Ile kropek będzie wyświetlonych?
Mamy daną zmienną: n typu int o wartości 1-20
Napisz program który rysuje trójkąt (prostokątny, równoramienny) o wysokości n z gwiazdek.
Np. dla n = 6:
* ** *** **** ***** ******Hint:
help(print) print("x", end="")
Dwię pętle:
n = 6 i = 1 while i <= n: j = 0 while j < i: print("*", end="") j += 1 print() i += 1
Mnożenie napisów:
n = 6 i = 0 while i < n: print("*" * (i + 1)) i += 1
Specjalny typ do przechowywania wielu wartości:
li = [1, 2, 3, 4] ls = ["a", "b", "c"] lm = [1, "a", 2, "c",] ll = [[1, 2], [3, 4], [5,6]] le = [] type(li) type(ls) type(lm) type(le)
Lista pamięta kolejność elementów. Elementy mogą być dowolnego typu.
Wyciąganie elementów listy:
l = ["asia", "basia", "casia", "dasia"] l[0] # -> "asia" l[1] # -> "basia" l[2] # -> "casia" l[3] # -> "dasia" len(l) # -> 4
Indeksowanie od 0 - typowe dla programowania.
Jak wyciągnąć ostatni element? (klasycznie i pythonowo)
Dana jest lista l zawierająca integery. Np. :
l = [4, 6, 7, 13, 21, 42, 144]
Napisz program który wypisze każdy z elementów listy l w nowej lini. Np.:
4 6 7 13 21 42 144
Iteracja po wszystkich elementach listy za pomocą pętli while:
l = [4, 6, 7, 13, 21, 42, 144] i = 0 while i < len(l): print(l[i]) i += 1
Pętla for iteruje po strukturach danych takich jak listy:
l = [4, 6, 7, 13, 21, 42, 144] for element in l: print(element)
Dana jest lista l zawierająca listy, które zawierają integery. Np. :
l = [[2], [4, 8], [16, 32, 64]]
Napisz program który wypisze każdą liczbę w nowej lini. Np.:
2 4 8 16 32 62
l = [[2], [4, 8], [16, 32, 64]] for sublist in l: for element in sublist: print(element)
Wyciąganie podlisty więcej niż jednego elementu z listy:
l = [1, 2, 3, 4, 5, 6] l[0:3] # -> [1, 2, 3] l[3:6] # -> [4, 5, 6] l[7:9] # -> [] l[:3] # -> [1, 2, 3] l[3:] # -> [4, 5, 6] l[:] # -> [1, 2, 3, 4, 5, 6] l[-2:] # -> [5, 6]
Podlista jest zupełnie nową listą, kopią.
Dana jest lista l zawierająca integery. Np. :
l = [2, 4, 8, 16, 32]
Napisz program który wypisze wszystkie prefiksy tej listy. Prefix to taka podlista jakiejś innej listy, która zaczyna się tak samo jak ta inna lista.
[] [2] [2, 4] [2, 4, 8] [2, 4, 8, 16] [2, 4, 8, 16, 32]
l = [2, 4, 8, 16, 32] i = 0 while i < len(l): print(l[:i + 1]) i += 1
Dodawanie do listy:
l = [1, 2, 3] l = l + [5, 6]
Podmiana elementu:
l[3] = -1
Usuwanie z listy:
del l[0]
Dana jest lista l zawierająca integery. Np. :
l = [1, 2, 3, 4, 5]
Napisz program który stworzy nową listę r, która wypisze będzie zawierać kwadraty wszysztkich liczb z l. Na końcu wypisz listę r.
Oczekiwane wyjście dla wejścia powyżej:
[1, 4, 9, 16, 25]
l = [1, 2, 3, 4, 5] r = [] for e in l: r += [e ** 2] print(r)
Listy dostarczają różnych metod do wykonywania działań na ich zawartości:
- Sortowanie listy:
l.sort()- Odwracanie listy:
l.reverse()- Liczenie elementów w liście:
l.count(4)- Dokładanie na/sciąganie z końca listy:
l.append(4) l.pop() # -> 4
Napiszemy pętle która dla dowolnej listy l zawierającej liczby, stworzy analogiczną listę zawierającą wartości bezwzględne. Np. :
l = [1, -1, 2, -2, 3, -3] r = [1, 1, 2, 2, 3, 3]
l = [1, -1, 2, -2, 3, -3] r = [] for e in l: if e < 0: r += [-e] else: r += [e]
A teraz ... napiszemy jeszcze jedną pętle która dla dowolnej listy l2 zawierającej liczby, stworzy analogiczną listę zawierającą wartości bezwzględne. Np. :
l2 = [13, -12, 21, -20, 31, -32] r2 = [13, 12, 21, 20, 31, 32]
l = [1, -1, 2, -2, 3, -3] l2 = [1, -1, 2, -2, 3, -3] r = [] for e in l: if e < 0: r += [-e] else: r += [e] r2 = [] for e in l2: if e < 0: r += [-e] else: r += [e]
Zamykamy blok kodu wewnątrz funkcji:
def abs_list(l): r = [] for e in l: if e < 0: r += [-e] else: r += [e] return r
Ważne elementy:
- słowo kluczowe def do definiowania funkcji
- nazwa funkcji abs_list
- lista parametrów (w nawiasach) - tutaj tylko jeden paramet l, ale może być mniej, lub więcej, oddzielonych przecinkami
- dwukropek, wcięcie, kod, ...
- słowo kluczowe return które zwraca wartość (chociaż ogólnie funkcja nie musi zwracać wartości)
Wywoływanie funkcji (aka aplikacja funkcji):
def abs_list(l): r = [] for e in l: if e < 0: r += [-e] else: r += [e] return r l = [1, -1, 2, -2, 3, -3] l2 = [1, -1, 2, -2, 3, -3] r = abs_list(l) r2 = abs_list(l2)
Czy zmienna zdefiniowana wewnątrz funkcji jest widoczna na zewnątrz funkcji?
def f(): inner = 44 f() print(inner)
Czy zmienna zdefiniowana na zewnątrz funkcji jest widoczna na zewnątrz funkcji?
outer = 6 def g(): print(outer) def h(): outer = 7 g() h()
Wykonywanie metod:
li = [1, 2, 3] def foo(): li.append(4) foo() print(li)
Wykonywanie metod:
x = 0 l = [1, 2, 3] def foo(x, l): x = 1 l.append(4) foo(x, l) print(x, l)
def square_poly(x, a, b, c): return a * x ** 2 + b * x + c for e in [1, 2, 3, 4, 5, 6]: y = square_poly(e, 2, -4, 2) print(y) for e in [1, 2, 3, 4, 5, 6]: y = square_poly(a=2, b=-4, c=2, x=e) print(y)
def square_poly(x, a=0, b=0, c=0): return a * x ** 2 + b * x + c for e in [1, 2, 3, 4, 5, 6]: y = square_poly(e, b=2) print(y)
Funkcja - jak w matematyce:
- deterministyczna
- zwraca wynik przez return
- nie ma efektów ubocznych: nie modyfikuje zmiennych na zewnątrz funkcji, nie wyświetla nic na ekran itp.
Procedura:
- nie + w/w
Tyle do powiedzenia, tak mało czasu!
def fun(n): def more_fun(e="", i=0): if (i < n): return [e] + more_fun(i+1) else: return [] return more_fun magic = fun magic(5)(".")
Napisz funkcję która przyjmuje jeden argument-listę. Każdy element listy to średnia ocen jakiegoś studenta <2.0, 5.0>. Napisz (i przetestuj) funkcję która wystawia ocenę końcową - zwraca listę gdzie dla każdej oceny na liście wejściowej, na liście wyjściowej:
- dla przedziału <2.0, 3.0) jest 2.0
- dla przedziału <3.0, 3.5) jest 3.0
- dla przedziału <3.5, 4.0) jest 3.5
- dla przedziału <4.0, 4.5) jest 4.0
- dla przedziału <4.5, 5.0) jest 4.5
- dla wartości 5.0 jest 5.0
Good place to start:
def grade(averages): pass averages = [2.5, 3.1, 3.6, 4.0, 4.9, 5.0] grades = grade(averages) print(grades)
def grade(averages): r = [] for e in averages: if e < 3.: r += [2.] elif e < 3.5: r += [3.] elif e < 4.: r += [3.5] elif e < 4.5: r += [4.] elif e < 5: r += [4.5] else: r += [5] return r averages = [2.5, 3.1, 3.6, 4.0, 4.9, 5.0] grades = grade(averages) print(grades)
Jeszcze jedna przydatna struktura: słownik asocjacyjny:
d = {1: "a", 2: "b", 3: "b"}
Ważne elementy:
- Nawiasy klamrowe
- Zbiór kluczy (1, 2, 3) - klucze są unikalne, kolejność jest zapominana
- Wartości ("a", "b", "c")
Używanie:
d[1] # -> "a" d[4] = "d" del d[1] type(d) # -> dict 1 in d # -> False 2 in d # -> True
Przeglądanie zawartości:
d = {"a": 1, "b": 2, "c": 3, "d": 4} d.keys() # -> [2, 3, 4] d.values() # -> ["b", "c", "d"] for key in d: print(d[key])
Zastosowanie à la funkcja:
grade_labels = { 2.: "ndst", 3.: "dop", 3.5: "dop+", 4.0: "db", 4.5: "db+", 5.0: "bdb" } averages = [2.5, 3.1, 3.6, 4.0, 4.9, 5.0] grades = grade(averages) r = [] for e in grades r += [grade_labels[e]]
Zastosowanie à la struktura danych:
grade_labels = { "inf71746": [3., 4., 5.], "inf71748": [4., 3., 5.], "inf71749": [2., 3., 4.], "inf71750": [3., 2., 3.], "inf71751": [5., 3., 4.], }
Napisz funkcję która przyjmuje napis jako argument i zwraca słownik, który zawiera histogram tego napisu. Histogram mówi nam ile razy każda litera wystąpiła w tym napisie.
Np. dla napisu "ala ma kota" histogram to
histogram = { "a": 4, "l": 1, "m": 1, "k": 1, "o": 1, "t": 1, " ": 2, }
Informacja pomocnicza - napisy można traktować jak listę napisów zawierających pojedyncze znaki.
for letter in "ala ma kota" print(letter)
def histogram(text): histogram = {} for letter in text: if letter in histogram: histogram[letter] += 1 else: histogram[letter] = 1 return histogram
Stwórz plik plik.txt o treści:
11, 12, 13, 14 21, 22, 23, 24 31, 32, 33, 34 41, 42, 43, 44
Wczytaj plik (w trybie tylko-do-odczytu):
f = open("plik.txt", "r") f.read() # -> cała zawartość pliku jako string f.readlines() # -> cała zawartośc pliku jako lista stringów f.close()
Czytanie po kawałku (rzadko używane w praktyce):
f = open("plik.txt", "r") f.readline() # -> czyta jedną linię, przenosuwa wskaźnik f.seek(n) # przesuwa wskaźnik o n bajtów f.tell(n) # obecna pozycja wskaźnika f.read(n) # czytaj n bajtów f.close()
Zapis do pliku:
f = open("plik.txt", "w") f.write(s) # zapisuje string do pliku f.writelines(l) # zapisuje listę stringów do pliku f.close()
Linie mają znak nowej lini "n" na końcu - nie jest potrzebny:
f = open("plik.txt", "r") r = [] for line in f.readlines(): line = line[:-1] r += [line] f.close() println(r)
Podział pliku wg przecinków:
f = open("plik.txt", "r") r = [] for line in f.readlines(): line = line[:-1] fields = line.split(",") r += [fields] f.close() println(r)
Usuwanie zbędnych spacji:
f = open("plik.txt", "r") r = [] for line in f.readlines(): line = line[:-1] fields = line.split(",") clean_fields = [] for field in fields: clean_field = field.strip() clean_fields += [clean_field] r += [fields] f.close() println(r)
Python posiada rozległą bibliotekę standardową która rozwiązuje wiele problemów. Jak się dowiedzieć co w niej jest?
- <TAB> w ipython
- Funkcja help
- Dokumentacja https://docs.python.org/3/
- Stack Overflow http://stackoverflow.com/
Ściągnij plik tekstowy http://www.gutenberg.org/cache/epub/150/pg150.txt na dysk. Następnie napisz program usuwa z tekstu wszystkie znaki oprócz liter (i spacji) i zamienia małe litery na wielkie. Następnie użyj oczyszczonego tekstu żeby stworzyć histogram słów dla tego pliku. Następnie zapisz histogram jako plik histogram.txt na dysku w następującej formie:
EXPLAIN: 13 PARAGRAPHS: 3 ENVIRONMENT: 1 DEMAND: 7 OVERWHELMING: 1
Uwaga: do stworzenia programu brakuje Ci informacji!
def get_content(path): f = open(path, "r") content = f.read() f.close() return content def clean_content(content): clean_content = "" for letter in content: if letter.isalpha() or letter.isspace(): clean_content += letter.upper() return clean_content def histogram(words): histogram = {} for word in words: if word in histogram: histogram[word] += 1 else: histogram[word] = 1 return histogram def write_to_file(path, hist): f = open(path, "w") for key in hist: f.write(key + ": " + str(hist[key]) + "\n") f.close() text = get_content("pg150.txt") text = clean_content(text) words = text.split() hist = histogram(words) write_to_file('histogram.txt', hist)
Paradygmat obiektowy (object-oriented programming): wszystko jest obiektem.
Obiekt:
- atrybuty (pola) - stan
- procedury (metody) - kod który operuje na stanie
- klasa - obiekt należy do szerszej klasy/typu obiektów (podejście klasowe)
Wszechobecne podejście.
Cały czas używamy obiektów.
Definicja klasy:
class Kitty (object): mood = "neutral" # pole food = "hungry" # pole kitty1 = Kitty() # instancjalizacja -> instancja/obiekt kitty2 = Kitty() # instancjalizacja -> instancja/obiekt print(type(kitty1), kitty1.mood, kitty1.food) print(type(kitty2), kitty2.mood, kitty2.food) print(kitty1, kitty2)
Ważne elementy:
- słowo kluczowe class
- oznaczenie że jest typem obiektowym (object)
- nazwa klasy Kitty
- definicje pól
- tworzenie obiektów danej klasy
- dostęp do pól obiektu przez kropkę
Metody:
class Kitty (object): mood = "neutral" food = "hungry" def feed(self): self.food = "fed" def pet(self): if self.food == "fed": self.mood = "happy" kitty = Kitty() kitty.pet() kitty.feed()
Ważne elementy:
- metoda zdefiniowana jak funkcja
- pierwszy argument metody to referencja do obiektu (w 99.999% przypadków nazwany self)
- wywołanie metody przez kropkę, jeden mniej argument (bo self jest uzupełniany automagicznie)
Konstruktor:
class Kitty (object): mood = "neutral" food = "hungry" def __init__(self, name): self.name = name def feed(self): self.food = "fed" def pet(self): if self.food == "fed": self.mood = "happy" kitty = Kitty("Mr Bojangles") print(kitty.name)
Ważne elementy:
- metoda o specjalnej nazwie (dwa podkreślniki z przodu i z tyłu)
- przypisanie dynamicznie tworzy nowe pole
Inne magiczne metody:
class Kitty (object): mood = "neutral" food = "hungry" def __init__(self, name): self.name = name def __cmp__ (self, other_kitty): if self.name == other_kitty.name: return 0 # objects are equal elif self.name < other_kitty.name: return -1 # this object is smaller else: return 1 # this object is larger def __repr__(self): return self.name kitty1 = Kitty("Mr Bojangles") kitty2 = Kitty("Mr Fluffball") print(kitty1, kitty2) print(kitty1 < kitty2)
Więcej: http://www.rafekettler.com/magicmethods.html (np. kitty1 + kitty2, kitty1[0]).
Hierarchie klas: tworzymy klasy Dog i Cat które mają podobne charakterystyki, które wywodzą się ze wspólnej nadklasy: HousePet:
+------------+ | HousePet | +------------+ | pet() | | feed() | +------------+ ^ ^ | | +------------+ +-----------+ | | +---------------------------+ +------------------+ | Cat | | Dog | +---------------------------+ +------------------+ | walk_on_top_of(furniture) | | bark_all_night() | +---------------------------+ +------------------+
class HousePet (object): def pet(self): print("pet") def feed(self): print("feed") class Cat (HousePet): def __init__(self, name): self.name = name def walk_on_top_of(self, furniture): print("walk on top of " + str(furniture)) class Dog (HousePet): def __init__(self, name): self.name = name def bark_all_night(self): print("bark all night") cat = Cat("Mr Bojangles") dog = Dog("Holly") cat.pet() dog.pet()
Ważne elementy:
- zamiast dziedziczyć po obiekcie, dziedziczenie po innej klasie
class Cat (HousePet): def __init__(self, name): self.name = name def pet(self): print("run away") def feed(self): super(Cat, self).feed() print("meow endlessly") def walk_on_top_of(self, furniture): print("walk on top of " + str(furniture)) cat = Cat("Mr Bojangles") cat.feed() cat.pet()
Ważne elementy:
- proste redefiniowanie metod
- super zwraca wersje obiektu w typie nadklasy
Napisz klasę Employees, która jest książką kontaktów do pracowników w firmie Apples & Oranges pozwalająca dodawać, usuwać kontakty, wypisywać kontakty.
Firma dla każdego pracownika trzyma następujące informacje: imię, nazwisko, telefon, email, nr legitymacji.
Firma Apples & Oranges zatrudnia dwa profile pracowników: programistów i hodowców roślin.
Dla programistów firma trzyma także informację o tym w jakim języku programowania dany programista pisze.
Dla hodowców roślin, firma trzyma informację, jaką rośliną się zajmują.
Te informacje są ważne dla szefów w Apples & Oranges, więc Employees pozwala także wypisywać wszystkich programistów którzy piszą w konkretnym języku i wszystkich hodowców którzy hodują konkretną roślinę.
Może czas w końcu włączyć PyCharma?
class Employees (object): contacts = [] def add(self, employee): pass def remove(self, employee_id): pass def print_all(self): pass def print_language(self, language): pass def print_plant(self, plant): pass class Employee (object): pass class Programmer (Employee): pass class Planter (Employees): pass
class Employees (object): contacts = [] def add(self, employee): self.contacts += [employee] def remove(self, employee_id): for contact in self.contacts: if contact.id == employee_id: self.contacts.remove(contact) def print_all(self): for contact in self.contacts: print(contact) def print_by_language(self, language): for contact in self.contacts: if (type(contact) == Programmer): if (contact.language == language): print(contact) def print_by_plant(self, plant): for contact in self.contacts: if (type(contact) == Planter): if (contact.plant == plant): print(contact)
class Employee (object): def __init__(self, id, name, surname, telephone, email): self.id = id self.name = name self.surname = surname self.telephone = telephone self.email = email def __repr__(self): return str(self.id) + " " + self.name + " " + self.surname + " " + self.telephone + " " + self.email class Programmer (Employee): def __init__(self, id, name, surname, telephone, email, language): super(Programmer, self).__init__(id, name, surname, telephone, email) self.language = language def __repr__(self): return str(self.id) + " " + self.name + " " + self.surname + " " + self.telephone + " " + self.email + " " + self.language class Planter (Employee): def __init__(self, id, name, surname, telephone, email, plant): super(Planter, self).__init__(id, name, surname, telephone, email) self.plant = plant def __repr__(self): return str(self.id) + " " + self.name + " " + self.surname + " " + self.telephone + " " + self.email + " " + self.plant
employees = Employees() employees.add(Programmer(1, "Jan", "Kowalski", "665-0001", "jkowalski@aeto.com", "python")) employees.add(Programmer(2, "Jan", "Nowak", "665-0002", "jnowak@aeto.com", "python")) employees.add(Programmer(3, "Jan", "Wojciechowski", "665-0003", "jw@aeto.com", "java")) employees.add(Planter(4, "Tomasz", "Kowalski", "665-0004", "tkowalski@aeto.com", "orange")) employees.add(Planter(5, "Tomasz", "Nowak", "665-0005", "tnowak@aeto.com", "orange")) employees.add(Planter(6, "Tomasz", "Wojciechowski", "665-0006", "tw@aeto.com", "banana")) print("All employees") employees.print_all() print("All Python programmers") employees.print_by_language("python") print("All banana planters") employees.print_by_plant("banana")
Zaimportujmy moduł
import tkinter as tk
Słowo kluczowe import - ładuje zawartość pliku Tkinter.py (z bieżącego katalogu lub gdzieś z systemu).
Słowo kluczowe as - pozwala zmienić długą nazwę modułu na coś poręcznego
(Jeśli nie działa to: sudo apt-get install python3-tk ...)
Pierwsze okienko!
import tkinter as tk window = tk.Tk() label = tk.Label(window, text="Hello") label.pack() window.mainloop()
Ważne elementy:
- Tworzymy obiekt okna
- Tworzymy w oknie obiekt etykiety z napisem
- Pakujemy etykietę, żeby pasowała rozmiarem do okna
- Włączamy system okienkowy
import tkinter as tk window = tk.Tk() label = tk.Label(window, text="Hello") label.pack() def poke(): print("Ow!") button = tk.Button(window, text="Poke", command=poke) button.pack() window.mainloop()
Ważne elementy:
- Dodajemy przycisk
- Przycisk wykonuje po naciśnięciu funkcję
Bardziej interaktywny przycisk:
import tkinter as tk window = tk.Tk() label_text = tk.StringVar() label_text.set("Hello") label = tk.Label(window, textvariable=label_text) label.pack() def poke(): label_text.set("Ow!") button = tk.Button(window, text="Poke", command=poke) button.pack() window.mainloop()
Ważne elementy:
- Dodajemy zmieniający się tekst do etykiety
- Przycisk po naciśnięciu zmienia napis na etykiecie
Układanie widgetów:
import tkinter as tk window = tk.Tk() frame = tk.Frame(window) frame.pack(fill="x") label_text = tk.StringVar() label_text.set("Hello") label = tk.Label(frame, textvariable=label_text) label.pack(side=tk.RIGHT) def poke(): label_text.set("Ow!") button = tk.Button(frame, text="Poke", command=poke) button.pack(side=tk.LEFT) window.mainloop()
Ważne elementy:
- Dodanie ramki w oknie, która pozwala na pozycjonowanie
- Etykieta i przycisk są umieszczone w ramce
- Etykieta i przycisk podczas pakowania ustalają swoją pozycję
import tkinter as tk window = tk.Tk() frame = tk.Frame(window) frame.pack(fill="x") entry_text = tk.StringVar() entry = tk.Entry(frame, textvariable=entry_text) entry.pack(side=tk.TOP) label_text = tk.StringVar() label_text.set("Hello") label = tk.Label(frame, textvariable=label_text) label.pack(side=tk.RIGHT) def poke(): label_text.set(entry_text.get()) button = tk.Button(frame, text="Poke", command=poke) button.pack(side=tk.LEFT) window.mainloop()
Ważne elementy:
- Tworzymy obiekt typu Entry i wstawiamy go do ramki - obiekt używa zmiennej do przechowywania tekstu
- Po naciśnięciu przycisku, wyciągamy tekst ze zmiennej związanej z polem tekstowym i zapisujemy do zmiennej związanej z etykietą
Inne widgety:
- Button
- Canvas
- Checkbutton
- Entry
- Frame
- Label
- Listbox
- Menu
- Menubutton
- Message
- Radiobutton
- Scale
- Scrollbar
- Text
- LabelFrame
- PanedWindow
- Spinbox
Napisz interfejs graficzny dla listy kontaktów firmy Apples & Oranges, który pozwoli na wstawianie nowych pracowników.
Teraz na pewno już czas żeby włączyć PyCharma?
import tkinter as tk window = tk.Tk() def make_row(parent, caption): frame = tk.Frame(parent).pack(fill="x") tk.Label(frame, text=caption).pack(side=tk.LEFT) entry_text = tk.StringVar() tk.Entry(frame, textvariable=entry_text).pack(side=tk.RIGHT) return entry_text data = {} for row in ["ID", "Name", "Surname", "Telephone", "Email", "Employee Type", "Language/Plant"]: data[row] = make_row(window, row + ":") employees = Employees() def add_employee(): if data["Employee Type"].get() == "Programmer": employee = Programmer(int(data["ID"].get()), data["Name"].get(), data["Surname"].get(), data["Telephone"].get(), data["Email"].get(), data["Language/Plant"].get()) employees.add(employee) if data["Employee Type"].get() == "Planter": employee = Planter(int(data["ID"].get()), data["Name"].get(), data["Surname"].get(), data["Telephone"].get(), data["Email"].get(), data["Language/Plant"].get()) employees.add(employee) employees.print_all() frame = tk.Frame(window) frame.pack(fill="x") tk.Button(frame, text="Add", command=add_employee).pack(side=tk.BOTTOM) window.mainloop()
Czego jeszcze musisz się nauczyć?
Ale jak?
Konrad Siek <konrad.siek@cs.put.edu.pl>
http://www.cs.put.poznan.pl/ksiek
https://github.com/kondziu
https://twitter.com/kondziuKN SKiSR: https://dsg.cs.put.poznan.pl/wiki/
Space | Forward |
---|---|
Right, Down, Page Down | Next slide |
Left, Up, Page Up | Previous slide |
P | Open presenter console |
H | Toggle this help |