'''
Функции str() и print() вызывают __str__()
repr() - __repr__()

Если __str__ нет, то будет вызваться __repr__
'''


class User:

    def __init__(self, first_name):
        self.first_name = first_name

    def __str__(self):
        return f'User {self.first_name}'

    def __repr__(self):
        return f'Repr Usef {self.first_name}'

class Pizza:
    pass


def test_1():
    # print(repr([1, 2, 3]))
    user = User('John')
    print(repr(user))
    print(repr(Pizza()))

    

class UnknownUser:
    pass


def test_2():
    users = [UnknownUser(), UnknownUser()]
    print(users)

    users_with_name = [User('Billy'), User('Jimmy')]
    print(users_with_name)
    print(users_with_name[0])
    print(users_with_name[1])


class SuperUser:
    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name

    def __str__(self):
        return f"__str__ method: {self.first_name} {self.last_name}"

    def __repr__(self):
        return f"__repr__ method: {self.first_name} {self.last_name}"


def test_3():
    user = SuperUser("Vasya", "Pypkin")
    print(f"{repr(user)}")
    # или лучше воспользоваться !r
    print(f"{user!r}") # !r вызовет не __str__, а __repr__

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~        

class Pizza:
    
    def __init__(self, name, ingredients):
        self.name = name
        if ingredients is None:
            self.ingredients = []
        else:
            self.ingredients = ingredients
            
    def __repr__(self):
        self.ingredients.sort(key=lambda x: x.weight, reverse=True)
        ret = f'Пицца {self.name} состоит из:\n'
        for ing in self.ingredients:
            ret += ing.__repr__() + '\n'
        return ret[:-1]

class Ingredient:
    
    def __init__(self, name, weight):
        self.name = name
        self.weight = weight

    def __repr__(self):
        return f'{self.name}: {self.weight}г.'


def test_4():
    barbecue = Pizza('BBQ', [
        Ingredient('chicken', 200),
        Ingredient('mozzarella', 300),
        Ingredient('sauce bbq', 150),
        Ingredient('red onion', 150)
    ])

    print(barbecue)


def test_5():
    ing = [
        Ingredient('chicken', 200),
        Ingredient('mozzarella', 300),
        Ingredient('sauce bbq', 150),
        Ingredient('red onion', 150)
    ]

    ing.sort(key=lambda x: x.weight, reverse=True)
    print(ing)
    

    # foo = {x.name: x.weight for x in ing}
    # foo2 = sorted(foo.items(), key=lambda item: item[1], reverse=True)
    # print(foo)
    # print(foo2)


def main():
    # test_1()
    # test_2()
    # test_3()
    test_4()
    # test_5()

if __name__ == '__main__':
    main()