Декораторы · 12 из 15
Кисть по глубине
К Новому году отделение печатает открытки с цветущим деревом. Дерево рисует рекурсивная функция vetka: ствол, на нём две ветки поменьше, на каждой — ещё две. Рисует она одним цветом, а Зинаида Петровна хочет, чтобы ствол был коричневым, ветки — зелёными, а самые тонкие — розовыми, как цветы. Функцию писал сменщик, и трогать её она запретила: «Обёрните — вы же это умеете».
Что сделать
Напишите декоратор с доводом: обёрнутая рисующая функция красит каждый свой вызов в цвет по глубине рекурсии.
Что приходит
cveta— список цветов: первый — для самого внешнего вызова, второй — для вызова изнутри него, и так далее
Что вернуть
Декоратор: обёрнутая функция перед рисованием ставит черепашке цвет своей глубины и отдаёт ответ исходной функции.
Допишите функцию po_glubine в редакторе справа.
Рисуйте черепашкой t, как turtle дома, — проверка
сравнивает нарисованное; возвращать ничего не нужно.
с графикой когда тесты пройдут, ответ вашей функции нарисуется · все задачи с графикой
Ветка длиной 80 с цветами ["sienna", "green", "gold"]. Внешний вызов рисует ствол коричневым, два вызова изнутри него — ветки зелёными, их вызовы — золотыми. Точка на кончике каждой ветки ставится после её собственных веточек и всё равно красится цветом этой ветки.
po_glubine(cveta) возвращает декоратор, тот — обёртку. Первый довод обёрнутой функции — всегда черепашка t.
Глубина — сколько вызовов обёрнутой функции сейчас идут один в другом: самый внешний — глубина 1, вызов изнутри него — 2. При каждом вызове обёртка:
- ставит
t.pencolor(...)цвет своей глубины: глубина 1 —cveta[0], глубина 2 —cveta[1]; глубже, чем цветов в списке, — последний цвет; - зовёт исходную функцию со всеми доводами;
- после неё возвращает черепашке цвет того вызова, который её позвал (если он есть), — тот дорисовывает своё своим цветом;
- отдаёт то, что вернула исходная функция.
Глубина своя у каждой обёрнутой функции. Имя обёрнутой функции остаётся прежним (functools.wraps).
Образцовый тест целиком
from cherepashka import risunok as _risunok_p
@po_glubine(["sienna", "green", "gold"])
def vetka(t, dlina):
t.forward(dlina)
if dlina > 20:
t.left(30)
vetka(t, dlina / 2)
t.right(60)
vetka(t, dlina / 2)
t.left(30)
t.dot(5)
t.penup()
t.backward(dlina)
t.pendown()
_risunok_p(vetka, 80)
<рисунок: 7 линий, 7 точек, 3 цвета; от (0, -37.32) до (134.64, 37.32); отпечаток bd67f8f8a1>
Обсуждение
Вопросов пока нет.
Войдите, чтобы спросить.