Noticias Weblogs Código

Blog Bitix

10 razones para seguir usando Java

May 22, 2015 03:00 PM

Con ya dos décadas de vida y a lo largo de este tiempo Java se ha convertido en uno de los lenguajes más empleados para programar a día de hoy. En este periodo han surgido otros lenguajes en la propia plataforma de la JVM como Groovy, Scala o Clojure y fuera de ella como C#, Python, Ruby, PHP, Go o Dart ofreciendo algunas cosas adicionales o supliendo algunas carencias de Java. Aún con toda esta competencia esta es mi lista de 10 razones por las que creo que Java sigue siendo relevante.

Java

El sábado 23 de mayo de 2015 el lenguaje Java cumple 20 años de historia y aún hoy Java sigue siendo uno de los lenguajes de programación preferidos para desarrollar en un mundo tecnológico en el que unos pocos años pueden darse grandes cambios y en dos décadas ver surgir nuevas tecnologías y verlas languidecer. Algunas personas se jactan y hablan con un tono de desprecio y mofa nada agradable hacia Java mostrando su desconocimiento o prejuicios siguiendo algunos tópicos bastante difundidos la mayoría incorrectos. A otras personas quizá no les gusta Java no tanto por el lenguaje como por los proyectos que ha desarrollado en él, en consultoras cárnicas, para clientes con condiciones laborales paupérrimas, con tecnologías, librerías y frameworks obsoletos o códigos heredados programados por programadores aparentemente con poca experiencia que es un infierno mantener debido a una cantidad importante de errores, uso de tecnologías no adaptadas a la solución, malos funcionamientos y falta de documentación. Pero estas situaciones externas no tiene nada que ver con el lenguaje. Algunas otras personas quizá no les gusta porque no les ofrece el último azúcar sintáctico que han visto y usado en otros lenguajes o porque para propósitos específicos hay alternativas que permiten obtener una solución de una forma más sencilla.

Java 20 años (1995-2015)

En JavaWorld ha publicado varios artículos para celebrar el aniversario comentando su futuro, su pasado y presente o que notables características reunió en su momento para ser hoy uno de los lenguajes más usados.

Algún otros artículos interesantes son:

Aunque algunos parecen considerar ya hoy a Java el nuevo COBOL (y este último aún tiene futuro) y no sea lo habitual, en este artículo trataré de exponer algunos argumentos que posee Java para su defensa y por los que en mi caso aún no he tenido necesidad de buscar mayor felicidad programando en otra opción.

Java no es lento

Quizá en las primeras versiones de los 90 fuera así pero la realidad hoy con las mejoras introducidas en cada versión a la Java Virtual Machine (JVM) un programa Java es comparativamente igual de rápido que uno en C o C++, salvo para tareas muy específicas de cálculos intensivos no hay diferencia. Eligiendo las estructuras de datos adecuadas no tendría por qué haber una diferencia de rendimiento considerable y además para la mayoría de las tareas más importante que la rapidez es la legibilidad del código, su fácil desarrollo, mantenimiento o coste.

Javadoc

Java tiene una gran herramienta de documentación que permite embeber la misma en el código fuente de los archivos y generar una serie de documentos html para su posterior consulta. La documentación proporcionada en la API es extensa, completa y buena, siendo simple html puede ser alojada en cualquier servidor web y consultada en internet. Sin documentación la tarea de los programadores sería considerablemente más complicada, aún en el caso de falta de documentación javadoc el IDE con la asistencia de código puede ayudarnos gracias a la introspección incorporada en la plataforma.

Compilado, tipado estático

Las metodologías ágiles están siendo ampliamente adoptadas y algunos de sus defensores apuestan por lenguajes que consideran encajan con su metodología agilista confundiéndola con lenguajes dinámicos y menos verbosos, que puede ser acertado en ocasiones o circunstancias pero con Java también se puede ser ágil como el que más. Una de las buenas prácticas de las metodologías ágiles es tener teses unitarios del código al ser posible que lo cubra al 100%, sin embargo, la realidad es que nos será complicado tener el 100% del código cubierto con teses.

Con los lenguajes dinámicos hay que tener especial cuidado ya que por su propia naturaleza hace que algunos errores solo los encontraremos en la ejecución, por experiencia propia no será la primera vez (ni la centésima) que un error tan básico como de compilación por nombre de variable o método mal escrito es descubierto en producción. El IDE es la herramienta que en Java junto con el tipado estático y la ayuda al compilador permite detectar errores de compilación instantáneamente, por otra parte proporciona asistencia de código y a los programadores nos sirve como documentación de los tipos esperados en los argumentos de los métodos o propiedades de las clases. Los compiladores además de para traducir el código fuente a lenguaje máquina (o bytecode) están para capturar errores sintácticos y léxicos ante los cambios de una nueva característica, una refactorización o un merge con conflictos. Se puede pensar en el compilador como un test automatizado que cubre el 100% del código, con un IDE se obtienen los errores al instante después de escribir cada caracter ¿que hay mejor? ¡no lo desprecies!.

Escribir código menos verboso no hace que escribirlo sea más rápido ni necesariamente más legible, Java posee buenos IDEs con asistentes de código que con unas pocas pulsaciones permiten escribir el código igual o más rápido. Java es un lenguaje verboso y explícito en parte propiciado por su poco azúcar sintáctico pero las construcciones sintácticas pueden ser contraproducentes, un alto número de ellas y el código será muy críptico sin un conocimiento amplio del lenguaje. Uno de los éxitos de Java es su relativa simplicidad.

IDE

Con un IDE el código Java se ve de distinta forma, no como simple texto sino donde los métodos, clases y propiedades tienen entidad propia. La asistencia de código permite obtener métodos disponibles, ver los tipos y nombres de argumentos y retornos, las excepciones lanzadas, si el método es estático o de instancia y la visibilidad de acceso según escribimos. Con la ayuda de un IDE podemos encontrar todos los usos de un método o clase de forma totalmente exacta o cambiar un nombre por otro. Hay IDEs para lenguajes dinámicos como Groovy con IntelliJ IDEA o Python con PyCharm que proporcionan asistencia de código pero usando las características dinámicas de estos lenguajes el encontrar todos los usos de un método o variable no está garantizado.

Un IDE puede suponer la diferencia entre dedicar un tiempo considerable a tareas de bajo valor a ser mucho más productivo, o mejor aún, ayudando a evitar errores.

Refactorizaciones

Con la ayuda del compilador y de un IDE las refactorizaciones como renombrar una variable, propiedad, método o clase son más sencillas y con más garantías de no romper nada, además de poder realizarlo en unos pocos segundos y sin tener que buscar y sustituir las referencias como texto plano en todo el código del proyecto. En proyectos grandes en los que trabajan más de una persona y tienen un tiempo de vida y de mantenimiento de más de unos pocos meses hace que evitemos muchos problemas y programemos con más seguridad de que las modificaciones que hacemos no introducen errores por cosas tan básicas como la compilación.

Si el uso de un proyecto es prolongado en el tiempo este posiblemente tenga que adaptarse a necesidades inicialmente totalmente desconocidas, en estos casos será tarde o temprano necesario refactorizar. En un negocio en el que el tiempo es importante y en una tecnología en constante evolución realizar refactorizaciones pequeñas o grandes es una necesidad. La mayor certeza es el cambio y se dará en herramientas, frameworks, lenguajes, ideas de negocio, ….

Productividad y legibilidad

El compilador e IDE nos indican todos los errores léxicos y sintácticos después de escribir cada caracter sin tener que ejecutar el código o los teses unitarios para descubrirlos evitando que lleguen a producción en cuyo caso nos requerirá dedicar tiempo para corregirlos o con peores consecuencias para los usuarios de nuestro código y para el negocio. Que el IDE nos muestre sugerencias con la asistencia de código según escribimos o mediante refactorizaciones son un gran diferencia de productividad aunque algunos piensen que por ser el código más verboso o por escribir menos líneas de código se tarde en programar más la misma tarea, el compilador y el IDE son factores que permiten aumentar la productividad a pesar de la verbosidad.

Con la llegada de Java 8 y sus novedades se ha incorporado al lenguaje la programación funcional que permite expresar de una forma más natural para los humanos la tarea que se desea realizar, esto hace que el código sea más legible. Lo que en un lenguaje imperativo son varias líneas de código con una combinación de sentencias condicionales, bucles, asignaciones y llamadas a métodos con un objetivo poco claro sin un examen detallado del código ahora se puede expresar de forma funcional haciendo uso de los streams y expresiones lambda, también en menor número de líneas de código.

Software disponible

Java posee gran cantidad de software disponible, de gran calidad y en muchos casos con una licencia de código abierto o de software libre para cualquier tipo de necesidad en una aplicación de cualquier ámbito. A menudo hay no solo una opción sino varias disponibles y con la libertad de elegir la que más se adecue al proyecto o se prefiera. Ahí está la fundación Apache, Spring o JBoss con una buena colección de proyectos ampliamente utilizados.

Los cambios se producirán, por ello no te encadenes a una determinada tecnología que en un futuro te impida adaptarte a nuevas necesidades. En Java hay opciones para cada diferente aspecto de la aplicación (seguridad, persistencia, logging, framework web, …), por si en un futuro surge una nueva «cojoherramienta», y esto pasará tarde o temprano, diseña tu aplicación de tal forma que sea posible reemplazar una pieza por otra sin tener que reescribir la aplicación entera.

Ofertas de trabajo, desarrolladores

Dado que Java unos de los lenguajes más utilizados y es usado ampliamente en muchos ámbitos es más fácil encontrar a personas con conocimientos y expertos en Java. Por ello hay numerosas ofertas de trabajo para diversos ámbitos (web, escritorio, servidor, dispositivos móviles, …) algunas a considerar, aunque bastantes menos que ofertas.

Conservador, no anticuado

Java tarda en incorporar en el lenguaje algunas de las últimas técnicas de programación que un determinado momento tienen gran relevancia. No porque no pueda sino porque tienen una actitud conservadora, y esto no es malo ya que uno de sus principios hasta el momento es mantener la compatibilidad hacia atrás ¿qué lenguaje que ha ido incorporando nuevas características ha mantenido la compatibilidad de compilación en gran medida durante 20 años? Java pone gran énfasis en este aspecto en cada nueva versión. Esperando cierto tiempo asegura incorporar en el lenguaje aquellas nuevas posibilidades que realmente han demostrado ser útiles y no son simples modas pasajeras que más tarde dificultan la compatibilidad en futuras versiones. Esto no quiere decir que no evolucione, ya en Java 5 incorporó numerosas novedades como generics, … y en Java 8 programación funcional como streams para mejorar la legibilidad del código y aprovechar el procesamiento paralelo de los procesadores multinúcleo. Los métodos por defecto (default methods) en interfaces son una muestra del interés que hay en Java de mantener la compatibilidad hacia atrás. En el enlace está la evolución histórica durante estos años.

Propósito general

Java es un lenguaje de propósito general y multiplataforma ejecutable en cualquier dispositivo en el que haya una JVM disponible. No está restringido a un determinado ámbito o tipo de aplicación, el mismo conocimiento del lenguaje sirve para múltiples tipos de aplicaciones desde de escritorio, de servidor, procesamiento de datos, dispositivos móviles … incluso juegos, sí juegos. Hay muestras de algunos impresionantes con buen rendimiento, aunque alguno diría incorrectamente que no. Con jMonkeyEngine podemos hacer un juego que tiene poco que envidiar usando otro lenguaje ya que proporciona los mimbres comunes: bucle del juego, colisiones, física, 3D con OpenGL, sonido, entrada, …. Minecraft es una muestra, otras buenas muestras usando jMonkeyEngine son PirateHell, Hostile Sector, Imperii, Grappling Hook o 4089: Ghost Within y en la página de ejemplos hay alguno más.

Quizá en un futuro cambie pero hoy Java es el lenguaje en el que se programan las aplicaciones Android nativas y una de las plataformas móviles con mayor cuota de mercado. El lema “write once, run everywhere” sigue siendo aplicable hoy más que nunca haciéndole ideal para la nueva generación de dispositivos de la internet de las cosas (IoT, Internet of things).

Mi escala de preferencias para un lenguaje es de la siguiente forma de mayor a menor (aunque puede variar según la necesidad):

  • Ofertas de trabajo, alguna de Groovy, alguna de Python pero mucho menores que en Java, C# o PHP.
  • Propósito general, esto permite que el tiempo dedicado a aprender y convertirte en un experto en un lenguaje (que pueden ser de varios años) pueda ser aprovechado en el momento que el avance de la tecnología cambie las reglas de juego como la aparición de los dispositivos móviles. PHP es un lenguaje que fuera del ámbito de desarrollo web tiene poca presencia, dispone de buenas herramientas como Wordpress, Drupal o Symfony y hay ofertas de trabajo. En la plataforma Android Java es el lenguaje empleado.
  • Productividad, refactorizaciones y documentación disponible. Poder refactorizar el código de forma segura es un gran punto para la productividad y más importante aún evitar errores, por este motivo y a base de experiencia soy reticente a los lenguajes dinámicos. El tipado estático ayuda a evitar errores y servir como documentación, un buen IDE permite aumentar la productividad. Java es un lenguaje que está bien documentado con su Javadoc.
  • Software disponible, hay cantidad de lenguajes algunos de los más nombrados son Go o Dart pero en estos es probable que debiésemos desarrollar nosotros el software para una determinada necesidad que en otros lenguajes ya está implementado y más que probado pudiendo haber incluso varias opciones.
  • Legibilidad, cualquier añadido al lenguaje que haga más claro el propósito del código o en menos líneas es bienvenido pero como ves esto está abajo en esta lista según importancia.

Aunque no lo he puesto el divertirse y programar a gusto con un lenguaje también debería estar en esta lista pero esto en parte se consigue una vez que dominamos el lenguaje y su ecosistema sintiéndonos capaces de realizar cualquier tarea produciendo buen código, ya sea Java o cualquier otro.

Estas son otras listas de 10 razones por las que Java mola más que nunca y otras 10 razones para querer a Java y la JVM.

¡Larga vida a Java!

Referencia:
10 Reasons Why Java Now Rocks More Than Ever
10 Reasons to Love Java and the JVM

» Leer más, comentarios, etc...

El blog de Adrián Arroyo

La gestión de la memoria en Rust

May 21, 2015 10:00 PM

Finalmente ha sido publicada la versión 1.0 de Rust. El lenguaje diseñado por Mozilla basado en 3 principios:

  • Seguridad
  • Concurrencia
  • Rendimiento

Hoy voy a hablar del primer principio, la razón principal para querer ser un sustituto de C++. Porque C++ está bien, pero puedes liarla mucho si no sabes lo que haces.

Rust

El concepto de dueño

En Rust todo tiene un dueño. No puede haber más de uno ni ninguno, debe ser uno exactamente.

fn main(){
	let A = 5;
    // El dueño de A es main()

}

Hasta aquí todo es sencillo. Ahora pasaremos la variable A a otra función.

fn sumar(a: i32, b: i32) -> i32{
	a+b
}
fn main(){
	let A = 5;
	let suma = sumar(A,4);
	println!("{}",suma);
}

El programa compila y nos da el resultado, que es 9. En los lenguajes de bajo nivel las variables pueden usar memoria del stack o del heap. Un pequeño repaso sobre sus diferencias.

Stack
  • Se reserva su espacio en RAM cuando el programa arranca
  • Son más rápidas de acceder
  • No se les puede cambiar el tamaño
  • Son más seguras
Heap
  • Se debe reservar manualmente la RAM cuando queramos
  • Son más lentas de acceder
  • Pueden cambiar su tamaño en tiempo real
  • Son menos seguras. Pueden dar lugar a fugas de memoria.

En este último caso, la variable A cuyo dueño es main() le pasa la membresía temporalmente a sumar(). La membresía se devuelve a main() rápidamente y esta garantizado que así suceda. El compilador lo permite. Veamos ahora un ejemplo más complejo.

Veamos ahora un código más complejo

struct Config{
	debug_mode: bool
}

struct App{
	config: Config
}

fn main(){
	let config=Config{debug_mode: true};
	
	let app=App{config: config};
	
	println!("OK");
}

Por supuesto el código compila pero este de aquí abajo no y solo he cambiado una línea.

struct Config{
	debug_mode: bool
}

struct App{
	config: Config
}

fn main(){
	let config=Config{debug_mode: true};
	
	let app=App{config: config};
	let backup=App{config: config}; // He añadido esta línea
	
	println!("OK");
}

La razón es que cuando creamos la estructura de App por primera vez le pasamos la membresía de config a la estructura app. Así la función main no le puede pasar la membresía a backup porque ya se la pasó a app.

Referencias

Para solucionar este problema Rust usa las referencias. Así el dueño de config seguirá siendo main() pero lo podrán usar las estructuras app y backup. Para usar referencias usamos el símbolo &.

struct Config{
	debug_mode: bool
}

struct App{
	config: &Config
}

fn main(){
	let config=Config{debug_mode: true};
	
	let app=App{config: &config};
	let backup=App{config: &config};
	
	println!("OK");
}

La estrucura ahora acepta &Config en vez de Config. Es de decir usa una referencia en vez de un valor. Sin embargo esto no compilará. El compilador normalmente deduce si es posible hacer una referencia a algo no existente, un fallo común en C++. En caso de tener dudas no compilará. Rust es bastante inteligente pero no es mágico. En el caso de la estructura App, es necesario indicar que la propiedad config vivirá el mismo tiempo que la estructura.

struct Config{
	debug_mode: bool
}

struct App<'a>{
	config: &'a Config
}

fn main(){
	let config=Config{debug_mode: true};

	let app=App{config: &config};
	let backup=App{config: &config};
	println!("OK");
}

He usado la anotación de tiempo llamada a. Puedes poner cualquier nombre pero a es muy corto.

Implementaciones y referencias

Voy a introducir un concepto de Rust que son las implementaciones. Para haceros una idea rápida, serían como clases de C++, pero solo alojan funciones.

impl<'a> App<'a>{
	fn isDebugMode(&self) -> (){
		println!("DEBUG MODE: {}",self.config.debug_mode);
	}
	
	fn delete(self) -> (){
		
	}
}

He creado dos funciones para implementar App. Son idénticas salvo por un pequeño detalle, una toma el valor self (como this en C++) por referencia y la otra toma el valor directamente.

let app=App{config: &config};
	app.isDebugMode();
	app.delete();

Compila y funciona. Cambiemos el orden.

let app=App{config: &config};
    app.delete();
    app.isDebugMode();

Ya no compila. La razón es que cuando llamamos a delete() estamos pasandole la membresía de app entera. Ahora delete() es la dueña de app y cuando salimos de la función eliminamos app porque si su dueña ha muerto, app también debe morir (no es tan sangriento como pensais). Rust lo detecta y delete() será la última función que podemos llamar de app. Por cierto si os preguntais como funcionan las implementaciones en Rust (que no son clases), este código haría lo mismo llamando a funciones estáticas. Quizá así veais mejor como se pasa el concepto de dueños y membresía.

let app=App{config: &Config};
    App::isDebugMode(&app);
    App::delete(app);

Diversión con punteros en el heap

Todo estas variables eran del stack que siempre es la manera más sencilla de operar. Vamos ahora a ver como funcionaría esto con punteros. Los punteros operan como variables en el stack que hacen referencia a partes de la memoria que están en el heap. En Rust podemos operar con punteros con máxima seguridad pues todo lo aplicable a variables en el stack sigue siendo válido. Solo hay un dueño y podemos hacer referencias, aunque quizá necesitemos marcar el tiempo de vida manualmente.

let puntero: Box<i32>=Box::new(42);

Ahora el valor 42 estará en el heap y con puntero podremos acceder a él. Sin embargo como es lógico, no podemos operar directamente con él.

puntero+1 //No funciona

Para operar el valor directamente tenemos que derreferenciarlo. Se usa *

*puntero+1 // Sí funciona, y será 43

Así que esta operación sería correcto. Nótese el uso de mut para permitir editar el valor. En Rust por defecto las variables no son mutables. Ese privilegio tiene que ser declarado por adelantado.

let mut puntero: Box<i32>=Box::new(41);
    *puntero+=1;
  	println!("La respuesta es: {}",*puntero);

Como curiosidad mencionar que la macro println! (en Rust si algo termina con ! es una macro) acepta puntero o *puntero indistintamente ya que se da cuenta si es necesario derreferenciar o no.

El problema final

¿Qué pasaría si copiamos un puntero en otro? Pues como un valor en el heap solo puede tener un dueño, la membresía será del último puntero.

let mut puntero: Box<i32>=Box::new(41);
    *puntero+=1;
    let puntero_inmutable=puntero;
    println!("La respuesta es: {}",puntero); // Esta línea no compilará pues el acceso a la respuesta última del universo ahora es propiedad de puntero_inmutable
    println!("La respuesta, ahora sí, es: {}",puntero_inmutable);

Como curiosidad, este es un curioso método para bloquear en un determinado momento el acceso de escritura a nuestro puntero aunque es fácil volver a obtener el acceso a escritura con un nuevo cambio de dueño.

Conclusiones

Podemos ver que es un lenguaje que presta mucha atención a la seguridad. C++ es mucho más liberal en ese sentido y Mozilla cree que es un problema a la hora de desarrollar grandes aplicaciones. ¿Qué te ha parecido? Si tienes alguna duda no titubees y pregunta.

» Leer más, comentarios, etc...

Juanjo Navarro

Codificación de URLs

May 21, 2015 05:45 PM

En What every web developer must know about URL encoding se explica algo que resulta sorprendentemente difícil de hacer bien: Hacer encoding de URLs.

Algunas cosas destacables:

  • Las distintas partes de una url (el host, el path, el querystring) utilizan distintas codificaciones, por lo tanto no se puede hacer el encoding correctamente sin analizar la url (simplemente con un buscar y sustituir).
  • Sorprendente: La clase java.net.URLEncoder de Java no nos sirve para hacer encoding de URL (a pesar de su nombre). No solo eso, sino que la propia documentación oficial lo dice

Utility class for HTML form encoding. This class contains static methods for converting a String to the application/x-www-form-urlencoded MIME format.

  • Aparte de los parámetros de la query, existen los parámetros del path. Es más, cada segmento de path (lo que vendrían a ser cada uno de los directorios) pueden tener sus propios parámetros, que se separan del fragmento por “;”, como en este ejemplo que se me ocurre:
http://www.example.com/user;domain=main/6677/connections;start=0;count=20

» Leer más, comentarios, etc...

Picando Código

Rebeldes de los Datos

May 20, 2015 03:23 PM

Terminado el Taller de Datos Abiertos de Gobierno en Uruguay, volví a casa con un montón de ideas, nuevos contactos, y muchas ganas de seguir en el tema.

La instancia tuvo una estructura determinada con grupos de trabajo abiertos entorno a 4 temas: Regulación y Normativa, Reuso, Salud y Medio Ambiente. Cada grupo tuvo varias sesiones de trabajo en distintas mesas en el local de la Agencia Española de Cooperación Internacional para el Desarrollo en Ciudad Vieja.

Mesa de Trabajo

Cada mesa de trabajo sacó sus conclusiones y las presentó al final del evento. Los grupos de trabajo estaban conformados por personas pertenecientes a entes gubernamentales, integrantes de la sociedad civil y los invitados especiales de UNDESA, entre otros.

La idea con lo hecho era planear la agenda de Datos Abiertos de Gobierno a futuro. Si bien cada grupo planteó aspectos específicos, hubieron dos temas importantes que creo que todos tuvieron en común:

  • Legizlación – una ley de Datos Abiertos para regular el tema desde el gobierno por defecto.
  • Grupo de trabajo consolidado – Un grupo de trabajo con referentes de distintos entes impulsado desde el Estado para ayudar a llevar adelante la agenda.

Seguramente habrán noticias desde el gobierno en estos aspectos eventualmente. Pueden ver más información sobre las presentaciones y conclusiones en el siguiente enlace: . También hay información resumida en el sitio web de AGESIC – Tenemos tema: cerró el taller de datos abiertos.

Trabajando

Más allá de los resultados, hubo un aspecto interesante del evento que fue la instancia de encuentro para varias personas de distintos entes con la sociedad civil. El “networking” es uno de los aspectos fundamentales de varios eventos y en este caso no fue la excepción. Quiero aprovechar este post para reconocer a los “rebeldes de los datos” que tuve la oportunidad de conocer. Se me ocurrió este nombre durante una charla en alguno de los cortes para café, conversando con empleados de varios entes.

En general -sobretodo en Uruguay- tenemos una imagen muy negativa de los empleados públicos trabajando en entes gubernamentales. En muchos casos justificada tal vez, pero instancias como éstas nos dejan ver que no todo es tan malo como se puede creer desde afuera. Hay mucha gente adentro muy preocupada por las personas, el aire, el agua, los animales, etc. Más allá del partido político en el gobierno de turno, estas personas están pendientes de temas importantes para el resto y se preocupan por hacer algo al respecto. Y también están peleando constantemente contra la burocracia, dónde se invierten los recursos, etc. Pero es bueno saber que están ahí.

Los Datos Abiertos son una de las herramientas que tenemos para equilibrar el poder a favor de los ciudadanos, y cuánto más se trabaje en esa dirección, mejor. Están en la agenda política del gobierno actual dentro del marco de Gobierno Abierto. Necesitamos más rebeldes haciendo algo, hay mucho trabajo por hacer en este aspecto, y los Datos Abiertos no sirven de nada si no los explotamos por el bien común.

Asistentes taller AGESIC

Si te interesa empezar con el tema, en Uruguay existe DATA, la Asociación Civil con la misión de la creación de herramientas para el accionar colectivo, participativo y colaborativo, apoyándose en la comunidad a través de las tecnologías de la información y comunicación y el uso de la información pública. Contacta a DATA para conocer cómo ser parte.

Fotos por Mónica Camerlati de IMPO.

» Leer más, comentarios, etc...

Picando Código

Mini-truco: Crear un dump de base de datos Postgres en servidor por SSH y descargarlo

May 19, 2015 08:19 PM

PostgreSQLHace mucho que no publico nada bajo la categoría Mini-trucos: Cosas publico acá para compartir y tener de referencia.

En este caso de nuevo trabajando con PostgreSQL tuve que hacer un par de cosas bastante sencillas y probablemente comunes:

Crear un dump de la base de datos en el servidor remoto

Conectarse al servidor por SSH e ingresar:

pg_dump nombre_bd -U usuario_bd -W -h localhost -f ~/nombre_dump

-U para pasarle el usuario para acceder a la base de datos
-W para forzar que nos pida el password
-h localhost para evitar que intente autenticarse con el usuario actual en el sistema (que en mi caso era distinto al del de la base de datos por lo que el rol no existía)
-f archivo – Dónde guardarlo

Para descargarlo a nuestra computadora (desde el prompt de nuestra computadora):

scp usuario@servidor:/path/al/dump /directorio/local

Importar

psql bd_en_local < nombre_dump

Puede ser necesario crear archivo .pgpass para el usuario (en caso de una app Rails).

Actualización

¡Gracias Rodolfo por el aporte en los comentarios!

Fernando el ssh puede ejecutar el comando y la salida stdout es del lado del cliente (ssh), por lo que puedes colocarla dentro de un pipe:

ssh usuario@servidor pg_dump nombre_bd -U usuario_bd -W -h localhost | cat > /directorio/local/nombre_dump

con este único comando te evitas ocupar espacio en el servidor para el dump y el subsecuente scp.

» Leer más, comentarios, etc...

Variable not found

9 años ya, esto parece que va en serio…

May 19, 2015 08:38 AM

9 años de variable not foundPues sí, parece mentira, pero han pasado ya nueve años desde Variable not found comenzó tímidamente su andadura intentando hacerse un pequeño hueco en este océano de información en que se había convertido internet.

Sinceramente, y ya lo he comentado en alguna otra retrospectiva anual, nunca pensé que esta aventura duraría tanto tiempo y me traería tantas satisfacciones. Y aunque he de reconocer que no es una tarea sencilla, el hecho de estar todavía aquí con ganas de seguir aprendiendo y compartiendo todo lo que puedo es para mí una compensación más que suficiente a la dedicación que esto requiere :)

Como manda la tradición, voy a comentar algunos detalles objetivos sobre la salud blog y sus visitantes, porque alguna vez me habéis comentado que os resultan interesantes estos datos.

En cuanto a visitas, el blog sigue manteniéndose en buena forma. Siguiendo la tónica habitual de los últimos años, se siguen incrementando las visitas, aunque sin aumentos espectaculares. Creo que estamos en una fase de leve crecimiento sostenido, como muestra la siguiente gráfica:


Alcanzamos en total más de un millón y medio de páginas vistas, con un promedio de tiempo en la página de 4 minutos, lo cual creo que no está nada mal.

En este último año, las estadísticas indican un total de 270.000 páginas vistas por un total de 140.000 visitantes, datos ligeramente superiores a los del año anterior. La página de Facebook ronda los 750 amigos (+15%), y en Twitter superamos los 1.250 seguidores (+25%).

Los suscriptores al RSS, en cambio, han caído drásticamente por el cambio de política de Google que ha afectado a todos los usuarios que usábamos Feedburner; de más de 1.500 del año pasado, ahora no llegan a 400 (!) Algún día tendré que sustituir este servicio por algo más decente, supongo :(

Feedburner stats

En cuanto a vosotros, estimados amigos, este es vuestro perfil medio según los algoritmos mágicos de Google. La mayoría sois hombres (90%), de entre 25 y 35 años (60%), tecnófilos, aficionados al cine y TV y a la fotografía, muy inclinados a la tecnología, dispositivos, software, programación y a muchos os gustan los deportes en general, el fútbol en particular.
Browsers
El 70% utilizáis Chrome, creciendo sobre el año  anterior. Firefox (20%) e Internet Explorer (10%), han bajado respecto al último periodo.

España sigue siendo la principal fuente de visitantes con un 24%, bajando ligeramente respecto al año anterior por la subida de otros países del otro lado del Atlántico. México se sigue aproximando, rozando ya el 21% de visitantes. Ya a algo más de distancia, siguen subiendo Colombia (11%), Argentina (9%), Perú (8%) o Chile (6%).

Los buscadores aportan el 85% de los visitantes, siendo Google el usado el 99% de las veces. El acceso directo, es decir, los usuarios que introducen directamente la URL o usan los favoritos en su navegador alcanzan el 10%. Sólo un 5% de visitas se deben a enlaces externos.

La parejitaY ahora hablemos de los beneficios obtenidos durante el periodo, que seguro que también os interesan :)

Ya hace años llegué a la conclusión de que los ingresos por tener Adsense en el blog no eran una leyenda urbana, pero poco después descarté hacerme rico con ellos. En este sentido, este año hemos seguido en la misma línea; un par de veces me llega una transferencia de Google suficiente como para irme a almorzar con la familia, y poco más. Tampoco han vuelto los tiempos en los que he escrito algún post patrocinado, siempre algo mejor recompensados.

Pero claro que hay beneficios, negarlo sería faltar a la verdad. Lo que ocurre es que muchos de ellos son indirectos y otros muchos intangibles: satisfacciones, mucho aprendizaje, visibilidad y oportunidades increíbles… Por ejemplo, ¿quién me iba a decir hace unos años que tendría la oportunidad de publicar un libro de alcance mundial, traducido ya al inglés y al japonés? ¿O que tendría ocasión de trabajar para empresas de primer nivel del país (e incluso, cada vez más, en el extranjero) en proyectos impresionantes? ¿Y la satisfacción de haber formado a centenares de desarrolladores en mis cursos de CampusMVP? Es sencillamente increíble.

Y todo ello os lo debo a vosotros, queridos amigos. Gracias por leerme. Gracias por citarme. Gracias por recomendarme. Gracias por decírmelo cuando me equivoco. Gracias por aportar vuestra visión. Y sobre todo, gracias por el apoyo y cariño que me habéis demostrado durante tanto tiempo.

Espero veros a todos por aquí al menos un año más, ayudándome a buscar esta esquiva variable ;)

» Leer más, comentarios, etc...

Arragonán

Semana 362

May 18, 2015 01:14 PM

Semana muy movidita esta última respecto a posibles colaboraciones y proyectos (reuniones y emails a cascoporro), en la que finalmente hemos llegado un acuerdo con una empresa local con la que voy a estar colaborando una temporada. Vamos a empezar poco a poco, pero va a ir exigiendo bastante dedicación por mi parte tal y como pasen las próximas semanas y vaya cerrando los proyectos pendientes.

Tuvimos doble sesión de charlas en SenpaiDevs. El martes vino gimenete a hablar de javascript y a hacer una intro a node.js; mientras que el jueves Néstor preparó una sesión sobre DevOps (vagrant, ansible, packer.io, docker).

En otro orden de cosas, esta semana me he visto todos los capítulos de las 2 primeras temporadas de Black Mirror, una mini-serie que me habían recomendado en varias ocasiones, y con razón. Son historias que mezclan el lado oscuro de la naturaleza humana y el uso de la tecnología. Cada capítulo además es totalmente diferente e independiente del resto y cada uno deja, a su manera, sensaciones inquietantes. Muy recomendable.

Y volviendo a mis temas habituales, sobre proyectos actuales:

  • Tuvimos reunión de mhop, y el fin de semana estuve haciendo un par de pequeñas tarea. Posiblemente esta semana comunicaremos novedades.
  • Tras un par de cambios que me pidieron en One-step parece que está todo listo, a ver si esta semana concretamos el despliegue y lo damos por finiquitado.
  • En mosica estuve trabajando para tener una página de sala, modificando como se comparten los mensajes en redes sociales y terminé de implementar el buscador de conciertos en las aplicaciones móviles.
  • Continué con la importación de Bichomanía, acabé con la importación de usuarios y extendí algunas cosas de spree/devise para no tener que modificar las contraseñas de los clientes.
  • Seguimos con la negociación de colaboración de Minchador con otra compañía. A ver si esta semana se concreta el tema, o descartamos la colaboración.

Buena semana.

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 199

May 18, 2015 07:05 AM

Enlaces interesantesAhí van los enlaces recopilados durante la semana pasada, espero que os resulten interesantes :-)

.Net

ASP.NET

Conceptos/Patrones/Buenas prácticas

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Cross-platform

Otros

Publicado en Variable not found

» Leer más, comentarios, etc...

Koalite

Lectura de Códigos de Barras con HTML5 y Javascript

May 18, 2015 05:06 AM

Hace poco explicaba cómo capturar vídeo usando Javascript y HTML5. Uno de los posibles usos de esta captura de vídeo es la lectura de códigos de barras. Tradicionalmente para “leer” un código de barras se ha utilizado hardware específico, pero de un tiempo a esta parte, la capacidad de proceso es suficiente como para utilizar algoritmos de visión artificial que nos permiten localizar el código de barras dentro de una imagen y decodificarlo.

Implementar este tipo de algoritmos no es una tarea trivial (aunque tampoco es imposible), así que para ver cómo funciona vamos a usar una librería que se encarga de (casi) todo: QuaggaJS.

La librería

QuaggaJS es una librería que nos permite decodificar códigos de barras utilizando Javascript. Soporta varios tipos de códigos de barras, de momento todos unidimensionales, como EAN, Code128 o Code39.

Se trata de una librería bastante reciente (su primera versión de principios de este año) y con un desarrollo activo, por lo que todavía puede que no esté todo lo pulida que a uno le gustaría, y seguramente con el tiempo se añadan nuevas funcionalidades.

Para usarla, sólo necesitamos irla alimentando con imágenes, y ella se encargada de detectar los códigos de barras que aparezcan en las imágenes. Podemos proporcionarle imágenes estáticas, o podemos utilizar directamente el stream de vídeo procedente de la cámara para decodificar los códigos de barras en tiempo real.

El ejemplo

Vamos a ver un ejemplo de cómo decodificar códigos de barrras usando el vídeo capturado en tiempo real.

Lo primero será instalar QuaggaJS, cosa que podemmos hacer a través de npm (si vamos a usarla con browserify) o descargando y referenciando el fichero js, como hacían nuestros mayores antes de que los gestores de paquetes dominasen el mundo.

En nuestro HTML necesitaremos algo así:

<p>Barcode: <span class="found"></span></p>
<div id="interactive" class="viewport"></div>

Es muy importante que el elemento donde vamos a ir mostrando el vídeo tenga como id interactive y como class viewport. Resulta extraño, pero ahora mismo no hay ninguna forma de indicarle a la QuaggaJS el elemento que vamos a utilizar y busca directamente por esos valores.

Ahora que tenemos el HTML mínimo para realizar la captura de vídeo, podemos pasar a la parte Javascript. Empezamos por inicializar QuaggaJS:

Quagga.init({
  inputStream: {
      name: "Live",
      type: "LiveStream",
      constraints: {
            width: 640,
            height: 480,
            facing: "environment"
        }
  },
  locator: {
    patchSize: "medium",
    halfSample: true
  },
  numOfWorkers: 4,
  locate: true,
  decoder : {
      readers: ["code_128_reader", "ean_reader"]
  }
}, function() {
  Quagga.start();
});

El método init nos permite inicializar la librería estableciendo el origen del vídeo, que en este caso marcamos como LiveStream para indicar que queremos capturarlo de la cámara, los parámetros de captura, y varios parámetros del algoritmo de identificación de código de barras.

Es especialmente importante añadir en la colección de decoder.readers aquellos tipos de códigos de barras que queramos intentar decodificar, por si queremos limitar la lectura a algún tipo determinado (cosa que además acelerará ligeramente el proceso de decodificación).

Por último, podremos pasar la típica funcción callback que se invocará cuando la inicialización se haya completado. En este caso lo que haremos será iniciar el proceso de reconocimiento invocando el método Quagga.start().

Para ser notificados cuando se detecte un código de barras debemos emplear el método Quagga.onDetected(callback):

Quagga.onDetected(function(result) {
  var code = result.codeResult.code;
  document.querySelector(".found").innerHTML = code;
});

Además, podremos recibir información de cómo va el proceso de decodificación usando el método Quagga.onProcessed(callback), del cual podéis encontrar un ejemplo en el repositorio oficial.

Podéis ver el ejemplo funcionando y jugar con él en este jsfiddle.

Las pegas

Poder utilizar este tipo de funcionalidades en una aplicación web está muy bien, pero la realidad es que tiene unas cuantas limitaciones, algunas propias de la librería que hemos usado en el ejemplo y otras tal vez más ligadas a la plataforma.

En lo que respecta a QuaggaJS, se nota que todavía está un poco verde. La documentación es escasa e incompleta, y hay algunas cosas que resulta dificilmente justificables, como la obligatoriedad de identificar el elemento que va mostrar el video con un id y una clase determinada (cosa que además no he encontrado documentada en ningún sitio y me hizo perder un buen rato).

Por otra parte, su desarrollo está bastante vivo, por lo que cabe esperar que estas cosas se vayan resolviendo poco a poco.

Otro problema es el rendimiento a la hora de reconocer códigos de barras. Entiendo que el proceso que tiene que realizar es costoso porque necesita localizar el código dentro de la imagen antes de decodificarlo, pero la verdad es que no es demasiado rápido. Para leer un código de barras de vez en cuando está bien, pero si pretendes hacer una aplicación que realice una lectura intesiva de códigos de barras (por ejemplo una aplicación de inventario, de entrada de mercancía, de picking, etc.), es muy lento.

No sé hasta qué punto es culpa de los algoritmos elegidos, de la forma en la que están implementados, del rendimiento “puro” del motor de Javascript, o de la potencia del teléfono con el que he hecho las pruebas. Aun así, supongo que como todo lo que está relacionado con rendimiento será algo que vaya mejorando a lo largo del tiempo.

Posts relacionados:

  1. Cómo Generar Códigos QR en C#
  2. Captura de vídeo con HTML5
  3. La Vida en un Canvas de HTML5

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti)

Al principio fue el libro

May 17, 2015 06:43 PM

Parafraseando el título del libro de Neal Stephenson, en el principio fue el libro. Parece ya lejano el tiempo en que la mayoría de software, bien fuera especializado como de propósito general, se vendía acompañado de manuales impresos. Además multitud de autores y editoriales, complementaban dicha bibliografía con títulos dedicados a complementar dicho material. Desde MS-DOS 3.30, GW-BASIC 3.23, Lotus 1-2-3 2, IBM PC-DOS 5 o Windows 2, hasta herramientas más especializadas como Turbo C++ 1.0 o Visual BASIC 3, todos se hacían acompañar de sus recursos en papel. En algunos casos, el motivo era por la documentación y ayuda insuficiente en el propio paquete de software. Recordemos que en MS-DOS, no existía ni HELP, no la forma de uso de algunos de sus comandos. Otros como Quick BASIC 4.5 o el mencionado Visual BASIC, a pesar de incluir una excelente documentación en linea, usaban el papel como soporte adicional. [...]

» Leer más, comentarios, etc...

Blog Bitix

Nuevo diseño en Blog Bitix

May 16, 2015 10:00 AM

Hugo

En diciembre de 2013 pasé de utilizar Blogger a usar Octopress creando la bitácora Blog Bitix. Octopress fue una gran mejora a la hora de editar el contenido y gestionar las imágenes o trozos de código con gist. Hace relativamente poco que he pasado a utilizar Octopress pero desde hace un tiempo quería personalizar mucho más el diseño de la bitácora. Estaba esperando a ver como avanzaba el desarrollo de la siguiente versión sin embargo va lentamente por mucho que hayan dicho ya en el 15 de enero que Octopress 3 de está en camino, aún en mayo no hay ninguna nueva noticia desde entonces.

Posiblemente usando Jekyll directamente (Octopress está basado en Jekyll) podría conseguir el nivel de personalización que quería. Sin embargo, revisando otras opciones dí con otra plataforma de generación de sitios estáticos, Hugo. De Hugo me han gustado varias cosas que en Octopress no tenía:

  • Ejecutable: Hugo es un único binario, basta descargar este único archivo. Está desarrollado en el lenguaje go (Jekyll y Octopress en Ruby). No hay dependencias que descargar que «ensucien» el sistema, esto también tiene la ventaja de que la actualización a una nueva versión es sencilla.
  • Temas: crear un tema para Hugo es sencillo y hay una documentación básica pero suficiente.
  • Rapidez: el lenguaje go y Hugo alardean de rapidez y mis sensaciones coinciden con ello, la bitácora completa se genera en unos pocos segundos, los cambios en un artículo son casi instantáneos y el servidor web local arranca muy rápido.
  • Taxonomía: con Hugo al contenido se le puede aplicar una taxonomía muy versátil que por ejemplo permite crear series de artículos. Con Octopress tenía que modificar cada artículo de la serie para incluir uno nuevo, con Hugo basta que lo defina en el front matter y el resto de artículos de la serie se actualizarán incluyéndolo.

Con Hugo también he tenido que hacer algún hack y es que en los diferentes artículos de la bitácora suelo incluir enlaces a un montón de herramientas, para no estar repetirlos constantemente y en el caso de que uno cambie no tener que modificar los artículos individualmente tengo un archivo de enlaces comunes que incluyo en cada artículo, y en esta inclusión está el hack, usando algunas de las funciones que proporciona Hugo. También he tenido que crear un script para subir los cambios al alojamiento que uso con GitHub Pages cosa que Octopress proporciona de serie, usar Grunt para generar el archivo de estilos css a partir de un archivo Less o reescribir las urls de los feeds para que sean absolutas.

Entre las cosas de diseño que quería cambiar estaba la cabecera intentando que fuese pequeña verticalmente para que según se cargue la página se vea la mayor parte posible de contenido, con esto he quitado la descripción de la bitácora de la cabecera y la he puesto en el pié de página. En el menú he puesto enlaces a las secciones de las que suelo hablar: Java, GNU/Linux, JavaScript y Apache Tapestry. Los usuarios podrán encontar más fácilmente el contenido de los temas principales que escribo y quizá Google averigüe un poco mejor de que trata la bitácora. Entre otras cosas he cambiado el tema a uno basado en el color blanco, reorganizado los bloques de anuncios de publicidad Adsense, eliminado Karmacracy por nulo uso para compartir contenido y dejando solo Share This para este propósito, he situado los enlaces de sindicación al lado del logotipo para darles más visibilidad, cambiada la visualización de los thumbnails de las imágenes ahora se podrán ver en un tamaño mucho más grande y mejor, la página de inicio ahora solo incluye un resumen de los artículos en vez del artículo completo con lo que espero que esta página se cargue mucho más rápido, un fondo que varía de forma aleatoria en cada carga de página (lo mismo que hago en Blog Stack), añadidos algunos estilos para poner pies en las imágenes y algunas correcciones y modificaciones más en el pie y en la barra lateral.

Diseño de Blog Bitix ahora con Hugo y antes con Octopress

Las urls del contenido no han variado, sí algunas del archivo y de las etiquetas pero como tengo bloqueadas estas con el archivo robots.txt Google no me indicará errores 404. Probablemente si me informe de algún 404 en el contenido aunque espero que no muchos, si ocurre los corregiré en los próximos días o cualquier otra cosa de la que vaya dándome cuenta.

El código fuente completo del tema que he creado y del blog realizado con Hugo puedes encontrarlo en el siguiente repositorio de GitHub.

¿Que te parece el nuevo diseño?

Referencia:
Hola nuevo mundo

» Leer más, comentarios, etc...

Variable not found

Variables de sesión en MVC6 / ASPNET5

May 13, 2015 09:36 AM

ASP.NET MVC
Seguimos hablando de novedades que acompañarán la próxima versión de MVC y ASP.NET, y esta vez le toca el turno a otra de los grandes ausencias que podemos notar cuando creamos desde cero una aplicación utilizando estos frameworks: las variables de sesión.

Bueno, en realidad no se trata tanto de una ausencia como de un desplazamiento de esta característica. Resumidamente, las variables de sesión seguirán existiendo, pero no son parte del core de ASP.NET 5, como ocurría desde la primera versión de ASP.NET, sino un componente totalmente opcional implementado en forma de middleware que deberá ser instalado y configurado de forma independiente.

Pero antes de continuar, recordad que tanto MVC6 como ASP.NET 5 siguen estando en proceso de desarrollo, por lo que algunas de las cosas que contaremos podrían cambiar en las versiones definitivas, aunque espero que no demasiado.

Y dicho esto, vamos al lío: ¿cómo utilizamos variables de sesión en aplicaciones basadas en ASP.NET 5?

1. Descarga e instalación del middleware proveedor de sesión

Siguiendo la nueva filosofía modular de ASP.NET 5, los mecanismos de almacenamiento y recuperación de variables de sesión son ahora un componente que podemos añadir a nuestras aplicaciones de forma opcional.

Como es habitual, la descarga e instalación la realizaremos a través del interfaz de Nuget en Visual Studio, o bien añadiendo manualmente la referencia al archivo project.json. El nombre del paquete que nos interesa es Microsoft.AspNet.Session, como se muestra en la siguiente captura de pantalla:

Reference session package

Una vez hecho esto, ya tenemos en nuestro proyecto los componentes básicos que necesitamos para poder usar variables de sesión. Continuamos el proceso…

2. Añadir el middleware al pipeline

Session middleware in the pipelineEl estado de sesión es proporcionado por el middleware SessionMiddleware, presente en el paquete que acabamos de descargar. Este middleware, insertado en el pipeline de proceso de las peticiones, ofrecerá a los frameworks o componentes posicionados tras él la capacidad de usar variables de sesión.

El hecho de posicionarse en el pipeline y ser “atravesado” por la petición brinda a este middleware la posibilidad de establecer la cookie de sesión que distinguirá de forma única al usuario, preparar el acceso a sus datos y almacenar los cambios producidos durante el proceso de la petición.

Y ojo, que esto es importante: hay que añadir el middleware que proporciona el estado de sesión antes que el propio framework MVC. De no ser así, la petición será procesada por MVC antes de el middleware de sesión sea ejecutado, por lo que desde nuestras aplicaciones no tendremos acceso a las variables de sesión.

El siguiente ejemplo muestra cómo introducir el middleware en el pipeline, utilizando la memoria como almacenamiento para el estado de sesión:

UseInMemorySession

En aplicaciones pequeñas y sin demasiadas aspiraciones, almacenar las variables de sesión en memoria es una solución efectiva y razonable. Sin embargo, cuando la aplicación debe crecer a varios servidores o se necesita una solución menos volátil, podemos usar otros mecanismos de persistencia, utilizando el extensor UseDistributedSession() en lugar de UseInMemorySession() visto anteriormente. No entraremos en más detalle en este post, lo dejaremos para más adelante, pero es muy interesante el hecho de que esto descanse sobre el sistema de caching de ASP.NET, del que ha hablado el gran Unai hace poco.

Como suele ser habitual a la hora de añadir módulos al pipeline, es posible indicar opciones de configuración:

Middleware options

3. Establecer, obtener y eliminar variables de sesión

En primer lugar, es importante tener en cuenta que los pasos anteriores son obligatorios si queremos utilizar variables de sesión. Cualquier intento de utilización de las mismas sin haber instalado y configurado previamente los componentes que las proporcionan provocarán la aparición de un error:

Error trying to use Session vars without installing or configuring the middleware

El acceso a las variables de sesión se realiza utilizando la propiedad Context.Session, es decir, la clase Controller no proporciona ya una propiedad Session como en versiones anteriores de MVC, aunque obviamente siempre podríamos crearnos un atajo (por cierto, fijaos qué limpio queda usando las nuevas expresiones lambda en miembros de función de C# 6):

Session property
Los que ya habéis usado antes variables de sesión, seguro que os sorprende esos métodos GetInt() y SetInt() de la propiedad Session. Pues sí, esto otro cambio importante sobre las versiones anteriores del framework.

Hasta ahora podíamos introducir cualquier tipo de objeto en variables de sesión, y el abuso de esta capacidad ha generado muchísimos problemas. He llegado a ver incluso contextos de datos o conexiones a bases de datos mantenidas en memoria de esta forma, creando unos problemas terribles en tiempo de ejecución. También ha sido tradicionalmente un limitante de la posibilidad de escalado de las aplicaciones (aunque puede solventarse usando algunos trucos de balanceado), y un problema para la fiabilidad  de los sistemas (recordad que un reseteo del servidor, de IIS o incluso un reciclado del pool limpia la memoria).

Session vars are byte arraysPara evitar esto, a partir de ASP.NET 5/MVC 6 sólo podremos guardar en variables de sesión objetos serializados, y esto se manifiesta en el tipo de dato que es ahora el diccionario Session: un array de bytes. Con esto, se acabó el establecer o leer objetos completos directos como hemos hecho siempre, tendremos que serializarlos a un array de bytes para guardarlos el almacén de sesión, así como deserializarlos para poder acceder a ellos. De esta forma, simplificamos el uso de almacenamientos distintos a la memoria local para esta información, facilitando la escalabilidad y mejorando la fiabilidad.

El framework nos proporciona métodos extensores para facilitar las tareas de serialización y deserialización en escenarios comunes, como el almacenamiento y recuperación de variables de sesión de tipo entero y cadenas de texto, mediante los métodos GetInt(), SetInt(), GetString() y SetString(), como se muestra en el siguiente ejemplo:

Session extensions

Si por cualquier motivo queremos guardar un objeto o grafo complejo, tendremos que crear nuestro propio mecanismo de serialización. Aunque la primera tentación puede ser crear un serializador binario usando la clase BinaryFormatter de toda la vida, resulta que la serialización binaria no está soportada en .NET Core, supongo que debido al carácter cross platform de este framework.

Pero sí podríamos, por ejemplo, serializarlo a JSON y guardarlo como string en la variable de sesión y realizar el proceso inverso al recuperar el valor, o bien crear nuestras propias funciones extensoras para facilitarnos la vida en el futuro:

Serialization helpers

Así, ya podríamos usar construcciones más sencillas como las siguientes:

Helper usage

Nota: existen conversaciones en Github sobre la inclusión de métodos genéricos Set<T>() y Get<T>() que permitan indicar un componente de serialización como Protobuf o Bond, así que posiblemente las versiones finales de ASP.NET 5/MVC 6 encontremos algo de ello.

Por otra parte, para eliminar variables de sesión podemos seguir utilizando el método Remove(), al igual que hemos hecho siempre:

Context.Session.Remove()

4. Otros cambios respecto a versiones anteriores

Por último, vamos a comentar un par de detalles que han sido modificados respecto a versiones anteriores de ASP.NET.

Comenzaremos diciendo que en ASP.NET 5 no existe (al menos de momento) un método Abandon(). En cambio, se añade un método Clear() que permite eliminar toda la información de sesión del usuario conectado.

Y una última cosa interesante a tener en cuenta es que ya no están disponibles los eventos Session_Start() y Session_End() que podíamos capturar en el Global.asax en versiones anteriores del framework.

Bueno, pues de momento lo dejaremos aquí. Espero que lo visto os sea de utilidad para continuar interiorizando los cambio que se avecinan con las nuevas plataformas y que la transición a ellas sea un poco menos dolorosa ;)

Publicado en Variable not found.

» Leer más, comentarios, etc...

Picando Código

Datos Abiertos de Gobierno en Uruguay

May 13, 2015 01:55 AM

Datos AbiertosLos días 12 a 14 de mayo se está realizando en Montevideo el Taller de Desarrollo de Capacidades Datos Abiertos de Gobierno en Uruguay, evaluación y planificación estratégica. Es un nombre muy largo, pero de gran importancia para los uruguayos y la movida de Datos Abiertos en general.

Hoy martes 12 de mayo, tuvo una primera parte que consistió en una actividad cerrada para las autoridades de alto nivel. La idea de todo el evento es de sensibilizar a las nuevas autoridades con el tema y conectar actores clave del ecosistema de datos abiertos y empezar a preparar la política entorno a los Datos Abiertos para los próximos años.

Entre los asistentes se encontraban ciudadanos, organizaciones de la sociedad civil (DATA, CAINFO) y agencias como AGESIC, UNDESA y DPADM, funcionarios de distintos entes y más.

Estuve sacando algunas notas así que a continuación comento un poco sobre el primer día:

La segunda actividad de la tarde estaba abierta a mandos medios y referentes técnicos. Empezó con una presentación de Virginia Pardo, Directora del Área de Ciudadanía Digital de AGESIC. Contó sobre la primera etapa ya concluida en la agenda de Datos Abiertos 2011-1025, y que el objetivo con este taller era empezar a construir la nueva agenda 2016-2020. Las Naciones Unidas se involucrarían en esta nueva etapa con apoyo conceptual y capacitación.

Las Naciones Unidas, Datos Abiertos de Gobierno y Uruguay

La siguiente oradora fue Arpine Korekyan, Oficial de Gobernanza y Administración Pública en DPADM, UNDESA, básicamente centrada en Datos Abiertos de Gobierno con las Naciones Unidas.

UNDESA

En la encuesta Mi Mundo 2015, más de 7.5 millones de personas en el mundo decidieron cuáles eran los aspectos que más le importaban. Después de Educación, Salud y Trabajo como primeros tres temas en los resultados, un Gobierno honesto y receptivo tomó el cuarto lugar. En la conferencia Rio +20 también apareció como interés un gobierno efectivo y capaz de representar las voces e intereses de todos.

De esto se desprende que es un tema importante promover el acceso a la información de gobierno, promover sociedades pacíficas e inclusivas construyendo instituciones efectivas, responsables e inclusivas en todos los niveles.

Los Datos de Gobierno son información producida o recogida por entidades gubernamentales. Pasan a ser datos abiertos cuando pueden consultarse fácil y rápidamente y pueden ser reusadas por cualquiera con acceso (licencia libre y estructurados de forma que puedan ser procesados). Antes cualquier dato de gobierno era confidencial por defecto a menos que se especifique lo contrario. Ahora la tendencia es a hacerlos abiertos a menos que se especifique lo contrario.

Los beneficios de promover los Datos Abiertos de Gobierno para las Naciones Unidas y diría que en general:

  • Transparencia y confianza en el gobierno
  • Incentivar participación ciudadana en diseño de políticas y servicios
  • Mejorar efectividad y eficiencia
  • Oportunidade de negocios y trabajo
  • Innovación e investigación

¿Por qué Uruguay?

Habían varios factores a tener en cuanto cuando la ONU eligió los 4 países con los que colaboraría en la iniciativa de Datos Abiertos. El interés en este tipo de iniciativas, la infraestructura disponible, parámetros técnicos y apoyo en el área (contraparte de los gobiernos, etc.).

Esto deja muy bien parado a Uruguay en materia de Datos Abiertos, porque ha habido un trabajo importante desde el gobierno y varios de sus entes, y también la contraparte (hola DATA <3) en forma de sociedad civil. Necesitamos más involucrados :)

Los logros esperados son la capacitación de los cargos superiores de gobierno para formular políticas en conjunto con actores relevantes de la sociedad civil.

Qué, Por Qué y Cómo de los DAG para el desarrollo sustentable

Siguió Daniel Dietrich, consultor internacional DPADM y asesor en políticas de Datos Abiertos de Gobierno. Comentar que Daniel es alemán pero habló en un español casi perfecto. También fue el que nos informó del hashtag oficial del evento que pueden seguir en Twitter: #openUY.

Los Datos Abiertos crean valor social y económico en la sociedad. Traen consigo un cambio cultural en cómo el gobierno y los ciudadanos interactúan y cooperan. Citó la célebre frase de Abraham Lincoln sobre un gobierno ” del pueblo, por el pueblo y para el pueblo”. Si bien es una frase del siglo 19, ahora tenemos las herramientas y la tecnología para hacerlo una realidad.

Habló de la definición de Datos Abiertos (no lo voy a repetir, pero: Datos Abiertos: Qué son y por qué debería importarte), razones para usarlos y la implementación de un programa de Datos Abiertos. Mencionó ejemplos exitosos como en el tema ambiental Info Amazonia (noticias y reportes de la región en peligro del Amazonas) y en Estados Unidos la Energy Data Initiative (esfuerzo para liberar datos de gobierno y voluntarios para crear valor, trabajos y emprendimientos en la transición a una economía de energía limpia).

En materia de salud, comentó el caso de Sir Bruce Keogh, cirujano que convenció a sus colegas en de publicar los datos de los resultados de su trabajo, y 7 años más tarde se encontraron mejoras en los índices de supervivencia. También comentó como muchas veces los gobiernos mismos gastan dinero buscando datos necesarios para sus trabajos.

Casos de éxito con Datos Abiertos en Uruguay

Le tocó la palabra a Daniel Carranza, Consultor Nacional de DPADM y asesor en políticas de Datos Abiertos de Gobierno, y colega de DATA. Daniel comentó sobre el ecosistema en Uruguay con un diagrama que mostraba la intersección entre tres conjuntos: el gobierno, la sociedad civil y la empresas como los principales actores.

Habló de varios casos en Uruguay y el impacto que tuvieron interna y externamente (aportando valor a la sociedad y más). Comentó el caso de la Dirección Nacional de Catastro, donde se trabajó internamente en la gestión de datos y se terminaron liberando. También mencionó los Datos Abiertos de Compras Estatales, que ya tenía una buena gestión de datos interna, pero se trabajó para publicarlos. Aparentemente no hay un consumo externo ni participación ciudadana con los datos pero sí empresas que basan su negocio en ellos.

En el Municipio de Maldonado (¡mis pagos! \o/) se creó la aplicación ABREDATOS, que permite la gestión de datos abiertos por defecto. ¡Esta aplicación está siendo usada por la Ciudad de México para gestionar sus datos! También habló del caso de precios.uy y el trabajo entre AGESIC con su hackatón “Dateidea”, Defensa del consumidor y el grupo de trabajo que ejecutó el proyecto.

También se mencionó AtuServicio, proyecto del cual hablé por acá:
AtuServicio – Proyecto de Datos Abiertos con DATA

Hacia un estado más cercano

AGESICVolvió a tomar la palabra Virginia Pardo de AGESIC, comentando sobre las líneas de acción 2011-2015, normativas y buenas prácticas, tecnología y apropiación y fomento de uso. Comentó los hitos de AGESIC en la agenda de Gobierno Abierto y entre hackatones, proyectos y varios éxitos más, anoté que hoy en día hay 4 medios de prensa que trabajan con datos abiertos. AGESIC ya tuvo talleres de periodismo orientado a Datos Abiertos con investigación. Una lástima que la prensa uruguaya no sea participante más activa de este tipo de iniciativas.

Sesiones de trabajo

Tras las charlas se hizo un breve corte para tomar café y empezar las sesiones de trabajo en grupos. Hubo una separación en cuatro grupos para enfrentar temas distintos: Regulación y normativa, Reuso, Salud y Medio Ambiente. Ahí nos separamos en los 4 grupos con facilitadores y se discutieron ideas entorno a cada tema. Mañana se seguirá trabajando en los distintos temas y habrán conclusiones y más notas después. Ya les contaré qué tal al finalizar el evento.

» Leer más, comentarios, etc...

El blog de Adrián Arroyo

Crea tu propio lenguaje de programación

May 12, 2015 10:00 PM

Esta entrada la escribí en DesdeLinux hace ya un tiempo y la quiero conservar aquí. La entrada no es la original sino que la he modificado para que siga vigente - MAYO DE 2015

Lenguajes de programación

Después de escribir el primer artículo sobre cómo crear tu propio sistema operativo, alguien me dijo que si podía hacer un artículo sobre cómo crear un lenguaje de programación. Al principio no hice mucho caso, pero ahora y por otros caminos he aprendido bastante más sobre la creación de los lenguajes de programación. Así pues, vamos a hacer un lenguaje de programación básico, fácilmente empotrable en otros programas y que funcione con una máquina virtual que también diseñaremos. Hoy nos toca hacer la máquina virtual más básica.

Probablemente te preguntes: “¿una máquina virtual? ¿Pero eso no es muy difícil y además ralentiza los programas?” Al contrario, una máquina virtual simple es muy sencilla y relativamente rápida. He elegido Rust como lenguaje para la máquina virtual. Pero, ¿qué es Rust?

Rust es un lenguaje de programación que está enfocado en la seguridad en las ejecuciones, así que utilizándolo será prácticamente imposible que alguien consiga cerrar la máquina virtual. Es un lenguaje compilado en desarrollo creado por Mozilla. Servo, el sustituto de Gecko, se está desarrollando en él. Todavía puede cambiar su sintaxis pero el código que voy a usar va a mantenerse hasta la primera versión estable.

Rust se instala en Linux de manera sencilla. Antes se podía usar un PPA pero ahora el script de RustUp es muy bueno y se encarga de todo.

curl -s https://static.rust-lang.org/rustup.sh | sudo sh

###¿Cómo funciona una máquina virtual?

Si sabes como funciona el mundo en ensamblador es exactamente igual, con el stack o la pila. Si no, te lo explico. Imaginémonos el siguiente código:

print 2+3

El ordenador no entiende lo que significa 2+3, ni tampoco sabe qué orden hay que seguir. Los ordenadores funcionan con pilas o stacks en los que se van acumulando datos y se van sacando continuamente. Ese código en nuestra máquina virtual debería ser algo parecido a esto:

PUSH 2
PUSH 3
ADD
PRINT

Básicamente, pondríamos el 2 en la pila en lo alto, el 3 también. ADD sacaría (es decir, lo elimina de la pila y obtiene su valor) los 2 últimos elementos de la pila y añadiría el resultado en lo alto de la pila. PRINT cogería el último elemento de la pila y lo usaría para mostrárnoslo. Ahora hagamos eso en Rust.

Ahora es cuando deberías descargarte el código fuente que está en GitHub. Voy a empezar por el archivo vm.rs

Primeramente deberemos definir un lenguaje para el Bytecode, podríamos usar uno ya existente como el de Java o el CLR de .NET/Mono, pero vamos a crear nosotros uno más básico.

Usamos notación hexadecimal para cada instrucción. Para hacer la traducción entre el código hexadecimal y la instrucción voy a usar la librería (crate en el argot de Rust) de enum_primitive. Antes se podía usar #[derive(FromPrimitive)] pero en Rust 1.0 no está disponible.

Ahora debemos hacer una función que ejecute cada una de esas instrucciones. Para ello debemos leer un byte y compararlo con las instrucciones que tenemos en la enumeración. Si se encuentra alguna que exista se debe ejecutar su acción.

Eso hacemos para leer cada byte individualmente y para ejecutarlas:

Como ven, diferenciamos si antes se nos dio la orden de PUSH (nuestra orden INTEGER), el siguiente byte será llevado completamente a la pila. Ahí estamos usando dos funciones que no les he enseñado, self.pop() y self.push(), que se encargan obviamente de manejar el stack.

No son muy complejas, pero la función de pop tiene mecanismos de detección de errores. De hecho, en Rust, si quitásemos esos mecanismos nos daría un error de compilación. Ahora simplemente debemos llamar en un programa a Perin (nuestra máquina virtual) y que ejecute un bytecode.

Ese bytecode puede ser leído de un fichero, pero aquí para simplificar lo he almacenado en una variable. Si lo ejecutamos nos dará el resultado esperado:

Perin v0.1
Perin VM executes FlopFlip bytecode
Starting PerinVM instance
PerinVM v0.1.0
Integer value 5

Todo el código está disponible en GitHub bajo la Apache License 2.0: https://github.com/AdrianArroyoCalle/perin. Para compilar deben tener Cargo instalado y poner:

cargo run

» Leer más, comentarios, etc...

Arragonán

Semanas 360 y 361

May 12, 2015 01:49 PM

Vuelta a acumular semanas sin resumen, que la anterior ya cuando me planté a mitad decidí dejarlo para esta.

Durante estas dos semanas en SenpaiDevs tuvimos visitas de José Luis Lizano y Guillermo Latorre que nos hablaron de diseño y maquetación, también se vino Francho Joven a hablar de Rails y de cómo trabaja él. Además presentamos por fin el proyecto en el que veníamos trabajando con los kohais, un calendario de eventos tecnológicos en Zaragoza.

El pasado jueves tuvimos reunión mensual de Zaragoza.rb (la de abril que traíamos retrasada por el festivo del 1 de mayo), en la que hablamos a modo de comparativa de Middleman y Jekyll.

Estas semanas han llegado bastantes contactos para posibles nuevos proyectos, veremos si se van concretando o van cayéndose.

En cuanto a los actuales:

  • Retomando Bichomanía acabé con la importación de productos y sus respectivas imágenes, y me encontré con un problema con la codificación de caracteres que aún está a medio solucionar. También empecé a trabajar en la compatibilidad de las urls de la actual tienda para no romper los enlaces existentes.
  • Dejé ya casi cerrado One-step. Implementé una gestión de informes, finiquité la parte del frontend y estuve resolviendo un problema de integración. Ahora queda ver las cuestiones de despliegue y poco más.
  • Tuvimos un primer contacto para una posible colaboración de Minchador con otra compañía, veremos si llegamos a un acuerdo.
  • En Mosica nos dio por montar un grupo de telegram para ir a conciertos y estuve haciendo alguna mejora en la versión móvil. Además por fin tenemos publicadas las aplicaciones móviles en la app store y en play.

Buena semana.

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 198

May 11, 2015 08:52 PM

Enlaces interesantesAhí van los enlaces recopilados durante la semana pasada, espero que os resulten interesantes :-)

.Net

ASP.NET

Azure / Cloud

Data access

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Otros

Publicado en Variable not found

» Leer más, comentarios, etc...

Picando Código

Del Dicho al Hecho – ¿Cuánto cumplen los políticos de su discurso?

May 11, 2015 06:35 PM

En Uruguay terminó ayer domingo el período de elecciones 2014-2015 que pareció durar siglos. Durante este tiempo, mucha gente se pone la camiseta de su partido político cual cuadro de fútbol, para después de elegido el gobierno de turno se olvide que existe la política hasta las siguientes elecciones.

En los medios hay que escuchar peleas, discusiones, demagogia, y ante todo promesas, muchas promesas de los candidatos. Y así como la gente se olvida de su bandera y la camiseta de su partido por unos años, también se olvida de lo que hizo y prometió cada candidato. Pero la Tecnología Cívica llega al rescate.

Del Dicho al Hecho

En Chile, a la gente de Fundación Ciudadano Inteligente (Fundación Ciudadano Inteligente – Quiénes son, y por qué Google les donó 1/4 millón de dólares ), creó Del Dicho Al Hecho: proyecto que fiscaliza el cumplimiento de las promesas del Programa de Gobierno. En su momento escribí al respecto en el blog, y ahora contamos con una nueva instancia de la aplicación en Uruguay de la mano de UYCheck:

Del Dicho al HechoDel Dicho al Hecho es una plataforma dedicada al monitoreo del cumplimiento de las propuestas electorales realizadas por los Intendentes más populares de nuestro país. Con una metodología específica (http://bit.ly/1HcxoLR), se genera un esquema de puntuaciones para un conjunto de propuestas seleccionadas relacionadas básicamente a algunos de los cometidos más destacados de los gobiernos departamentales.

Esta plataforma surge a partir de su homónimo chileno desarrollado por la Fundación Ciudadano Inteligente. Con el apoyo y mentoría de esta fundación, y en contexto de Elecciones Departamentales, el equipo de UYCheck se embarcó en la ardua tarea de darle forma y contenido a Del Dicho al Hecho Uruguay.

La búsqueda de la transparencia en las gestiones gubernamentales, el acceso a la información pública y el empoderamiento de la ciudadanía son los grandes objetivos de esta nueva herramienta.

Dado el amplio y complejo universo de candidatos y programas de gobierno que fueron presentados en estas elecciones departamentales, el estudio de Del Dicho al Hecho se centra en los intendentes más votados de cada partido político, así como en 4 áreas de propuestas: obras, higiene y medio ambiente, calles y tránsito, y desarrollo departamental. Cada 6 meses se presentará un avance sobre el estado de situación del cumplimiento  estas propuestas.

El sitio está disponible para los siguientes departamentos:

Este tipo de proyectos es genial y cuantos más proyectos de este estilo, mejor. Por un lado le devuelven poder a la ciudadanía de controlar a los gobernantes. Por otro lado, es un proyecto de colaboración entre grupos de países latinoamericanos y basado en Software Libre. El código está disponible en GitHub bajo licencia GPLv3.

Va a ser muy interesante poder ir viendo el avance (o falta de) respecto a las promesas de campaña. Y una vez terminado el período de gobierno, contrastar los resultados y sacar cuentas. Más allá de lo que pensemos de la política partidaria o el sistema electoral, este tipo de iniciativas generan cambios en la dirección correcta.

Felicitaciones a la gente de UYCheck por el proyecto y ojalá tenga mucho éxito y vengan más del estilo.

Ya que estamos con el tema de Tecnología Cívica, les recomiendo la lectura de la siguiente nota
Tecnología Cívica y Datos Abiertos: ¿Una relación evidente?

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti)

Vivaldi Browser

May 09, 2015 10:16 AM

Vivaldi Browser, es un nuevo navegador web gratuito, que se encuentra disponible para Windows, Mac y Linux, desararollado por Vivaldi Technologies, sobre la cual se encuentra en anterior fundador de Opera: Jon Stephenson von Tetzchner. Su objetivo es claro, crear un navegador web idóneo para usuarios avanzados, y para entusiastas del anterior Opera. Como decía, desde su paso a Blink, Opera 15 no tiene nada que ver con sus predecesores de la versión 12 y anteriores, siendo ahora un Chromium con una apariencia ligeramente distinta, pero habiendo perdido por el camino multitud de funciones, que aún no se han reimplementado. Os mencionaba Vivaldi con el anterior una de enlaces, pero creo que merece una cobertura más detallada. De cara a ganar tiempo en el desarrollo, parten de un enfoque revolucionario, toda la interfaz del programa, está desarrollada usando HTML y Javascript, que corre sobre el motor de Blink/Chromium/Chrome. Lo malo [...]

» Leer más, comentarios, etc...

Blog Bitix

Programación de juegos y 3D en Java con jMonkeyEngine

May 09, 2015 08:18 AM

jMonkeyEngine
Java

Erróneamente se sigue pensado que Java es un lenguaje lento en ejecución, en las primeras versiones era cierto pero hoy la realidad es que con las mejoras introducidas en cada versión de Java y la máquina virtual el rendimiento actual es comparable a C y C++. En la programación de juegos y 3D gran parte del proceso de representación gráfica se ha descargado de la CPU a las cada vez más potentes tarjetas gráficas, la potencia de estas GPU son las que determinan la capacidad de proceso gráfico y la calidad gráfica de los juegos.

Java no suele ser considerado como opción para programar videojuegos triple AAA pero ahí está Minecraft uno de los juegos más populares y un ejemplo de que un juego de buena calidad y rendimiento también se puede hacer en Java. Hay algunos otros ejemplos notables como de variados estilos RPG, Puzzle, MOBA, Rogue, RTS, Card MMOG, FPS, Arcade, Platform ,…:

Este es un vídeo del juego PirateHell que tiene una pinta muy buena:

Algunas capturas de imagen de estos juegos, en los enlaces anteriores se pueden encontrar vídeos de algunos de ellos.

Todos estos juegos están programados utilizando el lenguaje de programación Java y la librería jMonkeyEngine que facilita las tareas de programación de videojuegos proporcionando programación gráfica en 3D usando OpenGL, manejo de eventos de entrada como teclado o ratón, manejo de sonido, pantallas de menús o red. Usando jMonkeyEngine se pueden hacer cosas muy interesantes como se ve en los ejemplos. En el siguiente enlace se pueden encontrar el código fuente de varios ejemplos que podemos probar.

A continuación mostraré el código y unas capturas de pantalla de algunas las posibilidades de jMonkeyEngine. Primeramente veamos como crear un ejemplo básico con un cubo aplicándole una textura con el que veremos como crear una escena. El segundo ejemplo aplica texturas de diferentes formas que varían la visualización de un elemento geométrico.

<noscript><pre>https://gist.githubusercontent.com/picodotdev//raw/HolaMundoJMonkeyEngine.java</pre></noscript>
<noscript><pre>https://gist.githubusercontent.com/picodotdev//raw/Materiales.java</pre></noscript>

Se pueden crear objetos con texturas transparentes, efectos de luz, ray casting, sistemas de partículas con las que simular fuego, chispas, polvo, establecer animaciones a objetos como cuando un personaje está descansando, terrenos, paisajes, aplicar efectos simulando la física del mundo real, sonido ambiental y posicional y más cosas. En las siguientes imágenes se pueden ver algunos ejemplos de las anteriores posibilidades (la tasa de fps normal es de 60, al tomar las capturas baja).

Un videojuego se compone de múltiples recursos como imágenes, modelos 3D, música, sprites, texturas, fuentes de texto, sonidos, iconos… en la página Open Game Art podemos encontrar todo este tipo de material sin necesidad de tener que crearlo desde la nada.

jMonkeyEngine ofrece un entorno de desarrollo (IDE) basado NetBeans. Descargando el paquete de jMonkeyEngine y copiando las librerías .jar los programas se puede ejecutar perfectamente independientemente del IDE y desarrollar con eclipse y usar la herramienta de construcción gradle.

Para instalar jMonkeyEngine debemos descargar el SDK adecuado para la plataforma que usemos ya sea Windows, Linux o Macintosh. En el caso de Linux es un archivo .sh que deberemos ejecutar (dando permisos de ejecución si es necesario), seguimos las instrucciones y seleccionamos el directorio de instalación del SDK. En jmonkeyplatform/libs de la carpeta de instalación encontramos los archivos .jar que deberemos usar en el IDE o en los programas de los ejemplos.

El libro jMonkeyEngine 3.0 Beginners Guide me ha resultado muy interesante como punto de introducción a la programación gráfica 3D con Java, pero también si realmente nos interesa la programación de videojuegos es muy recomendable leer el material ofrecido en el Curso de Experto en Desarrollo de Videojuegos, un libro de una extensión de más de 1100 páginas de muy buena calidad, en español y descargables gratuitamente. En la wiki de jMonkeyEngine se pueden encontrar numerosos tutoriales para principiantes, también numerosos artículos de nivel más avanzado y el javadoc de la API.

Otras librerías como Slick2D permiten hacer videojuegos en 2D como serían los juegos de plataformas, más o menos lo que permite jMonkeyEngine en el 3D aplicado a 2D también usando como lenguaje Java. Sin duda los videojuegos han sido el motivo en parte de que muchos hoy seamos programadores e informáticos aunque en nuestro trabajo nos dediquemos a otro tipo de aplicaciones y entornos.

Que, ¿aún crees que en Java no se pueden hacer juegos que no tienen que envidiar a muchos otros?

Referencia:
jMonkeyEngine
Curso Experto Desarrollo Videojuegos
Libro jMonkeyEngine 3.0 Beginners Guide
Slick2D
libGDX

» Leer más, comentarios, etc...

xailer.info

Xailer 4.0.1

May 08, 2015 12:37 PM

Estimados usuarios de Xailer,

Tenemos el placer de anunciaros una nueva versión de Xailer que incluye un montón de novedades y mejoras, a destacar las siguientes:

  • IDE:
    • TTreeView: Error al guardar los treeviewitems en los .xfm
    • User controls: Mejorados mensajes de error
    • SQLite editor: Posibilidad de salvar los registros a visualizar
    • Incluida libreria iphlpapi en configuración de MinGW

     

  • DataControls
    • TSQLite: Cambiado en CreateTable() el tipo “M” de “MEMO” a “MEMOTEXT”
    • TWebDataSource: Error en busqueda de clave primaria por no usar acentos delimitando el nombre de tabla
    • TDbfdataset: Soporte de lAutoSeek en datasets DBF
    • TDataSource: Nuevo evento OnExecute( oSender, cSql )

     

  • Controles
    • TLabelEx: Error en cálculo de posición de enlaces
    • TOcx: Pasar los parametros VT_DISPATCH como objetos TOleAuto en los eventos
    • TOcx: Error con fechas en blanco
    • TLabelEx: Error en recepción de foco
    • TRichedit: Nuevas propiedades lRE70, lRE80 y nUlineColor
    • TCombobox: Al cambiar el foco durante un OnExit, no se restauraba el foco correctamente
    • TDateEdit: Soporte de mouse wheel en edicion que permite scroll de dias, meses o años
    • TPicture: Perdida de memoria cuando se cargaba una imagen con gdi+

     

  • Clases
    • TApplication: Mejora con lSingleInstance para que active la instancia existente

     

  • Fast-Report
    • TFastReport: Error en llamada a funcion LOADIMAGEFROMHBVAR
    • TFastReport: Correcion menor para tipos BLOB que fallaban a partir de Harbour 4

Os recordamos que para poder usar esta nueva versión hay que tener una suscripción activa de Xailer y que exige realizar de nuevo el registro de todas sus instalaciones. Todos los usuarios con suscripción activa deben haber recibido un E-mail con la nueva información de registro, pero en cualquier caso puede volver hacer el registro directamente desde la opción de menú Ayuda-Registrar el producto.

En caso de no tener una suscripción activa sólo podrá utilizar Xailer 4 en modo DEMO y por lo tanto deberá instalarla en un distinto directorio.

Un saludo

[El equipo de Xailer]

» Leer más, comentarios, etc...

xailer.info

Cancún Junio 2015

May 08, 2015 11:12 AM

Estimados usuarios de Xailer,

Más o menos cada dos años , tengo el placer de poder reunirme en la ciudad de Cancún con una importante comunidad de usuarios de Xailer, que mayoritariamente provienen del propio Mexico, pero también acuden normalmente colegas de Brasil, República Dominicana y Venezuela, entre otros.  Espero que está vez podamos contar con más colegas de distintos países. A los españoles es difícil de mover ya que hay que cruzar el charco, pero es que además tiene más fácil acceder al equipo de Xailer ya que de forma periódica se organizan reuniones como lo que acaba de producirse en Madrid hace muy poco tiempo.

En cada reunión intento presentar algo especial de Xailer que entiendo puede interesar a los programadores de Xailer que ya tienen cierta experiencia. Esta vez quiero centrarme básicamente en la migración a sistemas SQL, desarrollo de aplicaciones en la nube e integración con herramientas CRM. No obstante, aprovecharemos la ocasión para ver todas las mejoras que incluye Xailer 4. Intentaremos evitar profundizar demasiado en las características del lenguaje SQL ya que entendemos que es algo que posiblemente muchos usuarios ya conocerán, pero si mostraremos la potente herramienta que incluye Xailer 4 para diseñar visualmente las consultas SQL.

Voy a intentar exponer a continuación las directrices del temario que seguiremos en el curso:

  • Novedades de Xailer 4
  • Introducción a Sqlite, MariaDB y MySQL
  • Instalación de servidores locales XAMP (Apache, MySQL, PHP)
  • Uso de servidores externos proporcionados por ISPs. Ventajas e inconvenientes
  • Migración a SQL desde DBF: diferencias entre ambos sistemas, haciendo hincapié en bloqueos, transacciones, índices, grandes tablas, campos BLOB, tipos de datos y uso de claves primarias
  • Conversión de tablas DBF a SQL: Consideraciones, herramientas de Xailer 4
  • Cuando usar SQLite y cuando usar MariaDB/MySql
  • Datasets en memoria: Ventajas e inconvenientes
  • TWebdatasource: ventajas e inconvenientes. Cuando usarlo
  • Uso de modelo vista-controlador
  • Base de datos en la nube: ventajas e inconvenientes
  • Bases de datos locales: sincronización y  propagación hacia servidores en la nube
  • Introducción a CRM Prestashop
  • Protocolo REST: introducción y uso básico
  • Datasource para Prestashop
  • Acceso directo al protocolo REST de Prestashop
  • Recepción de eventos de Prestashop con programación multi-hilo

A todos los asistentes se les entregará una licencia del nuevo datasource para Prestashop que se pondrá en venta inmediatamente después del evento a un precio de 150 euros.

Y eso es todo. Espero que el curso sea de vuestro interés. Si tenéis alguna sugerencia me encantará leerla. Os ruego utilicéis los comentarios para ello.

¡Hasta pronto!

 

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti)

Opera no muestra imágenes de Tinypic

May 05, 2015 04:16 PM

Muchos ya os habréis dado cuenta que los magníficos navegadores web Opera, basados en el antiguo motor Presto, no visualizan bien las imágenes de TinyPic desde hace unas semanas, cosa que antes no daba ningún problema. El problema se aplica a Opera 12.x y anteriores, así como a Opera Mini, y está causado por un problema en la última actualización de TinyPic, que intencionadamente o no, esconde las imágenes a navegadores basados en Presto, de modo que al final, estas no se visualizan. La solución que he creado, se basa en user.js que ha creado Drozdman de Informatics Stuff, pero que por varios motivos no me gustaba por los siguientes motivos: 1) Dependía de jQuery, que lo hace más lento y pesado. 2) No comprobaba posibles condiciones de error. 3) Era demasiado lento al usar innecesariamente expresiones regulares de búsqueda y reemplazo. De ese modo he creado mi propia adaptación, [...]

» Leer más, comentarios, etc...

Picando Código

Usando Por Mi Barrio

May 05, 2015 04:02 PM

Ya he escrito antes de Por Mi Barrio, una aplicación adaptada a Montevideo por DATA que pone al alcance de un clic el poder de hacer un reclamo directo a la Intendencia de Montevideo:

Por Mi Barrio, una plataforma que permite a las personas que viven en Montevideo enviar reportes sobre daños, desperfectos, vandalismo y otros problemas de nuestra ciudad desde su computadora o celular.

Por Mi Barrio se conecta al Sistema Único de Reclamos de la IM, por lo que se asegura que los reportes denunciados van a llegar a la división correspondiente de la comuna y permite recibir notificaciones sobre respuestas de la IM.

Hace un tiempo ingresé un reporte y la experiencia de usar la aplicación es genial. Andando en bicicleta por las calles de Montevideo detecté que hay un semáforo muy difícil de ver yendo por Bvar. España hacia el centro.  Así que decidí estrenar mi usuario en Por Mi Barrio ingresando un reporte.

Reporte en Por Mi Barrio

Para dar de alta el reporte, simplemente di clic en el lugar del mapa donde se encuentra el problema, lo categoricé y agregué una breve descripción. El asunto fue ingresado al sistema de la Intendencia y ya puedo comprobar que hubo dos inspecciones: de Téc. Jardinero e Ing. agrónomo.

Di de alta el problema en febrero, y todavía no ha sido resuelto. Está el tema de la burocracia de enviar dos inspectores distintos a comprobar que el problema existe (el 23 de marzo fue la primera inspección y el 30 de abril la segunda). Pero todos sabemos que los entes gubernamentales son monstruos burocráticos gigantes y difícilmente se caractericen por ser eficientes.

Lo importante es que tenemos una forma muy sencilla de hacer algo al respecto con los problemas de nuestros barrios, en vez de salir a llorar indignados en las redes sociales que hay un pozo sin arreglar en la calle de enfrente. Así que aprovechémoslo. El sistema implementado por DATA no sólo nos da ese poder, sino que brinda transparencia al proceso de trabajo de la Intendencia respecto a los reportes ingresados.

Una parte nueva y sumamente jugosa de la aplicación son las estadísticas. Ahí podemos ver varias gráficas que muestran la cantidad de reportes ingresados, en progreso y resueltos desglosado en las distintas categorías. Podemos por ejemplo detectar qué área de la intendencia es más/menos eficiente con los reportes ingresados por este sistema. Los datos son abiertos y se pueden descargar para estudiarlos o crear nuevas aplicaciones en base a ellos.

Por Mi Barrio - Estadísticas

Por Mi Barrio está basado en FixMyStreet, una aplicación de My Society que puede ser adaptada a otras ciudades. Así que si querés podés llevarlo a tu ciudad con un poco de trabajo. Y si vivís en Montevideo, evitá el llanto fácil en las redes sociales o la queja de bar cuando ves que algo está roto, sucio, o en falta en tu barrio. Usá Por Mi Barrio.

Pueden mantenerse al tanto de las noticias de DATA en su sitio web o su cuenta de Twitter.

» Leer más, comentarios, etc...

Navegapolis

Agilidad para incautos

May 05, 2015 08:32 AM

vendidoLos "CMMI's" cada vez se llevan menos. Tras 20 años de ayudar a las empresas de programación, no se sabe si a mejorar el software, o a licitar con ventaja en los concursos públicos, han perdido fuelle y terreno frente a la agilidad.

Así que ahora le toca al negocio de la consultoría renovarse, porque el asesorar con "CMMI's" se vende cada vez peor, y la agilidad es sin duda la nueva tendencia. Lo malo es que algunos, o bien no entienden lo que venden, o sólo les preocupa hacer el dibujo de un marco lo suficientemente creíble para engatusar a los clientes que se conforman con aparentar e ir a la moda.

 

agile for phbs

 

Así que van a convertir a la agilidad en otro modelo de procesos, porque gracias a su capacidad de marketing, van a ser muchas las empresas a las que les van a enseñar cómo deben organizar a los equipos autoorganizados, o a las que convencerán de que Scrum tan sólo es un ciclo iterativo que pueden implementar sin dejar de "embau-contratar" con clientes y administraciones como hasta ahora, porque su marco ágil funciona sin esa bobada de la colaboración estrecha entre cliente y desarrolladores, que sólo serviría para destapar información inconveniente, como que le están facturando 7 "recursos senior" y en su proyecto sólo hay dos becarios desmotivados.

Y de cosas como la autonomía y "empowerment" de los equipos, cultura ágil de la organización... mejor ni hablar.

 

» Leer más, comentarios, etc...

Variable not found

Interpolación de cadenas en C# 6, a fondo

May 05, 2015 06:50 AM

C# 6Ya jugando con Visual Studio 2015 y C# 6, estoy comprobando que la interpolación de cadenas es una de las características más interesantes y prácticas de las novedades que presentará la nueva versión del lenguaje, porque no son pocas las ocasiones en las que creamos expresiones concatenando literales de cadena y variables, o que hacemos uso de String.Format() para construir strings más complejos.

Hace unos meses ya adelantamos por aquí sus principales características, aunque aún era algo pronto para poder probar en profundidad esta nueva y esperada feature. Ahora, más avanzado ya su desarrollo, ha llegado el momento de echarle otro vistazo más en profundidad y ver cómo queda finalmente (o casi finalmente, todavía podría cambiar algo!).

En este post vamos a ver rápidamente los puntos principales a tener en cuenta para dominar esta nueva característica que sin duda facilitará nuestro trabajo y nos hará más productivos.

1. Interpolación de cadenas a vista de pájaro

Consiste en introducir valores de variables o expresiones en el interior de cadenas de texto sin usar los tradicionales mecanismos, molestos y propensos a errores, como la concatenación o el formateo con String.Format().

Y como un poco de código vale más que mil palabras, he ahí un ejemplo que creo ilustra bastante bien de qué estamos hablando:

Interpolated strings at a glance

Las cadenas interpoladas comienzan con el prefijo “$”, y pueden aparecer en los mismos lugares que una cadena de caracteres tradicional. Es decir, donde siempre hemos podido introducir una cadena de texto, podremos introducir ahora la nueva construcción $"something".

2. Parámetros en cadenas interpoladas

Cuando el compilador de C# encuentra una cadena precedida por el símbolo “$” entenderá que es una cadena con interpolación, y creará el string resultante sustituyendo las expresiones contenidas entre llaves por su valor evaluado en el ámbito local.

Por ejemplo, en la siguiente porción de código se muestra el uso correcto de la variable local name y de la propiedad estática LastName, mientras que la propiedad age no puede referenciarse desde el método estático Main() por ser un miembro de instancia:

Interpolation parameters must be in scope

Si queremos introducir los caracteres de apertura o cierre de llaves en alguna de estas cadenas, debemos escaparlos introduciéndolos dos veces consecutivas:

Curly braces must be scaped

3. Intellisense, refactorings y errores en compilación

Visual Studio nos ayudará durante la codificación de estas cadenas gracias al soporte completo de intellisense en el interior de las expresiones interpoladas:

Intellisense in string interpolation

También estos parámetros en el interior de las cadenas de texto serán sensibles a refactorizaciones. Por ejemplo, si en el código anterior renombramos la variable name a fullName, el nuevo nombre será introducido también automáticamente en el interior de la cadena:

Interpolated string parameters support refactorings
Y por supuesto, cualquier error a la hora de codificar las expresiones se nos notificará en tiempo de compilación, evitando así problemas posteriores, e incluso Visual Studio nos propondrá posibles soluciones para corregirlo:

Compilation errors in string interpolation

4. Expresiones como parámetros

Aunque la forma habitual de uso será probablemente utilizar directamente variables o propiedades como parámetros en las cadenas interpoladas, en realidad entre la apertura y cierre de las llaves podemos poner cualquier expresión que evalúe a object. En la práctica, cualquier expresión no void valdrá:

Expressions in string interpolation

Por supuesto, podemos incluir todo tipo de expresiones, aunque a veces será necesario el uso de paréntesis:

Complex parameters in interpolated strings

La única condición es que la expresión sea válida y compilable en el punto exacto en el que se produce la interpolación. Si la expresión contiene términos definidos en espacios de nombre distintos al actual, o bien se cualifican por completo o bien se insertan los using necesarios en el archivo de código fuente en el que se encuentra la expresión.

5. Los parámetros pueden ser formateados

Al igual que ocurre en el clásico String.Format(), podemos incluir información de formato en los parámetros que incluimos en las cadenas interpoladas con una sintaxis bastante predecible: simplemente, tras la expresión a evaluar, incluimos el carácter dos puntos “:” y a continuación la cadena de formato que especifica cómo debe presentarse la información.

Las cadenas de formato son las estándar en .NET, las que hemos usado toda la vida en String.Format(). Veamos unos ejemplos:

Standard formatting strings

Opcionalmente podemos indicar también el número de caracteres del resultado insertando antes de la especificación el número separado por una coma, y la alineación del contenido (derecha positivo, izquierda negativo):

Formatting and padding in C# string interpolation

6. Los parámetros pueden ser objetos IFormattable

Si parámetros introducidos en una cadena interpolada son objetos IFormattable, se invocará a su método ToString() para que sea él mismo el que se formatee:

Interpolated strings with IFormattable parameters

7. La cultura por defecto es la del hilo actual

Si vamos a utilizar formateo, este detalle es importante: la cultura aplicable será la activa en el hilo de ejecución actual.

String interpolation culture in C#

Esto tiene bastante sentido porque este comportamiento es consistente con su equivalente utilizando String.Format().

8. Las cadenas interpoladas actúan como strings

En los ejemplos que hemos visto hasta ahora, las cadenas interpoladas eran meros sustitutos de un string clásico. El compilador de C# detecta este escenario y durante el proceso de compilación son transformadas en una llamada al método string.Format() como podemos observar en el siguiente código:

Interpolated strings are just strings

Por cierto, si queréis ver cómo funciona esta transformación por dentro, podéis hacer pruebas en la dirección http://tryroslyn.azurewebsites.net/, un sitio web powered by Roslyn en el que podréis introducir código C# 6.0 y ver el resultado descompilado. Muy interesante y recomendable :)

9. Las cadenas interpoladas también actúan como objetos IFormattable

Si el compilador detecta que estamos usando una cadena interpolada en lugar de un objeto IFormattable, actuará de forma ligeramente diferente, lo que nos da alguna ventaja si queremos intervenir en el proceso de formateo de estas cadenas.

Fijaos en este código, donde pasamos la cadena interpolada a una función cuyo parámetro se espera que sea IFormattable:

Interpolated strings as IFormattable objects

En este caso, el código equivalente generado por Roslyn será el siguiente. Se puede observar que no ha sido transformado en una llamada a String.Format() sino en una invocación a FormattableStringFactory.Create(), que construirá el objeto IFormattable que espera la función ToUpper() vista anteriormente.

Interpolated strings as IFormattable objects

¿Y por qué es interesante esto? Pues porque esta técnica nos permite crear formateadores personalizados de forma relativamente sencilla.

Por ejemplo, podemos usar esta capacidad para crear funciones que nos ayuden a formatear una cadena en una cultura determinada. El siguiente código, un clásico entre los ejemplos de uso de esta característica, muestra cómo podemos usar una función para formatear usando cultura invariante:

Format using invariant culture

Otros ejemplos muy ingeniosos que he visto consisten en utilizar esta característica para construir cadenas que requieren un tratamiento especial, como puede ser la construcción de una URL, o incluso una sentencia SQL. En ambos casos es interesante “retocar” el proceso de formateo de parámetros, en el primer caso para introducir codificación, y en el segundo para evitar efectos no deseados como inyecciones de script. No dejéis de echar un vistazo al blog de Thomas Levesque para verlos.

10. ¡Soporte para Heredoc!

En el primer vistazo que dimos a la interpolación de cadenas en C# 6 ya comenté que no había visto soporte para Heredoc o cadenas verbatim, un escenario en el que esta característica tenía mucha aplicación. Bien, pues esto parece que por fin ha cambiado, y ahora sí que podemos ya implementar cadenas interpoladas con múltiples líneas de texto.

Simplemente tenemos que insertar el carácter $ que caracteriza a las cadenas interpoladas justo antes de la arroba @ que indica el comienzo de la cadena verbatim:

Heredoc & interpolated strings

11. Sólo es syntactic sugar, aplicable en tiempo de compilación

Es importante tener en cuenta que esta característica es principalmente lo que solemos denominar syntactic sugar, es decir, una ayuda sintáctica destinada a endulzar la vida del desarrollador, por lo que se resuelve en tiempo de compilación, antes de ejecutar la aplicación.

No existe, por tanto, ningún tipo de penalización del rendimiento en runtime por usar esta técnica más allá del que encontraríamos al utilizar String.Format().

12. ¿Uso en versiones del framework anteriores a la 4.6?

Si usamos cadenas interpoladas como puros string, comentado en el punto 8 de este post, no tendremos problemas en usar esta característica. Es decir, podremos compilar sin problema nuestra aplicación usando C# 6 aunque el target del proyecto sea un .NET framework anterior al 4.6 y todo funcionará bien.

Sin embargo, sí tendremos problemas cuando tratamos cadenas interpoladas como IFormattable, y la explicación la tenéis un poco más atrás, en un sutil detalle que hemos deslizado cuando hablábamos del tratamiento de cadenas interpoladas como objetos IFormattable. Como decíamos, éstas se transformaban en una llamada a FormattableStringFactory.Create(), lo que obviamente implica que el compilador está asumiendo que esta clase existe, cuando en realidad esto no es así en las versiones anteriores a la 4.6 del framework.

En estos casos, la solución consiste únicamente en crear en el proyecto actual las clases FormattableStringFactory y FormattableString, cuyo código fuente podemos obtener desde Github mediante los enlaces anteriores. Y para los perezosos, existe un paquete Nuget (no oficial) que lo hace, y que podemos instalar así:

PM> Install-Package StringInterpolationBridge

Bueno, y es todo, creo ;) Espero que esta revisión en profundidad de la interpolación de cadenas os sea útil para conocer un poco mejor en qué consisten y cómo podrán ayudarnos en nuestro día a día cuando comencemos a trabajar con C# 6.

Publicado en Variable not found.

» Leer más, comentarios, etc...

Meta-Info

¿Que es?

Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.

rss subscripción

Sponsors

Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
planetacodigo

planetacodigo

Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

Idea: Juanjo Navarro

Diseño: Albin