Portada de libro electrónico gratuitaPython desde cero con mini-retos: aprende programando (sin teoría eterna)

Python desde cero con mini-retos: aprende programando (sin teoría eterna)

Nuevo curso

12 páginas

Mini-reto: conversor de unidades con reglas y precisión

Capítulo 8

Tiempo estimado de lectura: 6 minutos

+ Ejercicio

Objetivo del mini-reto

Vas a construir un conversor de unidades por consola que aplique reglas (qué conversiones están permitidas) y entregue resultados con precisión controlada (redondeo consistente). La idea es que tu programa no solo “haga cuentas”, sino que también se comporte como una herramienta confiable: valida la solicitud, rechaza combinaciones inválidas y formatea la salida.

Qué significa “reglas” en un conversor

Un conversor real no permite cualquier combinación. Por ejemplo, convertir metros a kilogramos no tiene sentido. Aquí las “reglas” se implementan como un catálogo de conversiones válidas, agrupadas por categoría (longitud, masa, temperatura, etc.).

Reglas mínimas recomendadas

  • Solo se puede convertir dentro de la misma categoría (longitud con longitud, masa con masa).
  • Si una unidad no existe en el catálogo, se rechaza.
  • Si la conversión no está definida, se rechaza (aunque ambas unidades existan).
  • La salida debe respetar una cantidad de decimales configurable.

Qué significa “precisión” (y por qué importa)

En conversiones, especialmente con decimales, es común obtener resultados como 1.9999999997 por cómo se representan los números en la computadora. Para que el usuario vea un resultado “humano”, se define una regla de redondeo: por ejemplo, mostrar siempre 2 o 3 decimales.

Decisiones de precisión

  • Decimales fijos: siempre mostrar N decimales (útil para consistencia).
  • Decimales configurables: el usuario elige N (útil para flexibilidad).
  • Redondeo: usar round(valor, decimales) y/o formateo con f-strings.

Diseño del conversor: enfoque práctico

Para que sea fácil de ampliar, separa el problema en dos partes: (1) un catálogo de unidades y reglas, (2) una función que resuelva la conversión y aplique precisión.

Catálogo por categorías (con factores)

Para unidades lineales (longitud, masa), una forma simple es definir un “factor” respecto a una unidad base. Ejemplo: en longitud, base = metro. Entonces km vale 1000 metros, cm vale 0.01 metros, etc. Convertir se vuelve: valor_en_base = valor * factor_origen y luego valor_destino = valor_en_base / factor_destino.

Continúa en nuestra aplicación.

Podrás escuchar el audiolibro con la pantalla apagada, recibir un certificado gratuito para este curso y además tener acceso a otros 5.000 cursos online gratuitos.

O continúa leyendo más abajo...
Download App

Descargar la aplicación

UNIDADES = {    "longitud": {        "m": 1.0,        "km": 1000.0,        "cm": 0.01,        "mm": 0.001    },    "masa": {        "kg": 1.0,        "g": 0.001,        "lb": 0.45359237    } }

Para temperatura, no alcanza con factores porque hay desplazamientos (C↔F). Ahí conviene definir reglas como funciones específicas.

def c_a_f(c):    return (c * 9/5) + 32def f_a_c(f):    return (f - 32) * 5/9

Guía paso a paso (implementación)

Paso 1: define las reglas de conversión

Combina dos enfoques: factores para categorías “multiplicativas” y funciones para casos especiales como temperatura.

UNIDADES = {    "longitud": {"m": 1.0, "km": 1000.0, "cm": 0.01, "mm": 0.001},    "masa": {"kg": 1.0, "g": 0.001, "lb": 0.45359237}}TEMPERATURA = {    ("c", "f"): lambda c: (c * 9/5) + 32,    ("f", "c"): lambda f: (f - 32) * 5/9,    ("c", "k"): lambda c: c + 273.15,    ("k", "c"): lambda k: k - 273.15}

Nota: usa claves en minúsculas para simplificar la validación. Si el usuario escribe KM, lo pasas a km.

Paso 2: crea una función para detectar la categoría

Necesitas saber si ambas unidades pertenecen a la misma categoría (longitud o masa) para permitir la conversión por factores.

def categoria_de(unidad):    for categoria, mapa in UNIDADES.items():        if unidad in mapa:            return categoria    return None

Paso 3: implementa la conversión con reglas

La función debe: validar unidades, decidir si usa factores o funciones especiales, y rechazar lo inválido con un mensaje claro.

def convertir(valor, origen, destino):    origen = origen.lower().strip()    destino = destino.lower().strip()    # 1) Reglas especiales: temperatura    if (origen, destino) in TEMPERATURA:        return TEMPERATURA[(origen, destino)](valor)    # 2) Reglas por categoría (factores)    cat_origen = categoria_de(origen)    cat_destino = categoria_de(destino)    if cat_origen is None or cat_destino is None:        raise ValueError("Unidad desconocida (no está en el catálogo)")    if cat_origen != cat_destino:        raise ValueError("Conversión inválida: unidades de categorías distintas")    factor_origen = UNIDADES[cat_origen][origen]    factor_destino = UNIDADES[cat_origen][destino]    valor_base = valor * factor_origen    return valor_base / factor_destino

Paso 4: aplica precisión y formatea la salida

Decide cuántos decimales mostrar. Puedes pedirlos al usuario o fijarlos. Aquí se muestra un ejemplo configurable.

def formatear_resultado(valor, decimales):    redondeado = round(valor, decimales)    return f"{redondeado:.{decimales}f}"

Esto asegura decimales fijos. Por ejemplo, con 2 decimales, 3 se muestra como 3.00.

Paso 5: arma el flujo por consola (entrada → reglas → salida)

Este flujo guía al usuario y muestra errores sin “romper” la experiencia. Mantén el intercambio simple: valor, unidad origen, unidad destino, decimales.

def main():    print("Conversor de unidades")    print("Ejemplos: 1500 m a km | 2.5 kg a lb | 100 c a f")    valor_txt = input("Valor: ")    origen = input("Unidad origen: ")    destino = input("Unidad destino: ")    dec_txt = input("Decimales (por ejemplo 2): ")    try:        valor = float(valor_txt)        decimales = int(dec_txt)        if decimales < 0 or decimales > 10:            raise ValueError("Decimales fuera de rango (0 a 10)")        resultado = convertir(valor, origen, destino)        salida = formatear_resultado(resultado, decimales)        print(f"Resultado: {salida} {destino.lower().strip()}")    except ValueError as e:        print(f"Error: {e}")

Mini-reto: requisitos exactos a cumplir

Parte A (obligatoria): conversiones por factores

  • Soporta al menos longitud: mm, cm, m, km.
  • Soporta al menos masa: g, kg, lb.
  • Rechaza conversiones entre categorías (ej.: m a kg).
  • Rechaza unidades desconocidas.
  • Permite elegir decimales (0 a 10).

Parte B (obligatoria): reglas especiales de temperatura

  • Soporta al menos cf y ck.
  • Estas conversiones deben funcionar aunque no estén en el mapa de factores.

Parte C (precisión): salida consistente

  • Muestra el resultado con el número de decimales indicado.
  • Evita mostrar “ruido” de coma flotante (usa round y formateo).

Casos de prueba rápidos (para verificar reglas y precisión)

  • Longitud: 1500 m → km con 2 decimales debe dar 1.50.
  • Longitud: 1 km → mm con 0 decimales debe dar 1000000.
  • Masa: 2.5 kg → lb con 3 decimales debe dar aproximadamente 5.512.
  • Temperatura: 100 c → f con 1 decimal debe dar 212.0.
  • Regla de categorías: 10 m → kg debe dar error de categorías distintas.
  • Unidad desconocida: 3 foo → m debe dar error de unidad desconocida.

Extensiones opcionales (si terminas rápido)

1) Sinónimos de unidades

Permite que el usuario escriba metros y lo mapeas a m, o kilometros a km.

SINONIMOS = {"metro": "m", "metros": "m", "kilometro": "km", "kilometros": "km"}def normalizar_unidad(u):    u = u.lower().strip()    return SINONIMOS.get(u, u)

2) Tabla de conversiones permitidas

En vez de permitir cualquier par dentro de una categoría, puedes definir un conjunto explícito de pares permitidos y rechazar el resto.

PERMITIDAS = {    "longitud": {("m","km"), ("km","m"), ("cm","m"), ("m","cm")},    "masa": {("kg","lb"), ("lb","kg"), ("g","kg"), ("kg","g")}}# Si activas esta regla, valida (origen, destino) antes de convertir.

3) Modo “lote”

Permite ingresar varias conversiones separadas por coma y devolver una lista de resultados, aplicando las mismas reglas y precisión.

Ahora responde el ejercicio sobre el contenido:

En un conversor de unidades con reglas y precisión, ¿qué comportamiento es el más adecuado cuando el usuario intenta convertir entre categorías distintas o usa una unidad que no está en el catálogo?

¡Tienes razón! Felicitaciones, ahora pasa a la página siguiente.

¡Tú error! Inténtalo de nuevo.

Un conversor confiable debe validar: si la unidad no existe en el catálogo o las unidades pertenecen a categorías distintas, la conversión se rechaza con un error. Solo se convierte cuando la regla está definida y luego se formatea con la precisión indicada.

Siguiente capítulo

Mini-reto: agenda simple con operaciones CRUD usando listas

Arrow Right Icon
Descarga la aplicación para obtener una certificación gratuita y escuchar cursos en segundo plano, incluso con la pantalla apagada.