import math
from typing import Counter


def entropy(data, unit='natural'):
    """
    Compute and return the entropy of a stream of data.

    :param bytearray data: Stream to compute entropy on.
    :param str,optional unit: Passed to math.log calculation.
    Default is natural.

    :return: Entropy calculation
    :rtype: float
    """
    base = {
        'shannon': 2.,
        'natural': math.exp(1),
        'hartley': 10.
    }

    if len(data) <= 1:
        return 0

    counts = Counter()

    for d in data:
        counts[d] += 1

    probs = [float(c) / len(data) for c in list(counts.values())]
    probs = [p for p in probs if p > 0.]

    ent = 0

    for p in probs:
        if p > 0.:
            ent -= p * math.log(p, base[unit])

    return ent