"""One solution. Try the exercise first."""
import math
import zlib

WORDS_PER_SECOND = 2.7


def length_ratio(n_words: int, speech_seconds: float) -> float:
    return n_words / (WORDS_PER_SECOND * speech_seconds + 0.2)


def compression_ratio(text: str) -> float:
    data = text.encode()
    return len(data) / len(zlib.compress(data)) if data else 0.0


def repeated_ngrams(text: str, n: int = 4) -> float:
    words = text.lower().split()
    grams = [tuple(words[i:i + n]) for i in range(len(words) - n + 1)]
    return 1 - len(set(grams)) / len(grams) if grams else 0.0


def wilson(k: int, n: int, z: float = 1.96) -> tuple[float, float]:
    if n == 0:
        return 0.0, 1.0
    p = k / n
    centre = (p + z * z / (2 * n)) / (1 + z * z / n)
    half = z * math.sqrt(p * (1 - p) / n + z * z / (4 * n * n)) / (1 + z * z / n)
    return max(0.0, centre - half), min(1.0, centre + half)
