1. OOP Basic

1.1. Object Paradigm

  • Odwzorowanie świata na obiekty i relacje między nimi
  • Class
  • Objects, Instances
  • Fields, Properties, Attributes
  • Methods

1.2. Classes

  • CamelCase names
Code Listing 1.8. Defining and naming classes with single word names
class Astronaut:
    pass
Code Listing 1.9. Defining and naming classes with CamelCase names
class CosmonautPilot:
    pass

1.3. Classes vs Objects

  • Objects, Instances
  • snake_case names
Code Listing 1.10. Classes and Objects
class Astronaut:
    pass


jose_jimenez = Astronaut()
mark_watney = Astronaut()
Code Listing 1.11. Classes and Objects
class Astronaut:
    pass


class Cosmonaut:
    pass


jose = Astronaut()
ivan = Cosmonaut()

1.4. Fields

  • Fields, Properties, Attributes
  • snake_case names
Code Listing 1.12. Fields
class Astronaut:
    pass


jose = Astronaut()
ivan = Astronaut()

jose.name = 'José Jiménez'
ivan.name = 'Иван Иванович'

print(jose.name)    # 'José Jiménez'
print(ivan.name)    # 'Иван Иванович'

1.5. Methods

  • Methods are functions in the class
  • self - Instance as an argument
  • przy uruchomieniu funkcji nie podajemy jawnie argumentu self

1.5.1. Simple Methods

Code Listing 1.13. Simple Methods
class Astronaut:
    def say_hello(self):
        print('Hello!')


jose = Astronaut()

jose.say_hello()         # Hello

1.5.2. Methods accessing fields

Code Listing 1.14. Methods accessing fields
class Astronaut:
    def say_hello(self):
        print(f'My name... {self.name}')


jose = Astronaut()
jose.name = 'José Jiménez'

jose.say_hello()         # My name... José Jiménez!

1.5.3. Methods with default arguments

Code Listing 1.15. Methods with arguments
class Astronaut:
    def say_hello(self, text):
        print(text)


jose = Astronaut()

jose.say_hello(text='Privyet')     # Privyet
jose.say_hello('Hello')            # Hello
jose.say_hello()                   # TypeError: say_text() missing 1 required positional argument: 'text'

1.5.4. Methods with default arguments

Code Listing 1.16. Methods with default arguments
class Astronaut:
    def say_hello(self, text='Ehlo World!'):
        print(text)


jose = Astronaut()

jose.say_hello(text='Privyet')     # Privyet
jose.say_hello('Hello')            # Hello
jose.say_hello()                   # Ehlo World!

1.5.5. Methods call other methods

Code Listing 1.17. Methods call other methods
class Astronaut:
    def say_hello(self):
        name = self.get_name()
        print(f'My name... {name}')

    def get_name(self):
        return 'José Jiménez'


jose = Astronaut()

jose.get_name()         # 'José Jiménez!'
jose.say_hello()         # My name... José Jiménez!

1.6. Initializer Method

  • __init__() to nie konstruktor
  • Domyślny __init__() gdy niezdefiniowaliśmy własnego
  • Inicjalizacja pól klasy tylko w __init__
Code Listing 1.18. __init__() - Initializer Method
class Astronaut:
    def __init__(self, first_name, last_name, agency='NASA'):
        self.first_name = first_name
        self.last_name = last_name
        self.agency = agency


jose = Astronaut(first_name='José', last_name='Jiménez')
ivan = Astronaut(first_name='Иван', last_name='Иванович', agency='Roscosmos')


print(jose.first_name)  # José
print(jose.last_name)   # Jiménez
print(jose.agency)      # NASA

print(ivan.first_name)  # Иван
print(ivan.last_name)   # Иванович
print(ivan.agency)      # Roscosmos

1.7. Stringify object

  • print converts it’s arguments to str() automatically before printing
Code Listing 1.19. Print object without __str__() method overloaded
class Astronaut:
    def __init__(self, name):
        self.name = name


jose = Astronaut(name='José Jiménez')

str(jose)       # <__main__.Astronaut object at 0x01E3FDF0>
print(jose)     # <__main__.Astronaut object at 0x01E3FDF0>
Code Listing 1.20. Stringify object
class Astronaut:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return f'My name... {self.name}'


jose = Astronaut(name='José Jiménez')

str(jose)       # My name... José Jiménez
print(jose)     # My name... José Jiménez

1.8. One class per file?

  • Osobne pliki - gdy klasy są duże

  • Jeden plik - gdy klasy są małe i czytelne

    Code Listing 1.21. Classes and Objects
    class Astronaut:
        pass
    
    
    class Cosmonaut:
        pass
    
    
    jose = Astronaut()
    ivan = Cosmonaut()
    

1.9. Assignments

1.9.1. Basic Address Book

  1. Dla danych z listingu poniżej napisz książkę adresową

    Code Listing 1.22. Address Book
    [
        {"first_name": "Pan", "last_name": "Twardowski", "addresses": [
            {"street": "Kamienica Pod św. Janem Kapistranem", "city": "Kraków", "post_code": "31-008", "region": "Malopołskie", "country": "Poland"}]},
    
        {"first_name": "José", "last_name": "Jiménez", "addresses": [
            {"street": "2101 E NASA Pkwy", "city": "Houston", "post_code": 77058, "region": "Texas", "country": "USA"},
            {"street": "", "city": "Kennedy Space Center", "post_code": 32899, "region": "Florida", "country": "USA"}]},
    
        {"first_name": "Mark", "last_name": "Watney", "addresses": [
            {"street": "4800 Oak Grove Dr", "city": "Pasadena", "post_code": 91109, "region": "California", "country": "USA"},
            {"street": "2825 E Ave P", "city": "Palmdale", "post_code": "93550", "region": "California", "country": "USA"}]},
    
        {"first_name": "Иван", "last_name": "Иванович", "addresses": [
            {"street": "", "city": "Космодро́м Байкону́р", "post_code": "", "region": "Кызылординская область", "country": "Қазақстан"},
            {"street": "", "city": "Звёздный городо́к", "post_code": 141160, "region": "Московская область", "country": "Россия"}]},
    
        {"first_name": "Melissa", "last_name": "Lewis", "addresses": []},
    
        {"first_name": "Alex", "last_name": "Vogel", "addresses": [
            {"street": "Linder Hoehe", "city": "Köln", "post_code": 51147, "region": "North Rhine-Westphalia", "country": "Germany"}]}
    ]
    
  2. W zadaniu mamy doczynienia z trzema klasami, wymień je.

  3. Zamodeluj problem wykorzystując trzy klasy i relacje między nimi

  4. Użytkownik może mieć wiele adresów

  5. Użytkownik może nie mieć żadnego adresu

About:
  • Filename: oop_addressbook_basic.py
  • Lines of code to write: 10 lines
  • Estimated time of completion: 20 min
The whys and wherefores:
 
  • myślenie obiektowe i odwzorowanie struktury w programie
  • praca z obiektami
  • zagnieżdżanie obiektów
  • rzutowanie obiektu na stringa oraz jego reprezentacja (które i kiedy użyć)

1.9.2. Address Book from API

  1. API programu powinno być tak jak na Code Listing 1.23.
  2. Zrób tak, aby się ładnie wyświetlało zarówno dla jednego wyniku jak i dla wszystkich w książce
  3. Address ma mieć zmienną liczbę argumentów
About:
  • Filename: oop_addressbook_api.py
  • Lines of code to write: 15 lines
  • Estimated time of completion: 20 min
The whys and wherefores:
 
  • Korzystanie z .__str__()
Code Listing 1.23. Address Book
class AddressBook:
    pass

class Contact:
    pass

class Address:
    pass


melissa = Contact(imie='Melissa', nazwisko='Lewis')
print(melissa)
# Melissa Lewis

mark = Contact(imie='Mark', nazwisko='Watney', adresy=[Address(miasto='Houston'), Address(miasto='Cocoa Beach')])
print(mark)
# Mark Watney [Houston, Cocoa Beach]

addressbook = AddressBook([
    Contact(imie='Matt', nazwisko='Kowalski', adresy=[
        Address(ulica='2101 E NASA Pkwy', miasto='Houston', stan='Texas', kod='77058', panstwo='USA'),
        Address(ulica=None, miasto='Kennedy Space Center', kod='32899', panstwo='USA'),
        Address(ulica='4800 Oak Grove Dr', miasto='Pasadena', kod='91109', panstwo='USA'),
        Address(ulica='2825 E Ave P', miasto='Palmdale', stan='California', kod='93550', panstwo='USA'),
    ]),
    Contact(imie='José', nazwisko='Jiménez'),
    Contact(imie='Иван', nazwisko='Иванович', adresy=[]),
])


print(addressbook)
# [Matt Kowalski [Houston, Kennedy Space Center, Pasadena, Palmdale], José Jiménez, Иван Иванович]

1.9.3. Dragon (Part 1)

../_images/dragon.gif

Fig. 1.2. Firkraag dragon from game Baldur’s Gate II: Shadows of Amn

  1. Smok ma mieć:

    • nazwę smoka
    • pozycja x na ekranie
    • pozycja y na ekranie
    • teksturę, domyślnie img/dragon/alive.png
    • punkty życia, domyślnie losowy int z zakresu od 50 do 100
  2. Smok może:

    • otrzymywać obrażenia
    • zadawać komuś losowe obrażenia z przedziału od 5 do 20
    • być ustawiony w dowolne miejsce ekranu
    • być przesuwany o zadaną liczbę punktów w którymś z kierunków
  3. Jeżeli konieczne jest wprowadzenie nowej metody, klasy lub pól to należy to zrobić

  4. Przyjmij górny lewy róg ekranu za punkt (0, 0)

    • idąc w prawo dodajesz x
    • idąc w lewo odejmujesz x
    • idąc w górę odejmujesz y
    • idąc w dół dodajesz y
  5. Przy każdym obrażeniu wypisz na ekranie nazwę smoka, ilość obrażeń i pozostałe punkty życia

  6. Nie można zadawać smokowi obrażeń, jeżeli już nie żyje

  7. Kiedy punkty życia smoka spadną do, lub poniżej zera:

    • ustaw status obiektu na dead
    • na ekranie ma pojawić się napis ‘XXX is dead’ gdzie XXX to nazwa smoka
    • zmień teksturę smoka na img/dragon/dead.png
    • na ekranie pojawi się informacja ile złota smok wyrzucił (losowa 1-100)
    • na ekranie pojawi się informacja o pozycji gdzie smok zginął
  8. Przeprowadź grę:

    • Stwórz smoka w pozycji x=50, y=120 i nazwij go Wawelski
    • Ustaw nową pozycję na x=10, y=20
    • Przesuń smoka o 10 w lewo i 20 w dół
    • Przesuń smoka o 10 w lewo i 15 w prawo
    • Przesuń smoka o 15 w prawo i 5 w górę
    • Przesuń smoka o 5 w dół
    • Zadaj 10 obrażeń smokowi
    • Zadaj 5 obrażeń smokowi
    • Zadaj 3 obrażeń smokowi
    • Zadaj 2 obrażeń smokowi
    • Zadaj 15 obrażeń smokowi
    • Zadaj 25 obrażeń smokowi
    • Zadaj 75 obrażeń smokowi
About:
  • Filename: oop_dragon_1.py
  • Lines of code to write: 100 lines
  • Estimated time of completion: 75 min
  • Don’t delete code, assignment will be continued