Presentaciones en LaTeX con Beamer, un ejemplo

Una presentación en Beamer

Como se menciono en la entrada anterior el paquete Beamer permite realizar
presentaciones de diapositivas en LaTeX, ahora pues se mostrara el uso básico
de dicho paquete.

Para comenzar se detallaran los paquetes que se deben incluir para generar la
diapositiva, en todo caso los paquetes a incluir se indican con la instrucción
\usepackage, estos son:

  • beamer: El paquete principal, contiene las funciones que generan las diapositivas.
  • utf8 o latin1: Para poder escribir directamente los acentos y ñ en sistemas Linux o Windows respectivamente.
  • babel: Con la opción spanish, con esto los texto generados por LaTeX (Figura, Bibliografía, etc) aparecerán en Español
  • hyperref: Habilita los enlaces en el documento, de modo que al dar click en un numero de referencia, lo lleve a dicha referencia.
  • multicol: Para presentar listas en múltiples columnas
  • graphicx: Para redimensionar tablas.

Generación de las Diapositivas

El uso de paquete Beamer es muy sencillo, primero que nada debe especificar
la clase de documento como beamer con ayuda del siguiente comando al inicio de
su documento.

\documentclass{beamer}

Con este el compilador de LaTeX ya sabrá que estamos creando una presentación
de diapositivas y aceptara los comandos específicos a esta clase de documento,
los cuales se describirán a continuación.

\titlepage

El comando \titlepage le permite generar la portada de su presentación, por
defecto es solo muestra su nombre, el titulo de la presentación y la fecha,
pero hay plantillas que pueden hacer la portada mas interesante.
Para especificar el titulo, autor y fecha debe usar los siguientes comandos:

\title{Titulo de la presentación}
\author{Nombre del autor}
\date{Fecha}

\begin{frame} y \end{frame}

Los comandos \begin{frame} y \end{frame} delimitan una diapositiva de
nuestra presentación, lo que coloque entre ambos comandos aparecerá en una
pagina.
Una consideración que debe tomar es que la diapositiva no escala
automáticamente el contenido, de modo que debe tener cuidado de no incluir
imágenes, listas o tablas que sean demasiado grandes para caber en la
diapositiva, no se preocupe hay comandos para encargarse de eso y veremos
algunos mas adelante.

Agregando texto e imágenes a una diapositiva

Esto es muy simple basta con poner el texto entre los comandos \begin{frame}
y \end{frame} este aparecerá en la diapositiva, se pueden aplicar todos los
comandos usuales para texto y generación de formulas.
Con respecto a las imágenes también se colocan como en un documento normal,
solo recuerde la limitación de tamaño, en el caso de que su imagen no quepa
puede usar el parámetro scale para ajustar a un tamaño menor.

Listas

De modo similar a las imágenes las listas se agregan como en un documento
normal y del mismo modo puede encontrarse con el problema de que no quepan
en su diapositiva, en este caso puede hacer uso de los comandos
\begin{multicols} y \end{multicols} para que su lista aparezca como
columnas y quepa mejor en la diapositiva, \begin{multicols} toma un
parámetro que indica el numero de columnas que desea utilizar, como se ve
a continuación.

\begin{multicols}{3}
	\begin{enumerate}
		\item Elemento 1
		\item Elemento 2
		\item Elemento 3
    \end{enumerate}
\end{multicols}

En este caso el 3 es para indicar que deseamos repartir esa lista en 3
columnas.

Tablas

Donde el primer parámetro controla el ancho al que desea redimensionar su
tabla y el segundo la altura que desea tenga la tabla, un ! indica que ese
parámetro se elija automáticamente para mantener la proporción de la tabla en
base al otro parámetro, solo uno de los parámetros puede usar !.

Referencias

Estas se agregan como de costumbre vía los comandos \label y \ref

Ejemplo

Para mostrar todo esto hagamos un ejemplo que combine todo, este muestra todo
lo que se presentó en esta entrada.

\documentclass{beamer}
\usepackage[utf8]{inputenc} % remplace utf8 con latin1
                            % si va a compilar en un sistema
                            % Windows
\usepackage{hyperref}
\usepackage[spanish]{babel}
\usepackage{multicol}
\usepackage{graphicx}

% Agregamos información del autor y titulo

\title{Ejemplo en Beamer}
\author{David Raygoza Gómez}
\date{5 de Diciembre del 2018}

\begin{document}

\begin{frame}
	\titlepage
\end{frame}

\begin{frame}
	Este es un ejemplo basico en beamer, el paquete para generar presentaciones en \LaTeX.
\end{frame}

\begin{frame}
	Las instruciones \emph{ \textbackslash begin\{frame\} } y \emph{\textbackslash  end\{frame\}} delimitan lo que aparecera en una diapositiva, podemos usar cualquier instrucción de \LaTeX sin problemas.
\end{frame}

\begin{frame}
	
	Como lo es poner figuras.
	
	\begin{figure}
		\includegraphics[scale=0.2]{imagenes/actividad.png}
		\caption{Actividad}
		\label{img_1}
	\end{figure}

	Cambiando su tamaño con [scale=escala]

	\begin{figure}
		\includegraphics[scale=0.1]{imagenes/actividad.png}
		\caption{La misma imagen a la mitad de la escala}
		\label{img_2}
	\end{figure}
	
	Teniendo cuidado de que sean del tamaño adecuado, o no cabra en la diapositiva.
	
\end{frame}

\begin{frame}
	Listas
	
	\begin{enumerate}
		\item Elemento 1
		\item Elemento 2
		\item Elemento 3
	\end{enumerate}

	\begin{itemize}
		\item Un elemento
		\item Otro elemento
		\item Algo mas
	\end{itemize}

	Como con las imagenes recuerde no pasarse de lo que quepa en la diapositiva,
	
\end{frame}

\begin{frame}
	Aunque podemos usar \emph{multicols} para automaticamente mostrar la lista en varias columnas y que asi quepan.

	\begin{multicols}{3}
		\begin{enumerate}
			\item Elemento 1
			\item Elemento 2
			\item Elemento 3
			\item Elemento 4
			\item Elemento 5
			\item Elemento 6
			\item Elemento 7
			\item Elemento 8
			\item Elemento 9
			\item Elemento 10
			\item Elemento 11
			\item Elemento 12
			\item Elemento 13
			\item Elemento 14
			\item Elemento 15
			\item Elemento 16
			\item Elemento 17
			\item Elemento 18
			\item Elemento 19
			\item Elemento 20
		\end{enumerate}
	\end{multicols}


\end{frame}

Y usar \emph{resizebox} para evitar que las tablas se salgan de la diapositiva.

\begin{table}
	\centering
	\resizebox{10cm}{!} {
	\begin{tabular}{|c|c|c|c|c|c|c|c|c|}
	\hline
	\multicolumn{5}{|c|}{Puerto fuente} & \multicolumn{4}{|c|}{Puerto destino} \\ \hline
	\multicolumn{9}{|c|}{Numero de secuencia} \\ \hline
	\multicolumn{9}{|c|}{Numero de reconocimiento} \\ \hline
	Longitud cabecera & Reservado & URG & ACK & PSH & RST & SYN & FIN & Tamaño ventana \\ \hline
	\multicolumn{5}{|c|}{Suma verificación} & \multicolumn{4}{|c|}{Puntero a datos urgentes} \\ \hline
	\multicolumn{9}{|c|}{Opciones} \\ \hline
	\multicolumn{9}{|c|}{Datos} \\ \hline
	\end{tabular}
	}
	\caption{Tabla Ejemplo.}
	\label{c2_tabla_segento_tcp}
	\end{table}

\begin{frame}
	\begin{center}
		Tambien puede centrar elementos con ayuda de \emph{center}
	\end{center}	
\end{frame}

\begin{frame}
	Y referencias figuras, como la Figura \ref{img_1} o a la tabla \ref{c2_tabla_segento_tcp} con ayuda de  \emph{\textbackslash ref}
\end{frame}

\end{document}

El código de este ejemplo puede encontrarlo en: https://gitlab.com/ticomWebcomic/beamerexample

Espero que esta entrada le sea de utilidad, nos vemos en la próxima y si desea cooperar con la causa


Anuncios

Consultar la dirección IP desde Java

Consultamos la IP desde Java
Consultamos la IP desde Java

Considere la siguiente situación, su aplicación en Java esta ejecutándose en una red local y por motivos de seguridad, control de acceso o simplemente para almacenarlo en la bitácora correspondiente necesita la dirección IP del equipo en que se esta ejecutando su programa, ¿Como obtenerlo durante tiempo de ejecución? Aquí esta como.

InetAddress

La clase InetAddress proporciona un método estático .getLocalHost() el cual le regresa la dirección IP v4 del equipo en que el programa se este ejecutando, el uso es tan simple como podría ser, solo llame InetAddress.getLocalHost() y obtendrá la dirección IP, solo recuerde capturar las excepciones que genera esa llamada.

Ejemplo

Como es lo usual veamos un ejemplo sencillo para explicar todo esto, lo se hará es mostrar la dirección IP en pantalla.

package mx.com.hash.checkip;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author David
 */
public class CheckIP {
    static private final Logger LOGGER = Logger.getLogger("mx.com.hash.checkip.CheckIP");

    String obtenerIP() throws UnknownHostException {
        InetAddress ip = InetAddress.getLocalHost();
        return ip.getHostAddress();
    }
    
    static public void main(String[] args) {
        try {
            CheckIP checkIP = new CheckIP();
            System.out.println("La IP de su compuradora es " + checkIP.obtenerIP());
        } catch (UnknownHostException ex) {
            LOGGER.log(Level.SEVERE, "Error al consultar el Host");
            LOGGER.log(Level.SEVERE, null, ex);
        }        
    }    
}

Una vez que ejecute este código le aparecerá en pantalla su dirección IP, la cual puede verificar con el comando ipconfig en Windows.

El código de este ejemplo lo puede encontrar en: https://github.com/HashRaygoza/CheckIP


Espero que esta entrada la fuera de utilidad y si lo fue y desea cooperar con la causa.

Ko-Fi


Publicidad furry

Cerveza Albul - Chico Temido
Cerveza Albul – Chico Temido

Saben, empiezo a pensar que eso de vender cosas con mascotas animales antropomórficas es de hecho una cosa generacional que va a crecer/envejecer con nosotros y adaptarse a los productos acorde a la edad 😛

Configurar la zona horaria de MySQL en Fedora Linux

Configuración MySQL
Configuración MySQL

Después de instalar un servidor MySQL nuevo en su sistema Fedora Linux es muy posible que sus programas le empiecen a mandar errores al conectarse al nuevo servidor, mencionando algo relacionado con la zona horaria, si eso le pasa aquí esta la solución.

Archivo de configuración

En Fedora el archivo de configuración de MySQL se encuentra en la ruta /etc/my.cnf editelo como root y agregue la siguiente linea

default-time-zone = "-06:00"

Aquí le esta indicando al servidor cual zona horaria desea usar, estas se deben poner en el formato de zonas horarias GMT indicando cuantas horas hay que sumar o restar de la hora de Greenwich [1].

Hecho esto reinicie el servidor MySQL con los siguientes comandos, todo esto como usuario root

systemctl stop mysqld.service
systemctl start mysqld.service

Y listo, con eso ya queda configurada la zona horaria de la base de datos.

Referencias

Consulte la zona horaria GMT – http://es.thetimenow.com/gmt/greenwich_mean_time


Espero que esta entrada le sea de utilidad y si desea cooperar con la causa.

ko-fi

Evitando que un error detenga un Timer

Error, pero el programa continua funcionando
Error, pero el programa continua funcionando

La razón mas común por la que usuaria un Timer en su aplicación Java es el tener funciones corriendo en segundo plano, usualmente para transmitir o recibir datos en forma periódica durante un periodo prolongado, usualmente todo el día y sin demasiada vigilancia por parte de un usuario y esto implica preparar su aplicación para que una excepción no trabe o cierra la aplicación, por que le garantizo eso siempre pasara en el peor momento posible.

¿Que detiene un Timer?

El Timer se detiene en el caso de que una excepción no manejada ocurra dentro del método run del TimerTask siendo ejecutado por el Timer, esto es una excepción que no tenga un catch para manejarla, esta excepción saltara mas arriba en su código y en el proceso detendrá el Timer.

¿Como nos afecta esto? bueno recuerde que aunque el compilador le exige capturar algunas excepciones hay varias que pueden aparecer sin avisar como CommunicationsException (la cual aparece si la conexion a una base de datos se pierde por causa de la red) o un error al convertir un JSON a objeto, o una excepción aritmética resultado de una división con mas decimales de lo esperado.

Por fortuna prevenir esto es muy sencillo.

Prevenir que una excepción detenga el Timer.

La mejor forma de prevenir el Timer de ser detenido por una excepción es capturar todas las excepciones posibles y aunque eso es posible capturando cualquier objeto de la clase o subclase Exception se recomienda aprovechar que cada excepción significa algo diferente y excepto algunas cosas como fallos de red o de conexión a base de datos seguro habrá varios casos que pueda corregir

Pero suficiente teoría pasemos a un ejemplo.

Ejemplo.

Usaremos de ejemplo un caso que seguramente le a pasado, que la conexión a una base de datos ser pierda por un momento, esto lo simularemos parando el servicio MySQL mientras el programa corre.

package mx.hashCode.TimerError;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

public class TimerSQL extends TimerTask {
    static private final Logger LOGGER = Logger.getLogger("mx.hashCode.TimerError.TimerSQL");

    public Connection crearConexion() throws SQLException, ClassNotFoundException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        String usuario = "archivista";
        String passwd = "123456789";

        Connection cx = DriverManager.getConnection ("jdbc:mysql://127.0.0.1:3306/"+ "?useSSL=false&" + "user="+ usuario + "&" + "password=" + passwd + "");

        return cx;
    }

    @Override
    public void run() {
        try {
            String sql = "SELECT * FROM pruebas.juegos;";            
            
            try(Connection cx = this.crearConexion(); Statement consulta = cx.createStatement()) {
                ResultSet data = consulta.executeQuery(sql);

                LOGGER.log(Level.INFO, "Presentaremos los datos");
                System.out.println("");
                while(data.next() == true) {
                    System.out.print(data.getString("nombre") + " ");
                    System.out.println(data.getString("consola"));
                }
                System.out.println("");
                data.close();
            }

        } catch (SQLException | ClassNotFoundException e) {
            LOGGER.log(Level.SEVERE, "OCURRIO UN ERROR DE ACCESO A DB!!!");
            LOGGER.log(Level.SEVERE, "Pero el ciclo deberia repetirse sin problema");
            //LOGGER.log(Level.SEVERE, null, e);
        }
    }

}
package mx.hashCode.TimerError;

import java.util.Timer;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Hello world!
 *
 */
public class App 
{
    private static final Logger LOGGER = Logger.getLogger("mx.hashCode.TimerError.App");

    public static void main( String[] args )
    {
        LOGGER.log(Level.INFO, "Inicializamos el timer");
        Timer timer = new Timer();
        TimerSQL timerSQL = new TimerSQL();

        timer.schedule(timerSQL, 0, 1000*10);
    }
}

Esta es la tabla que consulta el programa.

CREATE TABLE `juegos` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `consola` varchar(100) DEFAULT NULL,
  `nombre` varchar(100) DEFAULT NULL,
  `obtenido` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1

Obviamente deberá modificar los datos de conexión poner algún que otro dato en la tabla, hecho eso corra el programa con el servicio MySQL activo y vera la siguiente salida

Salida Correcta
Salida Correcta

Ahora desactive el servicio MySQL (esto variara dependiendo de su sistema operativo) y vera

Salida sin MySQL
Salida sin MySQL

Y sin embargo el programa no se a caído, como puede ver espera el tiempo que le indicamos, realiza la conexión y si algo sale mal (cosa que se indica con una excepción) el bloque catch correspondiente nos lo informa que ocurrió algo y previene que se detenga el ciclo.

No solo eso, sino que como es en el run donde se efectúa todo el proceso si inicia de nuevo el servicio MySQL

Tras reiniciar MySQL
Tras reiniciar MySQL

El programa vuelve a funcionar sin problema.

Obviamente para sacarle ventaja a todo esto debe diseñar su programa para que una excepción de ese tipo no vaya a causar errores de calculo o duplicidad de datos, la solución mas adecuada dependerá del caso especifico que este manejando.


Espero que esta entrada les fuera de utilidad y si fue así y desean cooperar con la causa.

ko-fi

Ejecutar periódicamente una función en Java

Función periodica
Función periódica

Una de las situaciones con las que seguro tendrá que lidiar al realizar una aplicación es ejecutar un método en forma periódica cada vez que pase un intervalo de tiempo especificado, ya sea para verificar el estado de un sensor, consultar o actualizar una base de datos, generar un reporte o enviar datos a un servidor, pero no se preocupe, hacer esto en Java es muy sencillo gracias a las clases Timer y TimerTask.

Timer

La clase Timer nos permite ejecutar una función en forma periódica a un intervalo especificado, su uso es bastante sencillo basta con crear un objeto Timer y usar el método scheduleAtFixedRate el cual toma tres argumentos que son los siguientes:

  • task, un objeto TimerTask cuyo método run se ejecutara al intervalo indicado
  • delay, la cantidad de milisegundos que queremos esperar antes de comenzar
  • period, cada cuanto en milisegundo queremos ejecutar el método run del objeto TimerTask

Esto en código se ve de la siguiente manera:

temporizador.scheduleAtFixedRate(tarea, 0, 1000*segundos);

Como notara no es nada del otro mundo, basta con pasarle los parámetros indicados y una vez pasado el retraso indicado por delay la función se llamara cada tantos milisegundos hasta que termine el programa o cancele la ejecución del objeto Timer llamando al método cancel.

TimerTask

Ya definimos cuando y cada cuanto queremos que una función se ejecute, ahora llego el momento de definir dicha función, para hacer esto debemos crear una subclase de TimerTask y redefinir el método run de modo que ejecute el código que nosotros queramos, como se ve en el siguiente ejemplo

package mx.com.hash.tareaprogramada;

import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author david
 */
public class Tarea extends TimerTask {
    static private final Logger LOGGER = Logger.getLogger("mx.com.hash.tareaprogramada.Tarea");
    private Integer contador;    

    public Tarea() {
        contador = 0;
    }

    @Override
    public void run() {
        LOGGER.log(Level.INFO, "Numero de ejecución {0}", contador);
        contador++;
    }

}

De nuevo dentro del método run puede poner el código que quiera, llamar a otras clases y demas, no sienta que debe limitarse a funciones de la subclase de TimerTask.

Otro detalle a recordar es que el Timer llama al método run del objeto que le pasamos, de modo que si almacena información en ese objeto esta estará disponible entre cada ejecución del Timer, esto quedara mas claro en el ejemplo.

Ejemplo

Para dejar mas en claro todo esto hagamos un pequeño ejemplo, llamando a una función cada 5 segundos que nos escriba en pantalla cuantas veces hemos llamado a la función, para esto usaremos el siguiente código.

package mx.com.hash.tareaprogramada;

import java.util.Timer;
import java.util.logging.Logger;

/**
 *
 * @author david
 */
public class TareaProgramada {
    static private final Logger LOGGER = Logger.getLogger("mx.com.hash.tareaprogramada.TareaProgramada");

    static public void main(String[] args){
        Tarea tarea = new Tarea();
        Timer temporizador = new Timer();
        Integer segundos = 5;

        temporizador.scheduleAtFixedRate(tarea, 0, 1000*segundos);
    }
}
package mx.com.hash.tareaprogramada;

import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author david
 */
public class Tarea extends TimerTask {
    static private final Logger LOGGER = Logger.getLogger("mx.com.hash.tareaprogramada.Tarea");
    private Integer contador;    

    public Tarea() {
        contador = 0;
    }

    @Override
    public void run() {
        LOGGER.log(Level.INFO, "Numero de ejecución {0}", contador);
        contador++;
    }

}

Y al ejecutarlo veremos la siguiente salida.

Ejemplo de función periodica
Ejemplo de función periódica

Como puede ver el objeto tarea no se destruye durante la ejecución del Timer, por lo que la información en el persiste e ejecución en ejecución.

¿Que pasa si la función tarda mucho en ejecutarse?

Un caso que puede presentarse es que la función tarde tanto en ejecutarse que llegue el momento de volverla a ejecutar y aun no halla acabado, cosa muy posible si depende de conexiones a base de datos, servidores externos o conexiones, ¿En ese caso que pasaría?

Bueno hagamos la prueba, modifiqué la clase Tarea para que quede así

package mx.com.hash.tareaprogramada;

import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author david
 */
public class Tarea extends TimerTask {
    static private final Logger LOGGER = Logger.getLogger("mx.com.hash.tareaprogramada.Tarea");
    private Integer contador;    

    public Tarea() {
        contador = 0;
    }

    @Override
    public void run() {
        LOGGER.log(Level.INFO, "Numero de ejecución {0}", contador);
        contador++;

        try {
            // Con esto hacemos que la funcion tarde *mas* en ejecutarse que
            // el periodo especificado
            Thread.sleep(10000);
        } catch (InterruptedException ex) {
            LOGGER.log(Level.SEVERE, "Error de interrupcion");
        }
    }

}<span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"></span>

Lo que hacemos aquí es agregar un retraso  a la función run de modo que tarde 10 segundos en ejecutarse pero no modificamos lo demas, de modo que el temporizador ejecutara cada 5 segundos una función que tarda 10 segundos en ejecutarse, el resultado se ve a continuación.

Una función que tarda mas en ejecutarse
Una función que tarda mas en ejecutarse

Como ve el retraso entre llamadas es el indicado por la función, el Timer no llamara al método run sino hasta que este halla acabado por lo que no debe preocuparse de que queden cosas incompletas, lo que si puede pasar es que si ya paso el periodo entre llamadas el método run se llame inmediatamente después de terminar la llamada que tardo demas.

El código de este ejemplo lo puede encontrar aquí: https://gitlab.com/ticomWebcomic/tareaprogramada


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

Habilidad Geriatrica

Habilidad Geriatrica
Habilidad Geriatrica

La sabiduría de los ancianos

Transcript

Mike: ¡ESA COSA ES DEL DIABLO!

Mike: ¡¡¡COMO EL POKE MONGO Y EL IMSS TANGRAM!!

Narrador: Los mayores no sabran de técnologia, pero son expertos en detectar que es del Diablo.


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

ko-fi