def words_amount_needed(entropybits: Union[int, float],
                        entropy_w: Union[int, float],
                        entropy_n: Union[int, float],
                        amount_n: int) -> int:
    """Calculate words needed for a passphrase based on entropy."""
    # Thanks to @julianor for this tip to calculate default amount of
    # entropy: minbitlen/log2(len(wordlist)).
    # I set the minimum entropy bits and calculate the amount of words
    # needed, cosidering the entropy of the wordlist.
    # Then: entropy_w * amount_w + entropy_n * amount_n >= ENTROPY_BITS_MIN

    if not isinstance(entropybits, (int, float)):
        raise TypeError('entropybits can only be int or float')
    if not isinstance(entropy_w, (int, float)):
        raise TypeError('entropy_w can only be int or float')
    if not isinstance(entropy_n, (int, float)):
        raise TypeError('entropy_n can only be int or float')
    if not isinstance(amount_n, int):
        raise TypeError('amount_n can only be int')
    if entropybits < 0:
        raise ValueError('entropybits should be greater than 0')
    if entropy_w <= 0:
        raise ValueError('entropy_w should be greater than 0')
    if entropy_n < 0:
        raise ValueError('entropy_n should be greater than 0')
    if amount_n < 0:
        raise ValueError('amount_n should be greater than 0')

    amount_w = (entropybits - entropy_n * amount_n) / entropy_w

    if amount_w > -1.0:
        return ceil(fabs(amount_w))

    return 0
Calculate words needed for a passphrase based on entropy.