from typing import Iterable
from typing import Tuple
import functools


def min_max(x: Iterable[int]) -> Tuple[int, int]:
    """ Returns both the min and max of a sequence.
    This, rather than calling min(x), max(x), will work when a generator (or other single-use iterator) is passed in
    """
    try:
        seq = iter(x)
        start = next(seq)
    except StopIteration:
        raise ValueError('min_max() arg is an empty sequence')
    return functools.reduce(lambda left, right: (min(left[0], right), max(left[1], right)), seq, (start, start))