Классы и ООП
Разбор Д/З
ООП (предупреждение: не читайте Википедию, там частное вместо общего  ):
 ): 
- Инкапсуляция: иерархическое пространство объектов (как правило реализовано деревом пространства имён) - категоризация объектов
- связь объекта и его namespace 
- механизм реализации наследования и полиморфизма
- Python3 (и не только  ): объект.поле ): объект.поле- на самом деле это просто словари   
 
 
- Наследование: повторное использование свойств объекта при создании нового (есть несколько путей: прототипирование, классы/подклассы, /?\ что ещё?) - описание только разницы между исходным и новым объектом 
- знание о предках и их свойствах (интроспекция) - ⇒ объектное планирование сложных и сверхсложных систем
 
- Python3 (и не только): классы и подклассы
 
- Полиморфизм: повторное использование возможностей объекта при использовании принципиально другого объекта - реализация только разницы возможностей между исходным и новым объектом (во многих языках совпадает с механизмом наследования) - ⇒ объектное планирование сложных и сверхсложных систем
 
- правила работы с отличающимися свойствами (например, то делать с дополнительными полями? много ещё чего)
- Python3 (ещё примеры? Ruby?): параметрический полиморфизм, он же в данном случае Duck Typing: любой метод/функцию можно применять к любым объектам, лишь бы - этот метод был,
- количество параметров было допустимым
- эти три правила были применимы к коду метода/функции 
 
 
Спецметоды и перегрузка операций
Базовая статья: datamodel.html
Операций нет, а есть методы; операции — это
- вызов метода, или
- логика вызовов нескольких методов
Базовые функции
- __dict__() :), примеры 
- __init__() / __del__() (Note: del x doesn’t directly call x.__del__()) 
- __str__(),__repr__(),__bytes__() — str(x) 
- __bool__(), __len__() — пустой ли? 
- __getattr__() / __getattribute__() / __setattr__() / __delattr__() / __dir__() — «.» и около 
- сравнения: __lt__(self, other), __le__(self, other), __eq__(self, other), __ne__(self, other), __gt__(self, other), __ge__(self, other) - Достаточно __lt__() и __le__() 
 
Последовательности и прочие хранилища
- __getitem__() / __setitem__() / __delitem__()/ __missing__() 
- __iter__() 
- __reversed__() или len() + getitem() — reversed(x) 
- __contains__() — a in x 
Числа
- Базовые операции (типа __add__()), в т. ч. несуществующая @ (__matmul__()) 
- Инкрементальные операции типа += (__iadd__()) 
- Правые операции (__radd__()), их происхождение и протокол применения - "qwe"*3 vs. 3*"qwe" vs. "qwe".__mul__(3) vs. 3.__mul__("qwe") vs. "qwe".__rmul__(3) 
 
- Порождение новых объектов: c = a + b, какого типа c? 
Возможности какие-то запредельные, если вдуматься
Д/З
- Прочитать: - Про классы в учебнике 
- Про спецметоды в документации 
 
- EJudge: SimpleVector 'Простой вектор' Input:- Определить класс Vector, работающий с трёхмерными векторами Вектора должны поддерживать: - Конструктор вектора из трёх вещественных чисел
- Сложение и вычитание векторов A+B, A-B
- Умножение и деление на число A*n, A/n; а также и n*A
- Скалярное произведение A@B
- Преобразование в строковый вид "x:y:z, где x, y и z — представление вещественного числа с двумя знаками после запятой (см. пример)
 Output:- A = Vector(1,2,3) B = Vector(-1,3,-2) C = Vector(7,3,5) print("A, B, C:", A, B, C) print(A, "+", B, "=", A+B) print(A, "-", C, "=", A-C) print(A, "*", 2, "=", A*2) print(2, "*", B, "=", 2*B) print(C, "/", 3, "=", C/3) print(B, "@", C, "=", "{:.2f}".format(B@C))- A, B, C: 1.00:2.00:3.00 -1.00:3.00:-2.00 7.00:3.00:5.00 1.00:2.00:3.00 + -1.00:3.00:-2.00 = 0.00:5.00:1.00 1.00:2.00:3.00 - 7.00:3.00:5.00 = -6.00:-1.00:-2.00 1.00:2.00:3.00 * 2 = 2.00:4.00:6.00 2 * -1.00:3.00:-2.00 = -2.00:6.00:-4.00 7.00:3.00:5.00 / 3 = 2.33:1.00:1.67 -1.00:3.00:-2.00 @ 7.00:3.00:5.00 = -8.00 
- EJudge: StrangeDots 'Странные отрезки' Input:- Написать класс Dots, генерирующий заданное количество точек на заданом отрезке - При создании объекта типа Dots задаются вещественные границы отрезка 
 - Объект d типа Dots должен поддерживать индексирование по таким правилам: - d[n] — последовательность из n равноудалённых точек от начала до конца отрезка (включая конец) 
- d[i:n] — i-я точка такой последовательности 
- d[i:j:n] — последовательность начиная с i-той и заканчивая j-1-й точкой такой последовательности 
- Выход за границы отрезка означает экстраполяцию (см. пример)
 Output:- a = Dots(0,40) print(*a[5]) print(a[0:5]) print(a[2:5]) print(a[4:5]) print(a[7:5]) print(a[-7:5]) print(*a[1:3:5]) print(*a[:3:5]) print(*a[2::5]) print(*a[::5]) print(*a[-2:6:5]) - 0.0 10.0 20.0 30.0 40.0 0.0 20.0 40.0 70.0 -70.0 10.0 20.0 0.0 10.0 20.0 20.0 30.0 40.0 0.0 10.0 20.0 30.0 40.0 -20.0 -10.0 0.0 10.0 20.0 30.0 40.0 50.0 
- EJudge: UnaryNumber 'Палочная система счисления' Input:- Написать класс Unary, реализующий единичную систему счисления. Палочное представление L числа N - создаётся из любой строки длиной N
- представляется в виде строки из N символов "|"
- имеет длину N
- можно пройти циклом (при этом N раз возвращается палочная единица)
- можно дополнить другим палочным числом K с помощью L |= K (при этом длина L увеличивается на длину K) 
- можно поделить пополам нацело с помощью ~L (лишняя палка исчезает) 
- можно дополнить одной палкой с помощью +L 
 - Во всех случаях изменения числа идентификатор объекта сохраняется. Унарныеоперации не только изменяют объект, но и возвращают его. Output:- || |||| |||||| ||| | . || .. ||| | . || .. ||| | . || .. ||| True 
- EJudge: TrianglesCmp 'Сравниваем треугольники' Input:- Написать класс Triangle, моделирующий треугольник - объект T типа Triangle создаётся из трёх вещественных чисел — сторон треугольника 
- T пуст, если не выполняется строгое неравенство треугольника или хотя бы одна из сторон не положительна 
- abs(T) — площадь треугольника (0, если T пуст) 
- сравнение на неравенство двух объектов типа Triangle есть результат сравнения их площадей 
- два объекта S и T типа Triangle равны, если попарно равны их стороны (в некотором порядке) 
- строковое представление: a:b:c, где a, b и c — стороны треугольника в порядке их задания 
 Output:- 3.0:4.0:5.0 3.0:4.0:5.0=6.00 5.0:4.0:3.0=6.00 True True False 5.0:4.0:3.0 5.0:4.0:3.0=6.00 7.0:1.0:1.0=0.00 False True False 5.0:5.0:5.0 7.0:1.0:1.0=0.00 5.0:5.0:5.0=10.83 False False True 5.0:5.0:5.0 5.0:5.0:5.0=10.83 7.0:4.0:4.0=6.78 False True False 
