Python. Выражения и инструкции, стили описания и тесты

Чтобы сделать какую-нибудь программу нужно написать код. Он компилируется или интерпретируется, собирается в .EXEшник или в .APPник, и программой можно пользоваться.
.EXEшники собираются на виндовс и запускаются на виндовс, .APPшники работают только на маках.

Чтобы код работал и собирался, нужно правильно пользоваться элементами кода: выражениями и инструкциями.

Выражение — часть кода, которая становится значением, например 5 + 3.
Инструкция — часть для управления выражениями, например объявление и передача значения переменной: x = 5.

Выражения не изменяют состояние программы, а меняют состояния значений.

Декларативное и императивное программирование

Способов описания элементов кода тоже два: декларативный и императивный.

Декларативный

Описывает сам объект, что он из себя представляет и его характеристики.
Например, мы хотим бутерброд. «ЗАХААААР, сделай мне бутерброд». Он идёт на кухню и делает бутерброд как умеет.

Для примера кода, мы выбрали вычисление факториала.

  1. Обозначаем, что будет при факториале единицы
  2. Прописываем рекурсивную формулу для вычисления факториала
  3. Возвращаем результат
def factorial(num):
    if (num == 1):  # Это условие для факториала единицы 1! = 1 
        return 1

    # А это вычисление любого факториала
    num = num * factorial(num - 1)
    return num

Императивный

Описывает как найти объект или вычислить его значение.
Опять таки мы хотим бутерброд. «ЗАХАААР, иди на кухню, возьми и порежь хлеб, намажь на него масло и положи сверху три кусочка колбасы.» Идёт и делает по вашему алгоритму, а не как он умеет.

А вот факториал в императивном стиле.

  1. Объявляем счётчик
  2. Ставим цикл для вычисления любого факториала
  3. Возвращаем результат
    Разница в том, что тут нет рекурсии, условия для факториала единицы и структура построена иначе.
def factorial(num):
    counter = 1  
    result = 1  

    while(counter <= num):  # Выполняется пока счётчик не дойдёт до края, а если край один — сразу выходит из цикла
        result *= counter  # Сокращённое выражение result = result * counter
        counter += 1  # Сокращённое выражение counter = counter + 1

    return result

В маленьких проектах, разница между этими способами не сильно заметна, так что заставлять себя делать конкретно императивно или конкретно декларативно не нужно.
Это нужно для отдельных языков, например SQL — язык для работы с базами данных. В нём объекты и запросы описываются декларативно, вот так

/* Покажи имена сотрудников-инженеров из таблицы stuff. */
SELECT stuff_name FROM stuff WHERE post=‘Engineer’
/* SQL понимает задачу, а решение ему не дано и он делает всё сам. */

Тесты

Чтобы ловить логические ошибки и хитро скрытые баги существует библиотека PyTest. Использовать её на максимум мы пока что не можем — для этого нужно знать ООП и фикстуры. Про ООП будет позже, а про фикстуры ниже.
PyTest ставится через pip3.

На маках/линуксе
pip3 install pytest

На винде
pip install pytest

Фикстуры

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

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

Для примера по-проще, напишем код для вычисления наибольшего общего делителя по алгоритму Евклида. Пишем код в файле gcd.py

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

Чтобы запустить тесты пишем: pytest имя_файла.py.

assert вычисляет выражение в True или False. Если False, то это ошибка и тесты проваливаются. True — всё хорошо и красиво.


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

А вот так пройденный.



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

Поделиться
Отправить
Запинить
Популярное