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

Д/З

  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. <!> Написать класс Grange, реализующий отрезок целочисленной геометрической прогрессии ( (!) по аналогии с range(), но есть и отличия) $$ b_n=b_0*q^n $$.

    • В классе должны быть:
      1. Конструктор по трём параметрам (b0 , q и граница, за которую не заходит bn)

      2. Длина отрезка len(прогрессия)

      3. Прогрессия с нулевой длиной отрезка должна быть пустой

      4. Индексирование прогрессия[i] = bi ; индекс может быть любым неотрицательным целым (граница отрезка не проверяется)

      5. Итератор iter(прогрессия) (все элементы отрезка)

      6. Секционирование вида прогрессия[начало:конец] должно давать новую прогрессию с тем же q

      7. Секционирование вида прогрессия[начало:конец:знаменатель] должно давать новую прогрессию с qзнаменатель

        • Будем считать, что знаменатель только натуральный, проверять не надо
      8. Оба метода .__str__() и __repr__() должны возвращать grange(b₀, q, bmax)

      Input

         1 f, g, h = Grange(1, 2, 1048575), Grange(1, 2, 1048576), Grange(1, 2, 1048577)
         2 o, e = Grange(1, 2, 1), Grange(100, 10, 200)
         3 print(f"{f=}, {g=}, {h=}")
         4 print(f"{list(o)}({not(o)}), {list(e)}({not(e)})")
         5 print(f"{len(f)=}, {len(g)=}, {len(h)=}")
         6 print(f"{len(list(f))=}, {len(list(g))=}, {len(list(h))=}")
         7 print(f"{f[0]=}, {h[24]=}")
         8 a, b = f[3:32767], h[3:32767:2]
         9 print(f"{a=}, {a[5]=}")
        10 print(f"{b=}, {b[5]=}, {list(b)=}") 
      

      Output

      f=grange(1, 2, 1048575), g=grange(1, 2, 1048576), h=grange(1, 2, 1048577)
      [](True), [100](False)
      len(f)=20, len(g)=20, len(h)=21
      len(list(f))=20, len(list(g))=20, len(list(h))=21
      f[0]=1, h[24]=16777216
      a=grange(3, 2, 32767), a[5]=96
      b=grange(3, 4, 32767), b[5]=3072, list(b)=[3, 12, 48, 192, 768, 3072, 12288
    • В каждом из собственных тестов надо проверять все восемь свойств прогрессии

LecturesCMC/PythonIntro2022/Prac/08_ObjectModel (последним исправлял пользователь FrBrGeorge 2022-11-05 23:27:41)