Skip to content

Latest commit

 

History

History
98 lines (82 loc) · 3.8 KB

Контрактное программирование .md

File metadata and controls

98 lines (82 loc) · 3.8 KB

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

Контрактное программирование (design by contract (DbC), programming by contract, contract-based programming) — это метод проектирования программного обеспечения. Он предполагает, что проектировщик должен определить формальные, точные и верифицируемые спецификации интерфейсов для компонентов системы. При этом, кроме обычного определения абстрактных типов данных, также используются предусловия, постусловия и инварианты. Данные спецификации называются «контрактами» в соответствии с концептуальной метафорой условий и ответственности в гражданско-правовых договорах.

pycontracts — способ проверять данные на входе/выходе функции в runtime.

Такой подход позволяет:

  • проще писать тесты – проблемы с валидацией не возникают, и покрывается только бизнес-логика.
  • гарантировать формат и качество ответа в API – появляются жесткие рамки того, что мы готовы принять и что мы можем отдать.
  • проще понимать/рефакторить формат ответа, если это сложная структура с разными уровнями вложенности.

Контракты могут быть реализованы тремя способами:

Использование @contract декоратор:

@contract(a='int,>0', b='list[N],N>0', returns='list[N]')
def my_function(a, b):
    ...

Использование аннотаций (for Python 3):

@contract
def my_function(a : 'int,>0', b : 'list[N],N>0') -> 'list[N]':
     # Requires b to be a nonempty list, and the return
     # value to have the same length.
     ...

Использование строк документации, вместе с :type: и :rtype: tags:

@contract
def my_function(a, b):
    """ Function description.
        :type a: int,>0
        :type b: list[N],N>0
        :rtype: list[N]
    """

Подробнее о pycontracts(список литературы 2 строчка)

Пример функций

from contracts import contract

#  решение функции x^2/y*2
@contract
def foo(x, y):
    """
    :type x: int|float,!= 0
    :type y: int|float, != 0
    :rtype: int|float
    """
    if x != 0 & y != 0:
        return (x**2)/(y*2)
    else:
         return -1

# возведение x в степень a(где a>=0)
@contract
def exponentiationFoo(x, a):
    """
    :type x: int|float, > 0
    :type a: int|float, >= 0
    :rtype: int|float
    """
    if a >= 0:
        return x**a
    else:
        return -1

Схема программы

Начало
ввод(x, y, z);
если p1(x,y,z) то на L3
    если p2(x,y) и p2(x,z) то на L1;
        если p2(y,z) то на L2;
            z=g1(x,y);
            на L3;
L1: x= g1(y,z);
на L3;
L2: y= g1(x,z);
L3: вывод(x,y,z);
Конец
        

Список литературы