Yokai Gameplay Volumen 1

Se me a olvidado ponerlo aquí, pero he estado haciendo un webcomic basado en un gameplay de Yokai Watch, aquí estan los comics cubriendo el primer capitulo del juego.

Si le interesa como va este proyecto aca es donde puede ver el comic 🙂

yokai_watch

Si puede dele una visita, se actualiza (en lo posible :P) cada Martes y Jueves


Y si también pueden visiten mi pagina en Ko-fi y cooperen con la causa 😀

ko-fi

 

Anuncios

Materiales de dibujo

tools

Y finalmente me doy cuenta por que se hicieron TAN populares las tabletas digitalizadoras, no solo dejan deshacer cada error y ahorran hacer el escaneo sino que además evita el circo que es tratar de conseguir los materiales usuales de dibujo.

Sonara como broma para literalmente fue comprar la tinta en un Office Max, buscar plumillas en una tienda de arte, solo para ver que costaban un ojo de la cara y luego buscar un estilografo en otro Office Depot, por que no tenian ni en el Office Max ni en la tienda de arte.

Pero bueno, ya conseguí los materiales que necesitaba, a dibujar 😛

 

 

Convertir objetos Java a JSON y de regreso

JSON
JSON

El formato JSON se a convertido rápidamente en un estándar en como enviar y recibir información a y desde un webservice, si bien es un formato que se originó en JavaScript usarlo en Java es muy sencillo gracias a la librería Gson.

Gson

Gson es una librería en Java creada por Google que permite convertir un objeto Java a JSON y un JSON a un objeto Java, su uso es increíblemente sencillo, por eso se lo recomiendo.

Convirtiendo un Objeto Java a JSON.

Como primer ejemplo veamos como se convierte un objeto Java a JSON, para esto necesitara crear un objeto de clase Gson el cual se encargara de realizar la conversión y además deberá de asegurarse que la clase del objeto que desea convertir tenga todos los getter y setter necesarios, como se ve a continuación.

package mx.com.pydee.jsonexample;

import java.math.BigDecimal;

/**
 *
 * @author David
 */
public class DetallesVenta {
    private String producto;
    private BigDecimal importe;
    private BigDecimal precioUnitario;
    private Integer cantidad;
    
    public DetallesVenta(String prod, BigDecimal pu, BigDecimal imp, Integer cant) {
        producto = prod;
        precioUnitario = pu;
        importe = imp;
        cantidad = cant;
    }

    /**
     * @return the producto
     */
    public String getProducto() {
        return producto;
    }

    /**
     * @param producto the producto to set
     */
    public void setProducto(String producto) {
        this.producto = producto;
    }

    /**
     * @return the importe
     */
    public BigDecimal getImporte() {
        return importe;
    }

    /**
     * @param importe the importe to set
     */
    public void setImporte(BigDecimal importe) {
        this.importe = importe;
    }

    /**
     * @return the precioUnitario
     */
    public BigDecimal getPrecioUnitario() {
        return precioUnitario;
    }

    /**
     * @param precioUnitario the precioUnitario to set
     */
    public void setPrecioUnitario(BigDecimal precioUnitario) {
        this.precioUnitario = precioUnitario;
    }

    /**
     * @return the cantidad
     */
    public Integer getCantidad() {
        return cantidad;
    }

    /**
     * @param cantidad the cantidad to set
     */
    public void setCantidad(Integer cantidad) {
        this.cantidad = cantidad;
    }
}

Esto es necesario ya que de otro modo le objeto Gson mandara errores de acceso a las propiedades del objeto.

Ya que halla cumplido esos dos detalles la conversión es tan sencilla como llamar al método toJson del objeto Gson, como se ve a continuación.

String JSON = gson.toJson(detalle1);

Y el resultado se vera mas o menos asi

{"producto":"Aceite","importe":120.0,"precioUnitario":12.00,"cantidad":10}

Si el objeto que convirtió a JSON contenia un arreglo de objetos estos se agregaran con la notación adecuada, como se ve a continuación

{
	"fecha": "Jul 10, 2018 1:12:58 AM",
	"cliente": "CLIENTE DE PRUEBA",
	"detalle": [{
		"producto": "Aceite",
		"importe": 120.0,
		"precioUnitario": 12.00,
		"cantidad": 10
	}, {
		"producto": "Anticongelante",
		"importe": 90.0,
		"precioUnitario": 45.00,
		"cantidad": 2
	}, {
		"producto": "Reparacion Rin",
		"importe": 400.0,
		"precioUnitario": 400.00,
		"cantidad": 1
	}]
}

Convirtiendo de JSON a Objetos Java

Al usar un webservice no solo enviaremos información en forma de JSON sino que también la recibiremos en el mismo forma, asi que veamos como convertir de JSON a un objeto Java, la misma observación aplica aquí, el objeto receptor debe de tener todos los getter y setters necesarios o tendrá un error de conversión

El método usado para realizar la conversión es fromJson el cual toma dos argumentos, la cadena String con el JSON y la clase del objeto al que queremos convertir el Json.

Con la cadena de texto debe recordar un detalle importante y es que las comillas dobles son caracteres reservados en Java por lo que recomiendo revisar el Json que regreso el webservice y remplazar esas por comillas simples, para evitar problemas de conversión.

Con respecto a la clase del objeto esa se obtiene facilmente con la propiedad .class de la clase que deseamos usar

Para simplificar las cosas a continuación se presenta un ejemplo

String jsonComplejo = "{'fecha':'Jul 9, 2018 3:37:49 PM','cliente':'LIMPIEZA Y ASEO PROFESIONAL','detalle':[{'producto':'Cloro','importe':150.0,'precioUnitario':15.00,'cantidad':10},{'producto':'Escoba','importe':30,'precioUnitario':30.00,'cantidad':1},{'producto':'Aromatizante ambiental','importe':100.0,'precioUnitario':10.00,'cantidad':10}]}";

Venta venta2 = gson.fromJson(jsonComplejo, Venta.class);

Como notara la conversión puede encargarse sin problemas de un arreglo contenido

El ejemplo completo con lo puede encontrar aquí: https://gitlab.com/ticomWebcomic/JsonExample

Referencias.

Pagina oficial de Gson: https://github.com/google/gson


Espero que esta entrada fuera de utilidad y si lo fue y quiere cooperar con la causa tengo una pagina en Ko-fi para aceptar donativos

ko-fi

Marcar registros modificados en MySQL

Trigger
Trigger

Supongamos el siguiente problema, tiene una tabla MySQL que va a ser modificada, a la brava por un programa tercero y cada vez que se modifique esa tabla debe usar esos valores para recalcular un total en otro lado, ¿Como le hace?

Si bien lo obvio es tener algún programa que revise esa tabla en forma regular queda el problema de como saber cual registro se modificó, bueno hay una solución que aprovecha una característica de MySQL, los disparadores o triggers.

Triggers

Estos son funciones que se llaman automáticamente al insertar, actualizar o borrar un registro de una tabla y nos permiten efectuar comparaciones y modificar los valores justo antes o después de que ocurra uno de los eventos mencionados, como se ven el la figura con los seis triggers disponibles: before insert, after insert ,before update, after update, before delete y after delete.

Para nuestro caso de marcar un registro modificado usaremos el trigger before update.

Trigger Before Update

Este es el trigger en particular que usaremos para detectar y marcar modificaciones en la tabla, se activa justo antes de aplicar los cambios en base de datos, al momento en el que ambos, el registro actualizado y el registro anterior, están en la memoria de modo que podemos acceder a los valores de ambos, usando NEW y OLD para representar los registros antes y después de la actualización, para efectuar comparaciones.

Ejemplo

Como un ejemplo para dejar las cosas en claro crearemos un trigger que cambie el campo modificado de cero a uno cada vez que se modifique ese registro y que nos deje cambiar el campo modificado a cero otra vez.

Sobra decir que la tabla donde quiera aplicar este trigger debe tener un campo que se llame modificado y que acepte 0 y 1 como valores, si no lo tiene modifique una tabla que tenga para hacer el experimento.

Para crear el trigger usaremos el siguiente comando:

CREATE DEFINER=`root`@`localhost` TRIGGER `test`.`folios_test_BEFORE_UPDATE` BEFORE UPDATE ON `folios_test` FOR EACH ROW
BEGIN
if old.modificado = 0 then
set new.modificado = 1;
end if;
END

Puede hacerlo directamente desde las consultas de MySQL Workbench o desde las propiedades de la tabla en la pestaña Triggers como se ve en la figura al inicio.

Lo que estamos haciendo aquí es lo siguiente:

  1. Antes de aplicar la actualización vemos si el campo modificado del registro previo a la actualización (OLD) esta en cero, si lo esta procedemos al paso 2 sino se deja como esta, esto es necesario para poder regresar el registro de uno a cero.
  2. Cambiamos el valor de modificado a 1 en el registro actualizado (NEW)
  3. Se actualiza el registro con los valores de NEW, esto lo hace automáticamente la base de datos, pero lo pongo para que sepa por que cambiamos el valor de modificado usando NEW

Ya que aplique el trigger, sea corriendo el comando o desde las propiedades de la tabla, abra la tabla donde aplicó el trigger y modifique un registro.

Tabla antes de modificar
Tabla antes de modificar
Tabla despues de modificar
Tabla despues de modificar

Notara que el valor de modificado cambio de 0 a 1, ahora mueva el valor de modificado de vuelta a 0.

Modificado en cero
Modificado en cero

Notara que aunque modificamos el registro el valor de modificado no paso a 1 automáticamente, esto se debe al if que pusimos en el trigger que solo permite cambiar el valor de modificado si este esta en cero.

No hay un limite a la cantidad de instrucciones que puede poner dentro de un trigger y tampoco se limitan a esa misma tabla, por lo que podría usar un trigger para modificar otra tabla al instante sin problemas, nada mas recuerde no excederse o podría volver muy lentas las operaciones donde se corra el trigger.


Espero que esta entrada fuera de utilidad y si lo fue y quiere cooperar con la causa tengo una pagina en Ko-fi para aceptar donativos

ko-fi

Ejecutando Pharo en GNOME 3

Acceso Pharo
Acceso Pharo

Uno de los cambios mas recientes al escritorio GNOME es el ya no poder ejecutar ejecutables, binarios o scripts, directamente desde el navegador de archivos Nautilus, esto como una medida de seguridad contra archivos ejecutables disfrazados y para evitar errores monstruosos, esto normalmente no seria un problema hasta que llega a aplicaciones que normalmente se ejecutan desde la carpeta que venia en el .zip, como lo es Pharo Smalltalk, por suerte hay una forma muy elegante y sencilla de corregir esta inconveniencia.

Archivo .desktop

En el escritorio GNOME los accesos a las aplicaciones son representados por archivos con extensión .desktop, estos le indican al escritorio y aplicaciones del escritorio GNOME la ubicación el ejecutable, icono a utilizar y categoría de la aplicación y lo mejor, estos archivos son muy sencillos de crear, es solo un archivo de texto en el siguiente formato

[Desktop Entry]
Encoding=UTF-8
Version=1.0
Type=Application
Terminal=false
Exec=/home/david/Workbench/Pharo/pharo
Name=Pharo
Icon=/home/david/Workbench/Pharo/Pharo.svg

Aquí las lineas que nos interesan son Exec, Name e Icon las cuales indican la ruta al ejecutable, el nombre de la aplicación y la ruta al icono que deseamos aparezca.

Archivo .desktop
Archivo .desktop

Obviamente las rutas de Exec e Icon deberá acomodarlas según donde halla puesto el ejecutable y el icono deseado, para el icono puedo sugerirle el siguiente

Icono Pharo
Icono Pharo

El cual puede encontrar en su forma de svg en la siguiente ubicación: https://files.pharo.org/media/logo/Pharo%20Logo%20SVG/Pharo_Icon_v3.0.svg

Y ya que quede todo el resultado se vera como en la siguiente imagen

Acceso a Pharo
Acceso a Pharo

Es posible que la primera vez que de doble clic al archivo le aparezca una pregunta de seguridad, solamente responda que si y a partir de ahí con solo dar doble clic a ese acceso..

Pharo Iniciado
Pharo Iniciado

Podra iniciar Pharo desde la interfaz gráfica sin problemas.


Referencias

Nautilus Will No Longer Launch Binaries Or Desktop Files


Espero que esta entrada fuera de utilidad y si lo fue y quiere cooperar con la causa tengo una pagina en Ko-fi para aceptar donativos

ko-fi

BigDecimal, no mas errores de redondeo

Suma de Doubles
Aquí veremos como evitar esto

Si ha usado Java para el desarrollo de aplicaciones donde los datos que maneje representen dinero seguramente se a encontrado con situaciones donde las operaciones con decimales le dan resultados incorrectos, específicamente en los decimales con el resultado quedando centésimas arriba o abajo del resultado correcto.

Esto se debe a la forma en que funciona la aritmética binaria a la hora de representar los decimales, si buen para la mayoría de los casos esos errores son demasiado pequeños las operaciones financieras usualmente implican la combinación ganadora de exigir precisión y operaciones sobre una cantidad significativa de datos de modo que esos pequeños errores de la aritmética binaria se acumulan y termina con una factura un centavo entero mas grande de lo esperado, y si cree que no le van a pelear ese centavo se equivoca, cuando es dinero hasta una décima de centavo basta para darse un encontrón con un cliente.

Por fortuna ya desde hace varias versiones Java incluye una clase que permite hacer esas operaciones sin preocuparnos por errores causados por la aritmética binaria, la clase BigDecimal.

BigDecimal.

La clase BigDecimal nos permite representar un numero decimal con las siguientes características

  • Operaciones decimales: Las operaciones sobre este tipo se realizan internamente en base 10, eso implica una perdida de rendimiento pero a cambio los errores de aritmética binaria se previenen por completo.
  • Precisión arbitraria: No se impone un limite en la cantidad de decimales, la cantidad de decimales a usar esta limitada únicamente por la memoria del sistema
  • Inmutable: Una vez creado un objeto BigDecimal el valor de este NO puede ser modificado, cada operación le generara un objeto nuevo con el valor resultado de la operación.

Si bien la perdida de rendimiento puede sonar preocupante esta esta en el area de mili/micro segundos, el usuario de su aplicación financiera no va a notar la diferencia e incluso si lo nota ese milisegundo es preferible a pelearse con un cliente por un centavo.

Operaciones con BigDecimal.

Las operaciones disponibles son las que espera, suma, resta, multiplicación, división, modulo, potencia, etcetera.

Sin embargo al momento de usarlas debe de tomar dos consideraciones, primero ya que en Java la sobrecarga de operadores no existe debera de usar los métodos .add, .multiply, .divide, .substract, .pow, etc

BigDecimal valor = new BigDecimal("10.0");
BigDecimal factor = new BigDecimal("5.5");

System.out.println("Suma: " + valor.add(factor));
System.out.println("Resta: " + valor.subtract(factor));
System.out.println("Multiplicación: " + valor.multiply(factor));
// MathContext indica cuandos bits deseamos usar para decimales, esto es debe especificar
// para manejar los casos donde la cantidad de decimales sea enorme (1/3 por ejemplo)
System.out.println("Division: " + valor.divide(factor, MathContext.DECIMAL128));
System.out.println("Potencia: " + valor.pow(3));

Hay que notar que las operaciones donde sea posible que ocurran numeros con decimales infinitos se debe especificar la cantidad de decimales a usar via la constante MathContext adecuada.

Otro detalle es que los objetos BigData son inmutables, por lo que las operaciones crean un objeto nuevo para el resultado por lo que debe asignar ese resultado a un objeto BigDecimal para poder usarlo

BigDecimal resultado = valor.add(factor);
System.out.println(“El resultado se guardo y accede desde la variable resultado: ” + resultado);

Ejemplo

Y para no dejar esta entrada sin ejemplo veamos como seria la sumatoria de la imagen en el inicio de la entrada usando BigDecimal en lugar de Double

package mx.hashCode.bigDecimal;

import java.math.BigDecimal;

public class App {    
    static public void main(String[] args){
        BigDecimal resultado = new BigDecimal("0.0");
        BigDecimal cent = new BigDecimal("0.01");

        resultado = resultado.add(cent);
        resultado = resultado.add(cent);
        resultado = resultado.add(cent);
        resultado = resultado.add(cent);
        resultado = resultado.add(cent);
        resultado = resultado.add(cent);

        System.out.println("Resultado de sumar 6 veces el valor 0.01 guardando en una variable BigDecimal");
        System.out.println(resultado);
    }
}

Y el resultado seria el siguiente:

Resultado de sumar 6 veces el valor 0.01 guardando en una variable BigDecimal
0.06

Referencias:

Por que usar BigDecimal (y no Double) para calculos aritmeticos financieros


Espero que esta entrada fuera de utilidad y si lo fue y quiere cooperar con la causa tengo una pagina en Ko-fi para aceptar donativos

ko-fi

Gracias y nos vemos en la próxima entrada :).