py_stepik/mod_oop/3.9_11_tablevalues.py

144 lines
6.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
https://stepik.org/lesson/701994/step/10?unit=702095
В программе необходимо реализовать таблицу TableValues по следующей схеме:
Каждая ячейка таблицы должна быть представлена классом Cell. Объекты этого класса создаются командой:
cell = Cell(data)
где data - данные в ячейке. В каждом объекте класса Cell должен формироваться локальный приватный атрибут __data с соответствующим значением.
Для работы с ним в классе Cell должно быть объект-свойство (property):
data - для записи и считывания информации из атрибута __data.
Сам класс TableValues представляет таблицу в целом, объекты которого создаются командой:
table = TableValues(rows, cols, type_data)
где rows, cols - число строк и столбцов таблицы; type_data - тип данных ячейки (int - по умолчанию, float, list, str и т.п.). Начальные значения в ячейках таблицы равны 0 (целое число).
С объектами класса TableValues должны выполняться следующие команды:
table[row, col] = value# запись нового значения в ячейку с индексами row, col (индексы отсчитываются с нуля)
value = table[row, col] # считывание значения из ячейки с индексами row, col
for row in table: # перебор по строкам
for value in row: # перебор по столбцам
print(value, end=' ') # вывод значений ячеек в консоль
print()
При попытке записать по индексам table[row, col] данные другого типа (не совпадающего с атрибутом type_data объекта класса TableValues), должно генерироваться исключение командой:
raise TypeError('неверный тип присваиваемых данных')
При работе с индексами row, col, необходимо проверять их корректность. Если индексы не целое число или они выходят за диапазон размера таблицы, то генерировать исключение командой:
raise IndexError('неверный индекс')
P.S. В программе нужно объявить только классы. Выводить на экран ничего не нужно.
"""
class Cell:
def __init__(self, data=0):
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
@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 TableValues:
def __init__(self, rows, cols, type_data=int, data=None):
self.rows, self.cols, self.type_data = rows, cols, type_data
if data:
self.cells = tuple(tuple(Cell.wrap(x) for x in row) for row in data)
else:
self.cells = tuple(
tuple(Cell.wrap(self.type_data()) for _ in range(cols))
for _ in range(rows)
)
def __len__(self):
return self.rows
def validate_index(self, index):
if not isinstance(index, tuple):
raise IndexError("неверный индекс")
row, col = index
if (
not isinstance(row, int)
or not 0 <= row < self.rows
or not isinstance(col, int)
or not 0 <= col < self.cols
):
raise IndexError("неверный индекс")
return row, col
def __getitem__(self, index):
row, col = self.validate_index(index)
return self.cells[row][col].data
def __setitem__(self, index, new_value):
row, col = self.validate_index(index)
if not isinstance(new_value, self.type_data):
raise TypeError("неверный тип присваиваемых данных")
self.cells[row][col].data = new_value
def __iter__(self):
return (
(self.cells[row][col].data for col in range(self.cols))
for row in range(self.rows)
)
def __repr__(self):
return f"{self.__class__.__name__}({self.rows!r}, {self.cols!r}, {self.type_data.__name__}, {self.cells!r})"
def tests():
code = (
b"bYdVqAXH&uY-LtqY;|RGC^IY|GARmfAUz;$AUz;33TAI|AaZYaAZczObYeORARr(hZXhc?ATbI"
+ b"cARr)SZ*m}ZVQh6}AZczOa&LD!3LqdLARr(hAZ;KkJs>d(ARr(hARr(hVRLh3a&#bcd2nSYc42IF"
+ b"Who#%Js@drbRc1FWFU57Y;|QIJv|^WEFdD#ztMouxFFEK(6!Nk(6!L9(7w@t(6u1YzR<DJiqN&ty"
+ b"3vBruprR7(7VvE(Sgx{(6As>VPb4$R$**)Wpg0WfgsSo(7w>T(7w@$(TvfKAkebVyU@PSw$QcEz0"
+ b"keUi_wK3(T32t(7MpO(7w>JAZBlJEFjRd(7w>S(6-RE(7hnhfzZ9su+fLmu+Y2EuprQ~(7w>O(6Z"
+ b"5h(6G^o(6G^h(Tvf7(T^a|xY2^pwb6jku+f6hzR`dn(6rFI(T^a}fzg7|fY83sx-1~juprR4(6G^"
+ b"h(6!LKEFjU1(Sp#v(Sjh*xY2^pwb6jku+f6hzR`dn(6rFL(7VvK(6!LLAkebVzR<VOveAIhu+fRo"
+ b"u+f6ij3Cj5(6!LJ(TmWvAkl}=xY2>oyU?&8DA2diz0k1HhtRdqz0kPPk08;3(7w>V(Sp#j(6!Nm("
+ b"Sgx|(6Z5k(T>rH(74fsAkmM}htRdqwa~gLA_^cNARr(hARr21b8}^KbRcdZJ|Hn5VQyp~Z6H1%F)"
+ b"Sb=(7n*L(6Z3A(SXps(7qthzR`lwfY7kevCzKJg3z$gyU@5G(6Z3G(7w>N(6!LL(7n-%(6u1ZhS0"
+ b"dsy3o7Piy+Xn(7Vx(Ake?iwb6jkwa~H9zR`ftuprTo(TC8r(6!LIAkl)*u+Xv4yU@7NhS7^63JMB"
+ b"zVp}jQATV7ZJs>eK3So0|WpZ>NbYfdDEFdslAU!=GF)%D3BGA3iwII=e(6G?4(7w@v(6G?8(Sjh*"
+ b"x6rWAztFhRfzga0(7n*U(6Z3J(6i9KAkeqaz0k1HhtRdqz0kPPk08*pAkmM}htRdqxzM`NgCNm@("
+ b"6G?4(7VvM(T35BA_@u$baHt*3LqdLAar6|GAtl4T_8OmH7+s=Wq4y{aC9J4d2nS#a&m8SItm~lAR"
+ b"u9Lb7gXLAXIX7WeR0%b7eXTARr(hVRLh3a&#a@VQh0{EFdD#z0kEF(Sgvj(6!LL(6!Nk(74fn(7w"
+ b">J(6G?E(7w@u(TpI_xY2>oy3o7Pj?stEwa~rLxX`sARC#b^MRIa)av}-}3UqRLItm~lARu8NJs@;"
+ b"qTQV#lG+hd1cw=R7bRbD?WMz0oa&m8SItm~lARu9Lb7gXLAXIX7WeR0%b7eXTARr(hVRLh3a&#a@"
+ b"VQh0{EFdD#z0kEF(Sgvj(6!LL(6!Nk(74fn(7w>J(6G?E(7w@u(TpI_xY2>oy3o7Pj?stEwa~rLx"
+ b"X`sANp56ictvt@Z*n3"
)
exec(__import__("base64").b85decode(code))
if __name__ == "__main__":
import doctest
doctest.testmod()
tests()