#%% Import
#
# Pro Python 3.6 je potřeba nejprve nainstalovat balíček dataclasses::
#
#   pip install dataclasses
#
from dataclasses import dataclass, field


#%% Jednoduchá dataclass:
@dataclass()
class Person:
    first_name: str
    last_name: str

    def full_name(self):
        return f'{self.first_name} {self.last_name}'


speaker = Person('Jan', 'Smitka')
print(f'Yet another example of formatting: {speaker.first_name}')
print(f'Auto-generated repr: {repr(speaker)}')


#%% Porovnání na rovnost:
class PersonRegular:
    def __init__(self, first_name: str, last_name: str):
        self.first_name = first_name
        self.last_name = last_name


r_speaker_1 = PersonRegular('Jan', 'Smitka')
r_speaker_2 = PersonRegular('Jan', 'Smitka')
print(f'r_speaker_1 == r_speaker_2? {r_speaker_1 == r_speaker_2}')

dc_speaker_1 = Person('Jan', 'Smitka')
dc_speaker_2 = Person('Jan', 'Smitka')
print(f'dc_speaker_1 == dc_speaker_2? {dc_speaker_1 == dc_speaker_2}')
print()


#%% Výchozí hodnoty atributů:
def create_empty_person():
    return Person('', '')


@dataclass()
class Order:
    id: int
    total_value: float = 0
    items: list = field(default_factory=list)
    customer: Person = field(default_factory=lambda: Person('', ''))
    customer_2: Person = field(default_factory=create_empty_person)


order_1 = Order(1)
print(f'order_1 = {order_1}')

order_2 = Order(2)
order_2.customer.first_name = 'Arthur'
order_2.customer.last_name = 'Dent'
print(f'order_1 = {order_1}')
print(f'order_2 = {order_2}')


#%% Freeze - hashování!
@dataclass(frozen=True)
class PhoneNumber:
    number: str


call_history = {}
call_history[PhoneNumber('226 7709')] = '29 Arlington Avenue, Islington N1'
print(f'We arrived to {call_history[PhoneNumber("226 7709")]}')


#%% Pokus o změnu freezed dataclass:
phone = PhoneNumber('111 222 333')
phone.number = '0'


#%% Porovnávání pomocí relačních operátorů:
@dataclass(order=True)
class VersionSpec:
    major: int
    minor: int
    patch: int


py_37 = VersionSpec(3, 7, 0)
py_27 = VersionSpec(2, 7, 15)
print(f'py_37 > py_27? {py_37 > py_27}')


#%% Úprava porovnávání:
@dataclass(order=True)
class PersonCmp:
    first_name: str = field(compare=False)
    last_name: str = field(compare=True)


smitka_1 = PersonCmp('Vladimír', 'Smitka')
smitka_2 = PersonCmp('Jan', 'Smitka')
print(f'smitka_1 == smitka_2? {smitka_1 == smitka_2}')

quido = PersonCmp('Quido', 'Python')
print(f'smitka_2 > quido? {smitka_2 > quido}')


#%% Další možnosti:

@dataclass(eq=False)
class Person:
    name: str = field(init=False, hash=False)


speaker = Person()
