§20. Составление программ. Использование подпрограмм (вспомогательных алгоритмов)

20.1. Понятие вспомогательного алгоритма

Как видно из предыдущего параграфа, исполнителю Черепаха нередко приходится строить одно и то же изображение в одной программе несколько раз. Построение этого изображения удобно оформить в виде отдельного алгоритма. Такие алгоритмы называют вспомогательными.

Вспомогательный алгоритм – алгоритм, который можно целиком использовать в других алгоритмах.

Вспомогательный алгоритмы можно использовать необходимое число раз, обращаясь к его названию (имени). Для обращения к вспомогательному алгоритму в блок-схемах используется блок:

Вспомогательный алгоритм в языке Python записывается в виде функции:

Имя функции может содержать буквы латинского алфавита, цифры, знак подчеркивания (_). Первый символ в имени процедуры не может быть цифрой. После имени функции ы скобках могут указываться параметры, от которых зависит результат работы функции. Если параметров нет, то наличие скобок все равно является обязательным. После скобок ставится двоеточие – «:». Все команды, которые относятся к телу функции пишутся со сдвигом вправо. Сдвиг устанавливают клавишей Tab.

Команду выполнения вспомогательного алгоритма называют вызовом функции. Команду вызова записывают в основном алгоритме (программе) путем указания имени процедуры.
Пример 20.1. Написать программу для рисования елочки с использованием вспомогательного алгоритма.
В примере 19.8 мы уже строили елочку, используя изображение треугольников. Если проанализировать алгоритм, то можно увидеть, что команда Построить треугольник указана трижды. Это значит, что можно не копировать три раза команды для изображения треугольника, а оформить вспомогательный алгоритм, который будет строить треугольник.
Треугольник строился с помощью следующих команд:

turtle.forward(100)
turtle.left(120)
turtle.forward(100)
turtle.left(120)
turtle.forward(100)
turtle.left(120)

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

turtle.penup()
turtle.setpos(…, …)
turtle.pendown()

Эти команды позволяют осуществить переход от одного треугольника к другому Различие в использовании этих команд только в координатах, в которые должна переместиться Черепаха. Можно оформить еще одну функцию, которая будет осуществлять переход. Эта функция будет зависеть от координат точки, в которую нужно переместит Черепаху. Назовем эту функцию – p(x, y). В примере 20.2 приведена измененная программа.

Если считать, что рисование треугольника зависит от точки, в которой Черепаха начинает его рисовать, то функция рисования треугольника тоже будет зависеть от параметров (x, y). Алгоритм рисования треугольника в этом случае буде начинаться с команды перевода Черепахи в точку с координатами (x, y). Программа приведена в примере 20.3. В данном примере функция p вызывается из функции treug.

20.2. Решение практических задач с использованием функций

Пример 20.4. Оформить с помощью функций программу рисования трех троек на почтовом конверте из примера 19.11.

Функция для рисования одной тройки cifr_3 будет функцией, которая зависит от начального положения Черепахи – координат (x, y). Функцию р(x, y) , устанавливающую Черепаху в нужную точку возьмем из примера рисования елочки.

Поскольку каждая тройка должна рисоваться своим цветом, то добавим еще один параметр c в описание функции.

На примере рисования елочки и трех троек мы увидели, что вспомогательные алгоритмы позволяют сократить код программы, поскольку не приходится одинаковые части программы записывать несколько раз. Однако вспомогательные алгоритмы используют и тогда, когда задача разбивается на части – подзадачи. Вспомогательный алгоритм решает некоторую подзадачу основной задачи.

Пример 20.5. Написать программу для построения изображения, состоящего из трех цифр 1, 3 и 7, изображенных красным, зеленым и синим цветами.
В данном случае в изображении нет повторяющихся фрагментов. Однако задача разбивается на три подзадачи:

  1. нарисовать цифру 1;
  2. нарисовать цифру 3;
  3. нарисовать цифру 7.

Функцию для рисования цифры 3 можно взять из предыдущего примера. Остается написать функции для рисования цифр 1 и 7.

При решении реальных задач над проектом могут работать несколько человек. Каждый выполняет свою часть работы и оформляет ее как отдельный вспомогательный алгоритм. Важно, чтобы вспомогательные алгоритмы, написанные разными людьми, правильно выполнялись в одном проекте. Для этого устанавливаются определенные договоренности, позволяющие определить единые подходы к написанию текста программы.

Для исполнителя Черепаха такой договоренностью условимся считать следующее правило: рисование любой фигуры начинается с перевода Черепахи в начальную точку. Начальной точкой договоримся считать нижний левый угол изображения. В начальной точке Черепаха смотрит вправо (на восток).

Рассмотрим следующий пример. Пусть нескольким шестиклассникам поручили разработать программу рисования некоторого «пейзажа». «Пейзаж» состоит из следующих элементов: дом, три ели (одна большая и две маленькие) и сосна (пример 20.6).

Список функций для рисования «пейзажа» приведены в примере 20.7

Шестеро шестиклассников могут распределить работу между собой следующим образом:

  • первый пишет вспомогательный алгоритм рисования сосны;
  • второй пишет вспомогательный алгоритм рисования дома;
  • третий пишет вспомогательный алгоритм рисования треугольника. В этом алгоритме желательно добавить еще один параметр – длина стороны треугольника;
  • четвертый пишет вспомогательный алгоритм для маленькой елки, основываясь на вспомогательном алгоритме рисования треугольника. Координата x у обоих треугольников одинакова, координата y может быть вычислена по формуле y + 0.86•d, где d – длина стороны треугольника;
  • пятый пишет вспомогательный алгоритм для большой елки, основываясь на вспомогательном алгоритме рисования маленькой елки;
  • шестой пишет основной алгоритм, размещая элементы пейзажа на поле Черепахи.

Программа рисования «пейзажа» размещена в примере 20.8.
Имея в своем распоряжении вспомогательные алгоритмы, можно легко изобразить и другие «пейзажи». При этом не придется переписывать сами вспомогательные алгоритмы. Достаточно выбрать место размещения объекта на поле Черепахи, указав координаты начальной точки объекта.

Например, можно сохранить все функции из примера 20.8, а в текст основной части программы внесли изменения (пример 20.9).

Результат работы программы после изменений показан в примере 20.10.

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

для получения решения задачи некоторые действия приходится повторять неоднократно (как в примерах 20.2 и 20.4;

задача разбивается на независимые подзадачи  (как в примерах 20.5, 20.8, 20.9).

На заре создания первых компьютеров при разработке программ применялся прием проектирования «снизу вверх»: вначале создавали простейшие подпрограммы, затем их использовали в более сложных программах. В середине 60-х гг. XX в. стал применяться метод пошаговой детализации алгоритмов (проектирование «сверху вниз»). Этот метод заложен в основу процедурных языков программирования (Pascal, C, Python и др.).

Пример 20.1. Рисование елочки.
Блок-схема алгоритма рисования елочки включает:
1. Блок-схему вспомогательного алгоритма для рисования одного элемента елочки (треугольника):

2. Блок-схему построения елочки с использованием вспомогательного алгоритма treug.

Программа построения елочки

import turtle

turtle.shape(‘turtle‘)
turtle.pensize(2)
def treug():
    turtle.forward(100)
    turtle.left(120)
    turtle.forward(100)
    turtle.left(120)
    turtle.forward(100)
    turtle.left(120)
#нижний треугольник
turtle.penup()
turtle.setpos(-50, -85)
turtle.pendown()
treug()
#средний треугольник
turtle.penup()
turtle.setpos(-50, 0)
turtle.pendown()
treug()
#верхний треугольник
turtle.penup()
turtle.setpos(-50, 85)
turtle.pendown()
treug()

Пример 20.2. Измененная программа рисования елки.

import turtle

turtle.shape(‘turtle‘)
turtle.pensize(2)
def treug():
    turtle.forward(100)
    turtle.left(120)
    turtle.forward(100)
    turtle.left(120)
    turtle.forward(100)
    turtle.left(120)
def p(x, y):
    turtle.penup()
    turtle.setpos(x,y)
    turtle.pendown()
#нижний треугольник
p(-50, -85)
treug()
#средний треугольник
p(-50, 0)
treug()
#верхний треугольник
p(-50, 85)
treug()

 Если сравнить количество строк в программах из примеров 19.8 и 20.2, можно заметит, что их стало меньше. Использование вспомогательных алгоритмив позволяет сделать программу короче.

Пример 20.3. Новые изменения в программе рисования елки.

В теле функции treug убрали последнюю команду turtle.left(120), которая разворачивала Черепаху в начальное положение. Вместо нее в функцию p добавлена команда turtle.setheading(0), которая устанавливает угол поворота, равный 0.

import turtle

turtle.shape(‘turtle‘)
turtle.pensize(2)
def treug(x, y):
    p(x, y)
    turtle.forward(100)
    turtle.left(120)
    turtle.forward(100)
    turtle.left(120)
    turtle.forward(100)
def p(x, y):
    turtle.penup()
    turtle.setpos(x, y)
    turtle.pendown()
    turtle.setheading(0)
#нижний треугольник
treug(-50, -85)
#средний треугольник
treug(-50, 0)
#верхний треугольник
treug(-50, 85)

Пример 20.4. Программа построения изображения из примера 19.11.

import turtle

turtle.shape(‘turtle‘)
turtle.pensize(2)
def cifr_3(x, y, c):
    p(x, y)
    turtle.color(c)
    turtle.forward(30)
    turtle.right(135)
    turtle.forward(42)
    turtle.left(135)
    turtle.forward(30)
    turtle.right(135)
    turtle.forward(42)
def p(x, y):
    turtle.penup()
    turtle.setpos(x, y)
    turtle.pendown()
    turtle.setheading(0)
#первая тройка
cifr_3(-50, 60, ‘red’)
#вторая тройка
cifr_3(0, 60, ‘green’)
#третья тройка
cifr_3(50, 60, ‘blue’)

Пример 20.5. Программа построения изображения

import turtle

turtle.shape(‘turtle‘)
turtle.pensize(2)
def cifr_1(x, y, c):
    p(x, y)
    turtle.color(c)
    turtle.left(45)
    turtle.forward(42)
    turtle.right(135)
    turtle.forward(60)
def cifr_3(x, y, c):
    p(x, y)
    turtle.color(c)
    turtle.forward(30)
    turtle.right(135)
    turtle.forward(42)
    turtle.left(135)
    turtle.forward(30)
    turtle.right(135)
    turtle.forward(42)
def cifr_7(x, y, c):
    p(x, y)
    turtle.color(c)
    turtle.forward(30)
    turtle.right(135)
    turtle.forward(42)
    turtle.left(45)
    turtle.forward(30)
def p(x,y):
    turtle.penup()
    turtle.setpos(x,y)
    turtle.pendown()
    turtle.setheading(0)
cifr_1(0, 30, ‘red‘)
cifr_3(50, 60, ‘green‘)
cifr_7(100, 60, ‘blue‘)
p(150,0)

Пример 20.6. «Пейзаж»

Пример 20.7. Список функций для рисования «пейзажа».

  • treug – для построения треугольника;
  • p – для перевода Черепахи в начальную точку;
  • b_el – для рисования большой ели;
  • m_el – для рисования маленькой ели;
  • dom – для рисования дома;
  • sosna – для рисования сосны.

Пример 20.8. Программа для рисования «пейзажа».

import turtle
turtle.shape(‘turtle‘)
turtle.pensize(2)
def treug(x, y, d):
    p(x,y)
    turtle.forward(d)
    turtle.left(120)
    turtle.forward(d)
    turtle.left(120)
    turtle.forward(d)
def p(x,y):
    turtle.penup()
    turtle.setpos(x,y)
    turtle.pendown()
    turtle.setheading(0)
def m_el(x, y, d):
    treug(x, y, d)
    treug(x, y + d * 0.86, d)
def b_el(x, y, d):
    m_el(x, y, d)
    m_el(x, y + d * 1.72, d)
def dom(x, y, d):
    p(x,y)
    turtle.forward(d)
    turtle.left(90)
    turtle.forward(d)
    turtle.left(60)
    treug(x, y + d, d)
    turtle.left(30)
    turtle.forward(d)
def sosna(x, y, d):
    p(x + d / 8 , y)
    turtle.left(90)
    turtle.forward(d)
    p(x, y + d / 2)
    turtle.left(60)
    turtle.forward(d / 4)
    turtle.right(120)
    turtle.forward(d / 4)
    p(x, y + 3 * d / 4)
    turtle.left(60)
    turtle.forward(d / 4)
    turtle.right(120)
    turtle.forward(d / 4)
turtle.color(‘green’)
b_el(-250,-285, 100)
turtle.color(‘lime’)
m_el(210, -180, 50)
m_el(290, -180, 60)
turtle.color(‘brown’)
dom(-30, -50, 120)
turtle.color(‘darkgreen’)
sosna(120, 120, 120)
p(0,-100)

Пример 20.9. Изменения в программе.

turtle.color(‘green‘)
m_el(-350, -220, 150)
m_el(-170, -220, 60)
turtle.color(‘lime‘)
b_el(300,-135, 40)
turtle.color(‘brown‘)
dom(-100, -100, 200)
turtle.color(‘darkgreen‘)
sosna(190, 120, 70)
turtle.color(‘teal‘)
sosna(190, -120, 120)
p(0,-150)

Пример 20.10. Результат изменений.

 

 

1. Какие алгоритмы называются вспомогательными? 
2. Для чего нужны вспомогательные алгоритмы?
3. Какое ключевое слово используется для описания функции?
4. Как выполнить вызов функции?
5. Как понять, какие команды составляют тело функции?

Упражнения

1. Измените программу рисования елочки так, чтобы треугольник рисовался закрашенным.
2. Используя составленные ранее программы для исполнителя Черепаха, как вспомогательные, составьте программу для построения изображения.
3. Используя функции из примера 20.8, придумайте свой пейзаж.
4. Составьте программы построения изображения всех цифр от 0 до 9.
5. Запишите программы написания слов для исполнителя Черепаха. Используйте вспомогательные алгоритмы рисования букв.

a)

б)



6. Составьте программы построения изображений. Что могут обозначать эти изображения?

a)

б)

 

в)

г)

 

7. Составьте программу для построения изображения.