НОЧУ ДПО "Национальный открытый университет "ИНТУИТ"
Опубликован: 24.01.2021 | Доступ: свободный | Студентов: 2489 / 106 | Длительность: 03:57:00
Лекция 15:

Функциональное программирование

< Лекция 1 || Лекция 15: 12

Смотреть на youtube

Проект для лекции Lecture5.rar.

Язык Python поддерживает различные стили программирования, начиная с простейших вариантов до наиболее популярного объектно-ориентированного стиля программирования.

Работа в интерактивном режиме

На первых советских компьютерах была возможность выполнять программу в командном режиме и видеть результаты выполнения каждой команды. Более того, можно было отдельную команду выполнять по тактам. Интерпретатор Python позволяет проводить подобные эксперименты, работая в интерактивной среде IDLE, где можно выполнять фрагменты кода оператор за оператором, просматривая результаты работы каждого оператора.

Вот пример подобного стиля работы:


Программа Python как неделимый модуль

Язык Python позволяет написать простую программу от начала и до конца как последовательность операторов, не привлекая функций и других средств модульности. Программа выполняется оператор за оператором, в соответствии с ее текстом. Текст управляет выполнением. Чтобы написать такую программу, достаточно создать файл, представляющий модуль языка Python . Файл сохраняется с уточнением .py. Двойной щелчок на этом файле позволяет запустить модуль интерпретатором Python и выполнить программу. Для простых программ весьма удобная технология работы.

Запишем наш предыдущий пример как программу Python :


Результаты работы:


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

Функциональное программирование

Для серьезных и сложных программ могут использоваться такие технологии как функциональное, модульное, объектно-ориентированное программирование в чистом виде или как смесь технологий в одном проекте (решении). Пожалуй, только стиль логического программирования явно не поддерживается в Python .

Все стили программирования в первую очередь направлены на борьбу со сложностью программ и позволяют декомпозировать сложную программу, представляя ее в виде совокупности более простых элементов - функций в функциональном программировании, модулей - в модульном программировании, классов - в объектно-ориентированном программировании. Исторически первым появился стиль функционального программирования. Уже в первом языке программирования Fortran58 программа (routine) могла содержать подпрограммы (subroutine). В следующем языке Algol60 программа могла включать процедуры и функции. Стиль функционального программирования в этих популярных языках того времени стал общепринятым.

В чисто функциональных языках программирования, следуя математике, каждая программа P(X, Y) рассматривается как функция F: X => Y, задающая отображение данных из области определения X, содержащей входные данные, в область значений функции Y, - содержащей результаты вычислений. Декомпозиция программы F означает, что функция F представляет композицию более простых функций f_1, \dots f_k, вызывая эти функции в процессе вычисления результата функции. Каждая функция f может быть, в свою очередь, декомпозирована и представлять композицию функций. Суперпозиция - один из основных инструментов функционального программирования - предполагает, что функции могут выступать в качестве аргументов других функций.

Язык Python поддерживает стиль функционального программирования.

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

def f(x: float)-> float:
    return 2 * x + 1
def g(y: float)-> float:
    return y * y + 4 * y - 5
def F (x: (int, float), f : 'function', g : 'function')-> float:    """
    Функция как объект. F- Функция высших порядков - аргументы f, g являются функциями  
    """
    return f(g(x)) 
def test1():
    x = 2
    y = 3
    r1 = F(x, f, g)
    r2 = F(y, g, f)
    print('r1 = ', r1 )
    print('r2 = ', r2)
test1()

В этом примере определены три функции. Функции f и g определены над числами и возвращают число в качестве результата. Функция F - это функция высших порядков, она представляет суперпозицию функций f и g: F(x) = f(g(x)). У функции три аргумента, первый это число, второй и третий аргументы - это функции.

Функции F передать функции f и g также просто, как и число 5. Вот результат выполнения:


Рассмотрим теперь классическую содержательную задачу, требующую введения функции высшего порядка. Это задача вычисления определенного интеграла. Функция Integral, вычисляющая интеграл, имеет три параметра, - пределы интегрирования a, b и подынтегральную функцию f. Поскольку в языке Python функции являются объектами, такими же, как и, например, числа, то передавать функции Integral конкретную подынтегральную функцию в качестве фактического параметра также просто, как передать число.

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

Для вычисления площади фигуры применяется метод трапеций. Интервал интегрирования разбивается на n частей. Площадь каждой части вычисляется как площадь трапеции. В цикле выполняется удвоение n. Вычисления заканчиваются, когда площадь фигуры при n-разбиении и 2n-разбиении отличается менее чем на малую величину eps, которая задается как еще один параметр функции Integral.

Приведу реализацию этой функции:

def Integral(a, b, f, eps):
    """
    Вычисление определенного интеграла на интервале [a, b]
    с подынтегральной функцией f(x).
    Интеграл вычисляется как площадь.
    eps - точность вычислений
    """

    n = 1;    d = b - a;    s0 = -1;    h = d/2
    sf = (math.fabs(f(a)) + math.fabs(f(b)))/2
    s1 = sf * d
    while math.fabs(s1 - s0) > eps:  
        for i in range(n):
            sf += math.fabs(f(a + h + 2 * i * h))        
        s0 = s1;  s1 = sf * h; n = 2 * n;  h = h /2
    return s1

Функция Integral является функцией высших порядков, поскольку один из ее параметров является функцией. Давайте вычислим интеграл для нескольких подынтегральных функций. Две из этих функций - f и g были определены выше, третья функция является встроенной в класс math функцией sin(x):

import math
def test2():
    eps = 1e-7
    mix = Integral(0, 2, f, eps)
    print(mix)
    mix = Integral(0, 2, g, eps) 
    print(mix)
    mix = Integral(0, math.pi, math.sin, eps)
    print(mix)
test2()

Точные значения площади для всех трех случаев легко вычисляются. Результаты вычислений функции Integral с заданной точностью eps совпадают с точными значениями. Вот результаты вычислений:


< Лекция 1 || Лекция 15: 12
Алексей Авилов
Алексей Авилов

Неужели не нашлось русских специалистов, чтобы записать курс по пайтону ? Да, можно включить переводчик и слушать с переводом, но это что? Это кто-то считает хорошим и понятным курсом для начинающих? 

Елена Лаптева
Елена Лаптева

Думаю. что не смогу его закончить. Хотелось предупредить других - не тратьте зря время, ищите другой курс.