Regístrate para acceder a más de 15 cursos gratuitos de programación con un simulador

Invariantes Python: Abstracción con datos

✅ La abstracción nos permite usar algo sin preocuparnos por cómo funciona. Esto hace el código más limpio, flexible y facilita cambios sin afectar su uso.

Además, ayuda a mantener la consistencia de los datos. En esta lección veremos tres conceptos clave:

  • Invariantes: reglas que aseguran datos coherentes.
  • Normalización: mantener los datos en un formato estándar.
  • Ocultamiento de datos: evitar modificaciones inesperadas.

Invariantes

La invariante en programación es una regla que siempre debe cumplirse para que los datos sean consistentes.

Cuando trabajamos con números racionales (fracciones), esperamos que la abstracción funcione de manera predecible.

Por ejemplo, si tenemos funciones para crear y acceder a números racionales:

num = make_rational(3, 4)

numer = get_numer(num)
denom = get_denom(num)

print(numer == 3)  # Esperamos True
print(denom == 4)  # Esperamos True

Aquí asumimos que si creamos un número racional con 3/4, entonces la función get_numer nos devolverá 3, y get_denom nos devolverá 4.

Si la implementación internamente alterara estos valores sin que lo sepamos, el comportamiento sería inesperado.

Invariantes al comparar números racionales

Una fracción como 1/2 es igual a 2/4, aunque tengan numerador y denominador diferentes. Pero si los comparamos directamente sin normalizarlos, obtenemos un resultado incorrecto:

num1 = make_rational(2, 4)
num2 = make_rational(8, 16)

print(num1 == num2)  # Falso, pero deberían ser iguales

Esto sucede porque internamente num1 y num2 tienen numeradores y denominadores distintos, aunque representan la misma fracción. Para corregir esto, usamos normalización.

Normalización

La normalización es el proceso de convertir los datos a una forma estándar para evitar inconsistencias.

En el caso de las fracciones, podemos dividir el numerador y denominador por su máximo común divisor (MCD) para asegurar que guardamos siempre la versión más simple.

Ejemplo de normalización:

num = make_rational(10, 20)

print(get_numer(num))  # 1
print(get_denom(num))  # 2

Internamente, 10/20 se convierte en 1/2, evitando problemas al comparar fracciones.

Dónde hacer la normalización

Podemos normalizar en dos puntos:

Método Ventajas y desventajas
En la creación de la fracción (make_rational) Se normaliza solo una vez, lo que es más eficiente, evitando recalcular en cada acceso.
Al acceder a los datos (get_numer y get_denom) Cada acceso normaliza los datos, lo cual puede ser costoso si se llama muchas veces.

Para evitar recálculos innecesarios, podemos usar memoización, que almacena los valores ya calculados.

Ocultar Datos

Hasta ahora, hemos asumido que los datos solo se pueden modificar mediante nuestras funciones.

🤔 Pero, ¿qué pasa si alguien accede directamente y modifica los valores?

num = make_rational(10, 20)
num["numer"] = 40  # Modificación directa

print(get_numer(num))  # Ahora devuelve 40 en lugar de 1
print(get_denom(num))  # 20 en lugar de 2

Aquí se rompe la abstracción porque alguien cambió directamente el numerador sin aplicar normalización.

Para evitar esto, podemos aplicar ocultamiento de datos:

🫣 En algunos lenguajes, hay formas de marcar atributos como "privados" (por ejemplo, __atributo en Python).
🫣 También podemos evitar exponer estructuras de datos directas y solo ofrecer acceso controlado mediante funciones.
🫣 Técnicas como closures permiten encapsular datos sin exponerlos directamente.

En la práctica, la mayoría de los programadores respetan la abstracción sin intentar romperla. Incluso en lenguajes sin protecciones estrictas, es común simplemente seguir las reglas establecidas por el código.


Resumen

  • La invariante es una regla que garantiza que los datos sean consistentes.
  • La normalización convierte los datos a una forma estándar para evitar inconsistencias.
  • Si no se normalizan las fracciones, es posible que tengan diferentes representaciones pero no sean iguales en una comparación.
  • Para evitar modificaciones directas e inesperadas, podemos ocultar datos utilizando abstracciones y técnicas como closures o atributos privados.

Materiales adicionales

  1. Memoización 📚 Wikipedia
  2. Reflection 📚 Wikipedia

Para acceder completo a curso necesitas un plan básico

El plan básico te dará acceso completo a todos los cursos, ejercicios y lecciones de Códica, proyectos y acceso de por vida a la teoría de las lecciones completadas. La suscripción se puede cancelar en cualquier momento.

Obtener acceso
130
cursos
1000
ejercicios
2000+
horas de teoría
3200
test

Obtén acceso

Cursos de programación para principiantes y desarrolladores experimentados. Comienza tu aprendizaje de forma gratuita

  • 130 cursos, 2000+ horas de teoría
  • 1000 ejercicios prácticos en el navegador
  • 360 000 estudiantes
Al enviar el formulario, aceptas el «Política de privacidad» y los términos de la «Oferta», y también aceptas los «Términos y condiciones de uso»

Nuestros graduados trabajan en empresas como:

Bookmate
Health Samurai
Dualboot
ABBYY