# jednoduché objekty reprezentující osoby se jménem a věkem class Person1: def __init__(self, name, age): self.name = name self.age = age def say_hello(self): print(self.name + " says hello.") def rename_to(self, new_name): print(self.name + " renamed to " + new_name + ".") self.name = new_name # zkuste si: # >>> homer = Person1("Homer Simpson", 34); # >>> print(homer.name) # >>> print(homer.age) # >>> homer.say_hello() # >>> homer.rename_to("Homer Jay Simpson") # >>> print(homer.name) # Příklad: knihovna # objekty typu Book reprezentují knihy class Book: def __init__(self, author, title, isbn): self.author = author self.title = title self.isbn = isbn # takto vytváříme knihy dune = Book("Frank Herbert", "Dune", "978-0441172719") temno = Book("Bohuslav Balcar & Petr Štěpánek", "Teorie množin", "80-200-0470-X") # formát souboru s databází knih: # autor;název;isbn # (tzv. CSV formát, dá se importovat např. do Excelu) # načtení seznamu knih ze souboru def load_library(filename): book_list = [] with open(filename, "r") as f: for line in f: a, t, i = line.split(";") book_list.append(Book(a, t, i)) return book_list # uložení seznamu knih do souboru def save_library(filename, book_list): with open(filename, "w") as f: for book in book_list: f.write(book.author + ";" + book.title + ";" + book.isbn + "\n") # zkuste si: # >>> save_library("library.csv", [dune, temno]) # >>> bl = load_library("library.csv") # >>> for book in bl: # ... print(book.author + ": " + book.title) # Příklad: studenti a předměty # objekty typu Student představují studenty s UČem a jménem # objekty typu Course představují předměty s kódem a seznamem studentů class Student: def __init__(self, uco, name): self.uco = uco self.name = name class Course: def __init__(self, code): self.code = code self.students = [] def add_student(self, student): self.students.append(student) def print_students(self): i = 1 for s in self.students: print(str(i) + ".", str(s.uco) + "\t" + s.name) i += 1 # takto vytváříme studenty jimmy = Student(555007, "James Bond") # takto vytváříme předměty ib111 = Course("IB111") # takto přidáváme studenty k předmětu ib111.add_student(Student(555000, "Jan Novák")) ib111.add_student(jimmy) ib111.add_student(Student(555555, "Kryštof Harant")) # zkuste si: # >>> ib111.print_students() # Příklad: reprezentace času # objekty typu Time drží čas v rozumném formátu # (sekundy jsou mezi 0 a 59 apod.) class Time: def __init__(self, h, m, s): # zde by mohla být kontrola vstupu self.hours = h self.minutes = m self.seconds = s self.validate() def validate(self): if self.seconds >= 60: self.minutes += self.seconds // 60 self.seconds = self.seconds % 60 if self.minutes >= 60: self.hours += self.minutes // 60 self.minutes = self.minutes % 60 def pretty_print(self): print("{}:{:02}:{:02}".format(self.hours, self.minutes, self.seconds)) def add_seconds(self, sec): self.seconds += sec self.validate() # zkuste si: # >>> t = Time(1,30,72) # >>> t.pretty_print() # >>> t.add_seconds(107) # >>> t.pretty_print() # Příklad: matice class Matrix: def __init__(self, rows, cols): self.rows = rows self.cols = cols self.matrix = [[0 for i in range(self.cols)] for i in range(self.rows)] def check(self, row, col): if row < 0 or row >= self.rows: print("Bad row index.") return False if col < 0 or col >= self.cols: print("Bad column index.") return False return True def get(self, row, col): if self.check(row, col): return self.matrix[row][col] def set(self, row, col, value): if self.check(row, col): self.matrix[row][col] = value def matrix_mult(matL, matR): if matL.cols != matR.rows: print("Incompatible matrices.") return result = Matrix(matL.rows, matR.cols) for i in range(matL.rows): for j in range(matR.cols): for k in range(matL.cols): result.set(i, j, result.get(i, j) + matL.get(i, k) * matR.get(k, j)) return result # zkuste si vynásobit matice: # 0 1 1 1 # 1 1 * 1 0 # >>> a = Matrix(2,2) # >>> b = Matrix(2,2) # >>> a.set(0,1,1) # >>> a.set(1,0,1) # >>> a.set(1,1,1) # >>> print(a.matrix) # >>> b.set(0,1,1) # >>> b.set(1,0,1) # >>> b.set(0,0,1) # >>> print(b.matrix) # >>> c = matrix_mult(a,b) # Příklad: vlastní datová struktura -- jednoduchý zřetězený seznam # objekty typu Node jsou položky v seznamu # (drží nějaká data a odkazují na další položku v seznamu) # objekt typu List reprezentuje seznam # (drží odkaz na první položku v seznamu) class Node: def __init__(self, data): self.data = data self.next = None class List: def __init__(self): self.first = None def insert_at_start(self, data): node = Node(data) node.next = self.first self.first = node def delete_first(self): if self.first != None: self.first = self.first.next def output(self): node = self.first while node != None: print(node.data) node = node.next # zkuste si: # >>> s = List() # >>> s.insert_at_start("Hello") # >>> s.insert_at_start("Ahoj") # >>> s.output() # >>> s.delete_first() # >>> s.output() # Příklad: rodokmen # objekty typu Person reprezentují osoby včetně informace o rodiči a dětech # (pro zjednodušení předpokládáme jen jednoho rodiče v rodokmenu) class Person: def __init__(self, name): self.name = name self.parent = None self.children = [] def add_child(self, child): self.children.append(child) child.parent = self # textové vykresleni rodokmenu def draw_family_tree(person, level=0): print((" " * level) + person.name) for child in person.children: draw_family_tree(child, level + 1) # jsou osoby a, b sourozenci? def siblings(a, b): return a.parent != None and a.parent == b.parent # kdo je nejstarší předek zadané osoby v rodokmenu? def oldest_ancestor(person): if person.parent == None: return person return oldest_ancestor(person.parent) # totéž, bez rekurze def oldest_ancestor2(person): while person.parent != None: person = person.parent return person # kolik (přímých i nepřímých) potomků má daná osoba? def count_offspring(person): count = 0 for child in person.children: count += 1 + count_offspring(child) return count # pomocná funkce def add_transitions(person): for child in person.children: print('"' + person.name + '" -> "' + child.name + '"') add_transitions(child) # vykreslení rodokmenu ve formátu GraphViz # výstup můžete zkusit použít například na www.webgraphviz.com def create_family_tree_graph(person): print("digraph {") add_transitions(person) print("}") # nějaké rodiny na vyzkoušení abe = Person("Abraham Simpson") homer = Person("Homer Simpson") abe.add_child(homer) homer.add_child(Person("Bart Simpson")) homer.add_child(Person("Lisa Simpson")) homer.add_child(Person("Maggie Simpson")) bart, lisa, maggie = homer.children queen = Person("Queen Elisabeth II") charles = Person("Prince Charles") anne = Person("Princess Anne") andrew = Person("Prince Andrew") edward = Person("Prince Edward") william = Person("Prince William") henry = Person("Prince Henry") george = Person("Prince George") charlotte = Person("Princess Charlotte") beatrice = Person("Princess Beatrice") eugenie = Person("Princess Eugenie") louise = Person("Lady Louise Windsor") james = Person("James, Viscount Severn") peter = Person("Peter Phillips") savannah = Person("Savannah Phillips") isla = Person("Isla Phillips") zara = Person("Zara Tindall") mia = Person("Mia Tindall") queen.add_child(charles) queen.add_child(anne) queen.add_child(andrew) queen.add_child(edward) charles.add_child(william) charles.add_child(henry) william.add_child(george) william.add_child(charlotte) andrew.add_child(beatrice) andrew.add_child(eugenie) edward.add_child(louise) edward.add_child(james) anne.add_child(peter) anne.add_child(zara) peter.add_child(savannah) peter.add_child(isla) zara.add_child(mia) # zkuste si: # >>> draw_family_tree(abe) # >>> draw_family_tree(queen) # >>> draw_family_tree(charles) # # >>> print(bart.name) # >>> print(bart.parent.name) # >>> print(siblings(bart, lisa)) # >>> print(siblings(homer, bart)) # >>> print(siblings(maggie, abe)) # >>> print(count_offspring(abe)) # # >>> p = oldest_ancestor(charlotte) # >>> print(p.name) # # >>> create_family_tree_graph(queen) # Ilustrace nečekaných problémů, pokud omylem použijeme statické atributy: class Student1: hobbies = [] # statický atribut, patří třídě, ne objektům def __init__(self, name): self.name = name def add_hobby(self, hobby): self.hobbies.append(hobby) mirek = Student1("Mirek Dušín") mirek.add_hobby("pomáhání slabším") mirek.add_hobby("světový mír") bidlo = Student1("Dlouhé Bidlo") bidlo.add_hobby("alkohol") # zkuste si: # >>> print(mirek.hobbies) # k zamyšlení: jak to opravit?