domingo, 27 de junio de 2021

Erlang: constantes


Una variable es, básicamente, algo que puede cambiar de valor. Incluso de tipo en lenguajes de programación de tipado dinámico. Por el contrario, una constante es algo que no puede variar. Algo que permanece sin cambio, inmutable.

Para definir constantes en Erlang debemos crear una macro.

%% Macro
-define(MYMACRO (X,Y), X+Y).

%% Valor constante
-define(CONSTANTE, 3300).

Como se puede ver es muy parecido a lo que se hace en lenguajes como C.
// Macro
#define MYMACRO (X,Y) (X+Y)

// Valor constante
#define CONSTANTE 3300

Todo claro hasta aquí...pero, ¿cómo usamos estas constantes (Macros)?

%% ...
%% ...
io:format("Suma = ~p~n",[?MYMACRO(34.5,32.1)]),
io:format("Constante: ~p~n",[?CONSTANTE]).
Esto muestra como podemos hacer uso de estas constantes (Macros) en Erlang. Crearemos un programa llamado constantes.erl el cual tendrá dos constantes y una macro.
constantes.erl
%% @doc Constantes en Erlang
-module(constantes).
-author("Codemonkey Junior").
-version("1.0.0").
-export([start/0]).
-define(TITULO,"====== CONSTANTES EN ERLANG ======").
-define(MAX, 1000).
-define(SUMA (X,Y), X+Y).

start()->
   io:format("~p~n",[?TITULO]),
   io:format("MAX = ~p~n",[?MAX]),
   X = 8.7,
   Y = 4.32,
   io:format("X = ~p, Y = ~p ~n",[X,Y]),
   io:format("SUMA = ~p~n",[?SUMA(X,Y)]).


%% erl
%% > c(constantes).
%% constantes:start().
Ejecutando...
$ erl
Erlang/OTP 24 [erts-12.0.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit]

Eshell V12.0.2  (abort with ^G)
1> c(constantes).
{ok,constantes}
2> constantes:start().
"====== CONSTANTES EN ERLANG ======"
MAX = 1000
X = 8.7, Y = 4.32 
SUMA = 13.02
ok
3> 

Enlaces:
https://erlang.org/doc/reference_manual/macros.html

sábado, 26 de junio de 2021

Erlang: sitios para aprender


He aquí algunos recursos para poder aprender Erlang, el lenguaje de programación concurrente que muchos deberían conocer.

Erlang/OTP
Un Mundo Concurrente
https://erlang-otp.es/
Ideal para conocer las características del lenguaje y muchas otras cosas más.

Learn you some Erlang
https://learnyousomeerlang.com/content
El libro para aprender el lenguaje Erlang "Learn You Some Erlnag For Geat Good" en línea.

Try Erlang
https://www.tryerlang.org/
Si quieres probar el shell de Erlang este es el sitio adecuado.

Erlang, sitio oficial
http://erlang.org
El sitio oficial del lenguaje de programación Erlang.

Erlang Factory
https://www.erlang-factory.com/
Sitio con noticias referentes al lenguaje Erlang.

Erlang by Example
https://erlangbyexample.org
Un sitio ideal para ver ejemplos de código hechos con Erlang.

Adopting Erlang
https://adoptingerlang.org
Sitio de los programadores Tristan Sloughter y Fred Hebert sobre el lenguaje de programación Erlang.

sábado, 19 de junio de 2021

Node en ejemplos: importando paquetes

 

Node JS es una plataforma que nos permite correr aplicaciones Javascript del lado del servidor.  En post pasados hemos visto su instalación y algunos ejemplos. 

Instalación en distribuciones Ubuntu.


$ curl -fsSL https://deb.nodesource.com/setup_14.x | sudo -E bash -
$ sudo apt-get install -y nodejs

Comprobamos su instalación:
$ npm -v
$ node -v
Paquetes en Node JS.

Un paquete son archivos JS empaquetados. Es una parte fundamental en la reutlización de código.

Node JS nos permite importar paquetes para realizar ciertas funciones especiales, así como importar nuestros propios paquetes.


Ejemplo. Importar el paquete 'path' de Node Js. Para ello necesitamos tener un archivo texto.txt.
const path = require('path');
const print = console.log;

print("Archivo:");
print(path.parse("/home/codemonkey/Documentos/pruebasNodeJS/texto.txt"));
La salida:
Archivo:
{
  root: '/',
  dir: '/home/codemonkey/Documentos/pruebasNodeJS',
  base: 'texto.txt',
  ext: '.txt',
  name: 'texto'
}
Ejemplo. Crear un paquete llamado suma e importarlo en otro archivo denominado test_suma.js.
suma.js
exports.sumar = (x,y) => x+y;
test_suma.js
// Importamos suma.js
const operacion = require('./suma');
var x = 4, y = 3;
console.log(`Suma de ${x} + ${y} es: ${operacion.sumar(x,y)}`);

// Creamos una clase
class Operacion{
   getOperacion(x,y){
      const operacion = require('./suma.js');
      return operacion.sumar(x,y);
   }
}

x = 7;
y = 8;
let my_operacion = new Operacion().getOperacion(x,y);
console.log(`Suma de ${x} + ${y} es: ${my_operacion}`);
Ejecutamos:
$ node test_suma.js
Resultado:
Suma de 4 + 3 es: 7
Suma de 7 + 8 es: 15

Nota:
  Cuando es un paquete de Node JS no es necesario poner el punto y diagonal. Solo cuando es un paquete hecho por nosotros. También se puede omitir la extensión *.js en paquetes propios como se puede ver:
// Importo paquete de Node JS
const path = require("path");

// Importo mi paquete 
const path = require("./saludo");
Y un ejemplo más...
const path = require('path');
const print = console.log;

print("Archivo:");
print(path.parse("/home/codemonkey/Documentos/pruebasNodeJS/texto.txt"));


const saludo = require('./saludo');
saludo.saludo();
saludo.despedida();

const opera = require('./suma');
let x = 87.5;
let y = 45.8;
console.log(`Numeros >> x = ${x}, y = ${y} `);
console.log("Suma: ",opera.sumar(x,y));

const os = require('os');
console.log("Info del sistema:");
console.log("Arquitectura:",os.arch());
console.log("Hostname:",os.hostname());


Enlaces:
https://codemonkeyjunior.blogspot.com/search?q=node
https://nodejs.org

sábado, 12 de junio de 2021

Ballerina en ejemplos

Ballerina es un lenguaje de programación de código abierto para la nube que facilita el uso, la combinación y la creación de servicios de red. A primera vista recuerda a lenguajes como Java y o Typescript. Ballerinta maneja tipos básicos como in, float, string, boolean, etc. La síntaxis de estructuras de control secuencial e iterativa son similares a Java. La extensión de un programa es *.bal
En post anteriores hemos hablado sobre Docker. En este post usaremos una imagen de Ballerina y la descargaremos con Docker.
$ docker pull ballerina/ballerina
$ docker images

Para compilar y ejecutar un programa escribimos este script bash:
ejecuta.sh
#!/bin/bash

# Mostramos el nombre del programa a compilar y ejecutar
echo "Ejecutamos $1"
docker run -v `pwd`:/home/ballerina -it ballerina/ballerina:1.0.2 ballerina build $1
docker run -v `pwd`:/home/ballerina -it ballerina/ballerina:1.0.2 ballerina run $1
Para usar el script es necesario darle permiso de ejecución y pasar el nombre del programa como argumento de entrada:
$ sudo chmod +x ejecuta.sh
$ ./ejecuta.sh programa.bal

Comencemos con algunos ejemplos.

Ejemplo. El clásico programa de "Hola, mundo".
holamundo.bal
import ballerina/io;

public function main(string... args) {
    io:println("Hola en Ballerina!!");
 
}
Compilamos y ejecutamos:
$ ./ejecuta.sh holamundo.bal
Ejemplo. Obtener el mayor de tres número enteros.
mayor_tres_numeros.bal
import ballerina/io;

public function main(string... args) {
	int a = 4;
	int b = -32;
	int c = 1;
	int mayor = a; 
        io:println("Numeros:\na:",a,",b:",b,",c:",c);
	if(mayor < b){
	  mayor = b;
	}
	if(mayor < c){
	  mayor = c;
	}
	io:println("mayor:",mayor);
}
    

Compilamos y ejecutamos:
$ ./ejecuta.sh mayor_tres_numeros.bal

Ejemplo. Crear dos funciones, una para sumar y otra para multiplicar dos números enteros.
funciones.bal
import ballerina/io;

public function sumar(int a, int b) returns int {
    return a + b;
}

public function multiplicar(int a, int b) returns int {
    return a * b;
}

public function main(string... args) {
        int a=7;
	int b=5;
	io:println("Suma de 5 y 7 es: ",sumar(a,b));
	io:println("Producto de 5 y 7 es: ",multiplicar(a,b));   
}

Compilamos y ejecutamos:
$ ./ejecuta.sh funciones.bal

¿Qué podemos analizar con estos ejemplos?
io:println("Hola en Ballerina!!");
Con esta instrucción imprimimos a pantalla.
int entero = 34;
io:println("Entero: ",entero);

Las instrucciones deben terminar con ;
Además se debe respetar el tipo de dato (esto no es Javasript u otro lenguaje de tipado dinámico).  Las funciones pueden o no devolver valores, si devuelven deben llevar la palabra returns en la cabecera indicando el tipo a devolver y return para devolver el valor calculado.
 

Ejemplo. Crear un programa que haga uso de sentencias iterativas con for y while.
bucles.bal

import ballerina/io;

public function main(string... args) {
        io:println("Elemento 0: ",numeros[0]);//1
	io:println("Elemento 5: ",numeros[5]);//6
        io:println("Tamaño: ",numeros.length());//8
	foreach var num in numeros{
		io:println("Elemento: ",num);
	}
	io:println("======================================");
	foreach var i in 0...9 {
        io:println("Numero: ",i);    
    }  
	io:println("======================================");
	int cont=0;
	while (cont < 10) {
        io:println("Cont: ",cont);
        cont = cont + 1;
    }

}

Compilamos y ejecutamos:
$ ./ejecuta bucles.bal

Como se puede ver la síntaxis es casi idéntica a la de Java y/o C#. Para quienes tienen cierta experiencia programando en lenguajes similares se les facilitará aprenderlo.
En próximos post veremos más ejemplos.
Enlaces:
https://alquimistadecodigo.blogspot.com/2020/09/docker-instalando-ballerina.html
https://ballerina.io/

martes, 8 de junio de 2021

100 días de código Javascript... 7ma parte


Ejemplo. Validar datos con Javascript.
main.js
document.addEventListener("DOMContentLoaded", function(event) {
    
    console.log('Se ha ejecutado código JS');
    const btnActivar = document.getElementById("btnActivar");

    function activarEnvio(){
         alert("Enviando los datos...");
    }


    var tabla1Fila1 = false;
    var tabla1Fila2 = false;
    var tabla1Fila3 = false;

    var tabla2Fila1 = false;
    var tabla2Fila2 = false;
    var tabla2Fila3 = false;
   

    function validarFormulario(){
    var nomProd1 = "";
    var monto1 = "";
    var numContrato1 = "";
    
    if(nomProd1!=""){
      if(nomProd1!=""&&monto1!=""&&numContrato1!=""){
         document.getElementById("infoError1").style.display="none";tabla1Fila1=true;
      }else{
        document.getElementById("prrfError1").style.color="red";
        document.getElementById("prrfError1").innerText="Error: Debe completar todos los datos de la tabla 1 fila 1.";
        document.getElementById("infoError1").style.display="block";
      }
    }else{
        if(monto1!=""&&numContrato1!=""){
           document.getElementById("prrfError1").style.color="red";
           document.getElementById("prrfError1").innerText="Error: Debe completar todos los datos de la tabla 1 fila 1.";
           document.getElementById("infoError1").style.display="block";
        }else{
           document.getElementById("infoError1").style.display="none";tabla1Fila1=true;
        }
    }

    var nomProd2 = "";
    var monto2 = "";
    var numContrato2 = "";

    if(nomProd2!=""){
      if(nomProd2!=""&&monto2!=""&&numContrato2!=""){
         document.getElementById("infoError2").style.display="none";tabla1Fila2=true;
      }else{
        document.getElementById("prrfError2").style.color="red";
        document.getElementById("prrfError2").innerText="Error: Debe completar todos los datos de la tabla 1 fila 2.";
        document.getElementById("infoError2").style.display="block";
      }
    }else{
        if(monto2!=""&&numContrato2!=""){
           document.getElementById("prrfError2").style.color="red";
           document.getElementById("prrfError2").innerText="Error: Debe completar todos los datos de la tabla1 fila 2.";
           document.getElementById("infoError2").style.display="block";
        }else{
           document.getElementById("infoError2").style.display="none";tabla1Fila2=true;
        }
    }

    var nomProd3 = "";
    var monto3 = "";
    var numContrato3 = "";

    if(nomProd3!=""){
      if(nomProd3!=""&&monto3!=""&&numContrato3!=""){
         document.getElementById("infoError3").style.display="none";tabla1Fila3=true;
      }else{
        document.getElementById("prrfError3").style.color="red";
        document.getElementById("prrfError3").innerText="Error: Debe completar todos los datos de la tabla 1 fila 3.";
        document.getElementById("infoError3").style.display="block";
      }
    }else{
        if(monto3!=""&&numContrato3!=""){
           document.getElementById("prrfError3").style.color="red";
           document.getElementById("prrfError3").innerText="Error: Debe completar todos los datos de la tabla 1  fila 3.";
           document.getElementById("infoError3").style.display="block";
        }else{
           document.getElementById("infoError3").style.display="none";tabla1Fila3=true;
        }
    }



   var tv1 = "9";
   var nb1 = "4";
   var nt1 = "7";
   var cp1 = "12";
   var s1 = "1234";
   var pt1 = "1200";

   if(tv1!=""){
      if(tv1!=""&&nb1!=""&&nt1!=""&&cp1!=""&&s1!=""&&pt1!=""){
         document.getElementById("infoError4").style.display="none";tabla2Fila1=true;
      }else{
        document.getElementById("prrfError4").style.color="red";
        document.getElementById("prrfError4").innerText="Error: Debe completar todos los datos de la tabla 2  fila 1.";
        document.getElementById("infoError4").style.display="block";
      }
    }else{
        if(nb1!=""&&nt1!=""&&cp1!=""&&s1!=""&&pt1!=""){
           document.getElementById("prrfError4").style.color="red";
           document.getElementById("prrfError4").innerText="Error: Debe completar todos los datos de la tabla 2 fila 1.";
           document.getElementById("infoError4").style.display="block";
        }else{
           document.getElementById("infoError4").style.display="none";tabla2Fila1=true;
        }
    }


   var tv2 = "B";
   var nb2 = "y";
   var nt2 = "6";
   var cp2 = "99";
   var s2 = "1204";
   var pt2 = "1900";

    if(tv2!=""){
      if(tv2!=""&&nb2!=""&&nt2!=""&&cp2!=""&&s2!=""&&pt2!=""){
         document.getElementById("infoError5").style.display="none";tabla2Fila2=true;
      }else{
        document.getElementById("prrfError5").style.color="red";
        document.getElementById("prrfError5").innerText="Error: Debe completar todos los datos de la tabla 2 fila 2.";
        document.getElementById("infoError5").style.display="block";
      }
    }else{
        if(nb2!=""&&nt2!=""&&cp2!=""&&s2!=""&&pt2!=""){
           document.getElementById("prrfError5").style.color="red";
           document.getElementById("prrfError5").innerText="Error: Debe completar todos los datos de la tabla 2 fila 2.";
           document.getElementById("infoError5").style.display="block";
        }else{
           document.getElementById("infoError5").style.display="none";tabla2Fila2=true;
        }
    }



   var tv3 = "G";
   var nb3 = "8";
   var nt3 = "87";
   var cp3 = "4";
   var s3 = "8";
   var pt3 = "88";


    if(tv3!=""){
      if(tv3!=""&&nb3!=""&&nt3!=""&&cp3!=""&&s3!=""&&pt3!=""){
         document.getElementById("infoError6").style.display="none";tabla2Fila3=true;
      }else{
        document.getElementById("prrfError6").style.color="red";
        document.getElementById("prrfError6").innerText="Error: Debe completar todos los datos de la tabla 2 fila 3.";
        document.getElementById("infoError6").style.display="block";
      }
    }else{
        if(nb3!=""&&nt3!=""&&cp3!=""&&s3!=""&&pt3!=""){
           document.getElementById("prrfError6").style.color="red";
           document.getElementById("prrfError6").innerText="Error: Debe completar todos los datos de la tabla 2 fila 3.";
           document.getElementById("infoError6").style.display="block";
        }else{
           document.getElementById("infoError6").style.display="none";tabla2Fila3=true;
        }
    }
   }



    btnActivar.addEventListener("click", ()=>{
        console.log("Verificar datos");
        validarFormulario();
        if(tabla1Fila1 && tabla1Fila2 && tabla1Fila3 && tabla2Fila1 && tabla2Fila2 && tabla2Fila3){
           document.getElementById("infoFinal").style.display="block";
           document.getElementById("prrfFinal").innerText="Ya no hay errores, listo para enviar datos.";
           document.getElementById("prrfFinal").style.color="blue";
           activarEnvio();
        }else{
           document.getElementById("infoFinal").style.display="block";
           document.getElementById("prrfFinal").innerText="Hay errores, corrigalos por favor";
           document.getElementById("prrfFinal").style.color="red";
        }

    });



});

index.html
<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8">
  <title>Ejemplos en JS</title>
</head>
<script type="text/javascript" src="main.js">
</script>

<style type="text/css">
#infoError1{
  display: none;
}
#prrfError1{
  text-align: center;
}

#infoError2{
  display: none;
}
#prrfError2{
  text-align: center;
}

#infoError3{
  display: none;
}
#prrfError3{
  text-align: center;
}

#infoError4{
  display: none;
}
#prrfError4{
  text-align: center;
}

#infoError5{
  display: none;
}
#prrfError5{
  text-align: center;
}

#infoError6{
  display: none;
}
#prrfError6{
  text-align: center;
}


#infoFinal{
  display: none;
}
#prrfFinal{
  text-align: center;
}




</style>
<body>
  <h1>Programando en JS</h1>
  
  <div id="infoError1">
    <p id="prrfError1"></p>
  </div><br/>
  <div id="infoError2">
    <p id="prrfError2"></p>
  </div><br/>
  <div id="infoError3">
    <p id="prrfError3"></p>
  </div><br/>
  <div id="infoError4">
    <p id="prrfError4"></p>
  </div><br/>
  <div id="infoError5">
    <p id="prrfError5"></p>
  </div><br/>
  <div id="infoError6">
    <p id="prrfError6"></p>
  </div>
   <br/>
   <div id="infoFinal">
    <p id="prrfFinal"></p>
  </div>

  <div id="btnDiv">
  <button id="btnActivar">Verfificar</button>
  </div>
</body>
<html>

Validar RFC:
 <script>
            function rfcValido(rfc, aceptarGenerico = true) {
    const re = /^([A-ZÑ&]{3,4}) ?(?:- ?)?(\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])) ?(?:- ?)?([A-Z\d]{2})([A\d])$/;
    var validado = rfc.match(re);

    if (!validado)  // Coincide con el formato general del regex?
        return false;

    // Separar el dígito verificador del resto del RFC
    const digitoVerificador = validado.pop(),
        rfcSinDigito = validado.slice(1).join(''),
        len = rfcSinDigito.length,

        // Obtener el digito esperado
        diccionario = "0123456789ABCDEFGHIJKLMN&OPQRSTUVWXYZ Ñ",
        indice = len + 1;
    var suma,
        digitoEsperado;

    if (len == 12) suma = 0
    else suma = 481; // Ajuste para persona moral

    for (var i = 0; i < len; i++)
        suma += diccionario.indexOf(rfcSinDigito.charAt(i)) * (indice - i);
    digitoEsperado = 11 - suma % 11;
    if (digitoEsperado == 11) digitoEsperado = 0;
    else if (digitoEsperado == 10) digitoEsperado = "A";

    // El dígito verificador coincide con el esperado?
    // o es un RFC Genérico (ventas a público general)?
    if ((digitoVerificador != digitoEsperado)
        && (!aceptarGenerico || rfcSinDigito + digitoVerificador != "XAXX010101000"))
        return false;
    else if (!aceptarGenerico && rfcSinDigito + digitoVerificador == "XEXX010101000")
        return false;
    return rfcSinDigito + digitoVerificador;
}


        </script>

Validar RFC
function rfcValido(rfc) {
    var re = /^([ A-ZÑ&]?[A-ZÑ&]{3}) ?(?:- ?)?(\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])) ?(?:- ?)?([A-Z\d]{2})([A\d])$/,
        validado = rfc.match(re);
	
    if (!validado)  //Coincide con el formato general?
    	return false;
    
    //Separar el dígito verificador del resto del RFC
    var digitoVerificador = validado.pop(),
        rfcSinDigito = validado.slice(1).join('')
        
    //Obtener el digito esperado
    var diccionario  = "0123456789ABCDEFGHIJKLMN&OPQRSTUVWXYZ Ñ",
        lngSuma      = 0.0,
        digitoEsperado;

    if (rfcSinDigito.length == 11) rfc = " " + rfc; //Ajustar a 12
    for(var i=0; i<13; i++)
        lngSuma = lngSuma + diccionario.indexOf(rfcSinDigito.charAt(i)) * (13 - i);
    digitoEsperado = 11 - lngSuma % 11;
    if (digitoEsperado == 11) digitoEsperado = 0;
    if (digitoEsperado == 10) digitoEsperado = "A";
  
	//El dígito verificador coincide con el esperado?
    return digitoVerificador == digitoEsperado;
}
Continuaremos con más post sobre Javascript.