Объектно-ориентированное программирование
Вы будете реализовывать классы, и для каждого класса обязательно напишите код, который проверяет все его возможности.
Класс “Время”
- Заведите класс
Time
, который хранит информацию о количестве часов и минут. Т.е. добавьте конструктор, в котором можно сразу указать количество часов и минут. - Сделайте метод
show();
, который возвращает строку с часами и минутами через двоеточие. Например, он может вернуть"09:10"
. - Сделайте методы
isDay()
,isMorning()
,isEvening()
,isNight()
, которые возвращают верно ли, что сейчас, соответственно, день, утро, вечер, ночь. Придумайте сами, начиная с какого времени утро переходит в день и т.п. - Сделайте метод
sayHello()
, который возвращает строку “Доброе утро”, “Добрый день” и т.п. в зависимости от текущего времени. - Сделайте метод, который добавляет указанное количество минут:
c.add(20)
. Если было"9:10"
, то должно получиться"9:30"
. А если было"9:50"
, должно получиться"10:10"
. Еще пример."9:20"
плюс 120 минут должно быть"11:20"
.
ASCI-графика
Класс Drawing (изображение) хранит изображение в виде списка списков символов. Например,
[
['.', '.', '.', '.', '.', '.', '.', '.', '.'],
['.', '.', '.', '.', '.', '.', '.', '.', '.'],
['.', '.', '.', '.', 'x', '.', '.', '.', '.'],
['.', '.', '.', '.', '.', '.', '.', '.', '.']
]
Это соответствует картинке:
.........
.........
....x....
.........
- Создайте конструктор, в котором указывается размер (сколько строк и столбцов) и символ, которым изначально все заполнить. Например,
Drawing(20, 30, '.')
. - Создайте метод
print()
, он печатает на экране изображение - Метод
setPoint(x, y, char)
рисует один символ в изображении. Методу нужно указать, где и какой символ поставить. - Методы
drawVerticalLine(...)
,drawHorizontalLine(...)
рисуют вертикальную или горизонтальную линию от заданной точки до заданной. Определите сами параметры для методов, они должны определять расположение линии и символ, которым линию рисовать. - Метод
drawRectangle()
рисует прямоугольник по двум противоположным углам, стороны прямоугольника вертикальны и горизонтальны. Используйте методы, реализованные ранее. - Необязательно: Рисование произвольной линии (найдите в википедии алгоритм Брезенхема. Если википедия заблокирована, можно не решать)
- Рисование круга (или окружности методом Брезенхема — необязательно). Пользователь указывает центр и радиус, программа должна пройтись по всем точкам поля и, если они лежат в круге, зарисовать их указанным символом.
- Реализуйте метод
draw(x, y, drawing)
нарисовать одно изображение на другом. При вызове метода указывается, где и какое изображение рисовать. - (Необязательная задача). Сделайте Drawing неизменяемым: все функции рисования возвращают новый Drawing и не меняют текущий. Чтобы не портить старый класс, назовите новый ImmutableDrawing.
- Используйте все реализованные вами ранее методы, чтобы нарисовать Джоконду. Ну или домик.
Рациональные числа
Сделаем класс Rational, это рациональные числа, для которых хранится их числитель и знаменатель. С рациональными числами можно совершать арифметические операции.
- Создайте класс и добавьте поля
_n
и_d
(numerator, denominator - числитель, знаменатель). - Реализайте метод
__init__
, чтобы можно было создавать объекты с помощьюRational(3, 2)
иRational(3)
. Для этого сделайте последний аргумент метода__init__
равным по-умолчанию 1. - Добавьте метод
__str__()
, который возвращает естественное представление числа в виде строки, например,"5/7"
. Если знаменатель равен 1, его не нужно писать. Если числитель ноль, то"0"
, а не"0/2"
и т.п. - Добавьте метод as_number(), который возвращает значение в виде числа.
- Добавьте сокращение дроби в конструктор: поделить числитель и знаменатель на НОД, убедиться, что знаменатель положительный. Найдите в стандартной библиотеке python функцию, которая вычисляет НОД — не пишите его самостоятельно.
-
Арифметические функции. add, sub, mul, div:
r1 = r2.add(r3); # создает новое число r2.add_in_place(r3); # добавляет к r2 и изменяет его
Протестируйте! Проверьте, например, что \(\frac16 + \frac13 = \frac12\), и проверьте другие аналогичные равенства для других арифметических операций.
- Замените методы арифметических операций на магические методы:
__add__
,__sub__
,__mul__
,__truediv__
. in-place методы замените на__iadd__
,__isub__
,__imul__
,__itruediv__
. Проверьте, что эти методы можно вызывать и какr2.__add__(r3)
, и какr2 + r3
, и какr2.__iadd__(r3)
, и какr2 += r3
. Еще можно по желанию сделать метод__pow__
,__ipow__
для возведения в степень. - Перегрузите операторы сравнения
x == y __eq__(self, other) x != y __nq__(self, other) x < y __lt__(self, other) x <= y __le__(self, other) x > y __gt__(self, other) x >= y __ge__(self, other)
Подумайте, что сравнения выражаются друг через друга. Достаточно реализовать, например,
==
и<
, все остальное вы можете реализовать только через них. - Создайте функцию не в классе Rational, которая по n считает \(1 + \frac12 + \frac13 + \frac14 + \frac15 + … + \frac1n\) Проверьте, что f(1) = 1, f(2) = 1.5, f(3) = 1.833333333333333
- Сделайте так, чтобы числитель и знаменатель дроби стали приватными (название начинается с подчеркивания) и создайте методы, которые возвращают значение числителя и знаменателя.
- (Если знаете, что такое статический элемент класса или можете разобраться) Создайте статические константы ONE и ZERO типа Rational, хранящие элементы 0, 1 в виде рациональных чисел.
- (Если знаете, что такое статический элемент класса или можете разобраться) Создайте статическую функцию для генерации всех несократимых дробей:
irreducible(n)
должно возвращать список (или лучше генератор) всех правильных несократимых дробей с указанным знаменателем. Например,irreducible(1)
возвращает[0/1]
, аirreducible(10)
возвращает[1/10, 3/10, 7/10, 9/10]
. - Расширьте методы арифметических операций так, чтобы в качестве второго аргумента они принимали обычные целые числа. Кроме того, реализуйте методы типа
__radd__
, чтобы число могло быть первым аргументом, например,1 + r
вызоветr.__radd__(1)
.