""" https://stepik.org/lesson/701993/step/8?unit=702094 Ранее вы уже создавали стек-подобную структуру, когда один объект ссылается на следующий и так по цепочке до последнего: Для этого в программе объявлялись два класса: StackObj - для описания объектов стека; Stack - для управления стек-подобной структурой. И, далее, объекты класса StackObj следовало создавать командой: obj = StackObj(data) где data - это строка с некоторым содержимым объекта (данными). При этом каждый объект класса StackObj должен иметь следующие локальные атрибуты: data - ссылка на строку с данными, указанными при создании объекта; next - ссылка на следующий объект класса StackObj (при создании объекта принимает значение None). Класс Stack предполагается использовать следующим образом: st = Stack() # создание объекта стек-подобной структуры В каждом объекте класса Stack должен быть локальный публичный атрибут: top - ссылка на первый объект стека (если стек пуст, то top = None). А в самом классе Stack следующие методы: push(self, obj) - добавление объекта класса StackObj в конец стека; pop(self) - извлечение последнего объекта с его удалением из стека; Дополнительно в классе Stack нужно объявить магические методы для обращения к объекту стека по его индексу, например: obj_top = st[0] # получение первого объекта obj = st[4] # получение 5-го объекта стека st[2] = StackObj("obj3") # замена прежнего (3-го) объекта стека на новый Если индекс не целое число или число меньше нуля или больше числа объектов в стеке, то должно генерироваться исключение командой: raise IndexError('неверный индекс') Пример использования классов Stack и StackObj (эти строчки в программе не писать): st = Stack() st.push(StackObj("obj1")) st.push(StackObj("obj2")) st.push(StackObj("obj3")) st[1] = StackObj("new obj2") print(st[2].data) # obj3 print(st[1].data) # new obj2 res = st[3] # исключение IndexError P.S. В программе нужно объявить только классы. Выводить на экран ничего не нужно. """ from typing import List class StackObj: def __init__(self, data=None): self.__next = None self.__data = data @property def data(self): return self.__data @data.setter def data(self, value): self.__data = value @property def next(self): return self.__next @next.setter def next(self, value): if isinstance(value, (self.__class__, None.__class__)): self.__next = value def __repr__(self): return f"{self.__class__.__name__}({self.data!r})" def __str__(self): return str(self.data) class Stack: def __init__(self, data=None): self.top = None if not data: return for x in map(lambda x: isinstance(x, StackObj) and x or StackObj(x), data): self.push(x) @property def bottom(self) -> StackObj: curr, last = self.top, None while curr: curr, last = curr.next, curr return last def push(self, obj: StackObj): if not self.top: self.top = obj else: self.bottom.next = obj def __len__(self): count, obj = 0, self.top while obj: obj, count = obj.next, count + 1 return count def __getitem__(self, idx: int) -> StackObj: if not isinstance(idx, int) or not 0 <= idx < len(self): raise IndexError("неверный индекс") count, obj = 0, self.top while obj: if count == idx: return obj obj, count = obj.next, count + 1 def __setitem__(self, idx: int, value: StackObj): if not isinstance(idx, int) or not 0 <= idx <= len(self): raise IndexError("неверный индекс") if not isinstance(value, StackObj): value = StackObj(value) if idx == len(self): self.push(value) return old = self[idx] value.next = old.next if idx > 0: self[idx - 1].next = value else: self.top = value def pop(self) -> StackObj: if not self.top: return None a, b, c = [self.top] + [None] * 2 while a: a, b, c = a.next, a, b if c: c.next = None if self.top in [b, c]: self.top = None return b def get_data(self) -> List[StackObj]: return [x for x in self] def __repr__(self): return f"{self.__class__.__name__}({self.get_data()!r})" def __str__(self): return " -> ".join(self.get_data()) def tests(): code = ( b"b95j*AX9WctYfoZoC?ao" + b"SYB4e*DJcqbbS`jpb7&}2bYWv_Phx5)B5z`9F*715DGGCRTQOZAJs?wbVPk7gVrnQNZ(?dPEpBCZ" + b"A}I=Cb8}^KbRctdTQFTNWMOn+AU!=GB5z`9F)<<_VQyp~b97rVT`pu{bYUPpJs=`)VrnuiZe@2OE" + b"FdD#u+f6ifY7+mvC)Ikf*@pJbYURSzRNRC0A?3T13_WjYEVARr)Nb8}^KbRb4" + b"yY;$ESAR^Gc(6u1ZfzY$iwa~rLwb6jkxY2;nzRA9cW7yBWguue3LqdLAYpTJWpZ>NX>)0Ab97;DV`V64EFe>KVPk7gVrnTYAR^G" + b"d(6P~q(6!LI(Sjh+fzg7{wa~iIuprR1(7w>S(6-RE(7hngvC)gsg3*j1(T&i$(6`XF(7e#U(7Vx(" + b"(SXpt(7Yhfy3o7Ou+f3hfzYrZQ*>ctYfoZoA_^cNARulaD?K1F3LqdLAZQ>xAZRXbWq5Q7ARr(h3" + b"So0|WpZ>NZXi89ATlf