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

Diseño por niveles Python: Abstracción con datos

En esta lección, veremos cómo representar números racionales en Python 🧮, creando nuestra propia abstracción. También exploraremos las barreras de abstracción y cómo dividir un sistema en niveles bien definidos.


¿Qué es un número racional?

El número racional es aquel que se puede representar como el cociente de dos enteros:

\[ a/b \]

Donde:

  • a es el numerador (el número de arriba).
  • b es el denominador (el número de abajo) y no puede ser cero porque no podemos dividir entre cero.

Ejemplos de números racionales:

Representación fraccionaria Valor decimal
1/2 0.5
3/4 0.75
5/1 5.0

Python no tiene un tipo de dato específico para números racionales, por lo que crearemos nuestra propia abstracción.


Creando números racionales en Python

Para trabajar con racionales, necesitamos:

  1. Un constructor: para crear un número racional.
  2. Selectores: para obtener el numerador y el denominador.

Veamos un ejemplo:

# Creamos una fracción 1/2
num = make_rational(1, 2)

numer = get_numer(num)  # Obtenemos el numerador → 1
denom = get_denom(num)  # Obtenemos el denominador → 2

Aquí, make_rational() crea el número racional y get_numer() y get_denom() nos permiten extraer sus partes.

Podríamos representar el número racional de distintas maneras, por ejemplo, usando cadenas de texto:

def make_rational(numer, denom):
    return f"{numer}/{denom}"

def get_numer(rational):
    numer, _ = rational.split('/')
    return int(numer)

def get_denom(rational):
    _, denom = rational.split('/')
    return int(denom)

num = make_rational(10, 3)
print(num)  # "10/3"

Sin embargo, al representar los racionales como cadenas, la operación con ellos se vuelve difícil. La verdadera utilidad de la abstracción llega cuando podemos realizar operaciones matemáticas con nuestros números racionales.


Operaciones con números racionales

Si queremos operar con fracciones, podemos definir funciones para hacer operaciones básicas como suma, resta o multiplicación.

Por ejemplo, así funciona la multiplicación de fracciones:

\[ \frac{3}{4} \times \frac{4}{5} = \frac{3 \times 4}{4 \times 5} = \frac{12}{20} \]

Si estamos representando un número racional como un diccionario, nuestra función de multiplicación podría verse así:

def multiply_rational(rational1, rational2):
    return {
        "numer": rational1["numer"] * rational2["numer"],
        "denom": rational1["denom"] * rational2["denom"],
    }

Esta función respeta la abstracción: trabaja con "números racionales" sin preocuparse por cómo están implementados internamente.

Pero, ¿qué pasaría si cambiamos la estructura interna de nuestros racionales? Si lo hacemos, tendríamos que modificar todas las funciones que acceden directamente a numer y denom.

Para evitar esto, seguimos un principio fundamental en programación:

💡Cada parte del código debe trabajar en un único nivel de abstracción.

Esto nos lleva a un concepto clave en el desarrollo de software: el diseño por niveles.


Diseño por niveles

En sistemas complejos, usar una estructura por niveles facilita la organización del código.

Cada nivel de abstracción:

  1. Oculta los detalles de su implementación.
  2. Expone una forma clara de usarlo.
  3. Permite reutilizar sus funciones sin conocer cómo funcionan internamente.

Veamos un ejemplo de esta estructura en nuestra implementación de números racionales:

def multiply_rational(rational1, rational2):
    return make_rational(
        get_numer(rational1) * get_numer(rational2),
        get_denom(rational1) * get_denom(rational2),
    )

Aquí se respetan los niveles de abstracción:

  1. Nivel base: Los números y diccionarios de Python.
  2. Nivel de racionales: make_rational, get_numer, get_denom.
  3. Nivel de operaciones: funciones como multiply_rational.

Cada nivel puede cambiarse sin afectar el resto del código, siempre que las funciones de cada nivel se sigan usando correctamente.

Podemos usar estos niveles en una función que utilice varias operaciones:

def f(rational1, rational2):
    rational3 = multiply_rational(rational1, rational2)
    denom = get_denom(rational3)
    numer = get_numer(rational3)
    print(f"Denominador: {denom}")
    print(f"Numerador: {numer}")
💡 Esta manera de diseñar sistemas se aplica más allá de los números racionales. Toda la arquitectura del software sigue este principio de niveles.

Por ejemplo:

  • Los sistemas operativos tienen niveles: desde la interacción con el hardware hasta la interfaz gráfica.
  • En una página web: el backend gestiona datos y el frontend los muestra sin conocer su almacenamiento interno.

Resumen

  • Un número racional es un número que puede expresarse como a/b, donde b ≠ 0.
  • Python no tiene un tipo específico para números racionales, así que creamos nuestra propia abstracción.
  • Abstraemos los números racionales usando:
    • Un constructor (make_rational).
    • Selectores (get_numer y get_denom).
  • Las operaciones como la multiplicación se implementan sin depender de la estructura interna.
  • El diseño por niveles permite construir sistemas modulares y fáciles de modificar.

Siguiendo estas ideas, podemos modelar estructuras más complejas sin perder claridad en nuestro código.

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