from typing import Iterable


def first(it: Iterable, condition=lambda x: True):
    # noinspection PyUnresolvedReferences
    """Function returning the first item in the iterable that satisfies the
    condition.  This function is taken almost directly from:
    https://stackoverflow.com/a/35513376

    >>> first((1,2,3), condition=lambda x: x % 2 == 0)
    2
    >>> first(range(3, 100))
    3
    >>> first(())
    Traceback (most recent call last):
    ...
    StopIteration

    Parameters
    ----------
    it : Iterable
        Iterable to search.
    condition : boolean function (optional)
        Boolean condition applied to each iterable.  If the condition is not
        given, the first item is returned.

    Returns
    -------
    first_item :
        First item in the iterable `it` that satisfying the condition.

    Raises:
        StopIteration if no item satysfing the condition is found.
    """
    return next(x for x in it if condition(x))