Archivo

Archivo para la categoría ‘IT’

Convirtiendo archivos para grabar en dvd

Jueves, 25 de agosto de 2011 Sin comentarios

Muchas herramientas para grabar dvds (para reproducir en cualquier dvd doméstico) no tienen la capacidad de convertir al formato apropiado, por lo que hay que acudir a algo más. Esta apunte es tan solo un ayuda memoria de como convertir archivos de video a mpeg para grabar en un dvd.

Para convertir avis a mpeg, utilizo el ffmpeg y la sintaxis es la siguiente (cabe aclarar que esta herramienta puede hacer gran cantidad de cosas y tiene muchísimas opciones)

ffmpeg -i origen.avi -target pal-dvd -ps 2000000000 -aspect 16:9 destino.mpeg

El mpeg resultante puede ser grabado con cualquier software para crear dvds, tal como el Bombono

Categories: IT Tags: , , , ,

Informatizando el estado

Domingo, 10 de julio de 2011 Sin comentarios

Con gran beneplácito leo ésta noticia en Observa sobre la informatización de algunos trámites del estado pero fundamentalmente sobre el intercambio de información entre las distintas dependencias. Esto último es algo que realmente me ponía los pelos de punta cada vez que tenía que hacer un trámite y me pedían que demostrara que había nacido con algo más que mi presencia y mi cédula de identidad, lease partida de nacimiento. Es más que claro que si estoy ahí parado frente al funcionario con mi cédula en mano, nací, en algún momento, quizás hace mucho, pero nací. El estado no es lo suficientemente eficiente como para terminar con este absurdo requisito, pero al menos hay ahora un proyecto de ley que pretende que este tipo de información sea responsabilidad del estado y las distintas oficinas se comuniquen la información necesaria.

Desde un punto de vista estrictamente informático, la tecnología para hacer esto existe y está disponible en el país desde hace mucho tiempo y si bien la implementación no es algo sencillo y se enfrentará a muchos más problemas burrocráticos que técnicos, el estado tiene todo para hacerlo y para hacerlo bien, la tecnología, personal calificado y el dinero necesario. Sería muy bueno ver un estado que se moderniza y que trata de estar a la vanguardia de la burrocracia (por más paradójico que esto suene).

En cuanto a las dificultades legislativas, que supongo que habrá muchas, no hay más que cambiar las leyes necesarias y que a los legisladores no les tiemble el pulso de terminar con chacritas que los distintos trámites aseguran a varios sectores gremiales, el que no sea necesario haciendo lo que hace que se vaya a otro lado a hacer otra cosa y permita pasar el tren del progreso.

Creo que es una muy buena iniciativa, a la que habrá que estar atentos y colaborar en la medida de lo posible por el bien de todos. Estaremos atentos al sitio de Agesic y al proyecto.

El efecto Murro

Jueves, 31 de marzo de 2011 Sin comentarios

En la actualidad Internet ha copado casi todos los aspectos de la vida de las personas, cada vez son menos los que están ajenos a lo que pasa y cada vez tiene más incidencia en los aconteceres políticos, religiosos y culturales de todo el mundo. Al ser un medio que expone tanta información, es moneda corriente que se publiquen noticias inexactas, expresiones agraviantes o simplemente contenido que pueda molestar o disgustar a alguien, es inevitale. Pero ¿qué podemos hacer al respecto si nos vemos en esta situación?

Hay por supuesto un tema legal en el que no voy a entrar, ya que no es de mi interés en esta oportunidad, sino que me voy a remitir a cuando simplemente lo publicado molesta. El ejemplo práctico que voy a compartir a continuación refiere a las Elecciones de los directores sociales del BPS, para las cuales, como imagino que todos saben, se impulsaron las candidaturas de Homero Simpson y de Charlie Harper. Esas candidaturas molestaron a Murro (presidente del BPS) por diversas razones e hizo lo que nunca ddebería haber hecho, despotricó duramente contra estas iniciativas, logrando exactamente el efecto contrario al que quería, convirtiéndose inmediatamente en el principal difusor de las mismas y dándole una enorme relevancia al hecho y haciendo que captara la atención de diversos medios de prensa.

La iniciativa surgió en el Blog de Pablo Brenner y Sergio Fogel, y las declaraciones de Murro salieron en el diario El Pueblo de Salto.  Las repercusiones no se hicieron esperar y Montevideo Portal y Observa publicaron artículos al respecto.

No se como habrá impactado esta difusión de la iniciativa en el blog de Pablo y Sergio pero no dudo de que haya tenido un enorme impacto. Este humilde blog que no lee nadie (quién va a estar interesado en leer eso) tuvo un enorme crecimiento de visitas

El efecto Murro impactó las estadísticas del blog

Las visitas crecieron enormemente y pasaron de unas pocas decenas a mas de medio millar en los dias previos a la elección y hasta el domingo de la elección. Luego cayeron estrepitosamente al lugar desde nunca deberían haber salido.

Ya sabeis, si hay algo publicado por ahí que no te gusta, lo mejor que podés hacer es mutis por el foro y que la publicación muera con el tiempo, pero si lo comentás, lo difundís, twitteas o compartis en facebook, el efecto Murro atacará con toda sus fuerzas.

Actualización 26-04-2011: Esto se conoce como Efecto Streisand

Implementando Observers en Java

Jueves, 10 de febrero de 2011 Sin comentarios

Una aclaración antes de empezar: en Java existe un mecanismo para implementar Observers que requiere que la clase observada extienda Observable. Esto, en algunas situaciones puede ser una limitante ya que no es posible extender mas de una clase. Si por ejemplo, queremos observar una clase que ya extiende a otra, no seria posible incorporar este mecanismo con las herramientas built in de Java sin hacer cambios importantes. En esta situación, la mecanica que se explica a continuación puede ser de utilidad.

En muy pocas palabras, los patrones de diseño son soluciones conocidas para problemas conocidos, un esfuerzo por no reinventar la rueda cada vez que nos enfrentamos a un problema cotidiano en el mundo de la programación. Este patrón se utiliza cuando queremos que alguna entidad, se entere de que algo pasó en alguna otra parte de nuestro sistema. Por ejemplo, supongamos que tenemos una ventana con un cierto listado de datos, como la siguiente:

Carga de contenedores - Observa la actualización

Los datos que la tabla muestra pueden cambiar en función de acciones que se realizan en algún otro formulario de la aplicación que permita el ingreso o edición y el objetivo es que ésta tabla se actualice cuando esos datos cambian sin necesidad de que el usuario que hace uso de ella tenga que explícitamente recargar o refrescar los datos.

Este es un caso típico en que el patrón Observer nos será de gran utilidad y será la tabla de datos quien deberá observar los eventos que ocurran en el formulario de edición.

Además de los formularios para editar y mostrar los datos, la solución constará de dos clases adicionales, una interfase IObserver y una clase que hace de nexo entre las distintas partes que componen la solución y que llamaremos ObserverServer. La interfase IObserver deberá ser implementada por aquellas entidades que están observando a otras y contendrá los métodos necesarios para comunicar los cambios:

public interface IObserver {

public void notifyEvent( String eventName, HashMap parameters );

}

La clase interesada en la actualización de datos deberá implementar el método notifyEvent y deberá suscribirse ante el ObserverServer como observador del evento de actualización de datos. Veamos el ObserverServer para aclarar esta situación:

public class ObserverServer {

 private ObserverServer instance = null;
 private HashMap events;

 private ObserverServer getInstance() {
 if( instance == null ) instance = new ObserverServer();
 return instance;
 }

 private ObserverServer() {
 events = new HashMap();
 }

 public void registerTo( String eventName, IObserver caller ) {
 LinkedList callers = (LinkedList) events.get(eventName);
 if( callers == null ) {
 callers = new LinkedList();
 callers.add(caller);
 events.put(eventName, caller);
 } else {
 callers.add(caller);
 }
 }

 public void fireEvent( String eventName, HashMap parameters ) {
 LinkedList callers = (LinkedList)events.get(eventName);
 if( ! (callers==null) ) {
 Iterator it = callers.iterator();
 IObserver caller;
 while( it.hasNext() ) {
 caller = (IObserver)it.next();
 caller.notifyEvent(eventName, parameters);
 }
 }
 }

Dos precisiones sobre esta clase:

1) La calse es un singleton. Esto es necesario ya que todas las entidades que se comunican a través de ella deben acceder a la misma lista de eventos

2) La lista de eventos se modela como un HashMap (events) que contiene para cada evento una LinkedList con las entidades que esperan ser notificadas cuando el evento ocurra. Esto podría alterarse en función de necesidades específicas.

La clase ObserverServer cuenta con dos métodos, uno para suscribirse como observador de un evento, registerTo y otro para iniciar las notificaciones ante la ocurrencia de un evento, fireEvent.

El método registerTo recibe como parámetros el nombre del evento y una referencia a la clase que debe ser notificada y que implementa la interfase IObserver. El método simplemente agrega la referencia al observador en la lista correspondiente y en caso de que se la primera vez que una entidad se suscribe a dicho evento, creará una nueva lista. Nótese que no hay ningún tipo de control sobre los eventos a los que una entidad se registra. Esto podría cambiar según las necesidades especificas de lo que se está implementando, pero para mostrar el funcionamiento básico del patrón no es necesario agregar tal complejidad al ejemplo.

El método fireEvent recibe como parámetros el evento que ocurrió y una HashMap de parámetros relativos a dicho evento. En este caso, se recorrerá la lista de entidades suscritas al evento y para cada una de ellas se invocará el método notifyEvent. Nuevamente, aqui no hay ningún control que verifique que el evento sea válido. Quien dispara el evento y quien está suscrito a él deberán acordar los parámetros que se envían en el HashMap. El ObserverServer solo actúa como vehículo para la comunicación y no impone ningún tipo de restricción a los parámetros.

Veamos escuetamente como se usa todo esto para algo útil

Nuestro formulario de despliegue de datos quiere ser notificado cuando los datos cambian para mostrar la nueva realidad, por lo que va a suscribirse a un evento de notificación en su constructor


public class ContainerList implements IObserver {

private ObserverServer obs;

public ContainerList() {

obs = ObserverServer.getInstance();

obs.registerTo("ContainerUpdate",this);

}

...

public void notifyEvent( String eventName, HashMap parameters ) {

if( eventName.equals("ContainerUpdate") ) {

...

}

}

}

El formulario que muestra los datos se suscribe al evento ContainerUpdate y pasa una referencia a sí mismo. Cuando el evento ocurra, el ObserverServer invocará el evento notifyEvent el cual implementa la actualización de datos necesaria.

La otra parte de esto, el formulario de edición de datos deberá avisar cada vez que una modificación ocurrra


public class FrmContainerUpdate() {

public ObserverServer obs = ObserverServer.getInstance();

...

private SaveData() {

// Proceso los datos del formulario como normalmente lo haría

// y notifico del evento

HashMap params = new HashMap();

params.put("containerId",id); //Agrego todos los parametros necesarios al HashMap

obs.fireEvent("ContainerUpdate", params);

}

De esta manera, cada vez que ocurre una actualización de los datos de un contenedor, la tabla de datos es actualizada.

Este patrón es útil en una gran cantidad de situaciones que las que se quiere comunicar a varias entidades, sin embargo, no debe ser confundido con un mecanismo para la comunicación entre procesos en el que existe un flujo de información más o menos continuo, para eso existen otras herramientas.

Reseteando la contraseña en postgres

Miércoles, 11 de agosto de 2010 2 comentarios

Esto más que una entrada es un ayuda memoria para mí. Cada vez que me olvido o por algún otro motivo tengo que resetear la contraseña del usuario postgres tengo que salir en búsqueda de las notas de como hacerlo y por las leyes de murhpy éstas nunca aparecen.

Las ubicaciones de los archivos a continuación son válidas para Posgres 8.4 en Ubuntu 10.4 con la instalación por defecto.

Paso 1 – Habilitar el login del usuario postgres sin contraseña.

Para esto agregamos al archivo /etc/postgresql/8.4/main/pg_hba.conf la siguiente línea (en realidad modificamos una linea muy similar que hay en el archivo):

local all postgres trust

Paso 2 – Reiniciar el servidor postgres

/etc/init.d/postgresql-8.4 restart

Paso 3 – Nos autenticamos con el usuario postgres (sin password) y lo modificamos

#psql -U postgres template1

> alter user postgres with password ‘password’;

Paso 4 – Volver a la configuración original

Volvemos el archiv pg_hba.conf a su estado original y una vez más reiniciamos el servidor

Categories: IT Tags: , ,

PostgreSQL, Java y fechas

Sábado, 17 de julio de 2010 3 comentarios

Trabajando para un proyecto tuve que cambiar de mi querida MySQL a PosgreSQL y me encontré como era de esperar con unos cuantos problemas. Entre ellos, el que más dolores de cabeza me dio y sobre el que más variantes tuve que probar hasta encontrar con la más adecuada para las necesidades del momento fue el del almacenamiento y recuperación de fechas.

Evalué varias alternativas y vi mucha cosa al respecto y me quedé con la solución que a continuación presento, y que describo para salvar mis problemas de memoria y quizás para ayudar un poco a algún eventual lector que ande tras una solución para ese mismo problema.

La tabla

Las fechas son guardadas en campos de tipo timestamp without time zone. En el siguiente ejemplo solo se muestran dos columnas de la tabla y omití todo lo que no viene al caso.

CREATE TABLE trabajo ( nombre character varying(50) fecha timestamp without time zone );

La aplicación

La aplicación almacena las fechas en variables de tipo GregorianCalendar que es un objeto de Java muy flexible para el manejo de fechas.

class Trabajo {

private String nombre;
private GregorianCalendar fecha;

}

Además de los getters y setters habituales, escribí un par de métodos que permiten setear las fechas a partir de un String y recuperarlas como un String, lo cual es muy práctico al momento de mostrarlas o de setear fechas a partir del valor obtenido de un date picker.

public String getFechaAsString() {
SimpleDateFormat sdf = new SimpleDateFormat(“dd-MM-yyyy HH:mm”);
return( sdf.format( (this.fecha).getTime() ) );
}

El formato de fecha elegido está hardcoded pero en este caso no es una limitación. La clase SimpleDateFormat es muy flexible a la hora de parsear fechas con lo que el código anterior puede ser fácilmente modificable para soportar cualquier formato. En caso de quererse formatos más flexibles que se correspondan con las preferencias del usuario en el sistema operativo, tendrás que echar mano a la clase TimeZone. En el ejemplo no se manejan posibles errores al parsear la fecha (asumo que this.fecha siempre tiene un valor válido, el setter debería encargarse de eso).

public void setFechaAsString( String fecha ) {
if( fecha.length() != 0 ) {
SimpleDateFormat sdf = new SimpleDateFormat(“dd-MM-yyyy HH:mm”);
try {
java.util.Date d = sdf.parse( fecha );
(this.fecha) = new GregorianCalendar();
(this.fecha).setTime( d );
} catch ( ParseException e ) {
e.printStackTrace();
}
}

Las fechas son seteadas a partir de un String, el cual es parseado y en caso de no verificar exactamente el formato necesario, tira una excepción (en el ejemplo imprimo el stack trace, aunque en la realidad la excepción se maneja de manera un poquito más feliz).

La clase SimpleDateformat devuelve un objeto de tipo java.util.Date (no confundir con java.sql.Date) a partir del cual podemos establecer la fecha en nuestro GregorianCalendar.

Guardando fechas

Guardar las fechas es muy simple si echamos mano a nuestra clase getFechaAsString().

sql = “INSERT INTO trabajo (nombre,fecha) values(‘”+ this.nombre+”‘,’”+this.getFechaAsString()+”‘)”;

(Ojo con las comillas) y ese sql lo mandamos a la base de datos.

Recuperando fechas

Recuperar las fechas tiene tambien su truqito, veamos..

sql = “SELECT * FROM trabajo”;

ResultSet rs = st.executeQuery( sql ); donde st es un Statement valido conectado a la base de datos

Iteramos sobre el resultado


java.sql.Date d = rs.getDate(“fecha”);
if( d1 != null ) {
GregorianCalendar gc1 = new GregorianCalendar();
gc1.setTimeInMillis( d1.getTime() );
this.fecha = gc1;

Observar que getDate devuelve un objeto de java.sql.Date, pero igualmente podemos crear un GregorianCalendar a partir de él pasando la fecha a un timestamp.

Conclusiones

No es el más flexible de los métodos para almacenar y mostrar fechas, pero es lo suficientemente flexible si manejamos las fechas en un formato que no dependa de la configuración regional del usuario. Sin embargo, podemos mostrar las fechas en cualquier formato utilizando SimpleDateFormat para formatearlas de la manera que mas nos convenga.

Categories: General, IT Tags: , ,

Trending topics en Twitter

Viernes, 11 de junio de 2010 Sin comentarios

Siguiendo con el tema twitter, según las mediciones del sitio trendistic.com #URU era el trending topic número uno al momento de terminar el partido Uruguay – Francia. Es interesante como los trends fueron evolucionando con los partidos del mundial.

Los trending topics nos dicen quien entró a LA cancha quien está jugando, quien fue expulsado. Por supuesto que se cuelan algunas otras cosas más, claramente relacionadas con el mundial. Teniendo en cuenta que estas tendencias son globales, es llamativo como el mundial está por sobre todo a nivel mundial (no pun intended) y todos hablan de lo que está pasando en el momento. Tal vez si se tratara de países con más habitantes o quizás con mayor penetración de twitter (no nos engañemos en Uruguay somos relativamente pocos los que lo usamos) no me llamaría tanto la atención que fuesemos tendencia.

Categories: IT Tags: , ,

Twitter is over capacity

Viernes, 11 de junio de 2010 1 comentario

Estoy seguro que aquellos que usan Twitter vieron el mensaje de over capacity muchas veces. Haciendo la búsqueda over capacity en twitter se puede ver que una gran cantidad de usuarios están obteniendo este mensaje todo el tiempo.

En palabras simples, este error se produce cuando en un período de tiempo muy corto twitter recibe muchas peticiones juntas y no es capaz de atenderlas todas. No se refiere especificamente a un uso intenso durante largo tiempo, sino que los grandes picos de tráfico en períodos cortos pueden producir este tipo de errores.

Lo que más me llama la atención de esto es como Twitter ha logrado “zafar” de un fenómeno muy común en los sitios web. En general cuando un sitio o servicio deja de andar, los usuarios dejan de utilizar ese servicio y buscan uno alternativo. Es muy común que Twitter de problemas de capacidad, o que los tweets viejos no estén disponibles o las búsquedas no funcionen y sin embargo, la masa de usuarios crece sin para así como la cantidad de tweets.

Tan solo una relexión que me gustaría verdaderamente enteder más allá de las conjeturas y especulaciones que pueda hacer al respecto.

Categories: IT Tags: ,

Una maquina de Turing

Domingo, 18 de abril de 2010 Sin comentarios

Esta entrada va a ser disfrutable para los geeks que andan en la vuelta, para algunos interesados en la informática y/o tecnología y probablemente un poco aburrida para los demás, pero realmente vale la pena tomarse unos minutos.

Si sabes que es una máquina de Turing podés saltear éste párrafo. Una máquina de Turing es un dispositivo (máquina) teórico descrito por Alan Turing allá por 1937 al que llamó “automatic machine”. La misma es capaz de computar cualquier operación que una computadora puede hacer utilizando para ello un conjunto de 6 operaciones básicas: leer un caracter, escribir un caracter, moverse a la derecha, a la izquierda, cambiar de estado y detenerse. La máquina consta de una cinta infinita de donde lee y donde escribe y que oficia de entrada y salida de datos. Estas máquinas son de una gran importancia teórica y son estudiadas en todos las buenas carreras informáticas. Muchas veces son menospreciadas pero la realidad es que son una de esas maravillas con las que pocos genios contribuyen en el desarrollo del conocimiento.

Terminada la chachara inicial, le presento una máquina de Turing construida con tecnología del siglo XXI. Un excelente trabajo construido por un autodenominado inventor cuyo nombre no pude encontrar en el sitio web. Un fantástico trabajo que no deja de ser un poco bizarro por el hecho de recrear algo tan primitivo con tecnología compleja.. les dejo el video

Computar operaciones sencillas como sumas, restas o contar, pueden llevar una gran cantidad de operaciones con una máquina de este tipo y un enorme tiempo de cómputo, sin embargo sigo creyendo que son muy interesantes, útiles y entretenidas. ¿habrá llegado el momento de picar un poco de código?

La web del ideólogo de esta maravilla es http://www.aturingmachine.com/ hay ejemplos de programas y un poco de teoría.

Enlaces de interés:

http://en.wikipedia.org/wiki/Turing_machine

Alan Turing

Buzz, Google y la real-time web

Jueves, 11 de febrero de 2010 3 comentarios

Google Buzz

Google lanzó Buzz y ya comenzó el ruido en la blogocosa al respecto. Aún no todos los usuarios de GMail lo tienen disponible pero aún así las reacciones se están haciendo escuchar.

La primera impresión que me dio fue la de una aversión natural a lo desconocido y a no tener control absoluto de lo que se comparte. Sin que nadie diga nada y una vez que Buzz es activado, los contactos de GMail con los que se ha tenido interacción pasan a ser seguidos y seguidores. Me encontré con una larga lista de contactos que sigo y sobre los cuales no tengo el más mínimo interés (puedo haber tenido intercambios de emails por muy diversas razones pero no por ello estoy interesado en seguirlos). Por otro lado, Buzz comparte tus lecturas de Reader,  albumes de Picasa y el estatus del chat automáticamente. No son todas cosas que me interesa compartir sistemáticamente, es decir, no se tiene el fino control de lo que se comparte como el que se puede tener con Twitter o el estado de Facebook en donde uno explícitamente comparte lo que puede resultar interesante. Esa forma tan automatizada de compartir todo va a hacer que los Buzz de los usuarios no sean tan interesantes como los twitts y por lo tanto la red de seguidores y seguidos no va a crecer de la misma manera que la de twitter, por ejemplo.  Puede llegar incluso a ser más grande, por la forma en que se extiende, pero no va a ser igual. Buzz y Twitter no van  a ser directamente competidores y difícilmente deje Twitter por Buzz. Como dice Enrique Dans en su entrada El buzz sobre Google Buzz: la prueba de uso, Buzz se convertirá en una capa adicional de búsqueda a partir de la cual Google se quiere quedar con una parte de la real-time web.

Tal como comenta Marcos Crispino en su entrada Google Buzz y el futuro de las redes sociales, Buzz será un servicio más que debemos revisar, se suma a Twitter, Facebnook, el Feed reader que usemos, los correos y toda una serie de servicios que utilizamos para estar en contacto. Me parece muy buena la idea que propone de un servicio que permita concentrar todos estos sitios en un solo lado, pero lo veo difícil ya que cada uno de estos servicios hace las cosas a su manera, tiene su propia API y quiere que los usuarios entren a su web. Solo el tiempo dirá…

Google es una de esas empresas que logra imponer sus productos y hacer que todos se muevan en una determinada dirección y creo que la web se está dividiendo en dos la real-time web y la static-web (si es que se me permite el abuso del término, aquella compuesta por todo lo que no es real-time y que no es para nada static). La carrera recién está empezando y los servicios no han tomado aún su forma final, la cual indudablemente se verá influenciada por la repercusión que estos productos tengan en los usuarios. Por ahora, tanto real-time no me seduce y mi buzz se va a quedar desactivado.

¿Es real-time web lo que realmente queremos? Si bien creo que está muy bueno tener información actualizada sobre todo, ¿qué esperamos encontrar en un buscador si nuestros términos de búsqueda son el nombre de un famoso jugador de fútbol o de un celebre actor? La real-time web nos dice que metió un gol, que el chusmerío dice que está por firmar un contrato millonario, que es un divino, que apesta o que es el uno. Pero puede no ser esto lo que nos interesa y por ende, la static-web va a seguir teniendo un rol fundamental y no se verá sustituida por el nuevo chiche de la tecnología de búsquedas.