1"""
2Enterprise решение на задачата.
3Ако искате да видите адекватно решение - вижте на Виктор.
4"""
5
6from abc import ABC, ABCMeta, abstractmethod
7from itertools import repeat
8
9
10
11def unique_only(fun):
12 """Декоратор, който филтрира уникални стойности на генератор."""
13 def wrapper(*args, **kwargs):
14 yield from set(fun(*args, **kwargs))
15 return wrapper
16
17
18def listify(fun):
19 """Декоратор, който колапсва генератор към лист."""
20 def wrapper(*args, **kwargs):
21 return list(fun(*args, **kwargs))
22 return wrapper
23
24
25class Singleton(ABCMeta):
26 """Метаклас за singleton класове."""
27
28 _instances = {}
29
30 def __call__(cls, *args, **kwargs):
31 """Създаване на клас инстанция."""
32 if cls not in cls._instances:
33 cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
34 return cls._instances[cls]
35
36
37# Как да напиша "Лютеница" с латински букви? Грехота е. Ще използвам кирилица за това домашно.
38class Лютеница(ABC):
39 """Абстрактен клас Лютеница, защото без абстракция, не е никакъв enterprise."""
40
41 INGREDIENT_QUANTITY = 5
42
43 @property
44 @abstractmethod
45 def participants(self):
46 """Списък от хора, по чиято рецепта се приготвя лютеница."""
47 ...
48
49 @property
50 @listify
51 def shopping_list(self):
52 """Списък за пазаруване."""
53 for participant in self.participants[::-1]:
54 yield from getattr(getattr(self, participant), 'ingredients')[::-1]
55
56 @property
57 @listify
58 @unique_only
59 def unique_ingredients(self):
60 """Уникални стойности от списъка за пазаруване."""
61 yield from self.shopping_list
62
63 @property
64 def ingredient_quantities(self):
65 """Количество за всяка съставка от лютеница."""
66 all_quantities = dict(zip(self.unique_ingredients, repeat(self.INGREDIENT_QUANTITY)))
67 for participant in self.participants:
68 all_quantities.update(getattr(getattr(self, participant), 'BREAKFAST', {}))
69 return all_quantities
70
71 @property
72 def number_of_ingredients_to_buy(self):
73 """Количество за всяка съставка от лютеница."""
74 return len(self.ingredient_quantities)
75
76
77class Маняк(ABC):
78 """Абстрактен клас за маняк, който прави лютеница."""
79
80 @property
81 @abstractmethod
82 def ingredients(self):
83 """Списък от съставки за лютеницата на маняка."""
84 ...
85
86
87class Виктор(Маняк, metaclass=Singleton):
88 """Виктор - ват елс?"""
89
90 BREAKFAST = {'skyr': 1}
91
92 @property
93 def ingredients(self):
94 """Списък от съставки за лютеницата на маняка."""
95 # Взех дефиницията на тези стойности от домашното на Виктор,
96 # защото ме домързя да ги напиша сам. Дано са верни 🤞
97 return ['чушки', 'домати', 'моркови', 'ябълки', 'сол',
98 'черен пипер', 'кимион', 'зехтин']
99
100
101# Еднобуквените променливи НЕ ТРЯБВА ДА СЕ ИЗПОЛЗВАТ,
102# но в този случай просто няма алтернатива.
103class Я(Маняк, metaclass=Singleton):
104 """Я - ват елс?"""
105
106 @property
107 def ingredients(self):
108 """Списък от съставки за лютеницата на маняка."""
109 # Взех дефиницията на тези стойности от домашното на Виктор,
110 # защото ме домързя да ги напиша сам. Дано са верни 🤞
111 return ('чушки', 'домати', 'патладжан', 'люти чушки', 'олио',
112 'захар', 'чубрица', 'черен пипер', 'врачанска ракия')
113
114
115class ОктомврийскаЛютеница(Лютеница, metaclass=Singleton):
116 """Клас Октомврийска Лютеница, за да е по-интересно."""
117
118 Виктор = Виктор()
119 Я = Я()
120
121 @property
122 def participants(self):
123 """Списък от хора, по чиято рецепта се приготвя лютеница."""
124 return ('Виктор', 'Я')
125
126 @property
127 def viktors_ingredients(self):
128 return self.Виктор.ingredients
129
130 @property
131 def georgis_ingredients(self):
132 return self.Я.ingredients
133
134
135# Голяма простотия. Съвсем не е образцово!
136globals().update(
137 dict(
138 zip(
139 dir(ОктомврийскаЛютеница),
140 map(ОктомврийскаЛютеница().__getattribute__, dir(ОктомврийскаЛютеница))
141 )
142 )
143)
........
----------------------------------------------------------------------
Ran 8 tests in 0.000s
OK