11.05 Объектная модель Python

FIXME: в группе 321 все упражненьки прошли за 1 час, т.к. они простые. Подумать, чем можно дополнить. ИДЕЯ: именно на это занятие поставить массовую апробацию кросс-тестирования.

Д/З

  1. <!> Написать класс Omnibus

    • экземпляры которого (обозначим экземпляр omn) обладают следующими свойствами

      1. Для любого атрибута (если его имя не начинается на "_", такие имена не входят в тесты) можно написать операцию omn.атрибут = значение (значение не хранится и не используется, см. далее)

      2. После этого выражение omn.атрибут будет возвращать количество экземпляров класса, для которых было таким способом задано поле атрибут

      3. Операция del omn.атрибут отменяет действие пункта 1 (поле атрибут считается не заданным для данного объекта, у других объектов оно уменьшается на 1).

        • Если соответствующего атрибута у объекта нет, ничего не происходит.

      Input

         1 a, b, c = Omnibus(), Omnibus(), Omnibus()
         2 del a.random
         3 a.i = a.j = a.k = True
         4 b.j = b.k = b.n = False
         5 c.k = c.n = c.m = hex
         6 print(a.i, a.j, a.k, b.j, b.k, b.n, c.k, c.n, c.m)
         7 del a.k, b.n, c.m
         8 print(a.i, a.j, b.j, b.k, c.k, c.n)
         9 del a.k, c.m
        10 print(a.i, a.j, b.j, b.k, c.k, c.n)
        11 a.k = b.i = c.m = 777
        12 print(a.i, a.j, a.k, b.j, b.k, c.k, c.n, c.m)
      

      Output

      1 2 3 2 3 2 3 2 1
      1 2 2 2 2 1
      1 2 2 2 2 1
      2 2 3 2 3 3 1 1
    • В каждом из собственных тестов надо проверять все три свойства этого класса
  2. <!> Написать класс Triangle, треугольника на плоскости,

    • в котором будут:
      1. Конструктор по трём точкам на плоскости (три последовательности неотрицательных чисел из двух элементов каждая, не забыть преобразовать их в tuple или list)

      2. Площадь треугольника: abs(треугольник), равна нулю, если треугольник невозможен (реализуется с помощью .__abs__())

      3. Треугольник с нулевой площадью — пустой (реализуется с помощью метода .__bool__())

      4. Сравнение треугольников на "<" — это сравнение площадей

      5. Булевская операция треугольник1 in треугольник2 — проверка того, что один треугольник целиком содержится во втором (в частности, треугольник содержится сам в себе, а пустой треугольник содержится в любом)

      6. Булевская операция треугольник1 & треугольник2 — проверка того, что два треугольника пересекаются (треугольник с нулевой площадью не имеет точек и ни с чем не пересекается)

      Input

         1 r = Triangle((4, 2), (1, 3), (2, 4))
         2 s = Triangle((1, 1), (3, 1), (2, 2))
         3 t = Triangle((0, 0), (2, 3), (4, 0))
         4 o = Triangle((1, 1), (2, 2), (3, 3))
         5 print(*(f"{n}({bool(x)}):{round(abs(x), 3)}" for n, x in zip("rsto", (r, s, t, o))))
         6 print(f"{s < t=}, {o < t=}, {r < t=}, {r < s=}")
         7 print(f"{s in t=}, {o in t=}, {r in t=}")
         8 print(f"{r & t=}, {t & r=}, {s & r=}, {o & t=}")
      

      Output

      r(True):2.0 s(True):1.0 t(True):6.0 o(False):0
      s < t=True, o < t=True, r < t=True, r < s=False
      s in t=True, o in t=True, r in t=False
      r & t=True, t & r=True, s & r=False, o & t=False
    • В каждом из собственных тестов надо проверять все шесть свойств треугольника. Координаты в тестах предполагаются целочисленными. Точность вещественных чисел (например, площади) при выводе ограничивать до трёх знаков после запятой, как в примере.
    • Что-то наподобие спойлера

  3. <!> Написать класс Maze(N), задающий квадратный лабиринт размера N×N. По умолчанию между комнатами лабиринта прохода нет. Конструкция M[x0,y0 : x1,y1] = "·" открывает проход попарно между всеми соседними комнатами от x0, y0 до x1, y1 включительно при условии совпадения абсциссы или ординаты (порядок может быть любым), в противном случае ничего не происходит. Конструкция M[x0,y0 : x1,y1] = "█" закрывает проходы при тех же условиях. Конструкция M[x0,y0 : x1,y1] возвращает True, если комната x1, y1 достижима из x0, y0, в противном случае — False. Строковое представление лабиринта 4×4 (в начальном варианте со всеми стенами, и после открытия некоторых проходов) см. в примере.

    • Используйте приведённые символы
      • «·» (MIDDLE DOT) обозначает центр комнаты или проход

      • «» (FULL BLOCK) обозначает непроходимую стену

      • /!\ Если в вашем редакторе/IDE они не отображаются — это повод его настроить и/или сменить.

    • Исследуйте, что именно получают методы .__getitem__() / .__setitem__() в этих конструкциях

    • Ошибки (выход за границы лабиринта, попытка присвоить неправильные символы и т. п.) не обрабатывать и не тестировать.
    • возможно, вам пригодится разбор классической задачи про обход лабиринта

      • не забудьте только, что не стоит хранить информацию о просмотре в самом лабиринте
      • я просто сделал ещё одно множество — все просмотренные вершины — и проверял наличие x1, y1 в нём

      Input

         1 m = Maze(4)
         2 print(m)
         3 print(m[0,0 : 1,0],m[0,0 : 2,2],m[1,0 : 1,2])
         4 m[0,0 : 0,3] = m[0,3 : 3,3] = m[3,3 : 3,0] = m[3,0 : 2,0] = m[2,0 : 2,2] = m[1,0 : 1,2] = "·"
         5 print(m)
         6 print(m[0,0 : 1,0],m[0,0 : 2,2],m[1,0 : 1,2])
      

      Output

      █████████
      █·█·█·█·█
      █████████
      █·█·█·█·█
      █████████
      █·█·█·█·█
      █████████
      █·█·█·█·█
      █████████
      False False False
      █████████
      █·█·█···█
      █·█·█·█·█
      █·█·█·█·█
      █·█·█·█·█
      █·█·█·█·█
      █·█████·█
      █·······█
      █████████
      False True True

LecturesCMC/PythonIntro2024/Prac/08_ObjectModel (last edited 2024-11-05 12:09:47 by hbd)