from typing import Callable


def _integrate(function: Callable[[float, ], float],
               start: float, end: float, n: int) -> float:
    """
    Calculate defined integral of given `function` in range of
    [start, end]

    :param function: Function to integrate
    :param start: Left bound
    :param end: Right bound
    :param n: Number of parabolas used to compute integral
    :raise ValueError: When n is not even
    :raise ValueError: When start is greater or equal to end
    :return: Field of area under given `function`
    """
    if n % 2 != 0:
        raise ValueError("In Simpson rule n have to be even")
    if start >= end:
        raise ValueError(
            f"Upper bound ({end}) is lesser or equal to lower ({start})")

    step = (end - start) / n

    _sum = function(start) + function(end)
    for i in range(1, n):
        if i % 2 == 0:
            _sum += 2 * function(start + i * step)
        else:
            _sum += 4 * function(start + i * step)

    return (step / 3) * _sum