Внешние модули в Python

Внутренний функционал питона довольно мощный, и его вполне достаточно для реализации многих проектов. Однако питон не был бы таким популярным среди программистов, если бы не мог расширять свой функционал за счет дополнительных модулей (ещё их называют библиотеками или пакетами) с помощью всего лишь одной строчки кода.

Каждый существующий модуль написан для решения задач в конкретной области. И первым модулем, который не включён в стандартную библиотеку питона, с которым мы познакомимся, будет модуль drawzero.

drawzero — это простая и удобная графическая библиотека, в которой есть функции для рисования простых фигур. Чтобы получить к ним доступ, надо в начале программы написать строку

from drawzero import *

Установка drawzero

Перед первым использованием модуль drawzero нужно установить. Для этого в терминале нужно выполнить команду

pip install drawzero --upgrade --user

Под linux и MacOS вместо pip нужно вводить pip3.

Если слово «терминал» непонятно, то можно запустить вот такую программу:

import os, sys python = sys.executable user = '--user' if 'venv' not in python else '' cmd = '{} -m pip install drawzero --upgrade {}'.format(python, user) print(cmd) os.system(cmd)

Если в результате её запуска вывод будет примерно такой как ниже, то у вас успех!

C:\some\path\Python38\python.exe -m pip install drawzero --upgrade --user Collecting drawzero ... что-то про downloading или Using cached Collecting pygame ... что-то про downloading или Using cached Installing collected packages: pygame, drawzero Successfully installed drawzero-0.1.4 pygame-1.9.6

A. Основы основ

Итак, приступим к рисованию!

Скопируйте и запустите программу ниже. В результате запуска должно открыться окно с нарисованной по диагонали красной линией. Сдавать код этой задачи не нужно :)

from drawzero import * line('red', (0, 0), (1000, 1000))

Осваиваем геометрию с помощью кода

Система координат в программировании и система координат в математике немного отличаются. В программировании точка с координатами (0, 0) находится в верхнем левом углу. Ось x направлена от неё вправо, а ось y — вниз.

Любая точка имеет позицию (координату) относительно оси x и относительно оси y, поэтому координаты каждой точки это пара чисел — сначала x, потом y. Эти координаты указываются через запятую и записываются в круглых скобках.

Рисование отрезка выполняется, как мы уже знаем, с помощью команды line. В скобках указываются параметры: цвет и две точки — концы отрезка. Именно в таком порядке.

Цвет пока можно выбирать из следующих вариантов: "black", "white", "red", "green", "blue", "yellow", "brown". Скоро мы научимся выбирать любые цвета.

Например:

line('red', (300, 200), (700, 400))
# 'red' — цвет линии,
# (300, 200) — один конец отрезка,
# (700, 400) — второй конец отрезка

save_to_var

Новость: строчки кода, начинающиеся с символа "#" называются в Python комментариями. Эти строчки предназначены для пояснения частей кода, чтобы в нём было проще разобраться. Особенно когда этот код читает не тот, кто его писал. Всё, что написано в такой строке, не считается программой и не выполняется.

Закомментировать сразу несколько строк кода можно, предварительно выделив эти строки, нажать Ctrl-/ (нажав и удерживая клавишу Ctrl, нажать клавишу /). Повторное нажатие той же комбинации клавиш убирает комментарии в блоке кода, если он был перед этим закомментирован.

Рисование окружности выполняется с помощью команды circle. В скобках указываются параметры: цвет, координаты центра окружности и радиус:

circle('yellow', (500, 300), 200)
# 'yellow' — цвет окружности,
# (500, 300) — координаты центра окружности,
# 200 — радиус

save_to_var

Рисование прямоугольника выполняется с помощью команды rect. В скобках указываются параметры: цвет, координаты левой верхней вершины, ширина (вдоль оси x), высота (вдоль оси y). То есть, при помощи такой функции можно рисовать только прямоугольники, параллельные осям координат.

rect('blue', (300, 200), 400, 200)
# 'blue' — цвет,
# (300, 200) — координаты верхнего левого угла,
# 400 —  ширина,
# 200 — высота

save_to_var

B. Три линии

Нарисуйте три линии так, чтобы получился треугольник (любой).

save_to_var

C. Три окружности

Теперь нарисуйте три окружности. Все три центра должны быть разными точками, а окружности вложены друг в друга и не пересекаться. То есть вторая окружность должна быть строго внутри первой, а третья — внутри второй.

Примерно вот так:

save_to_var

D. Два прямоугольника

Нарисуйте прямоугольник внутри другого прямоугольника так, чтобы между ними получилась ровная "рамка".

save_to_var

Создание более сложных фигур

Рисуя треугольник линиями, можно заметить, что каждую точку мы выписывали дважды, потому что она была концом двух отрезков. Может быть можно сделать то же самое экономнее?

Нам поможет функция рисования многоугольника polygon. Первый параметр это уже знакомый нам цвет, после которого надо перечислить координаты вершин многоугольника.

polygon('blue', (300, 200), (700, 300), (500, 400))
# 'blue' — цвет,
# (300, 200) — первая точка многоугольника,
# (700, 300) — вторая точка многоугольника,
# (500, 400) — третья точка многоугольника

Если в многоугольнике больше трёх вершин, нужно учесть, что перечислять вершины в произвольном порядке нельзя. Представьте, что вы обходите эту фигуру по часовой стрелке или против часовой стрелки. В функции polygon надо перечислять вершины одним из этих способов, начиная с любой вершины. Если порядок вершин неверный, то может получиться, например, что-то такое:

save_to_var

Пока мы рисовали только контуры. Теперь научимся рисовать закрашенные фигуры. Это может быть круг, прямоугольник и многоугольник. Для получения закрашенной фигуры есть команды: filled_circle, filled_rect, filled_polygon с такими же параметрами, как и у неокрашенных фигур.

from drawzero import *
filled_circle("red", (550, 450), 50)
filled_rect("green", (700, 200), 200, 200)
filled_polygon("blue", (100, 100), (400, 200), (300, 300))

save_to_var

E. Три треугольника

Нарисуйте три треугольника так, чтобы два из них не пересекались и находились внутри третьего.

Примерно вот так:

save_to_var

F. Фоторамка

Теперь нарисуйте прямоугольную рамку зелёного цвета ('green'). Размер "внешней" части 700x400. Ширина рамки 100. Внутренность рамки должна быть чёрной ('black'). Постарайтесь обойтись всего двумя командами из библиотеки drawzero.

save_to_var

Использование переменных

Мы познакомились с основными возможностями библиотеки drawzero. Теперь пора вспомнить про переменные — они нам скоро пригодятся.

Попробуем нарисовать какую-нибудь простенькую фигуру, например прямоугольник с закруглёнными концами.

from drawzero import *
filled_rect('yellow', (300, 500), 500, 100)
filled_circle('yellow', (300, 550), 50)
filled_circle('yellow', (800, 550), 50)

Координаты центра окружности это середины левой и правой (вертикальных) сторон прямоугольника и их можно посчитать. Это и правда несложно. Но что, если эту картинку надо перерисовать в другом месте или, скажем, сделать исходный прямоугольник чуть выше или шире? Это по-прежнему будет несложно сделать, но придётся пересчитывать координаты центров окружностей. А если картинка такая?

from drawzero import *
filled_rect('yellow', (300, 500), 500, 150)
filled_circle('yellow', (300, 575), 75)
filled_circle('yellow', (800, 575), 75)
filled_rect('yellow', (475, 325), 150, 500)
filled_circle('yellow', (550, 325), 75)
filled_circle('yellow', (550, 825), 75)

Всего-то — сделали полоски чуть шире. Пришлось пересчитать почти все координаты. Теперь представим себе, что это всё надо будет пересчитать несколько раз.

Напишем ту же программу по шагам, но для вычисления координат станем использовать переменные. Что нам нужно знать об этой фигуре, для того, чтобы её нарисовать? Нам надо знать где она находится и её главные размеры.

save_to_var

Место можно задать по-разному. Мы запомним координаты левого верхнего угла. Размеры фигуры определяются размерами прямоугольника. А радиус круга это половина его высоты, поэтому размеров прямоугольника достаточно. Не поленимся ввести для радиуса отдельную переменную, код так будет лучше читаться.

left = 300
top = 500
w = 500
h = 150
r = h // 2

Итак, всё готово для рисования. Теперь пишем те же самые вызовы функций рисования прямоугольников и кругов, но для вычисления всех координат используем только переменные. Надо только придумать — как вычислить координаты вертикального прямоугольника, используя имеющиеся переменные?

save_to_var

Очень полезно нарисовать картинку на бумаге и разобраться, откуда берутся формулы в программе, представленной ниже.

from drawzero import *
# left, top — координаты левого верхнего угла прямоугольника
left = 300
top = 500
# w, h — ширина и высота прямоугольника; r — радиус окружности
w = 500
h = 150
r = h // 2
filled_rect('yellow', (left, top), w, h)
filled_circle('yellow', (left, top + r), r)
filled_circle('yellow', (left + w, top + r), r)
filled_rect('yellow', (left + w // 2 - r, top - w // 2 + r), h, w)
filled_circle('yellow', (left + w // 2, top - w // 2 + r), r)
filled_circle('yellow', (left + w // 2, top + w // 2 + r), r)

В нашей программе стало в 2 раза больше строк, зато перерисовать эту фигуру в другом месте или поменять её размер стало проще простого. Надо только изменить нужные переменные. И всё! Все координаты и размеры пересчитаются автоматически.

G. Два пластыря

В аптечке есть два пластыря в форме креста со скруглёнными краями. В коде ниже есть пример одного из них, размер второго (ширина) равен 300. Подберите место, куда надо «наклеить» эти два пластыря, чтобы закрыть все порезы, которые отмечены красными треугольниками.

Используйте для перемещения переменные, объявленные в коде. Пропорции должны быть сохранены (меньшая сторона в 5 раз меньше большей).

cross

from drawzero import * # это порезы, их не нужно трогать filled_polygon('red', (260, 340), (310, 310), (320, 390)) filled_polygon('red', (510, 295), (620, 305), (590, 405)) filled_polygon('red', (720, 600), (655, 700), (722, 730)) filled_polygon('red', (550, 550), (510, 350), (570, 430)) filled_polygon('red', (510, 70), (517, 134), (580, 200)) filled_polygon('red', (630, 340), (730, 360), (630, 390)) filled_polygon('red', (690, 820), (710, 760), (680, 780)) filled_polygon('red', (750, 690), (830, 710), (730, 720)) filled_polygon('red', (520, 620), (590, 610), (550, 640)) # left, top — координаты левого верхнего угла прямоугольника # w, h — большая и меньшая стороны прямоугольника r — радиус окружности # параметры ниже нужно подобрать left = 220 top = 650 w = 500 h = w // 5 r = h // 2 filled_rect('yellow', (left, top), w, h) filled_circle('yellow', (left, top + r), r) filled_circle('yellow', (left + w, top + r), r) filled_rect('yellow', (left + w // 2 - r, top - w // 2 + r), h, w) filled_circle('yellow', (left + w // 2, top - w // 2 + r), r) filled_circle('yellow', (left + w // 2, top + w // 2 + r), r)

H. Скруглим углы

Давайте теперь сделаем не такие острые углы. Нарисуйте такую картинку:

save_to_var

Только "скруглить" угол можно по-разному. В идеальной фоторамке ширина должна быть одинаковой и в углах тоже. Но как понять, что такое "ширина рамки в углу"?

Давайте так: ширина это расстояние от точки на внешней границы к ближайшей к ней точке на внутренней. Изучите картинку со схемой и вы поймёте, что надо нарисовать (и в какой последовательности).

А ещё хорошо бы сделать всё на белом фоне! Для того, чтобы залить весь экран одним цветом, используйте команду `fill`. Например, заливка красным выглядит так:

fill('red')

save_to_var

I. Мишень

Хм, простая картинка — колечки одинаковой ширины. Ясно, что рисовать чёрные 'black' и белые 'white' круги, но в какой последовательности? Справитесь?
Тут, кстати, и циклы могут пригодиться :)

save_to_var

J. Забор

Хорошо, мишень нарисовали, а куда её повесить? Может на забор?

save_to_var

Работа с цветами

Пора научиться создавать свои цвета. Каждый цвет состоит из трёх компонентов: красного, зелёного и синего. Наверняка вам встречалась аббревиатура RGB (сокращение от Red, Green и Blue).

Представьте, что в абсолютно тёмной комнате вы светите на стену тремя фонариками: красным, зелёным и синим. У каждого есть регулировка интенсивности — число от 0 (фонарик выключен) до 255 (фонарик светит максимально ярко). Все фонарики светят в одну и ту же точку стены и в зависимости от настроек интенсивности всех трёх фонариков на стене получается пятно определённого цвета. Вот несколько примеров:

В библиотеке drawzero можно определить свой цвет при помощи тройки чисел, взятой в скобки. Эту тройку можно запомнить в переменной и использовать при вызове всех функций рисования из модуля drawzero.

Цвета, приведённые в примере выше можно было сохранить так:

black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
violet = (255, 0, 255)

Нарисуем картинку из предыдущего параграфа, определив свои цвета:

from drawzero import *
light_blue = (73, 151, 231)
sand_yellow = (244, 215, 111)
coral_red = (245, 129, 129)
filled_circle(coral_red, (150, 150), 10)
filled_rect(sand_yellow, (200, 100, 50, 50))
filled_polygon(light_blue, (90, 100), (70, 120), (30, 80))

save_to_var

K. В правильном порядке

Нарисуйте закрашенные треугольник, прямоугольник и круг, так, чтобы они "накладывались" в таком порядке, как изображено на рисунке.

save_to_var

L. Даже так можно?

Нарисуйте такую фигуру:

save_to_var

Надо обойтись 5 вызовами функций из модуля drawzero.

Немного знаков дорожного движения

Мы познакомились с основными геометрическими понятиями и тем, как их использовать в программе на Python при помощи библиотеки drawzero. Также убедились на нескольких примерах, как можно быть полезно при рисовании использовать переменные для промежуточных вычислений. Пусть даже иногда программа и становится от этого немного длиннее.

M. Движение запрещено

save_to_var

N. Въезд запрещён

save_to_var

O. Одностороннее движение

Синий цвет задаётся такой тройкой чисел: R = 48, G = 151, B = 222.

save_to_var

P. Тупик

save_to_var

Знак имеет что-то общее с предыдущим и, немного поменяв параметры, можно почти половину взять оттуда. Используйте следующие цвета:

Q. Первая медицинская помощь

Используйте следующие цвета:

save_to_var

R. Главная дорога

То, как выглядит этот знак, найдите в поисковике. Скруглять углы и рисовать чёрные окантовки не нужно. Только белое и жёлтое.

S. Светофор

save_to_var

При рисовании красной треугольной рамки могут возникнуть сложности, если захочется сделать всё точно. Можно сделать и "на глаз".

T. Двустороннее движение

Теперь задача посложнее.

save_to_var

U★. Туннель

Сложный знак, придётся постараться.

save_to_var