viernes, 28 de marzo de 2025

Lenguajes dependientes de la Java Virtual Machine (JVM)

Un lenguaje de programación dependiente de la JVM es aquel que permite:

  • Ejecución en la JVM
  • Independencia de la plataforma. 
  • Gestión automática de memoria. 
  • Soporte para múltiples paradigmas. 
  • Interoperabilidad. 
  • Amplia biblioteca estándar. 
  • Compilación a bytecode
  • Soporte para concurrencia.

Es decir, un programa escrito en un lenguaje de programación dependiente de la JVM podrá ser:

  1. Ejecutado en cualquier sistema operativo que cuente con una JVM, sin la necesidad de ser modificado. 
  2. Su memoria se autogestionará gracias a un recolector de basura. 
  3. Se ejecutará en un entorno seguro, gracias a su modelo de seguridad. 
  4. Podrá implementar múltiples paradigmas de programación (estructurada, funcional orientada a objetos, etc.). 
  5. Puede emplear librerías creadas en otros lenguajes dependientes, lo que se se conoce como interoperabilidad. 
  6. El bytecode generado por la compilación es un código optimizado (optimización JIT), lo que mejora su ejecución y rendimiento. 
  7. Permitir el uso de hilos. 
  8. Etc.

He aquí una lista de los lenguajes de programación dependientes de la JVM más conocidos, sin tomar en cuenta a Java.

Ballerina

Es un lenguaje de programación de código abierto diseñado por WSO2, enfocado en aplicaciones nativas de la nube y la integración de servicios distribuidos.

https://ballerina.io/

Ceylon

Fue un lenguaje de programación de propósito general con una sintaxis similar a la de Java y C#. Imperativo, estático, estructurado en bloques, orientado a objetos y de orden superior.

https://projects.eclipse.org/projects/technology.ceylon

Actualmente se encuentra congelado. Una lástima, se esperaba mucho de este lenguaje. Al punto de que se creyó, realmente, como el verdadero sucesor de Java.

Concurnas

Es un lenguaje de programación JVM de código abierto diseñado para construir sistemas concurrentes, distribuidos y paralelos confiables, escalables y de alto rendimiento.

https://concurnas.com/

Clojure

Es un lenguaje de programación robusto, práctico y rápido con un conjunto de características útiles que juntas forman una herramienta simple, coherente y poderosa. Se basa en Lisp.

https://clojure.org/

Gosu

Un lenguaje JVM simple, muy simple.

https://gosu-lang.github.io/

Groovy

Es un lenguaje multifacético para la JVM. Su objetivo es proporcionar una experiencia y sintaxis similares a las de Java, pero con funciones de productividad adicionales.

https://groovy-lang.org/

Haxe

Es un lenguaje de programación estrictamente tipado, de alto nivel y código abierto con un compilador cruzado de rápida optimización.

https://haxe.org/

Jabaco

Es un lenguaje de programación dependiente de la JVM que usa como base a Visual Basic.

https://www.jabaco.org/

JRuby

Es una implementación de Ruby en Java.

https://www.jruby.org/

Jython

Se considera como una implementación de Python en Java.

https://www.jython.org/

Kotlin

Es un lenguaje de programación orientado a objetos multiplataforma, estáticamente tipado, de alto nivel y propósito general con inferencia de tipos. Actualmente muy usado para REST APIs y desarrollo de aplicaciones para móviles.

https://kotlinlang.org/

Scala

Es un lenguaje de programación multi-paradigma diseñado para expresar patrones comunes de programación en forma concisa, elegante y con tipos seguros.

https://www.scala-lang.org/

Existen más lenguajes, sin embargo la lista anterior solo incluye los más conocidos.

Enlaces:

https://web.mit.edu/ceylon_v1.3.3/ceylon-1.3.3/doc/en/spec/html_single/
https://codemonkeyjunior.blogspot.com/2024/12/concurnas-un-lenguaje-de-programacion.html
https://alquimistadecodigo.blogspot.com/2024/11/lenguajes-jvm-clojure-groovy.html

sábado, 22 de marzo de 2025

¿Cómo ser un mejor programador (en un mundo con I.A.)?

Hace décadas la Inteligencia Artificial era tan solo un mito futurista, un sueño salido de alguna película o libro de ficción.

Pensar que algún día la podríamos usar para preguntar cómo hallar la salida de un laberinto, calcular una operación muy compleja o tan solo hacer cuestionamientos sin importancia era como imaginar viajar en una nave espacial.

Hoy existe y no solo se emplea para muchas cosas como análisis estadístico, inversiones financieras, programación y cómputo sino también para cosas insulsas como recrear una batalla entre miles de pollos enfrentando a un mítico TRex o hasta crear imágenes de cualquier tipo.

Corregir o hasta mejorar guiones de películas, hacer tareas de estudiantes flojos, responder preguntas médicas, políticas, sociales o hasta psicológicas.

Aprender un idioma. Aprender matemáticas sin maestro. Crear estrategias o esquemas de trabajo. Sugerencias de proyectos, etc.

Eso plantea nuevas preguntas:

  • ¿Se acabará los profesionales médicos? 
  • ¿Ya no habrá necesidad de un programador? 
  • ¿Para que se necesitarán abogados si la I.A. podrá ayudar a resolver asuntos legales? 
  • Etc.

Los más pesimistas imagina un mundo caótico. Un mundo donde la I.A. reemplazará a las personas por máquinas.

Los más optimistas podrán vislumbrar un mundo lleno de posibilidades. Un mundo donde la I.A. podrá ser usada para el bien.

Imaginemos que estamos en esa posición de optimismo, de esperanza.

Imaginemos que todo será para bien.

En un mundo con I.A. el programador deberá ser más cauteloso, mejor preparado, no dormirse en sus laureles.

  1. Siempre habrá algo que aprender, siempre. 
  2. Crear una comunidad de personas a las que podrá acudir o ayudar.
  3. Aprender constantemente, aprender de sus errores, aprender de otros.
  4. Comprender que su verdadera herramienta de trabajo es su mente.
  5. Debe llenar su mente de cosas buenas, cosas positivas.

El programador de está época deberá adaptarse a los cambios.

Deberá usar lo que hay a su favor, usar la I.A. a su favor y no en contra.

Ninguna empresa es tan banal para depender de una I.A. programada por externos, todo lo "gratuito" tiene un costo.

Con el advenimiento de herramientas como DeepSeek, ChatGPT y Grok el programador deberá mantenerse actualizado.

En un futuro quizás el mundo cambie o se mantenga como está. Todo está en el mañana.

Enlaces:

https://codemonkeyjunior.wordpress.com/2019/05/28/how-can-i-programmer/


viernes, 21 de marzo de 2025

Funciones Javascript en BigQuery

 

BigQuery permite crear Stored Procedures y/o funciones usando como lenguaje base a Javascript. En este post veremos las UDF o las funciones definidas por el usuario.

Una función definida por el usuario (UDF) nos permite crear una función mediante una expresión SQL o código JavaScript.

Una UDF puede ser:

  1. Persistente o 
  2. Temporal (en el alcance de una única consulta).

Aquí podemos ver un ejemplo sacado de la página de documentación oficial de GCP:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
CREATE TEMP FUNCTION multiplyInputs(x FLOAT64, y FLOAT64)
RETURNS FLOAT64
LANGUAGE js
AS r"""
  return x*y;
""";

WITH numbers AS
  (SELECT 1 AS x, 5 as y
  UNION ALL
  SELECT 2 AS x, 10 as y
  UNION ALL
  SELECT 3 as x, 15 as y)
SELECT x, y, multiplyInputs(x, y) AS product
FROM numbers;

Se trata de una UDF temporal (usando TEMPORARY o TEMP)  que multiplica dos números tipo FLOAT64. Dentro del privote ``numbers`` habrá dos uniones con los datos a trabajar; invocaremos la función mediante una consulta SELECT y asignará el resultado como ``product``.

Tipos de datos permitidos

 Tipos de datos en BigQuery   Tipos de datos en Javascript  
 ARRAY  ARRAY
 BOOL  BOOLEAN
 BYTES  STRING base 64
 NUMERIC, BIGNUMERIC  Valor punto flotante
 STRING  STRING
 STRUCT  OBJECT
 TIMESTAMP  DATE
 DATE  DATE
 JSON  OBJECTS, ARRAY

Recordar que en Javascript no existen los tipos de manera explícita.

Ejemplo 1. Crearemos una función (persistente) BigQuery que use JS como lenguaje base para obtener la longitud de una cadena.

1
2
3
4
5
6
7
CREATE OR REPLACE FUNCTION `myproject.mydataset.longitud`(input STRING) RETURNS STRING LANGUAGE js AS '''
   if(input === '' || input ===null){
      return "La cadena tiene una longitud de 0 caracteres.";
   }else{
      return "La cadena tiene una longitud de: "+input.length+" caracteres.";
   }
'''

Para hacer uso de ella la invocaremos de esta forma:

1
2
DECLARE cadena STRING DEFAULT '';
SELECT `myproject.mydataset.longitud`(cadena) as resultado; 

El dato de entrada será la variable ``cadena`` cuyo valor será vacío. Lo que nos devolverá:

1
La cadena tiene una longitud de: 0 caracteres.

Está función obtiene la longitud de una cadena introducida por el usuario. No mucho por explicar.

Ejemplo 2. Crear una sencilla función para evaluar si una condición o valor booleano es "correcta" si es true, "incorrecta" si es false.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
CREATE OR REPLACE FUNCTION `myproject.mydataset.checkAssert`(condition BOOL) RETURNS STRING LANGUAGE js AS '''

  var result = "Evaluacion: "+condition+".";

  if(condition){
    result += " Es correcta.";
  }else{
    result += " Es incorrecta.";
  } 

  return result;

'''

Invocamos la función:

1
2
3
4
DECLARE condition BOOL;
SET condition= 34 > 0;

SELECT `myproject.mydataset.checkAssert`(condition) AS resultado ;

Hacer uso de UDF con Javascript como lenguaje base puede ayudarnos a resolver tareas que quizás de una manera más nativa sería algo más complicado.

Continuaremos con este tema en próximas entregas.

Enlaces:

https://cloud.google.com/bigquery/docs/user-defined-functions
https://stackoverflow.com/questions/62271743/bringing-in-a-function-from-javascript-to-big-query-standardsql
https://hoffa.medium.com/new-in-bigquery-persistent-udfs-c9ea4100fd83
https://briangrinstead.com/blog/js-functions-bigquery/

domingo, 9 de marzo de 2025

Criptomonedas: ¿Qué son y para qué sirven?

 


Una criptomoneda es:

  • Una moneda digital (no es física).
  • Descentralizada de todo gobierno o entidad bancaria (hasta que alguien demuestre lo contrario).
  • Sirve para comprar cosas como un NTF o enviar dinero e invertir.
  • Funciona con blockchain (un bloque de cadenas seguro y transparente que se distribuye en muchas computadoras).

Algunos ejemplos son: Bitcoin, Ethereum, Dogecoin.

Como se menciona las blockchains se usan en en criptomonedas, contratos digitales (Smart Contracts), votaciones seguras, rastreo de productos, etc.

Por ejemplo:

Cardano es un blockchain que funciona como una plataforma para crear y ejecutar Contratos Inteligentes, similar a Ethereum y tiene su propia criptomoneda llamada ADA. Usa el sistema Prueba de Participación en lugar de Prueba de Trabajo para validar transacciones.

Plutus es un lenguaje de programación que usa Cardano para escribir contratos inteligentes.

  1. Permite crear aplicaciones descentralizadas y seguras (dApps).
  2. Esta basado en Haskell.

Pero, ¿Qué es un Contrato inteligente?

Es un programa de computadora que se ejecuta automáticamente en una blockchain cuando se cumplen ciertas condiciones.

¿Cómo funciona? Veamos un ejemplo.

  1. Se escribe el contrato en Plutus o Solidity
  2. Se publica en la blockchain, donde nadie puede modificarlo o borrarlo. 
  3. Cuando se cumplen las condiciones, el contrato se ejecuta automáticamente.

Digamos que un usuario compra un NFT y realiza (envía) el pago. Entonces el contrato verifica el pago. Si es correcto, se le envía el NFT al usuario.

Aspectos que debe tener una criptomoneda segura

  1. Debe ser descentralizada. 
  2. Tener un blockchain seguro y transparente. 
  3. Un consenso confiable: PoW (Prueba de Trabajo) y PoS (Prueba de Participación). 
  4. Algoritmo de cifrado fuerte (SHA-256, etc.) 
  5. Resistencia a ataques. 
  6. Desarrollo activo y una comunidad fuerte. 
  7. Privacidad y anonimato.

Ejemplo usando Solidity

MiPrimerToken.sol

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Contrato ERC-20 básico
contract MiPrimerToken {
    // Variables de estado
    string public nombre = "MiPrimerToken";
    string public simbolo = "MPT";
    uint256 public totalSupply;

    // Mapeo para almacenar los balances de cada cuenta
    mapping(address => uint256) public balanceOf;

    // Evento para notificar transferencias
    event Transfer(address indexed from, address indexed to, uint256 value);

    // Constructor: inicializa el supply total y lo asigna al creador del contrato
    constructor(uint256 _supplyInicial) {
        totalSupply = _supplyInicial;
        balanceOf[msg.sender] = _supplyInicial; // El creador del contrato recibe todos los tokens
    }

    // Función para transferir tokens
    function transfer(address _to, uint256 _value) public returns (bool success) {
        require(balanceOf[msg.sender] >= _value, "Saldo insuficiente"); // Verifica que el remitente tenga suficientes tokens
        balanceOf[msg.sender] -= _value; // Resta los tokens del remitente
        balanceOf[_to] += _value; // Suma los tokens al destinatario
        emit Transfer(msg.sender, _to, _value); // Emite el evento de transferencia
        return true;
    }
}

Cómo Probar el Contrato

  1. Abre Remix.
  2.  Crea un nuevo archivo (MiPrimerToken.sol) y pega el código. 
  3.  Compila el Contrato: Ve a la pestaña "Solidity Compiler". 
  4.  Selecciona la versión 0.8.0 o superior. 
  5.  Haz clic en "Compile MiPrimerToken.sol". 
  6.  Despliega el Contrato: 
  7.  Ve a la pestaña "Deploy & Run Transactions". 
  8.  Selecciona el entorno "JavaScript VM" para pruebas locales. 
  9.  En el campo "Deploy", ingresa el _supplyInicial (por ejemplo, 1000000). 
  10.  Haz clic en "Deploy". Interactúa con el Contrato: 
  11.  Una vez desplegado, verás las funciones del contrato. 
  12.  Prueba la función transfer enviando tokens a otra dirección (puedes generar cuentas en Remix).

Este es un ejemplo básico, pero te da una idea de cómo funcionan los contratos inteligentes en Ethereum.

El mismo programa, pero en Plutus y Cardano.

{-# LANGUAGE DataKinds         #-}
{-# LANGUAGE DeriveAnyClass    #-}
{-# LANGUAGE DeriveGeneric     #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TemplateHaskell   #-}

module MiPrimerToken where

import           PlutusTx
import           PlutusTx.Prelude
import           Ledger
import           Ledger.Value
import           Ledger.Ada
import           Ledger.Typed.Scripts
import           Playground.Contract

-- Definimos el tipo de dato para nuestro token
data MiToken = MiToken
    { tokenName :: TokenName
    , tokenSymbol :: CurrencySymbol
    } deriving (Show, Generic, ToJSON, FromJSON)

-- Parámetros del contrato
data TokenParams = TokenParams
    { tpToken :: MiToken
    , tpAmount :: Integer
    } deriving (Show, Generic, ToJSON, FromJSON)

-- Validación del contrato
validateToken :: TokenParams -> () -> ScriptContext -> Bool
validateToken params _ ctx =
    -- Verificamos que la cantidad de tokens sea correcta
    let txOuts = txInfoOutputs $ scriptContextTxInfo ctx
        totalTokens = foldMap (valueOf (tpToken params)) txOuts
    in totalTokens == tpAmount params

-- Instancia de ScriptType para el contrato
instance ScriptType MiToken where
    type instance RedeemerType MiToken = ()
    type instance DatumType MiToken = ()

-- Compilación del validador
tokenValidator :: TokenParams -> Validator
tokenValidator params = mkValidatorScript $
    $$(PlutusTx.compile [|| validateToken ||])
    `PlutusTx.applyCode`
    PlutusTx.liftCode params

-- Código para interactuar con el contrato en el Playground
endpoints :: Contract () TokenParams Text ()
endpoints = do
    params <- endpoint @"crear-token"
    let val = tokenValidator params
    logInfo @Text $ "Token creado: " <> show (tpToken params)
    logInfo @Text $ "Cantidad total: " <> show (tpAmount params)
    void $ submitTxConstraints (typedValidator val) mempty

Continuaremos con este tema en próximas entregas.

Enlaces:

https://ethereum.org/en/developers/
https://docs.soliditylang.org/en/latest/

sábado, 1 de marzo de 2025

Determinar el biotipo de una persona en Go(lang)

Continuando con esta serie de programas que calculan el biotipo de una persona ahora veremos como implementarlo en Go.

Go (antes Golang) es un poderoso lenguaje de prgramación que nos recuerda a Python, C/C++ y a su hermano lejano Rust.

biotipos.go

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

func main() {
    // Diccionario de pesos
    pesoDict := map[string]float32{
        "85.54": 3.0, "83.79": 2.75, "82.04": 2.5, "80.29": 2.25,
        "78.54": 2.0, "76.79": 1.75, "75.04": 1.5, "73.29": 1.25,
        "71.54": 1.0, "69.79": 0.75, "68.04": 0.50, "66.29": 0.25,
        "64.54": 0.0, "62.79": -0.25, "61.04": -0.50, "59.29": -0.75,
        "57.54": -1.0, "55.79": -1.25, "54.04": -1.50, "52.29": -1.75,
        "50.54": -2.0, "45.79": -2.25, "47.04": -2.5, "45.29": -2.75,
        "43.54": -3.0,
    }

    // Diccionario de estaturas
    estaturaDict := map[string]float32{
        "1.87": 3.0, "1.86": 2.75, "1.85": 2.50, "1.83": 2.23,
        "1.82": 2.0, "1.81": 1.75, "1.79": 1.50, "1.78": 2.25,
        "1.77": 1.0, "1.75": 0.75, "1.74": 0.50, "1.73": 0.25,
        "1.71": 0.0, "1.7": -0.25, "1.69": -0.50, "1.67": -0.75,
        "1.66": -1.0, "1.65": -1.25, "1.63": -1.50, "1.62": -1.75,
        "1.61": -2.0, "1.59": -2.25, "1.58": -2.50, "1.57": -2.75,
        "1.55": -3.0,
    }

    // Entrada del usuario
    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Tu peso es de (ejemplo: 56.00): ")
    peso, _ := reader.ReadString('\n')
    peso = strings.TrimSpace(peso)

    fmt.Print("Tu estatura es de (ejemplo: 1.55): ")
    estatura, _ := reader.ReadString('\n')
    estatura = strings.TrimSpace(estatura)

    // Obtener valores
    valorPeso, pesoOk := pesoDict[peso]
    if !pesoOk {
        valorPeso = -999.0
    }
    valorEstatura, estaturaOk := estaturaDict[estatura]
    if !estaturaOk {
        valorEstatura = -999.0
    }

    if valorPeso == -999.0 || valorEstatura == -999.0 {
        fmt.Println("Error: Peso o estatura no válidos. Asegúrate de ingresar valores dentro del rango permitido.")
        return
    }

    desviacion := valorPeso - valorEstatura

    if desviacion < 0 {
        fmt.Println("Tu biotipo es: longitipo. Largo. Delgado. De apariencia frágil.")
    } else if desviacion > 0 {
        fmt.Println("Tu biotipo es: braquitipo. Sobrepeso. Acumula grasas. Puede ganar musculatura si realiza ejercicio.")
    } else {
        fmt.Println("Tu biotipo es: normotipo. Fuerte. Atlético. Musculoso.")
    }
}

El programa no dista de tener mucha diferencia con respecto al hecho en C y Python. Salvo algunas de sus peculiaridades.

El programa pedirá peso y talla y obtendrá el biotipo de una persona.

Dar formato:

$ go fmt biotipo.go

Construir:

$ go build biotipo.go

Ejecutar:

$ ./biotipo.exe

Solo ejecutar:

$ go run biotipo.go
Tu peso es de (ejemplo: 56.00): 73.29
Tu estatura es de (ejemplo: 1.55): 1.65
Tu biotipo es: braquitipo. Sobrepeso. Acumula grasas. Puede ganar musculatura si realiza ejercicio.

Continuaremos con este tema en próximas entregas.

Enlaces:

https://go.dev/
https://codemonkeyjunior.blogspot.com/2025/02/calcular-el-biotipo-de-una-persona-en.html

sábado, 22 de febrero de 2025

Determinar el biotipo de una persona en Python

Continuando con esta serie sobe el cálculo de biotipos en C y Java ahora veremos cómo se hace en Python.

Siguiendo la misma lógica de la entrega anterior tenemos:

biotipo.py

peso_dict = {
    "85.54": 3.0, "83.79": 2.75, "82.04": 2.5, "80.29": 2.25,
    "78.54": 2.0, "76.79": 1.75, "75.04": 1.5, "73.29": 1.25,
    "71.54": 1.0, "69.79": 0.75, "68.04": 0.50, "66.29": 0.25,
    "64.54": 0.0, "62.79": -0.25, "61.04": -0.50, "59.29": -0.75,
    "57.54": -1.0, "55.79": -1.25, "54.04": -1.50, "52.29": -1.75,
    "50.54": -2.0, "45.79": -2.25, "47.04": -2.5, "45.29": -2.75,
    "43.54": -3.0
}

estatura_dict = {
    "1.87": 3.0, "1.86": 2.75, "1.85": 2.50, "1.83": 2.23,
    "1.82": 2.0, "1.81": 1.75, "1.79": 1.50, "1.78": 2.25,
    "1.77": 1.0, "1.75": 0.75, "1.74": 0.50, "1.73": 0.25,
    "1.71": 0.0, "1.7": -0.25, "1.69": -0.50, "1.67": -0.75,
    "1.66": -1.0, "1.65": -1.25, "1.63": -1.50, "1.62": -1.75,
    "1.61": -2.0, "1.59": -2.25, "1.58": -2.50, "1.57": -2.75,
    "1.55": -3.0
}

def obtener_valor(diccionario, clave):
    return diccionario.get(clave, -999.0)

def main():
    peso = input("Tu peso es de (ejemplo: 56.00): ").strip()
    estatura = input("Tu estatura es de (ejemplo: 1.55): ").strip()

    valor_peso = obtener_valor(peso_dict, peso)
    valor_estatura = obtener_valor(estatura_dict, estatura)

    #print(f"valor peso: {valor_peso:.1f}")
    #print(f"valor estatura: {valor_estatura:.1f}")
    
    if valor_peso == -999.0 or valor_estatura == -999.0:
        print("Error: Peso o estatura no válidos. Asegúrate de ingresar valores dentro del rango permitido.")
        return

    desviacion = valor_peso - valor_estatura

    if desviacion < 0:
        print("Tu biotipo es: longitipo. Largo. Delgado. De apariencia frágil.")
    elif desviacion > 0:
        print("Tu biotipo es: braquitipo. Sobrepeso. Acumula grasas. Puede ganar musculatura si realiza ejercicio.")
    else:
        print("Tu biotipo es: normotipo. Fuerte. Atlético. Musculoso.")

if __name__ == "__main__":
    main()

Ejecutando:

Tu peso es de (ejemplo: 56.00): 75.04
Tu estatura es de (ejemplo: 1.55): 1.66
Tu biotipo es: braquitipo. Sobrepeso. Acumula grasas. Puede ganar musculatura si realiza ejercicio.

Como hemos mencionado, el código qrequiere ciertos ajustes para abarcar más pesos y tallas.

Enlaces:

https://ucsc.cl/medios-ucsc/blogs-academicos/biotipo-y-el-factor-mental/

domingo, 16 de febrero de 2025

Determinar el biotipo de una persona en C

En una pasada entrega vimos cómo calcular el biotipo de una persona en Java. Ahora lo haremos usando el lenguaje de programación C.

Pero, ¿Qué es el biotipo de una persona?

Es la forma característica de un animal o planta. Es el aspecto general de un sujeto de acuerdo a sus características somáticas o morfológicas y se basa en los datos que refleja su estructura corporal, en todo lo que se ve y se puede medir de su cuerpo.

Se refiere a las características corporales, como la estructura ósea, la musculatura y la predisposición al metabolismo, que influyen en la salud, el rendimiento físico y la respuesta a la dieta o ejercicio.

Establece que hay una relación entre las características físicas y la personalidad. Esto ya lo habiamos mencionado en la entrega pasada.

Para el programa en C:

  1. Crearemos un archivo de encabezado: biotipo.h 
  2. Un archivo donde tendremos las funciones necesarias para los cálculos: biotipo.c 
  3. Un programa main: main.c

Existen varios biotipos, pero el general comprende estos tres:

  • Ectomorfo: Cuerpo delgado, extremidades largas, dificultad para ganar peso o masa muscular, metabolismo rápido. En otras palabras, sería Longitipo
  •  Mesomorfo: Cuerpo atlético, facilidad para ganar músculo, estructura ósea equilibrada, metabolismo eficiente. En otras palabras, sería Normotipo.
  •  Endomorfo: Cuerpo con mayor tendencia a acumular grasa, estructura más ancha, metabolismo más lento. En otras palabras, sería Braquitipo.

El programa comprenderá dos "hashmap", hechos con estructuras. Uno para los pesos y el otro para las estaturas.

biotipos.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Estructura para simular el HashMap (clave-valor)
typedef struct {
    char *clave;
    double valor;
} ParClaveValor;

// Listas de pares clave-valor para peso y estatura
ParClaveValor mapaPeso[] = {
    {"85.54", 3.0}, {"83.79", 2.75}, {"82.04", 2.5}, {"80.29", 2.25},
    {"78.54", 2.0}, {"76.79", 1.75}, {"75.04", 1.5}, {"73.29", 1.25},
    {"71.54", 1.0}, {"69.79", 0.75}, {"68.04", 0.50}, {"66.29", 0.25},
    {"64.54", 0.0}, {"62.79", -0.25}, {"61.04", -0.50}, {"59.29", -0.75},
    {"57.54", -1.0}, {"55.79", -1.25}, {"54.04", -1.50}, {"52.29", -1.75},
    {"50.54", -2.0}, {"45.79", -2.25}, {"47.04", -2.5}, {"45.29", -2.75},
    {"43.54", -3.0}
};

ParClaveValor mapaEstatura[] = {
    {"1.87", 3.0}, {"1.86", 2.75}, {"1.85", 2.50}, {"1.83", 2.23},
    {"1.82", 2.0}, {"1.81", 1.75}, {"1.79", 1.50}, {"1.78", 2.25},
    {"1.77", 1.0}, {"1.75", 0.75}, {"1.74", 0.50}, {"1.73", 0.25},
    {"1.71", 0.0}, {"1.7", -0.25}, {"1.69", -0.50}, {"1.67", -0.75},
    {"1.66", -1.0}, {"1.65", -1.25}, {"1.63", -1.50}, {"1.62", -1.75},
    {"1.61", -2.0}, {"1.59", -2.25}, {"1.58", -2.50}, {"1.57", -2.75},
    {"1.55", -3.0}
};

// Tamaños de los mapas
const int TAMANO_PESO = sizeof(mapaPeso) / sizeof(mapaPeso[0]);
const int TAMANO_ESTATURA = sizeof(mapaEstatura) / sizeof(mapaEstatura[0]);

// Función para buscar el valor asociado a una clave en el mapa
double buscarValor(ParClaveValor mapa[], int tamano, const char *clave) {
    for (int i = 0; i < tamano; i++) {
        if (strcmp(mapa[i].clave, clave) == 0) {
            return mapa[i].valor;
        }
    }
    return -999.0; // Valor por defecto si no se encuentra la clave
}

// Función para obtener el peso (equivalente a getPeso en Java)
double obtenerPeso(const char *peso) {
    return buscarValor(mapaPeso, TAMANO_PESO, peso);
}

// Función para obtener la estatura (equivalente a getTalla en Java)
double obtenerEstatura(const char *estatura) {
    return buscarValor(mapaEstatura, TAMANO_ESTATURA, estatura);
}

int main() {
    char peso[10], estatura[10];
    double valorPeso, valorEstatura, desviacion;

    // Solicitar entrada al usuario
    printf("Tu peso es de (ejemplo: 56.00): ");
    fgets(peso, sizeof(peso), stdin);
    peso[strcspn(peso, "\n")] = 0; // Eliminar el salto de línea

    printf("Tu estatura es de (ejemplo: 1.55): ");
    fgets(estatura, sizeof(estatura), stdin);
    estatura[strcspn(estatura, "\n")] = 0; // Eliminar el salto de línea

    // Obtener los valores asociados a peso y estatura
    valorPeso = obtenerPeso(peso);
    valorEstatura = obtenerEstatura(estatura);

    printf("valor peso: %.1f\n", valorPeso);
    printf("valor estatura: %.1f\n", valorEstatura);
    // Verificar si se encontraron los valores
    if (valorPeso == -999.0 || valorEstatura == -999.0) {
        printf("Error: Peso o estatura no válidos. Asegúrate de ingresar valores dentro del rango permitido.\n");
        return 1;
    }

    // Calcular la desviación
    desviacion = valorPeso - valorEstatura;

    // Determinar el biotipo y mostrar el resultado
    if (desviacion < 0) {
        printf("Tu biotipo es: longitipo. Largo. Delgado. De apariencia frágil. \n");
    } else if (desviacion > 0) {
        printf("Tu biotipo es: braquitipo. Sobrepeso. Acumula grasas. Puede ganar musculatura si realiza ejercicio.\n");
    } else {
        printf("Tu biotipo es: normotipo. Fuerte. Atlético. Musculoso\n");
    }

    return 0;
}

Compilación y ejecución:

$ gcc -o biotipos.exe biotipos.c
$ ./biotipos.exe

Salida:

Tu peso es de (ejemplo: 56.00): 43.54
Tu estatura es de (ejemplo: 1.55): 1.61
valor peso: -3.0
valor estatura: -2.0
Tu biotipo es: longitipo. Largo. Delgado. De apariencia frágil.

El programa requiere ciertos ajustes para permitir otras entradas de estatura y peso.

Enlaces:

https://codemonkeyjunior.blogspot.com/2013/03/determinar-el-biotipo-de-una-persona-en.html