← Volver al listado de tecnologías

Capítulo 2: Conversor de Unidades

Por: SiempreListo
pythonzigclibásico

Conversor de Unidades

Un programa que convierte entre diferentes unidades de longitud, peso y temperatura.

Conceptos que Aprenderás

Python

from dataclasses import dataclass
from typing import Callable

@dataclass
class Conversion:
    nombre: str
    a_base: Callable[[float], float]
    de_base: Callable[[float], float]

LONGITUD = {
    'km': Conversion('kilómetros', lambda x: x * 1000, lambda x: x / 1000),
    'm': Conversion('metros', lambda x: x, lambda x: x),
    'cm': Conversion('centímetros', lambda x: x / 100, lambda x: x * 100),
    'mi': Conversion('millas', lambda x: x * 1609.34, lambda x: x / 1609.34),
}

TEMPERATURA = {
    'c': Conversion('Celsius', lambda x: x, lambda x: x),
    'f': Conversion('Fahrenheit', lambda x: (x - 32) * 5/9, lambda x: x * 9/5 + 32),
    'k': Conversion('Kelvin', lambda x: x - 273.15, lambda x: x + 273.15),
}

def convertir(valor: float, de: str, a: str, tabla: dict) -> float:
    en_base = tabla[de].a_base(valor)
    return tabla[a].de_base(en_base)

def main():
    print("Categorías: longitud, temperatura")
    cat = input("Categoría: ").lower()
    tabla = LONGITUD if cat == 'longitud' else TEMPERATURA

    print(f"Unidades: {', '.join(tabla.keys())}")
    de = input("De: ").lower()
    a = input("A: ").lower()
    valor = float(input("Valor: "))

    resultado = convertir(valor, de, a, tabla)
    print(f"{valor} {tabla[de].nombre} = {resultado:.4f} {tabla[a].nombre}")

if __name__ == "__main__":
    main()

Zig

const std = @import("std");

const Conversion = struct {
    nombre: []const u8,
    a_base: *const fn (f64) f64,
    de_base: *const fn (f64) f64,
};

fn identidad(x: f64) f64 { return x; }
fn km_a_m(x: f64) f64 { return x * 1000; }
fn m_a_km(x: f64) f64 { return x / 1000; }
fn cm_a_m(x: f64) f64 { return x / 100; }
fn m_a_cm(x: f64) f64 { return x * 100; }

const longitud = [_]struct { clave: []const u8, conv: Conversion }{
    .{ .clave = "km", .conv = .{ .nombre = "kilómetros", .a_base = km_a_m, .de_base = m_a_km } },
    .{ .clave = "m", .conv = .{ .nombre = "metros", .a_base = identidad, .de_base = identidad } },
    .{ .clave = "cm", .conv = .{ .nombre = "centímetros", .a_base = cm_a_m, .de_base = m_a_cm } },
};

fn buscar(clave: []const u8) ?Conversion {
    for (longitud) |item| {
        if (std.mem.eql(u8, item.clave, clave)) return item.conv;
    }
    return null;
}

fn convertir(valor: f64, de: Conversion, a: Conversion) f64 {
    const en_base = de.a_base(valor);
    return a.de_base(en_base);
}

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    const stdin = std.io.getStdIn().reader();
    var buf: [100]u8 = undefined;

    try stdout.print("De (km, m, cm): ", .{});
    const de_str = stdin.readUntilDelimiter(&buf, '\n') catch return;
    const de = buscar(de_str) orelse {
        try stdout.print("Unidad no válida\n", .{});
        return;
    };

    try stdout.print("A (km, m, cm): ", .{});
    const a_str = stdin.readUntilDelimiter(&buf, '\n') catch return;
    const a = buscar(a_str) orelse {
        try stdout.print("Unidad no válida\n", .{});
        return;
    };

    try stdout.print("Valor: ", .{});
    const val_str = stdin.readUntilDelimiter(&buf, '\n') catch return;
    const valor = std.fmt.parseFloat(f64, val_str) catch return;

    const resultado = convertir(valor, de, a);
    try stdout.print("{d} {s} = {d:.4} {s}\n", .{ valor, de.nombre, resultado, a.nombre });
}

Diferencias Clave

AspectoPythonZig
Estructurasdataclassstruct
FuncionesLambdasPunteros a función
Búsquedadict[key]Iteración manual

Ejercicios

  1. Agrega unidades de peso (kg, lb, oz)
  2. Implementa conversión de monedas con API externa
  3. Guarda conversiones frecuentes en archivo

← Anterior | Siguiente →