(Python) Подпрограммы: процедуры и функции - 1


Подпрограммы

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

Использование подпрограмм позволяет избежать дублирования кода, в случае если необходимо один и тот же код писать в разных местах программы. 
Библиотеки, которые импортируются в программу (например, математическая библиотека math) состоят из подпрограмм, которые уже кем-то составлены. Программистам не нужно думать о том, какие алгоритмы в них реализованы, а просто применяют их, задумываясь только о том, что именно они делают. Это большая экономия времени. Нет нужды писать алгоритм, который уже был кем-то написан.

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

Подпрограммы бывают двух типов - процедуры и функции.

Подпрограммы-процедуры выполняют некоторые действия, например, выводят результат на экран в определенном виде (простой пример, оператор print() - это стандартная подпрограмма-процедура, которая выводит данные на экран).

Подпрограммы-функции возвращают результат (число, символьную строчку и т.д.), который мы можем использовать в основной программе.

Давайте попробуем написать простую процедуру:
Предположим, что нам нужно выводить на экран строку "Error" каждый раз, когда в коде может возникнуть ошибка по вине пользователя Например, когда он вводит неверные данные.
Это можно сделать, написав оператор
print("Error")
А теперь представим, что такую строчку нужно вставить во многих местах программы. Конечно, можно везде ее просто написать. Но это решение имеет два недостатка.
1) Данная строка будет храниться в памяти много раз.
2) Если мы захотим изменить вывод при ошибке, то придется менять эту строку по всей программе, что достаточно неудобно

Для таких случаев процедуры и нужны.
Программа с процедурой может выглядеть следующим образом:
 
def printError():  # описание процедуры
    print("Error")

...
printError()      # запуск процедуры на выполнение. 
                  # Просто указываем имя процедуры, которую хотим выполнить
...
printError()


Надо запомнить!
  1. Процедура начинается со слова def (от англ. - define - определить). После имени процедуры записаны пустые скобки и двоеточие. Внутри скобок можно указывать параметры (об этом будем говорить позднее).
  2. Все операторы, которые выполняются в процедуре, записываются с отступом. 
  3. Чтобы выполнить процедуру, в основной программе необходимо вызвать ее по имени и не забыть написать скобки!
  4. Вызывать процедуру в программе можно сколько угодно раз.

Параметры и аргументы

А теперь представим, что нам необходимо в ответ на ошибку пользователя вывести разные сообщения, в зависимости от того, какую именно ошибку он сделал.
В этом случае можно для каждой ошибки написать свою процедуру: 
def printErrorZero():
    print("Error. Division by zero!")
def printErrorInput():
    print("Error in input!")

А если возможных ошибок будет намного больше? Такое решение нам не подойдет!
Надо научиться управлять процедурой, указывая ей, какое сообщение на ошибку нужно вывести.
Для этого нам понадобятся параметры, которые мы будем записывать в круглых скобках, после имени процедуры
def printError(s):
    print("s")

В данной процедуре s - это параметр - специальная переменная, которая позволяет управлять процедурой.
 
Параметр - это переменная, от значения которой зависит работа подпрограммы. Имена параметров перечисляются через запятую в заголовке подпрограммы.


Теперь при вызове процедуры нужно в скобках указывать фактическое значение, которое будет присвоено параметру (переменной s) внутри нашей процедуры
printError("Error! Division by zero!")

Такое значение называется аргументом.
 
Аргумент - это значение параметра, которое передается подпрограмме при ее вызове.

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

Локальные и глобальные переменные

Переменные, которые введены в основной программе, называются глобальные (или общие).

Обращаться к глобальным переменным можно из любой подпрограммы. 

Часто необходимо ввести дополнительные переменные, которые будут использоваться только в подпрограмме. Такие переменные называются локальными (или местными). С ними можно работать только внутри той подпрограммы, в которой они созданы. Остальные подпрограммы про них ничего не "знают".

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

Проанализируйте три программы:
Описание Программа
1) В этой программе переменная i локальная. Если в основной программе нет переменной i, то получим сообщение об ошибке. А если такая переменная есть (тогда это глобальная переменная), то на экран выводится ее значение.
def test():
    print(i)
2) Здесь, даже если есть глобальная переменная i, будет создана новая локальная переменная i со значением 2, и на экране появится 2.
def test():
    i = 2
    print(i)
3) В этой программе существует глобальная переменная i со значением 15. Ее значение можно изменить внутри подпрограммы, для этого необходимо явно объявить, что она глобальная (используем команду global).
Процедура будет работать с глобальной переменной i и ей будет присвоено новое значение 2. На экран выводится значение 2.
def test():
    global i  
    i = 2
    
# основная программа
i = 15
print(i)