Что такое рисование кодом
Рисование кодом — это способ получать изображения из правил: «пройди 100 шагов, повернись на 91 градус, повтори 72 раза». Узоры, которые рождаются из таких правил и случайных чисел, называют генеративными.
В обычном графическом редакторе каждый штрих приходится рисовать руками, и повторить его идеально точно не выйдет. В программе вы описываете правило один раз, а компьютер повторяет его сотни раз без ошибок. Поменяли одно число — получили новый рисунок. Именно поэтому рисование кодом так хорошо подходит для первых шагов в программировании: результат виден сразу, а связь между строкой кода и линией на холсте очевидна. Идея черепашьей графики пришла из языка Logo: Сеймур Пейперт из MIT предлагал детям учиться, командуя черепашкой и создавая собственные картинки[1]. Похожий исполнитель Черепашка есть и в школьной информатике: федеральная образовательная программа основного общего образования называет его среди тем 8 класса.
В Python за рисование отвечает модуль turtle, он входит в стандартную библиотеку и описан в официальной документации Python[2]. На сайте программы запускаются прямо в браузере: окно редактора вверху страницы уже содержит первую программу, а под ним появляется белый холст шириной 480 и высотой 320 точек с центром в точке (0, 0).
5 команд черепашки, которых хватит для узоров
Для всех 6 программ на этой странице достаточно пяти групп команд: движение, поворот, перо, цвет и скорость. Остальное делают циклы и случайные числа: из этих кирпичиков складываются все узоры на странице.
| Команда | Что делает | Где встречается |
t.forward(100) | Идёт вперёд на 100 шагов и рисует линию | Спираль, звезда, прогулка |
t.left(91), t.right(90) | Поворачивает на заданное число градусов | Почти все программы |
t.circle(70) | Рисует окружность радиусом 70 | Розетка, радуга |
t.penup(), t.pendown(), t.goto(x, y) | Поднимает перо, переносит черепашку, опускает перо | Конфетти, радуга |
t.pencolor("gold"), t.pensize(3) | Меняет цвет и толщину линии | Все программы |
t.speed(0) | Самая быстрая скорость рисования | Все программы |
Цвета можно задавать английскими названиями: "red", "gold", "deepskyblue". Если название написано с ошибкой, программа остановится с сообщением об ошибке, поэтому копируйте их внимательно. Полный список команд приводится в официальной документации Python, но для рисования кодом хватит таблицы выше. Все команды подробно разобраны в статье про модуль turtle в Python.
Программа 1: цветная спираль
Спираль получается, если на каждом шаге цикла черепашка проходит чуть больше, чем в прошлый раз, и поворачивает почти на 90 градусов. Именно лишний 1 градус закручивает квадрат в спираль.
import turtle
t = turtle.Turtle()
t.speed(0)
colors = ["red", "orange", "gold", "green", "blue", "purple"]
for i in range(72):
t.pencolor(colors[i % 6])
t.forward(i * 3)
t.left(91)
t.hideturtle()
Переменная i растёт от 0 до 71, поэтому длина отрезка i * 3 увеличивается с каждым витком. Цвет выбирается выражением colors[i % 6]: остаток от деления на 6 перебирает индексы списка по кругу — 0, 1, 2, 3, 4, 5, снова 0. Эта программа уже стоит в окне вверху страницы. Попробуйте заменить 91 на 90 — спираль станет ровной квадратной; на 89 — закрутится в другую сторону; на 120 — превратится в треугольную; на 144 — в звёздчатую. Не стоит ставить больше 100 витков: при шаге 3 спираль выйдет за края холста, и часть рисунка не поместится.
Программа 2: розетка из кругов
Розетка — это 36 одинаковых окружностей, каждая повёрнута на 10 градусов относительно предыдущей. Вместе 36 поворотов по 10 градусов дают ровно полный круг в 360 градусов.
import turtle
t = turtle.Turtle()
t.speed(0)
t.pensize(2)
colors = ["tomato", "orange", "gold", "limegreen", "deepskyblue", "orchid"]
for i in range(36):
t.pencolor(colors[i % 6])
t.circle(70)
t.left(10)
t.hideturtle()
Здесь работает простое правило: число повторов, умноженное на угол поворота, должно давать 360, тогда узор замкнётся. Можно взять 12 кругов с поворотом 30 или 72 круга с поворотом 5: чем больше кругов, тем плотнее цветок. Если нарушить правило, например повернуть на 11 градусов, рисунок останется незамкнутым и будет выглядеть «рваным». Такой эксперимент полезен: ребёнок сам выводит формулу, которую на уроке геометрии объясняют словами. Без цикла коротко записать такой узор не получится: понадобилось бы 72 строки вместо четырёх.
Программа 3: звезда из лучей
Если повернуть почти назад — на 170 градусов, — черепашка будет возвращаться через центр и рисовать острые лучи. За 36 повторов получается звёздный узор с густой серединой.
import turtle
t = turtle.Turtle()
t.speed(0)
t.penup()
t.goto(-140, -10)
t.pendown()
t.pencolor("navy")
for i in range(36):
t.forward(280)
t.left(170)
t.hideturtle()
Команды penup, goto и pendown переносят черепашку левее центра без следа, чтобы звезда целиком поместилась на холсте. Угол 170 выбран не случайно: 36 · 170 = 6120, а это ровно 17 полных оборотов, поэтому последний луч приходит в начальную точку. Попробуйте углы 150, 160 и 175, сравните, какой узор получается в каждом случае, и посчитайте, сколько повторов нужно, чтобы фигура замкнулась.
Программа 4: конфетти из случайных точек
Чтобы рисунок каждый раз был новым, координаты, размер и цвет берут из модуля random. Команда t.dot() ставит круглую точку, а перо поднято, поэтому линий между точками нет.
import turtle
import random
t = turtle.Turtle()
t.speed(0)
t.penup()
t.hideturtle()
colors = ["red", "orange", "gold", "green", "blue", "purple", "pink"]
for i in range(150):
x = random.randint(-230, 230)
y = random.randint(-150, 150)
t.goto(x, y)
t.dot(random.randint(5, 25), random.choice(colors))
Функция random.randint(-230, 230) выбирает целое число в заданных пределах, причём обе границы входят. Пределы подобраны так, чтобы точки не вылетали за край поля шириной 480 точек. Функция random.choice(colors) достаёт из списка случайный цвет. Запустите программу три раза подряд: картинки будут разными, хотя код один и тот же. Предсказать точный рисунок заранее не получится, и в этом суть генеративного рисования кодом: вы задаёте правила, а не результат. Больше о случайных числах рассказывает статья про модуль random в Python.
Программа 5: радуга из полукругов
Радуга — это 7 полуокружностей, у каждой следующей радиус на 12 точек меньше. Команда t.circle(radius, 180) рисует не весь круг, а только половину.
import turtle
t = turtle.Turtle()
t.speed(0)
t.pensize(12)
colors = ["red", "orange", "yellow", "green", "deepskyblue", "blue", "purple"]
radius = 150
for c in colors:
t.penup()
t.goto(radius, -80)
t.setheading(90)
t.pendown()
t.pencolor(c)
t.circle(radius, 180)
radius = radius - 12
t.hideturtle()
Цикл перебирает не числа, а сами цвета из списка. Перед каждой дугой исполнитель поднимает перо, переходит в правую точку будущей дуги и смотрит вверх — это делает строка t.setheading(90). Толщина пера 12 совпадает с шагом радиуса, поэтому полосы ложатся вплотную.
Программа 6: случайная прогулка
Случайная прогулка — это 300 шагов, каждый в случайном направлении из четырёх: вправо, вверх, влево или вниз. Если она подходит к краю, то возвращается в центр.
import turtle
import random
t = turtle.Turtle()
t.speed(0)
t.pensize(3)
colors = ["crimson", "darkorange", "seagreen", "royalblue", "purple"]
for step in range(300):
t.pencolor(random.choice(colors))
t.setheading(random.choice([0, 90, 180, 270]))
t.forward(15)
if abs(t.xcor()) > 220 or abs(t.ycor()) > 140:
t.penup()
t.goto(0, 0)
t.pendown()
t.hideturtle()
Условие if следит, чтобы рисунок не уходил за границы: функция abs отбрасывает знак, и одна проверка работает и для левого, и для правого края. Так из случайности и одного правила вырастает рисунок, похожий на карту запутанных улиц.
Миф: «Рисовать кодом могут только те, кто хорошо рисует руками». Это не подтверждается: в программе важны правила и числа, а не твёрдость руки. Красивые картинки здесь рождаются из цикла и одного удачного угла.
Как придумывать свои картинки
Чтобы придумать свой рисунок, меняйте в готовой программе по 1 числу за раз и записывайте, что получилось. Так видно, какое число за что отвечает.
- Выберите основу. Возьмите одну из шести программ и запустите её без изменений.
- Меняйте угол. Поворот сильнее всего влияет на форму: попробуйте значения рядом с 90, 120 и 144.
- Меняйте число повторов. Проверьте, замыкается ли фигура, — вспомните правило про 360 градусов.
- Добавьте цвет и случайность. Замените один цвет на
random.choice(colors)и сравните результаты. - Объедините две программы. Например, нарисуйте розетку, а вокруг — конфетти.
Такой подход совпадает с идеями Митчела Резника: учиться через проект, увлечённость, общение со сверстниками и игру[3]. Готовыми рисунками полезно обмениваться с друзьями и пытаться повторить чужой узор по картинке. Ещё десяток заданий с подсказками собран на странице с рисунками по возрастанию сложности.
Когда рисование кодом не поможет
Такие программы не помогут, если цель — научиться обрабатывать данные или готовиться к экзамену. В этих 4 случаях графику стоит отложить или совмещать с другими задачами.
- Подготовка к заданию 16 ОГЭ. Там нужна программа, которая читает числа и печатает ответ, а графики нет.
- Ребёнку 5–7 лет. Печатать код ещё трудно, лучше начать с ScratchJr или с игр без компьютера.
- Нужна точная картинка по размерам в 1 пиксель. Для иллюстраций удобнее обычный графический редактор.
- Программа рисует 10 000 фигур. В браузере сработает ограничение времени, и рисунок оборвётся.
Чего делать нельзя
Нельзя копировать программы, не разобравшись в них: тогда остаётся красивая картинка, но не навык. Шесть правил помогут извлечь из этих программ пользу.
- Нельзя менять сразу несколько чисел — непонятно, какое изменение что сделало.
- Не стоит убирать
t.speed(0)в больших программах: медленная отрисовка может упереться в лимит времени. - Не следует называть переменные одной буквой везде: по PEP 8 имена пишут понятно и в стиле snake_case, например
radius. - Не стоит ставить огромные числа шагов: линия уйдёт за край.
- Не допускается сравнивать рисунки детей по «красоте» — важнее, понял ли ребёнок правило.
- Нельзя забывать про отступы в цикле: без них повторится не та команда.
Миф: «Графика с исполнителем — детская забава, к настоящему программированию отношения не имеет». Это миф: в таких программах работают циклы, списки, условия и случайные числа. Федеральная образовательная программа основного общего образования называет исполнителя Черепашку среди тем 8 класса информатики[4].
Источники
[1] Papert S. Mindstorms: Children, Computers, and Powerful Ideas. New York: Basic Books, 1980.
[2] The Python Tutorial (официальная документация Python 3). Python Software Foundation.
[3] Resnick M. Lifelong Kindergarten: Cultivating Creativity through Projects, Passion, Peers, and Play. Cambridge, MA: MIT Press, 2017.
[4] Приказ Минпросвещения России от 18.05.2023 № 370 «Об утверждении федеральной образовательной программы основного общего образования».
[5] van Rossum G., Warsaw B., Coghlan N. PEP 8 — Style Guide for Python Code. Python Software Foundation, 2001.
Вопросы и ответы
Почему у меня ничего не рисуется?
Проверьте, что в начале есть строка import turtle и создана черепашка t = turtle.Turtle(). Белое поле для рисунка появляется под окном с кодом после запуска.
Можно ли залить фигуру цветом?
Да: перед фигурой вызовите t.begin_fill(), после неё — t.end_fill(), а цвет заливки задайте через t.fillcolor().
Как сохранить картинку?
Проще всего сделать снимок экрана. Код программы при этом сохраняется в браузере как черновик, и рисунок всегда можно получить заново.
Работает ли рисование кодом в IDLE?
Да, этот модуль входит в стандартную поставку Python. В IDLE рисунок откроется в отдельном окне, и иногда в конце программы нужна строка turtle.done(), чтобы окно не закрылось.
С какого возраста подходят эти программы?
Обычно с 10–11 лет, когда ребёнок уже уверенно печатает и знает цикл for. Младшим удобнее рисовать пером в Scratch.
Почему случайная картинка каждый раз другая?
Модуль random при каждом запуске выдаёт новые числа. Если нужен одинаковый результат, в начале программы вызывают random.seed(1).