domingo, 19 de marzo de 2023

Listado de primos empleando JavaScript

100 primeros números primos

const fnPrimosArrow = () => {
    let lista = [2]; // Inicia con 2
    let val = 3, cont = 0;
    while (cont < 99) { // Hace 99 inserciones más
        let aux = 0;
        for (let i = 2; i < val; i++) {
            if (val % i === 0){
                aux++; 
                continue; // Si hay 1 divisor avanza el bucle
            }
        }
        if (aux === 0) {
            lista.push(val);
            cont++;
        }
        val += 2; // Solo evalúa impares
    }
    return lista;
};
console.log(fnPrimosArrow());

Números primos con parámetro de cantidad

const fnPrimosArrow = cantidad => {
    let lista = [2];
    let val = 3, cont = 0;
    while (cont < cantidad - 1) {
        let aux = 0;
        for (let i = 2; i < val; i++) {
            if (val % i === 0){
                aux++; 
                continue;
            }
        }
        if (aux === 0) {
            lista.push(val);
            cont++;
        }
        val += 2;
    }
    return lista;
};
console.log(fnPrimosArrow(10).join(" - "));
// 2 - 3 - 5 - 7 - 11 - 13 - 17 - 19 - 23 - 29

sábado, 18 de marzo de 2023

Template literals

Es una forma de imprimir resultados en pantalla de forma más armoniosa o para almacenar sin tener que recurrir a demasiada concatenación variables de tipo String, para su uso se emplea comillas invertidas (``), atajo ALT + 96, en lugar de comillas ("") para definir una cadena. Sus usos son:

/*Mostrar datos en pantalla que contenga comillas simples o dobles*/

console.log(`Bienvenido a "JavaScript"`);
//Salida: Bienvenido a "JavaScript"

console.log(`Puedes emplear comilla doble " y simple '`);
//Salida: Puedes emplear comilla doble " y simple'

// Listar elementos con saltos de línea sin necesidad de \n

console.log(`LISTADO
1.- UNO
2.- DOS
3.- TRES`);

/*Salida:

LISTADO
1.- UNO
2.- DOS
3.- TRES

*/

// Interpolar valores y texto

let fecha = "6 de octubre"; 
let perro = {nombre: "Argos", raza: "pastor alemán"};

console.log(`Con fecha ${fecha} se registra a ${perro.nombre} de raza ${perro.raza}`);
//Salida: Con fecha 6 de octubre se registra a Argos de raza pastor alemán

NOTA: Para interpolar valores se emplea ${...}

jueves, 1 de diciembre de 2022

Base de datos para un punto de venta

El siguiente código es para dar soporte a un sistema de venta mediante la inclusión de una base de datos relacional llamada ventas.


Código SQL para MySQL

-- ------------------------------------
-- Tabla "categoria"
-- ------------------------------------
CREATE TABLE `ventas`.`categoria` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`nombre` VARCHAR(50) NOT NULL , 
	`descripcion` TEXT NULL , 
	PRIMARY KEY (`id`)
) ENGINE = InnoDB;

-- ------------------------------------
-- Tabla "producto"
-- ------------------------------------
CREATE TABLE `ventas`.`producto` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`nombre` VARCHAR(255) NOT NULL , 
	`precio` DECIMAL(10,2) NOT NULL , 
	`descripcion` TEXT NULL , 
	`cantidad` INT NOT NULL ,
	`categoria` INT NOT NULL , 
	PRIMARY KEY (`id`),
	CONSTRAINT fk_prod_cat
		FOREIGN KEY (categoria)
		REFERENCES categoria (id)
		   ON DELETE NO ACTION
		   ON UPDATE NO ACTION
) ENGINE = InnoDB;

-- ------------------------------------
-- Tabla "cliente"
-- ------------------------------------
CREATE TABLE `ventas`.`cliente` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`dni` VARCHAR(20) NOT NULL UNIQUE , 
	`nombres` VARCHAR(150) NOT NULL , 
	`apellidos` VARCHAR(150) NOT NULL , 
	`correo` VARCHAR(200) NOT NULL UNIQUE , 
	PRIMARY KEY (`id`)
) ENGINE = InnoDB;

-- ------------------------------------
-- Tabla "empleado"
-- ------------------------------------
CREATE TABLE `ventas`.`empleado` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`dni` VARCHAR(20) NOT NULL UNIQUE , 
	`nombres` VARCHAR(50) NOT NULL , 
	`paterno` VARCHAR(50) NOT NULL ,
	`materno` VARCHAR(50) NOT NULL , 
	`correo` VARCHAR(200) NOT NULL UNIQUE , 
	`telefono` VARCHAR(30) NOT NULL UNIQUE , 
	`clave` BLOB(200) NOT NULL ,
	PRIMARY KEY (`id`)
) ENGINE = InnoDB;

-- ------------------------------------
-- Tabla "venta"
-- ------------------------------------
CREATE TABLE `ventas`.`venta` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`cliente` INT NOT NULL , 
	`empleado` INT NOT NULL , 
	`monto` DECIMAL(10,2) NOT NULL , 
	`fecha` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP , 
	PRIMARY KEY (`id`),
	CONSTRAINT fk_venta_cliente
		FOREIGN KEY (cliente)
		REFERENCES cliente (id)
		   ON DELETE NO ACTION
		   ON UPDATE NO ACTION ,
	CONSTRAINT fk_venta_empl
		FOREIGN KEY (empleado)
		REFERENCES empleado (id)
		   ON DELETE NO ACTION
		   ON UPDATE NO ACTION
) ENGINE = InnoDB;

-- ------------------------------------
-- Tabla "detalle"
-- ------------------------------------
CREATE TABLE `ventas`.`detalle` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`venta` INT NOT NULL , 
	`producto` INT NOT NULL , 
	`precio` DECIMAL(10,2) NOT NULL , 
	`cantidad` INT NOT NULL , 
	PRIMARY KEY (`id`),
	CONSTRAINT fk_detalle_venta
		FOREIGN KEY (venta)
		REFERENCES venta (id)
		   ON DELETE NO ACTION
		   ON UPDATE NO ACTION ,
	CONSTRAINT fk_detalle_prod
		FOREIGN KEY (producto)
		REFERENCES producto (id)
		   ON DELETE NO ACTION
		   ON UPDATE NO ACTION
) ENGINE = InnoDB;

Datos para inicializar la base de datos

-- ------------------------------------
-- Datos de inicialización
-- ------------------------------------
-- 3 empleados
INSERT INTO empleado(dni, nombres, paterno,
	materno, correo, telefono, clave) VALUES 
('10001000','PAUL','GARCIA','MATTOS','paul@mail.com',
	'999888777',AES_ENCRYPT('2022','2022')),
('20002000','LORENA','HERRERA','SOTELO','lorena@mail.com',
	'999888666',AES_ENCRYPT('123456','123456')),
('30003000','DEMETRIO','GARCIA','GARCIA','demetrio@mail.com',
	'999888555',AES_ENCRYPT('ADMIN','ADMIN'));

-- 2 clientes
INSERT INTO cliente (dni, nombres, apellidos, correo) VALUES 
('10101010','EMILIA','MELGAREJO CHAVEZ','emilia@mail.com'),
('10201020','KAREN','TORRES ALVA','karen@mail.com');

-- 2 categorias
INSERT INTO categoria(nombre, descripcion) VALUES 
('BEBIDAS',null),('ENTRADAS','Lorem ipsum');

-- 5 productos
INSERT INTO producto(nombre, descripcion, precio, cantidad, categoria)  VALUES 
('Soda 500ml', 'Gaseosa de 500ml en botella de vidrio', 4.50, 100, 1),
('Soda 1l', 'Gaseosa de 1 litro retornable', 7.50, 50, 1),
('Chicha morada 500ml', 'Chicha morada de 500ml retornable', 3.50, 40, 1),
('Causa rellena - 250gr', 'Porción de causa de 250 gramos', 10.50, 10, 2),
('Papa a la huancaína', null, 11.00, 10, 2);

-- 3 Ventas
INSERT INTO venta(cliente,empleado,monto,fecha) VALUES
(1,1,100,"2022-04-03 14:00:45"),
(1,2,100,"2022-05-01 22:00:00"),
(2,2,100,"2022-08-13 21:30:45");

-- Detalle de cada venta
INSERT INTO detalle(venta,producto,precio,cantidad) VALUES 
(1,4,10,5),
(1,1,5,10);
INSERT INTO detalle(venta,producto,precio,cantidad) VALUES 
(2,2,7.50,10),
(2,3,2.50,10);
INSERT INTO detalle(venta,producto,precio,cantidad) VALUES 
(3,4,10,10);

Vistas de la base de datos

-- VISTAS
-- ------------------------------------
-- productos_view
-- ------------------------------------
CREATE VIEW productos_view AS SELECT 
    p.id,
    p.nombre,
    p.precio,
    p.descripcion,
    p.cantidad,
    c.nombre AS categoria
FROM producto p INNER JOIN categoria c 
ON p.categoria = c.id;

-- ------------------------------------
-- venta_view
-- ------------------------------------
CREATE VIEW venta_view AS SELECT 
    v.id,
    CONCAT_WS(' ', c.nombres,c.apellidos) AS cliente,
    CONCAT_WS(' ', e.nombres,e.paterno,e.materno) AS empleado,
    v.fecha,
    v.monto,
    c.id AS id_cliente,
    e.id AS id_empleado
FROM venta v 
INNER JOIN cliente c ON v.cliente = c.id 
INNER JOIN empleado e ON v.empleado = e.id;

-- ------------------------------------
-- detalle_view
-- ------------------------------------
CREATE VIEW detalle_view AS SELECT 
    d.id,
    v.id AS venta,
    p.nombre AS producto,
    p.id AS id_producto,
    d.precio,
    d.cantidad
FROM detalle d 
INNER JOIN venta v ON d.venta = v.id 
INNER JOIN producto p ON d.producto = p.id;

miércoles, 2 de marzo de 2022

Raspberry Pi - GPIO básico

Proyectos básicos

En este caso se presentarán 3 aplicaciones básicas en Raspberry Pi empleando diodos led, resistencias y pulsadores. Para el Raspberry Pi 4 modelo B, la distribución de sus 40 pines es:

EJERCICIO 01 - Encender y apagar un LED

El siguiente ejemplo encenderá un LED durante 5 segundos, luego lo apagará y así de forma consecutiva. Tener en cuenta que dependiendo del voltaje de funcionamiento del LED elegido se debe variar la resistencia para que este no resulte quemado y/o la luz se pueda apreciar.

Materiales:

  • Raspberry (Raspberry Pi 4 model B)
  • Led (Rojo con voltaje de 1.2v)
  • Protoboard
  • Cables dupont
  • Resistencia de 560 ohmnios

Diagrama de conexión:

Código

#Biblioteca GPIO para controlar los pines del Raspberry Pi
import RPi.GPIO as GPIO
#Biblioteca "time" útil para realizar pausas
import time

GPIO.setmode(GPIO.BCM)  #La numeración será según usar la numeración del chip BROADCOM
GPIO.setwarnings(False) #Se deshabilitan las advertencias cuando entramos en un bucle
GPIO.setup(21,GPIO.OUT) #Se indica que el PIN 21 es de salida

#Bucle infinito
while True:
    print("Encendido")        #Mensaje en pantalla
    GPIO.output(21,GPIO.HIGH) #El PIN 21 se enciende (HIGH)
    time.sleep(5)             #Se detiene 5 segundos
    print("Apagado")          #Mensaje en pantalla
    GPIO.output(21,GPIO.LOW)  #El PIN 21 se apaga (LOW)
    time.sleep(5)             #Se detiene 5 segundos
    GPIO.cleanup              #Se limpian los PINES

EJERCICIO 02 - Encender y apagar un LED con pulsador

El siguiente ejemplo encenderá un LED durante 5 segundos, luego lo apagará y así de forma consecutiva. Tener en cuenta que dependiendo del voltaje de funcionamiento del LED elegido se debe variar la resistencia para que este no resulte quemado y/o la luz se pueda apreciar.

Materiales:

  • Raspberry (Raspberry Pi 4 model B)
  • Led (Rojo con voltaje de 1.2v)
  • Protoboard
  • Pulsador
  • Cables dupont
  • Resistencia de 560 ohmnios

Diagrama de conexión:

Código

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
#Se indica expresamente que su estado por defecto es LOW (apagado)
GPIO.setup(21,GPIO.OUT,initial=GPIO.LOW)
#Se indica el PIN 20 como entrada. Además, configuración PULL DOWN
GPIO.setup(20,GPIO.IN,pull_up_down=GPIO.PUD_DOWN)

while True:
    if GPIO.input(20): #Se evalúa si el boton es pulsado
        print("Pulsado")
        GPIO.output(21,GPIO.HIGH)
    else:
        GPIO.output(21,GPIO.LOW)
    GPIO.cleanup

EJERCICIO 03 - Encender y apagar un LED con pulsadores sin mantener presionado

El siguiente ejemplo encenderá un LED durante 5 segundos, luego lo apagará y así de forma consecutiva. Tener en cuenta que dependiendo del voltaje de funcionamiento del LED elegido se debe variar la resistencia para que este no resulte quemado y/o la luz se pueda apreciar.

Materiales:

  • Raspberry (Raspberry Pi 4 model B)
  • Led (Rojo con voltaje de 1.2v)
  • Pulsador
  • Protoboard
  • Cables dupont
  • Resistencia de 560 ohmnios

Diagrama de conexión:

Código

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(21,GPIO.OUT,initial=GPIO.LOW)
GPIO.setup(20,GPIO.IN,pull_up_down=GPIO.PUD_DOWN)
#Variable auxiliar
estado = False

while True:
    if GPIO.input(20):
        estado = not estado #Se invierte el valor si se presiona el botón
    if estado:
        print("Encendido")
        GPIO.output(21,GPIO.HIGH)
    else:
        print("Apagado")
        GPIO.output(21,GPIO.LOW)
    GPIO.cleanup

Plataforma Arduino

 Según la documentación oficial de Arduino:

"Arduino es una plataforma electrónica de código abierto basada en hardware y software fáciles de usar. Las placas Arduino pueden leer entradas (luz en un sensor, un dedo en un botón o un mensaje de Twitter) y convertirlo en una salida: activar un motor, encender un LED, publicar algo en línea. Puede decirle a su placa qué hacer enviando un conjunto de instrucciones al microcontrolador en la placa. Para ello se utiliza el lenguaje de programación Arduino (basado en Wiring ), y el Software Arduino (IDE) , basado en Processing."

Las ventajas que ofrece Arduino frente a otras plataformas es el costo al ser en comparación más baratas que otras, su IDE es multiplataforma (sistemas operativos Windows, Mac y Linux), el IDE es basado en Processing empleando el lenguaje C++ que permite agregar nuevas bibliotecas y expandír aún más la cantidad de componentes y sistemas con los que puede interactuar. Finalmente, tanto el hardware como el software es abierto y extensible.

Modelos de Arduino

Arduino UNO

Características

  • Voltaje de entrada: 6v - 20v
  • Voltaje recomendado: 7v - 12v
  • Voltaje de operación: 5v
  • Pines digitales de entrada y salida: 14 (6 con salida PWM)
  • Pines análogos de entrada y salida: 6
  • Dimensiones: 68.6 mm por 53.4 mm

Arduino NANO

Características

  • Voltaje de entrada: 7v - 12v
  • Voltaje de operación: 5v
  • Pines digitales de entrada y salida: 22 (6 con salida PWM)
  • Pines análogos de entrada y salida: 8
  • Dimensiones: 18 mm por 45 mm

Arduino MEGA

Características

  • Voltaje de entrada: 6v - 20v
  • Voltaje recomendado: 7v - 12v
  • Voltaje de operación: 5v
  • Pines digitales de entrada y salida: 54 (15 con salida PWM)
  • Pines análogos de entrada y salida: 16
  • Dimensiones: 101.52 mm por 53.3 mm

Existen otros modelos como:

  • Arduino Zero
  • Arduino Due
  • Arduino Leonardo
  • Arduino Micro
  • Arduino Yún

Cada uno con sus características propias y variantes. Además, de otros modelos orientados a IoT como el Arduino MKR

Fuentes:

Arduino básico

Proyectos básicos

En este caso se presentarán 5 aplicaciones básicas en Arduino empleando diodos led, resistencias, pulsadores, interruptores DIP y potenciómetros.

EJERCICIO 01 - Encender y apagar un LED

El siguiente ejemplo encenderá un LED durante 3 segundos, luego lo apagará y así de forma consecutiva. Tener en cuenta que dependiendo del voltaje de funcionamiento del LED elegido se debe variar la resistencia para que este no resulte quemado y/o la luz se pueda apreciar.

Materiales:

  • Arduino (Arduino UNO)
  • Led (Verde con voltaje de 1.6v)
  • Protoboard
  • Cables dupont
  • Resistencia de 680 ohmnios

Diagrama de conexión:

Código

//Constante que hace referencia al PIN donde se conecta el LED
const int LED = 8;

void setup(){
  pinMode(LED, OUTPUT);   //Indica que el Pin es de salida
  digitalWrite(LED, LOW); //Indica que el LED por defecto esta apagado
}

void loop(){
  digitalWrite(LED, HIGH); //Enciende el LED
  delay(3000);             //Espera 3000 milisegundos
  digitalWrite(LED, LOW);  //Apaga el LED
  delay(3000);             //Espera 3000 milisegundos
}

EJERCICIO 02 - Encender y apagar un LED con pulsador

El siguiente ejemplo encenderá un LED mientras un pulsador se mantenga presionado, si se suelta se apagará y así de forma consecutiva. Tener en cuenta que dependiendo del voltaje de funcionamiento del LED elegido se debe variar la resistencia para que este no resulte quemado y/o la luz se pueda apreciar. Además, la configuración de la resistencia del pulsador es "PULL-DOWN" y de 10 KΩ

Materiales:

  • Arduino (Arduino UNO)
  • Led (Rojo con voltaje de 1.2v)
  • Protoboard
  • Pulsador
  • Cables dupont
  • Resistencias de 560Ω (LED) y 10KΩ (pulsador)

Diagrama de conexión:

Código

//Constante que hace referencia al PIN donde se conecta el LED
const int LED = 12;
//Constante que hace referencia al PIN donde se conecta el pulsador
const int PUL = 7;

void setup(){
  pinMode(LED, OUTPUT);   //Indica que el Pin es de salida
  pinMode(PUL, INPUT);    //Indica que el Pin es de entrada
  digitalWrite(LED, LOW); //Indica que el LED por defecto esta apagado
}

void loop(){
  if(digitalRead(PUL)){           //Si el pulsador esta presionado
  	digitalWrite(LED, HIGH);      //Enciende el LED
  }else{                          //Si el pulsador deja de estar presionado
  	digitalWrite(LED, LOW);       //Apaga el LED
  }
}

EJERCICIO 03 - Encender y apagar un LED con pulsadores sin mantener presionado

El siguiente ejemplo encenderá un LED mientras al presionar un interruptor y se apagará al presionar otro, no es necesario mantenerlos presionados. Tener en cuenta que dependiendo del voltaje de funcionamiento del LED elegido se debe variar la resistencia para que este no resulte quemado y/o la luz se pueda apreciar. Además, la configuración de la resistencia de los pulsadores es "PULL-DOWN" y de 10 KΩ

Materiales:

  • Arduino (Arduino UNO)
  • Led (blanco con voltaje de 3.7v)
  • Protoboard
  • Pulsadores
  • Cables dupont
  • Resistencias de 100Ω (LED blanco) y 10KΩ (2 para los pulsadores)

Diagrama de conexión:

Código

const int LED = 8;
const int PUL_ON = 5;
const int PUL_OFF = 2;
boolean estado; //variable auxiliar para capturar el estado

void setup() {
  pinMode(PUL_ON, INPUT);
  pinMode(PUL_OFF, INPUT);
  pinMode(LED, OUTPUT);
}

void loop() {
  //Estado en TRUE si se presiona el boton del PIN 5
  if(digitalRead(PUL_ON)){estado = true;}
  //Estado en FALSE si se presiona el boton del PIN 2
  if(digitalRead(PUL_OFF)){estado = false;}
  //Dependiendo del estado se enciendo o apaga el LED
  if(estado){
  	digitalWrite(LED, HIGH);
  }else{
  	digitalWrite(LED, LOW);
  }
}

EJERCICIO 04 - Encender y apagar varios LED con interruptores DIP

El siguiente ejemplo encenderá varios LED mientras el interruptor correspondiente se mantenga en ON (cerrando circuito). Tener en cuenta que dependiendo del voltaje de funcionamiento del LED elegido se debe variar la resistencia para que este no resulte quemado y/o la luz se pueda apreciar. Además, la configuración de la resistencia de los interruptores es "PULL-DOWN" y de 10 KΩ

Materiales:

  • Arduino (Arduino UNO)
  • LES (Rojo con voltaje de 1.2v, blanco y azul con voltaje de 3.7v y amarillo con voltaje de 1.6v)
  • Protoboard
  • Conmutadores DIP de 4 canales
  • Cables dupont
  • Resistencias de 100Ω (LED blanco y azul), 220Ω (LED rojo), 390Ω (LED amarillo) y 10KΩ (4 para los conmutadores DIP)

Diagrama de conexión:

Código

//Constantes para los LED
const int LED1 = 7;
const int LED2 = 8;
const int LED3 = 12;
const int LED4 = 13;
//Constantes para cada conmutador
const int PUL1 = 5;
const int PUL2 = 4;
const int PUL3 = 3;
const int PUL4 = 2;

void setup(){
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);  
  pinMode(PUL1, INPUT);  
  pinMode(PUL2, INPUT);  
  pinMode(PUL3, INPUT);  
  pinMode(PUL4, INPUT);
}

void loop(){
  //Control del LED blanco con el conmutador 1
  if(digitalRead(PUL1)){
  	digitalWrite(LED1, HIGH);
  }else{
  	digitalWrite(LED1, LOW);
  }
  //Control del LED rojo con el conmutador 2
  if(digitalRead(PUL2)){
  	digitalWrite(LED2, HIGH);
  }else{
  	digitalWrite(LED2, LOW);
  }
  //Control del LED amarillo con el conmutador 3
  if(digitalRead(PUL3)){
  	digitalWrite(LED3, HIGH);
  }else{
  	digitalWrite(LED3, LOW);
  }
  //Control del LED azul con el conmutador 4
  if(digitalRead(PUL4)){
  	digitalWrite(LED4, HIGH);
  }else{
  	digitalWrite(LED4, LOW);
  }
}

Funcionamiento:


EJERCICIO 05 - modificar la intensidad de un LED con un potenciómetro

El siguiente ejemplo encenderá un LED y se controlará su intensidad empleando un potenciómetro. Tener en cuenta que dependiendo del voltaje de funcionamiento del LED elegido se debe variar la resistencia para que este no resulte quemado y/o la luz se pueda apreciar.

Materiales:

  • Arduino (Arduino UNO)
  • Led (blanco con voltaje de 3.7v)
  • Protoboard
  • Potenciómetro de 5KΩ
  • Cables dupont
  • Resistencias de 100Ω (LED blanco)

Diagrama de conexión:

Código

//El PIN del led debe ser PWM (tener el símbolo ~)
const int LED =11;
//El potenciómetro se debe conectar a un PIN analógico
const int POT = A0;
//Variable auxiliar para almacenar el valor del potenciómetro
int aux;

void setup(){
  pinMode(LED,OUTPUT);
  digitalWrite(LED,LOW);
}

void loop(){
  //Capturar el valor del potenciómetro
  aux = analogRead(POT);
  //Se emplea MAP para dar un valor análogo entre 0 y 255 al valor recibido entre 0 y 1023
  analogWrite(LED, map(aux,0,1023,0,255));  
}

domingo, 30 de mayo de 2021

Arduino y Processing - Encender y apagar un LED

 Diagrama de conexión


Código en Arduino

const int LED = 5;
char dato;

void setup() {
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
}

void loop() {
  if (Serial.available() > 0)
  {
    dato = Serial.read();
    if (dato == 'E') {
      digitalWrite(LED, HIGH);
    } else {
      digitalWrite(LED, LOW);
    }
  }
}

Código en Processing

import processing.serial.*;

Serial port;
String TITULO="Control de LED - Arduino";
PFont font;
int qx=150;
int qy=150;
int qr=50;
boolean state = false;
String texto;

void setup()
{  
  //println(Serial.list()); 
  port = new Serial(this, Serial.list()[0], 9600);
  size(300, 300);   
  font = createFont("Arial", 20, true);
  frameRate(10);
}

void draw()
{
  background(220, 220, 220); 
  textFont(font, 20);
  fill(0);
  textAlign(CENTER);
  text(TITULO, width/2, 60);

  fill(0);  
  stroke(0, 255, 0);

  if (mouseX > qx-qr  && mouseX < qx+qr && 
    mouseY > qy-qr && mouseY < qy+qr && mousePressed) {
    state=!state;
  }
  noStroke();
  if (state) {  
    fill(0, 0, 255);
    texto="ON";
    port.write('E');
  } else {  
    fill(255, 0, 0);
    texto="OFF";
    port.write('A');
  }  
  rectMode(RADIUS);
  rect(qx, qy, qr, qr);
  fill(0);
  text(texto, 150, 150);
}

Interfaz gráfica




domingo, 13 de diciembre de 2020

Solución de Access denied en MySQL

Si aparece el error Access denied for user 'root'@'localhost' y se está empleando MySQL versión 8, la solución más sencilla es ejecutar en la línea de comandos de MySQL cualquiera de las siguientes sentencias dependiendo si se desea establecer o no una contraseña


Solución en LINUX

En el caso de LINUX el primer paso es abrir el terminal CTRL + ALT + T. Luego ingresar a la consola de MySQL con el comando:

sudo mysql -u root

Solución en WINDOWS

El primer paso en WINDOWS es abrir el CMD con WINDOWS + R o desde el menú inicio escribiendo CMD. Luego ingresar a la consola de MySQL con el comando:

mysql -uroot -p

Luego ingresar cualquiera de las siguientes dos opciones

Sin contraseña


  ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY ''
  

Con contraseña


  ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'clave';
  

viernes, 27 de noviembre de 2020

Creando una tabla en SQLite

Crear la base de datos

Se requiere de un programa que administre bases de datos de SQLite para crear las bases de datos y opcionalmente comprobar si los cambios realizados por aplicaciones externas funcionan. Se puede emplear alguno de estos u otros:

Las bases de datos de SQLite son archivos en lugar de un conjuntos de carpetas y archivos contenidos en un servidor, por lo cual no requieren un puerto.

Una vez instalado el programa, se selecciona la opción de agregar una base de datos

Se agrega una base de datos, se puede seleccionar una existente o crear una nueva

Se procede a crear una base de datos con la extensión "db" y luego realizar un test de conexión

Finalmente, aceptar


Crear la tabla

Mediante el programa se puede crear la tabla y las columnas seleccionando la base de datos:


Luego se debe seguir una serie de pasos para agregar columnas y configurarlas.

  1. Indicar el nombre de la tabla
  2. Agregar columnas
  3. Indicar el nombre de la columna y su tipo, adicionalmente el tamaño. Por ejemplo, columnas que contienen texto o números con decimales.
  4. Indicar los restricciones (constraints) como clave primaria, foránea, campo único, etc.
  5. En algunos casos es necesario agregar una configuración adicional a las restricciones.
  6. Por ejemplo, en los campos PRIMARY KEY de tipo entero, el autoincremento. Además, se puede colocar un nombre a la restricción. Por ejemplo, necesario para claves foráneas.
  7. Finalmente aplicar cambios y repetir el proceso para cada columna que se desee agregar.

Se confirman los cambios, luego aparece el código SQL generado que se puede guardar para tener un Script.



Código SQL

Si se desea, se puede colocar el código directamente, para ello se debe seleccionar el editor SQL como se muestra.

En el editor SQL se debe ingresar lo siguiente y ejecutar (F9 en Windows).

CREATE TABLE inquilinos (
    idinquilinos  INTEGER         PRIMARY KEY AUTOINCREMENT,
    dni           VARCHAR (8)     UNIQUE
                                  NOT NULL,
    nombres       VARCHAR (150)   NOT NULL,
    paterno       VARCHAR (150)   NOT NULL,
    materno       VARCHAR (150)   NOT NULL,
    telefono      VARCHAR (40),
    correo        VARCHAR (200),
    deuda         DECIMAL (10, 2) NOT NULL,
    fecha_ingreso DATE            NOT NULL
);

Finalmente, se podrá apreciar la estructura de la tabla dentro de la base de datos. Cabe recordar que la base de datos "blog.db" es un archivo que estará ubicado en la dirección seleccionada inicialmente y puede ser trasladado donde deseemos.


domingo, 11 de octubre de 2020

Clases y objetos en C++

Objetos

Según la POO son bloques de código que permiten representar cosas (reales o imaginarias) como una persona o una venta. Los objetos se dividen en tres partes:

  • El estado: conjunto de campos o variables (atributos o miembros)
  • El comportamiento: las funciones (métodos o funciones miembro)
  • La identidad: permite identificar un objeto de otro. De forma que cada objeto es identificable respecto a los demás.

Clases

Son estructuras que define las características que tendrá un objeto. Esto es lo que se llama encapsulamiento y es uno de los pilares de la POO.

Atributos

Son un conjunto de variables que definen el estado de una clase pueden ser tipos básicos:
  • int
  • float
  • char
  • bool
  • Tipo colecciones (array), vectores u otros objetos.
Estas no deben ser accesibles desde el exterior, por lo que debe ser de tipo privado.

Metodos

Estos permiten acceder y modificar el estado de una clase.Tenemos dos clases especiales: el constructor y el destructor (el primero permite inicializar o instanciar una clase y el otro liberar recursos)

Además, existen los tradicionales métodos de acceso llamados GET que permiten extraer o mostrar el contenido de los atributos, generalmente sin parámetros salvo en colecciones u otros casos. Debe ser de tipo público. También, están los de modificación llamados SET que permiten modificar desde el exterior el contenido de los atributos asegurando la integridad de la clase, generalmente tienen un parámetro que coincide con el tipo de dato al que desean modificar y son públicos.


#include<iostream>
using namespace std;

class point{
	private:
		double x;
		double y;
	public:		
		//Constructor
		point(double x=0.0,double y=0.0):
			x(x),y(y)// Inicialización
			{}// Sin asignación
            
		//Métodos SET y GET	
		double getX() const {return this->x;}
		setX(double x){this->x=x;}
		double getY() const {return this->y;}
		setY(double y){this->y=y;}
		
		/*Destructor*/
		~point(){
			cout<<endl<<"Elemento destruido"<<endl<<endl;
		}		
};

Tangram con MiniWin

En el siguiente ejemplo se van a recrear las piezas de un tangram empleando triángulos rectángulos para formarlas.

Esto implica crear una o varias funciones para dibujar los triángulos rectángulos. En este caso se optó por usar cuatro funciones llamadas:

  • tipoA
  • tipoB
  • tipoC
  • tipoD

Estas podrían ser "inline", pero se optó por funciones convencionales, las funciones serían:

/*Trabajando con 4 tipos de triángulos rectángulos*/
void tipoA(int x1, int y1, int ta){
	for(int i=0; i<=ta; i++){		
		linea(x1+ta-i,y1+i,x1+ta,y1+i);	
	}
}
void tipoB(int x1, int y1, int ta){
	for(int i=0; i<=ta; i++){		
		linea(x1,y1+i,x1+i,y1+i);	
	}
}
void tipoC(int x1, int y1, int ta){
	for(int i=0; i<=ta; i++){		
		linea(x1+i,y1+i,x1+ta,y1+i);	
	}
}
void tipoD(int x1, int y1, int ta){
	for(int i=0; i<=ta; i++){		
		linea(x1,y1+i,x1+ta-i,y1+i);	
	}
}

Donde cada función corresponde a:

Tipo A Tipo B
    *
   **
  ***
 ****
*****
*
**
***
****
*****
Tipo C Tipo D
*****
 ****
  ***
   **
    *
*****
****
***
**
*

El código completo sería:

#include "miniwin.h"
using namespace miniwin;

const int DIM = 200; // Valor medio del ancho

/*Funciones */
void tipoA(int x1, int y1, int ta){
	for(int i=0; i<=ta; i++){		
		linea(x1+ta-i,y1+i,x1+ta,y1+i);	
	}
}
void tipoB(int x1, int y1, int ta){
	for(int i=0; i<=ta; i++){		
		linea(x1,y1+i,x1+i,y1+i);	
	}
}
void tipoC(int x1, int y1, int ta){
	for(int i=0; i<=ta; i++){		
		linea(x1+i,y1+i,x1+ta,y1+i);	
	}
}
void tipoD(int x1, int y1, int ta){
	for(int i=0; i<=ta; i++){		
		linea(x1,y1+i,x1+ta-i,y1+i);	
	}
}

int main(){
	vredimensiona(2*DIM, 2*DIM);	
	color_rgb(0, 0, 0);
	rectangulo_lleno(0, 0, 2*DIM, 2*DIM);
	
	/*Pieza 1*/
	color(AZUL);
	tipoB(0,0,DIM);
	tipoD(0,DIM,DIM);
	
	/*Pieza 2*/
	color_rgb(255, 150, 0);	
	tipoC(0,0,DIM);
	tipoD(DIM,0,DIM);	
	
	/*Pieza 3*/
	color(VERDE);	
	tipoA(DIM*1.5,0,DIM/2);
	rectangulo_lleno(DIM*1.5,DIM/2,2*DIM,DIM);
	tipoD(DIM*1.5,DIM,DIM/2);
	
	/*Pieza 4*/
	color(ROJO);	
	tipoA(DIM,DIM,DIM);
	
	/*Pieza 5*/
	color(MAGENTA);	
	tipoA(0,DIM*1.5,DIM/2);
	tipoB(DIM/2,DIM*1.5,DIM/2);
	
	/*Pieza 6*/
	color(AMARILLO);	
	tipoA(DIM/2,DIM,DIM/2);
	tipoB(DIM,DIM,DIM/2);
	tipoC(DIM/2,DIM*1.5,DIM/2);
	tipoD(DIM,DIM*1.5,DIM/2);
	
	/*Pieza 7*/
	color_rgb(100,0,155);	
	tipoA(DIM,DIM/2,DIM/2);
	tipoC(DIM,DIM,DIM/2);
	
	refresca();
	return 0;

}

El resultado visual sería:




domingo, 13 de septiembre de 2020

MiniWin con C++


MiniWin es una pequeña biblioteca gráfica para el lenguaje C++ que permite crear una ventana, pintar en ella, detectar la presión de las teclas. Además del movimiento y botones del mouse. 

Estructura básica de un programa con MiniWin

Un programa que implemente esta biblioteca debe tener la siguiente estructura:

#include "miniwin.h"
using namespace miniwin;

int main(){
	// Código que implementa las funciones de MinWin
	return 0;
}

Ejemplos:
#include "miniwin.h"
using namespace miniwin;

int main(){
	/* Creando un mensaje en un ventana */
	vredimensiona(400, 300);
   	rectangulo(100, 100, 300, 200);
   	texto(145, 142, "Bienvenidos a C++");
   	refresca();
	return 0;
}

#include "miniwin.h"
using namespace miniwin;

int main(){
	/*Crea la ventana*/
	vredimensiona(200, 200);
	
	// Dibujando una línea
	linea(0, 0, 200, 200);
	
	// Dibujando un rectángulo amarillo
	color(AMARILLO);//Asigna color
	rectangulo(10, 10, 50, 50);
	
	// Dibujando una circunferencia roja
	color(ROJO);//Asigna color
	circulo(150, 50, 20);
	
	// Dibujando un círculo relleno azul
	color(AZUL);//Asigna color
	circulo_lleno(100, 100, 20);
	
	// Dibujando un rectángulo relleno verde
	color(VERDE);//Asigna color
	rectangulo_lleno(150, 150, 200, 200);
	
	refresca();//Dibuja en pantalla
	return 0;
}


Fuentes y enlaces externos:

jueves, 10 de septiembre de 2020

Estructuras en C++

Estructuras condicionales

Estas permiten ejecutar bloques de sentencias de código para una determinada condición, si esta no se cumple se puede optar por no realizar nada o llevar a cabo otro bloque de sentencias, de manera que no pueden ejecutarse ambos bloques, solo uno de ellos.



Condicional IF ELSE Condicional SWITCH CASE
if (condicion1) {
   //Sentencias si 
   //Condicion1 es verdad
}else if (condicion2) {
   //Sentencias si 
   //Condicion2 es verdad
}else {
   //Sentencias si condicion1 y
   //condicion2 no son verdad
}
switch (expresión) {
case x :
   //Sentencias si expresión es "x"
   break;
case y :
   //Sentencias si expresión es "y"
   break;
default:
   //Sentencias para otros casos
}

Aplicación

El siguiente programa pide dos valores al usuario y los compara mostrando el mayor o ambos si son iguales.

#include <iostream>
using namespace std;

int main()
{
	int a;
	int b;
	cout << "Ingrese dos números\n\n";
	cin >> a >> b;

	if (a > b) {
		cout << "Mayor: a = " << a;
	}
	else if (b > a) {
		cout << "Mayor: b = " << b;
	}
	else {
		cout << "Iguales a =  " << a << ', '
			 << "b = " << b << '\n';
	}
	return 0;
}

En el siguiente ejemplo se pide un valor numérico del 1 al 7 y se imprime el valor correspondiente de la semana y una advertencia si el valor es diferente del 1 al 7.

#include <iostream>
using namespace std;

int main()
{
	int num;
	cout << "Ingrese un numero de la semana\n\n";
	cin >> num;
	switch (num){
	case 1:
		cout << "Lunes";
		break;
	case 2:
		cout << "Martes";
		break;
	case 3:
		cout << "Miercoles";
		break;
	case 4:
		cout << "Jueves";
		break;
	case 5:
		cout << "Viernes";
		break;
	case 6:
		cout << "Sabado";
		break;
	case 7:
		cout << "Domingo";
		break;
	default:
		cout << "Valor erroneo";
		break;
	}
	return 0;
}

domingo, 6 de septiembre de 2020

Introducción a C++

Estructura básica

Para escribir un programa en C++ se debe considerar la siguiente estructura básica:


// Función principal
int main()
{
   /*
     El código c++ se coloca en esta sección
   */
   return 0;
}

En la primera línea se coloca la referencia a las bibliotecas que empleará el programa. Los comentarios pueden ser de dos tipos:

  • De línea: empleando //
  • De bloque: empleando /* y */

Entrada y salida de datos

Para escribir un programa en C++ se debe considerar la siguiente estructura básica:

#include <iostream>
using namespace std;

int main()
{
   //Declaración de variables
   int num;
   
   //Entrada de datos
   cin >> num;
   
   //Salida de datos
   cout << "Número: " << num;
   return 0;
}

Datos primitivos

  • bool: El tipo de dato bool, tiene un tamaño de 8 bits y un rango entre 0 y 1 (falso o verdadero).
  • int: El tipo de dato int, tiene un tamaño de 32 bits y un rango entre -2147483648 y 2147483647. Este se usa para números enteros (sin decimales). Sus variantes son:
    • short int: Tiene un tamaño de 16 bits y un rango entre -32768 y 32767.
    • unsigned short int: Tiene un tamaño de 16 bits y un rango entre 0 y 65535.
    • unsigned int: Tiene un tamaño de 32 bits y un rango entre 0 y 4294967295.
    • long long int: Tiene un tamaño de 64 bits y un rango entre -9223372775808 y 9223375775807.
    • unsigned long long int: Tiene un tamaño de 64 bits y un rango entre 0 y 2 elevado a la potencia 64.
  • float: Tiene un tamaño de 32 bits, es usado comúnmente en números con 6 o menos cifras decimales. Tiene un rango entre 1,17549*(e^-38) hasta 3,40282*(e^+38).
  • double: Tiene un tamaño de 64 bits, es usado para números de menos de 15 cifras decimales. Tiene un rango entre 2,22507*(e^-308) hasta 1,79769*(e^308).
    • long double: Tiene un tamaño de 96 bits y una precisión de 18 cifras decimales. Tiene un rango entre 3,3621*(e^-4932) hasta 1,18973*(e^4932).
  • char: Son variables de tipo vector que almacenan cualquier caracter y puede estar con o sin signo.
#include <iostream>
using namespace std;

int main()
{
	//Variables
	int num = 2;
	float dec1 = 3.14;
	double dec2 = -2.1213;
	bool val = false;
	char cad = 'a';
	return 0;
}

jueves, 16 de julio de 2020

Cargar datos en una lista desplegable con PHP

Supongamos que queremos agregar un registro a una tabla que se relaciona mediante una clave foránea con otra, solo requiere que se le ingrese el código o id, pero colocar ello en una caja de texto es incómodo, lo ideal sería desplegar en una lista desplegable vertical los registros de la tabla cuyo identificador o código queremos mostrar. Ilustremos ello con un ejemplo:


Sin lista desplegable Con lista desplegable

Agregar datos







Agregar datos








Trabajaremos con las siguientes tablas:




Ahora vamos a crear ese formulario donde se puedan cargar los datos de "inquilinos" y enviar el "id" a través de un formulario web. Este ejemplo no emplea programación orientada a objetos y nos limitamos a enviar la información.

Creamos el formulario en el archivo"pagoIns.php"
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <form class="jpcss" method="post" action="agregar_pago.php">    
            <fieldset>
                <legend>INGRESAR ABONO</legend><br> 
                Ingrese al aportante: <select name="personas">
                    <!--Aquí ira el código PHP-->
                </select><br><br>
                Ingrese el importe: S/ 
                <input type="number" name="importe" min="0.01" step="0.01" value="0.01"><br>  
                <br><br>
                <button onclick="return confirm('¿Seguro que deseas ingresar el pago?')">
                    INGRESAR
                </button>  
            </fieldset>
        </form>
    </body>
</html>

Ahora vamos a realizar tanto la conexión como la consulta SQL en código PHP
<?php
#Parámetros de la BD
$cfg['h'] = 'localhost';  #hostname
$cfg['u'] = 'root';       #usuario
$cfg['p'] = '';           #contraseña (password)
$cfg['b'] = 'blog';       #base de datos
$cfg['r'] = '3306';       #puerto 
#Conexión
$cnx = mysqli_connect($cfg['h'], $cfg['u'], $cfg['p'], $cfg['b'], $cfg['r']);
mysqli_query($cnx, "set names utf8");

#Consulta SQL
$sql = "SELECT idinquilinos id, "
        . "CONCAT_WS (' ',nombres,paterno,materno) "
        . "datos FROM inquilinos;";

#Capturando los datos
$bolsa = mysqli_query($cnx, $sql);
$salida = array();
if ($bolsa != null) {
    while ($row = mysqli_fetch_assoc($bolsa)) {
        $salida[] = $row;
    }
    mysqli_free_result($bolsa);
} else {
    $salida = false;
}
unset($row);
?>

Ese código lo colocaremos al inicio de la siguiente forma. Agregando el código que muestra los datos en la lista desplegable.
<?php
#Parámetros de la BD
$cfg['h'] = 'localhost';  #hostname
$cfg['u'] = 'root';       #usuario
$cfg['p'] = '';           #contraseña (password)
$cfg['b'] = 'blog';       #base de datos
$cfg['r'] = '3306';       #puerto 
#Conexión
$cnx = mysqli_connect($cfg['h'], $cfg['u'], $cfg['p'], $cfg['b'], $cfg['r']);
mysqli_query($cnx, "set names utf8");

#Consulta SQL
$sql = "SELECT idinquilinos id, "
        . "CONCAT_WS (' ',nombres,paterno,materno) "
        . "datos FROM inquilinos;";

#Capturando los datos
$bolsa = mysqli_query($cnx, $sql);
$salida = array();
if ($bolsa != null) {
    while ($row = mysqli_fetch_assoc($bolsa)) {
        $salida[] = $row;
    }
    mysqli_free_result($bolsa);
} else {
    $salida = false;
}
unset($row);
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <form class="jpcss" method="post" action="agregar_pago.php">    
            <fieldset>
                <legend>INGRESAR ABONO</legend><br> 
                Ingrese al aportante: <select name="personas">
                    <!--Código PHP-->                    
                    <?php
                    if ($salida) {
                        foreach ($salida as $persona) {
                            ?>
                            <option value="<?= $persona['id'] ?>">
                                    <?= $persona['datos'] ?>
                            </option>
                        <?php }
                    }
                    ?>                
                </select><br><br>
                Ingrese el importe: S/ 
                <input type="number" name="importe" min="0.01" step="0.01" value="0.01"><br>  
                <br><br>
                <button onclick="return confirm('¿Seguro que deseas ingresar el pago?')">
                    INGRESAR
                </button>  
            </fieldset>
        </form>
    </body>
</html>

Entre las líneas 42 y 51 se aprecia el código que despliega los datos en la lista desplegable pudiendo obtener el efecto deseado. Se emplea antes del foreach un condicional, en caso la tabla se encuentre vacía u ocurra un error.

viernes, 19 de junio de 2020

Lenguaje de intercambio JSON

JSON (JavaScript Object Notation - Notación de Objetos de JavaScript) es un formato de intercambio de datos entre sistemas independientes del lenguaje de programación derivado de JavaScript. Sin embargo debido a que emplea convenciones muy empleadas por programadores en la rama del lenguaje C, muchos lenguajes de programación han incluido código para generar y analizar datos en este formato para convertirlos en convertirlos en objetos del lenguaje propio, así se puede concluir que este presenta facilidad de entendimiento tanto para humanos como computadores.

Composición

JSON se construye a partir de dos tipos de estructuras
  • Colección de pares de clave/valor.
    • En lenguajes de programación se tranforman o provienen de un objeto, registro, estructura, diccionario, tabla hash, lista de claves o un arreglo asociativo.
  • Lista de valores. 
    • En lenguajes de programación, esto se implementa o proviene de arreglos, vectores, listas o secuencias.

Sintaxis


En el caso de objetos individuales, este esta delimitad por llaves, dentro aparecen los pares clave valor separados por dos puntos (:) cumpliéndose lo siguiente:
  • La clave siempre será una cadena de texto, el valor puede ser de tipo lógico, textual o numérico.
  • Los valores pueden tomar tres tipos:
    • En el caso del lógico puede ser true o false sin necesidad de comillas
    • En el caso del numérico se emplea el punto para separar enteros de decimales
    • En el caso del texto debe ir entre comillas.

Nota: Se puede dar el caso que el valor de una clave es otro objeto o una colección de estos.

Ejemplo en código:
{
 "alive":true,
 "birthday":"1993-05-17",
 "dni":"96584422",
 "name":"Paul",
 "weight":62.7
}

En el caso de colecciones de objetos, los objetos mantienen su notación anterior y se separan por comas. Además, toda la colección de objetos esta delimitada por corchetes "[" y "]"

Ejemplo en código:
[
 {
  "birthday":"1993-02-07",
  "dni":"10084422",
  "name":"Milagros",
  "weight":52.7
 },
 {
  "birthday":"1992-10-01",
  "dni":"00084422",
  "name":"Yadira",
  "weight":57.0
 },
 {
  "birthday":"1990-01-21",
  "dni":"41557422",
  "name":"Alejandra",
  "weight":49.9
 }
]

En el ejemplo anterior podemos encontrar una colección de tres objetos.


Anidamiento en JSON.

{
   "address":{
      "country":"Peru",
      "department":"Lima"
   },
   "alive":true,
   "birthday":"1993-05-17",
   "dni":"96584422",
   "languages":[
      "Spanish",
      "English"
   ],
   "name":"Paul",
   "pets":[
      {      
         "name":"Argos",
         "type":"dog"
      },
      {      
         "name":"Gardfield",
         "type":"cat"
      }
   ],
   "weight":62.7   
}

Se puede apreciar lo siguiente:

  • La dirección esta compuesta por país y departamento.
  • Tiene un campo lógico llamado "alive"
  • Las fechas viajan en formato de texto
  • Los números como  "weight" no requieren de comillas, pero los códigos como el DNI sí.
  • El campo languages tiene una colección de valores sin clave.
  • En el campo "pets" el valor es una lista de dos objetos con sus propias claves y valores.

Biblioteca gráfica ImageGD en PHP

PHP tiene su propia librería gráfica (al 2020 aún en desarrollo) que permite generar gráficos rectangulares, circulares, lineales y textuales. Además, usar colores en el formato RGB para estos.

Sobre esta biblioteca el manual de PHP menciona:
"PHP no está limitado a crear únicamente salidas HTML. También se puede usar para crear y manipular ficheros de imágenes en una variedad de diferentes formatos de imagen, incluyendo GIF, PNG, JPEG, WBMP y XPM. Aún más práctico es que PHP puede transferir flujos de imagen directamente al navegador. Necesitará compilar PHP con la biblioteca de funciones de imágenes GD para que esto funcione. GD y PHP también pueden requierir otras bibliotecas, dependiendo de los formatos de imagen con los que se quiera trabajar".
Esta biblioteca permite crear imágenes de tipo:
  • JPEG
  • GIF
  • PNG
  • SWF
  • TIFF
  • JPEG2000


Creando una imagen con "imagecreatetruecolor"

<?php

# Definir el tipo de contenido de la página
header("content-type:image/png");

#Crear la imagen con dimensiones de 200px por lado
$imagen = imagecreatetruecolor(200, 200);

# Mostrar la imagen en formato PNG
imagepng($imagen);

# Liberar memoria
imagedestroy($imagen);

?>


Creando colores con "imagecolorallocate"

<?php

# Permite definir un color RGB
$colorRojo= imagecolorallocate($imagen, 255, 0, 0);

# Permite definir un color RGB
$colorBlanco= imagecolorallocate($imagen, 255, 255, 255);

# Permite definir un color RGB
$colorAmarillo= imagecolorallocate($imagen, 255, 255, 0);

?>


Creando figuras

Tenemos diversos métodos para crear figuras con y sin relleno como:


Figuras sin relleno
  • imagearc — Dibuja un arco parcial
  • imageellipse — Dibuja una elipse
  • imagepolygon — Dibuja un polígono
  • imagerectangle — Dibuja un rectángulo
Figuras con relleno
  • imagefilledarc — Dibuja un arco parcial y rellenarlo
  • imagefilledellipse — Dibuja una elipse con relleno
  • imagefilledpolygon — Dibuja un polígono con relleno
  • imagefilledrectangle — Dibuja un rectángulo con relleno


<?php

# Definir el tipo de contenido de la página
header("content-type:image/png");

#Crear la imagen con dimensiones de 200px por lado
$imagen = imagecreatetruecolor(200, 200);

# Permite definir un color RGB
$colorAmarillo= imagecolorallocate($imagen, 255, 255, 0);
$colorRojo= imagecolorallocate($imagen, 255, 0, 0);

# Gráfica de un rectángulo
imagerectangle($imagen, 10, 10, 190, 190, $colorAmarillo);

# Gráfica de un rectángulo con color de relleno
imagefilledrectangle($imagen, 40, 40, 160, 160, $colorRojo); 

# Mostrar la imagen en formato PNG
imagepng($imagen);

# Liberar memoria
imagedestroy($imagen);

?>


IMAGELINE

Esta función permite la creación de líneas con la siguiente sintaxis:
imageline($image, $x1, $y1, $x2, $y2, $color);
  • image: Un recurso image, es devuelto por una de las funciones de creación de imágenes, como imagecreatetruecolor().
  • x1: Coordenada x del primer punto.
  • y1: Coordenada y del primer punto.
  • x2: Coordenada x del segundo punto.
  • y2: Coordenada y del segundo punto.
  • color: El color de la línea. Un identificador de color creado con imagecolorallocate().
<?php

header("Content-Type: image/png");
$imagen = imagecreatetruecolor(400, 400);
$color = imagecolorallocate($imagen, 255, 255, 0);

# imageline($image, $x1, $y1, $x2, $y2, $color);
imageline($imagen, 12, 33, 300, 200, $color);

# Mostrar la imagen en formato PNG
imagepng($imagen);

# Liberar memoria
imagedestroy($imagen);

?>


IMAGERECTANGLE

Esta función permite la creación de rectágulos con la siguiente sintaxis:
imagerectangle ($image, $x1, $y1, $x2, $y2, $color);
  • image: Un recurso image, es devuelto por una de las funciones de creación de imágenes, como imagecreatetruecolor().
  • x1: Coordenada x de partida.
  • y1: Coordenada y de partida.
  • x2: Coordenada x de llegada.
  • y2: Coordenada y de llegada.
  • color: El color de la línea. Un identificador de color creado con imagecolorallocate().
<?php

header("Content-Type: image/png");
$imagen = imagecreatetruecolor(400, 400);
$color = imagecolorallocate($imagen, 255, 255, 0);

# imagerectangle ($image, $x1, $y1, $x2, $y2, $color);
imagerectangle ($imagen, 12, 33, 300, 200, $color);

# Mostrar la imagen en formato PNG
imagepng($imagen);

# Liberar memoria
imagedestroy($imagen);

?>


IMAGEREARC

Esta función permite la creación de arcos y circunferencias con la siguiente sintaxis:
imagearc($image, $cx, $cy, $ancho, $largo, $inicio, $fin, $color);
  • image: Un recurso image, es devuelto por una de las funciones de creación de imágenes, como imagecreatetruecolor().
  • cx: Coordenada x del centro.
  • cy: Coordenada y del centro.
  • largo: largo del arco.
  • ancho: ancho del arco.
  • inicio: ángulo de inicio en grados sexagésimales.
  • fin: ángulo de fin en grados sexagésimales.
  • color: El color de la línea. Un identificador de color creado con imagecolorallocate()
<?php

header("Content-Type: image/png");
$imagen = imagecreatetruecolor(400, 400);
$color = imagecolorallocate($imagen, 255, 255, 0);

# imagearc($image, $cx, $cy, $an, $la, $ini, $fin, $col);
imagearc ($imagen, 200, 200, 100, 100,0, 360, $color);

# Mostrar la imagen en formato PNG
imagepng($imagen);

# Liberar memoria
imagedestroy($imagen);

?>




Métodos GET y POST con PHP

Para enviar información a través de la web tenemos dos métodos que son el protocolo HTTP que emplea el método POST y mediante la URL que emplea el método GET.


Método GET

Es mucho más veloz, pero tiene ciertas limitaciones como la cantidad de datos a enviar, no se permite enviar archivos y se visualiza el valor enviado por el URL, lo que lo puede hacer aparentemente frágil para sistemas de autentificación, pero si se le añade encriptamiento resulta en un método seguro y veloz.

Supongamos el siguiente formulario en una página llamada "formulario.html"
<!DOCTYPE html>
<html>
    <head>
        <title>Formulario GET</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <form action="receptorget.php" method="GET">
            <label>Nombre</label><br/>
            <input type="text" name="txtNombre"/><br/><br/>
            <label>Clave</label><br/>
            <input type="password" name="txtClave"/>
            <br/><br/>
            <select name="txtIdioma">
                <option value="esp">Español</option>
                <option value="ing">Inglés</option>
                <option value="fra">Francés</option>
            </select><br/><br/><br/>
            <button type="submit">Enviar por GET</button>
        </form>  
    </body>
</html>

Se aprecia que en el formulario aparecen dos atributos con sus respectivos valores que son:
  • action: indica a que página viajarán los datos
  • method: indica la forma de enviar los datos, en este caso GET

La salida visual sería:












En una página llamada "receptorget.php" vamos a recibir estos valores enviados por GET, el URL que aparecerá en el navegador tendrá la siguiente forma:

http://localhost/test/receptorget.php?txtNombre=Paul&txtClave=12345&txtIdioma=ing

El código de "receptorget.php" sería:
<?php

$nombre = $_GET["txtNombre"];
$clave = $_GET["txtClave"];
$idioma = $_GET["txtIdioma"];

echo "Nombre: $nombre <br/>";

echo "Longitud de la clave: " . strlen($clave) . "<br/>";

switch ($idioma) {
    case "esp":
        echo "Habla español";
        break;
    case "ing":
        echo "Habla inglés";
        break;
    case "fra":
        echo "Habla francés";
        break;
    case "":
        echo "No ingresó idioma";
        break;
    default:
        echo "ERROR";
        break;
} ?>

El resultado visual sería el siguiente:
Nombre: Paul
Longitud de la clave: 5
Habla inglés 

Método POST

Es menos veloz que el método GET, pero permite enviar una gran la cantidad de datos, incluidos archivos como fotos y no se visualiza los valores enviados en el URL, lo que lo convierte en el método favorito para inicio de sesión.

Supongamos el siguiente formulario en una página llamada "formulario.html"
<!DOCTYPE html>
<html>
    <head>
        <title>Formulario GET</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <form action="receptorget.php" method="POST">
            <label>Nombre</label><br/>
            <input type="text" name="txtNombre"/><br/><br/>
            <label>Clave</label><br/>
            <input type="password" name="txtClave"/>
            <br/><br/>
            <select name="txtIdioma">
                <option value="esp">Español</option>
                <option value="ing">Inglés</option>
                <option value="fra">Francés</option>
            </select><br/><br/><br/>
            <button type="submit">Enviar por POST</button>
        </form>  
    </body>
</html>

Se aprecia que en el formulario aparecen dos atributos con sus respectivos valores que son:
  • action: indica a que página viajarán los datos
  • method: indica la forma de enviar los datos, en este caso POST

La salida visual sería:












En una página llamada "receptorpost.php" vamos a recibir estos valores enviados por POST, el URL que aparecerá en el navegador no tiene ninguna modificación

El código de "receptorget.php" sería:
<?php

$nombre = $_POST["txtNombre"];
$clave = $_POST["txtClave"];
$idioma = $_POST["txtIdioma"];

echo "Nombre: $nombre <br/>";

echo "Longitud de la clave: " . strlen($clave) . "<br/>";

switch ($idioma) {
    case "esp":
        echo "Habla español";
        break;
    case "ing":
        echo "Habla inglés";
        break;
    case "fra":
        echo "Habla francés";
        break;
    case "":
        echo "No ingresó idioma";
        break;
    default:
        echo "ERROR";
        break;
} ?>

El resultado visual sería el siguiente:
Nombre: Paul
Longitud de la clave: 5
Habla inglés 



El método $_Request["name"]

PHP tiene como método de entrada a GET y POST, pero cuando se desconoce el medio por el que llegarán los datos se puede recurrir al método $

<?php
   $nombre = $_REQUEST["txtNombre"];
   $clave = $_REQUEST["txtClave"];
   $idioma = $_REQUEST["txtIdioma"];
?>

Modificaciones de seguridad

Por cuestiones de seguridad y adaptándonos a los nuevos cambios se reemplaza los $_GET y $POST por:
<?php
$dia =  filter_input(INPUT_GET, 'txtIdioma', FILTER_SANITIZE_STRING);
$clave = filter_input(INPUT_POST, 'txtIdioma', FILTER_SANITIZE_STRING); 
?>


jueves, 11 de junio de 2020

Sesiones en PHP

El manual PHP indica sobre el soporte de las sesiones en PHP: "El soporte para sesiones en PHP consiste en una manera de preservar ciertos datos a través de accesos posteriores, lo que permite crear aplicaciones más personalizadas y mejorar el atractivo de un sitio web."


Crear sesiones

Para mantener seguridad al inicio de sesión, por ejemplo. Se opta por el uso de sesiones, ya que estos valores son almacenados en el servidor y no la computadora del usuario.

Para crear una sesión:
<?php
   
   # Iniciar sesión
   session_start();

   # Declarar los identificadores de sesión y sus valores
   $_SESSION["sesion"]="hola";
   $_SESSION["valor"]=12;

?>

$_SESSION (y todas las variables registradas) son serializadas internamente por PHP.

Operaciones con sesiones
<?php

   # Iniciar sesión
   session_start();

   # Crear sesión
   $_SESSION["valor"]=12;

   # Ver el valor de una sesión
   echo $_SESSION["valor"];

   # Actualizar el valor de una sesión
   $_SESSION["valor"]=100;

   # Cerrar sesión
   unset ( $_SESSION["valor"] ); //Liberar memoria
   session_destroy(); //Cerra la sesión propiamente dicha

?>

Usos de las sesiones

"PHP permite el uso de sesiones, valores que podemos usar para autentificar a un usuario, debe ser una medida adicional al encriptado en la base de datos para iniciar sesión"


SESIÓN PARA INICIO DE SESIÓN

<?php

   /* Colocar dentro del método de autentificación de usuario */

   if (validar()=true){
      # Creamos una sesión
      session_star(); 
      # Creamos una clave
      $_SESSION[ "acceso" ]="E14007a"; 
      # Enviamos a la página de inicio
      header ("location: inicio.php"); 
   } else {
      # Creamos una sesión para evitar conflicto al cerrar la sesión
      session_star();
      # Destruimos la sesión
      session_destroy(); 
      # Lo retornamos a la página de login
      header ("location: login.php");
   }

?>


VALIDAR EL INICIO DE SESIÓN

<?php

   # Iniciamos sesión
   session_start();

   # si la sesion es diferente a la iniciada
   if($_SESSION[ "acceso" ] != "E14007a";){ 
      # Destruimos la sesión
      session_destroy();
      # Lo retornamos a la página de login
      header ("location: login.php");
   }
?>

<!-- CÓDIGO HTML -->

Cookies en PHP

Las cookies pueden ser borradas, aceptadas, ignoradas o bloqueadas según se desee, para esto se debe configurar convenientemente el navegador web.

Del punto de vista lingüístico, el término Cookie es un anglicismo para las "galletas informáticas", estas pueden ser borradas, aceptadas, ignoradas o bloqueadas por el cliente mediante la configuración del navegador web.

Tienen diversas aplicaciones como:
  • Como un contador de visitas al sitio web.
  • Un contenedor de información que se almacena en el computador cliente y puede ser consultado por el servidor. Por ejemplo, un carrito de compras virtual.
  • Hacer seguimiento al cliente. Por ejemplo, gustos de navegación, spyware, etc.
  • Uso con intenciones malignas. Por ejemplo, las Zombie cookies.


Crear COOKIES

Para crear una cookie básica se necesita dos parámetros: el nombre de la cookie y el valor asignado. Se debe crear antes de cargar el documento HTML.
<?php
   setcookie("texto", "Bienvenido a PHP");
   setcookie("contador", 12);
   setcookie("acumulado", 33.5);
?>

Del ejemplo anterior hemos creado 3 cookies que almacenan un valor tipo cadena, tipo entero y tipo decimal. Estos se almacenan en la computadora del usuario de modo que no consumen recursos del servidor.

Llamar COOKIES

Todas las cookies se almacenan en $_COOKIE que tiene forma de array, de forma que se les llama mediante su identificador y ese valor se puede almacenar en una variable o mostrar.
<?php

   //Creamos el cookie en un archivo
   setcookie("contador", 12);

?>
<?php
   //Llamamos al cookie desde otro archivo
   $dato = $_COOKIE["contador"];

   echo $dato; //Mostrara en pantalla 12
?>


Parámetros en una cookie

Los parámetros que podemos pasar son:
  • Clave: el nombre de la cookie.
  • Valor: el valor de la cookie.
  • Duración: el tiempo que la cookie está activa.
  • Ruta: el lugar donde se almacena la cookie.
  • Dominio: el servidor donde se almacena la cookie.
  • Protocolo de seguridad: la cookie se puede transmitir por HTTPS.
  • Uso solo de HTTP: la cookie solo es accesible por http y no por otros como javaScript por ejemplo

Cookie con tiempo y sin tiempo

Se puede indicar la duración de una Cookie, si no lo hacemos esta se destruye al cerrar el navegador.

<?php
   /*Sin tiempo*/
   setcookie("nombre","argos") ;
   /* Duración: hasta que se cierre el navegador*/

   /*Con tiempo*/
   setcookie("apodo","perrosaurio", time() + 30*24*60*60) ; 
   /* Duración: 1 mes
      Con Time() iniciamos en cero, y le agregamos un mes en segundos, 
      no afecta si el usuario cierra el navegador
   */
?>


Cookie con ruta

Se puede indicar una ubicación para almacenar las Cookies.
<?php

   #Con ruta simple
   setcookie("apodo","perrosaurio", time() + 30*24*60*60, "/"); 
   //Se guarda en el directorio raíz

   #Con ruta específica
   setcookie("apodo","perrosaurio", time() + 30*24*60*60, "/cookie"); 
   // Se guarda en la carpeta cookie dentro del directorio raíz

?>

Cookie con dominio

Se puede indicar una ruta distinta a la del computador del cliente para almacenar la información:
<?php

   #Con dominio
   setcookie("nombre","argos", time() + 1000, "/c", "www.argosperro.com") ;

   /*
    * Duración: 1000 segundos
    * Carpeta: "c" dentro del directorio del dominio
    * Dominio donde se almacena: www.argosperro.com
   */

?>

Cookie con protocolos HTTPS y HTTP

Se puede implementar protocolos seguros para las Cookies mediante el siguiente formato.
<?php

   #Si queremos usar un protocolo seguro, hacemos:

   setcookie("galleta", "Hola", time()+1000, "/", "www.gatofeliz.com", true, true);

   /*
    * El primer valor en "true" activa el protocolo seguro
    * El segundo "true" evita que se usen protocolos diferentes al HTTP
    * Es necesario establecer un dominio al cual mandar los valores
   */

?>