Saltar a contenido

API — Sugestor

rutificador.sugestor.sugerir_ruts

sugerir_ruts(valor: str, limite: int = 5) -> list[str]

Genera sugerencias de RUTs válidos basados en una entrada posiblemente errónea.

Utiliza heurísticas de OCR y distancia de edición para encontrar el RUT más probable.

Parameters:

Name Type Description Default
valor str

Cadena de entrada (ej: '12.345.678-k', '12435678-5', 'I2.345.678-5').

required
limite int

Número máximo de sugerencias a devolver.

5

Returns:

Type Description
list[str]

Lista de RUTs sugeridos en formato 'base-dv'.

Source code in rutificador/sugestor.py
def sugerir_ruts(valor: str, limite: int = 5) -> list[str]:
    """Genera sugerencias de RUTs válidos basados en una entrada posiblemente errónea.

    Utiliza heurísticas de OCR y distancia de edición para encontrar el RUT
    más probable.

    Args:
        valor: Cadena de entrada (ej: '12.345.678-k', '12435678-5', 'I2.345.678-5').
        limite: Número máximo de sugerencias a devolver.

    Returns:
        Lista de RUTs sugeridos en formato 'base-dv'.
    """
    candidatos_con_dist = _sugerir_ruts_con_distancia(valor, limite)
    return [rut for rut, dist in candidatos_con_dist]

rutificador.sugestor.mejorar_con_confianza

mejorar_con_confianza(valor: str, distancia_max: int = 1) -> str | None

Toma una decisión de corrección automática solo si es inequívoca.

Para ser 'segura', una sugerencia debe: 1. Ser la única con la distancia mínima encontrada. 2. Tener una distancia <= distancia_max (por defecto 1).

Returns:

Type Description
str | None

El RUT sugerido si es seguro, None en caso de ambigüedad o baja confianza.

Source code in rutificador/sugestor.py
def mejorar_con_confianza(valor: str, distancia_max: int = 1) -> str | None:
    """Toma una decisión de corrección automática solo si es inequívoca.

    Para ser 'segura', una sugerencia debe:
    1. Ser la única con la distancia mínima encontrada.
    2. Tener una distancia <= distancia_max (por defecto 1).

    Returns:
        El RUT sugerido si es seguro, None en caso de ambigüedad o baja confianza.
    """
    # Obtenemos las 2 mejores para detectar empates
    candidatos = _sugerir_ruts_con_distancia(valor, limite=2)

    if not candidatos:
        return None

    mejor_rut, mejor_dist = candidatos[0]

    # 1. Verificar umbral de confianza (distancia de edición razonable)
    if mejor_dist > distancia_max:
        return None

    # 2. Verificar ambigüedad (si hay un segundo candidato con la misma distancia mínima)
    if len(candidatos) > 1:
        segundo_rut, segunda_dist = candidatos[1]
        if mejor_dist == segunda_dist:
            logger.warning(
                "Ambigüedad detectada para '%s': varios candidatos a distancia %d. "
                "Opciones: %s, %s",
                valor,
                mejor_dist,
                mejor_rut,
                segundo_rut,
            )
            return None

    return mejor_rut

rutificador.sugestor.distancia_levenshtein

distancia_levenshtein(s1: str, s2: str) -> int

Calcula la distancia de Damerau-Levenshtein entre dos cadenas.

Detecta inserción, eliminación, sustitución y transposición de dos caracteres adyacentes (error común de digitación).

Source code in rutificador/sugestor.py
def distancia_levenshtein(s1: str, s2: str) -> int:
    """Calcula la distancia de Damerau-Levenshtein entre dos cadenas.

    Detecta inserción, eliminación, sustitución y transposición de dos caracteres
    adyacentes (error común de digitación).
    """
    d: dict[tuple[int, int], int] = {}
    long1 = len(s1)
    long2 = len(s2)
    for i in range(-1, long1 + 1):
        d[(i, -1)] = i + 1
    for j in range(-1, long2 + 1):
        d[(-1, j)] = j + 1

    for i in range(long1):
        for j in range(long2):
            costo = 0 if s1[i] == s2[j] else 1
            d[(i, j)] = min(
                d[(i - 1, j)] + 1,  # Eliminación
                d[(i, j - 1)] + 1,  # Inserción
                d[(i - 1, j - 1)] + costo,  # Sustitución
            )
            # Transposición (Damerau)
            if i > 0 and j > 0 and s1[i] == s2[j - 1] and s1[i - 1] == s2[j]:
                d[(i, j)] = min(d[(i, j)], d[(i - 2, j - 2)] + costo)

    return d[(long1 - 1, long2 - 1)]