Noticias Weblogs Código

Blog Bitix

Fechas y usos horarios en Java

January 31, 2015 10:32 AM

Java

Aunque en muchas aplicaciones no será necesario si desarrollamos una aplicación que trabaje con diferentes paises y fechas probablemente deberemos tener en cuenta múltiples usos horarios o zonas horarias. Según estos usos horarios, por ejemplo, en el momento que son las 12:00 en Madrid hora local no son las 12:00 en Buenos Aires, si dos ciudades emplean diferente uso horario hay que tenerlo en cuenta para obtener la hora local en cada ciudad.

Hasta la versión 7 de Java el trabajo con fechas era complicado con las clases proporcionadas GregorianCalendar y Date, una alternativa a la API de Java para el manejo de fechas hasta esta versión era emplear la librería JodaTime. JodaTime ofrece una API mejor y más completa para el manejo de fechas hasta la versión de Java 7. Con la nueva API para fechas de Java 8, entre otras novedades incluídas, la situación ha mejorado pero hasta que tengamos oportunidad de usar esta versión puede que pase bastante tiempo y sigamos obligados a usar JodaTime si tenemos posibilidad de usar esta librería o usar directamente la API de Java 7 si no podemos.

Otro aspecto que debemos tener en cuenta en una aplicación es en que uso horario vamos a guardar las fechas en la base de datos, para simplificar lo recomendable es guardar siempre las fechas en el mismo uso horario. Podemos elegir cualquier uso horario quizá la local del lugar donde estamos o una mas genérica como UTC.

Podemos convertir la fecha de un uso horario a otro uso horario con el siguiente código ya sea usando JodaTime, Java 7 o Java 8, ¿si en Madrid (España) son las 12:00 que hora sería en ese momento en Buenos Aires (Argentina)?:

<noscript><pre><code>package io.github.picodotdev.timezone; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.TimeZone; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; public class Main { public static void main(String[] args) { // JodaTime { DateTime fecha = new DateTime(2015, 1, 31, 12, 00, DateTimeZone.forID(&quot;Europe/Madrid&quot;)); System.out.println(&quot;JodaTime&quot;); System.out.printf(&quot;Hora Madrid:\t\t %s\n&quot;, fecha); System.out.printf(&quot;Hora Buenos Aires:\t %s\n&quot;, fecha.withZone(DateTimeZone.forID(&quot;America/Argentina/Buenos_Aires&quot;))); } // Java 8 { ZonedDateTime fecha = ZonedDateTime.of(2015, 1, 31, 12, 00, 00, 00, ZoneId.of(&quot;Europe/Madrid&quot;)); System.out.println(&quot;\nJoda 8&quot;); System.out.printf(&quot;Hora Madrid:\t\t %s\n&quot;, fecha); System.out.printf(&quot;Hora Buenos Aires:\t %s\n&quot;, fecha.withZoneSameInstant(ZoneId.of(&quot;America/Argentina/Buenos_Aires&quot;))); } // Java 7 { Calendar calendar = new GregorianCalendar(); calendar.set(2015, 0, 31, 12, 0, 0); SimpleDateFormat sdfMadrid = new SimpleDateFormat(&quot;yyyy-MM-dd'T'HH:mm:ssXXX&quot;); sdfMadrid.setTimeZone(TimeZone.getTimeZone(&quot;Europe/Madrid&quot;)); SimpleDateFormat sdfArgentina = new SimpleDateFormat(&quot;yyyy-MM-dd'T'HH:mm:ssXXX&quot;); sdfArgentina.setTimeZone(TimeZone.getTimeZone(&quot;America/Argentina/Buenos_Aires&quot;)); System.out.println(&quot;\nJava 7&quot;); System.out.printf(&quot;Hora Madrid:\t\t %s\n&quot;, sdfMadrid.format(calendar.getTime())); System.out.printf(&quot;Hora Buenos Aires:\t %s\n&quot;, sdfArgentina.format(calendar.getTime())); } } }</code></pre></noscript>
<noscript><pre><code>JodaTime Hora Madrid: 2015-01-31T12:00:00.000+01:00 Hora Buenos Aires: 2015-01-31T08:00:00.000-03:00 Joda 8 Hora Madrid: 2015-01-31T12:00+01:00[Europe/Madrid] Hora Buenos Aires: 2015-01-31T08:00-03:00[America/Argentina/Buenos_Aires] Java 7 Hora Madrid: 2015-01-31T12:00:00+01:00 Hora Buenos Aires: 2015-01-31T08:00:00-03:00</code></pre></noscript>

Java 7 requiere unas pocas líneas de código fuente más y en este caso se hace usando un SimpleDateFormat, en el caso de JodaTime y Java 8 el código es bastante similar.

El uso horario de Madrid es Europe/Madrid y el uso horario de Buenos Aires es America/Argentina/Buenos_Aires en el momento de escribir este artículo Madrid tiene un desplazamiento respecto a UTC de +01:00 y Buenos Aires de +03:00 con lo que entre estas dos ciudades hay una diferencia de cuatro horas en tiempo local. Quizá nos interese conocer el tiempo local actual en una ciudad y con el conversor entre usos horarios podemos comprobar que hemos programado correctamente la conversión en código.

Finalmente, hay que tener en cuenta que los horarios de verano que se establecen en cada país con la intención de ajustar normalmente el horario a las horas de luz y de este modo ahorrar energía. Estos horarios de verano los establece cada país y varían más a menudo de lo que podemos creer, a veces son una cuestión política. En el JDK para actualizar estos horarios de verano debemos actualizar el JDK esperando que Oracle los haya actualizado debidamente o usar la herramienta Timezone Updater Tool. El actualizar el JDK o usar la herramienta Timezone Updater Tool en un servidor para esto puede ser un problema o simplemente es algo que no controlamos como desarrolladores de la aplicación por no estar el servidor bajo nuestro control, esta es otra ventaja de usar JodaTime ya que esta librería como dependencia del proyecto si está bajo nuestro control y podemos ir actualizando la versión de la misma en la que los horarios de verano si están actualizados.

Referencia:
Java 7 Date API
Java 8 Time API
JodaTime
Novedades y nuevas características de Java 8

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

Blog Bitix

Internacionalización (i18n) en Javascript

January 31, 2015 12:00 AM

Javascript

Si desarrollamos una aplicación web, que es usada en múltiples idiomas y el lado del cliente tiene cierta complejidad quizá nos encontremos con la necesidad de proporcionar internacionalización (i18n) para los textos o mensajes mediante una librería javascript. Una de la que más me ha gustado de las que he encontrado ha sido i18next pero hay varias opciones más, incluidas dos que merecen ser nombradas que son polyglot y messageformat, estas tres opciones son parecidas pero no tiene exactamente las mismas funcionalidades deberemos evaluarlas para elegir una según lo que necesitemos.

La documentación de i18next no es muy extensa pero es suficiente, las funcionalidades que ofrece son:

  • Soporte para variables (interpolación)
  • Soporte para variables anidadas
  • Soporte para múltiples formas plurales e indefinidos
  • Soporte sprintf
  • Integración con jquery
  • Búsqueda de locales
  • Obtención de traducciones del servidor
  • Cacheo de recursos en el navegador
  • Algunas otras adicionales

Para mostrar su uso me basaré en el ejemplo Lista de tareas con Backbone y React al que le añadiré el soporte de internacionalización con i18next. Como en el ejemplo uso RequireJS usaré la versión de i18next con soporte para AMD. Una vez descargada y colocada en el directorio de los módulos de RequireJS deberemos añadir la dependencia a los módulos donde la usemos, en el caso del ejemplo en tareas.js. En el ejemplo los textos que se necesitan internacionalizar son el título, el texto que aparece en el input antes de introducir el nombre de una tarea, el número de tareas completadas y el texto del botón limpiar, para mostrar estos textos usaremos la función t de i18next que nos devolverá dada la clave del texto que queremos el valor adecuado según los archivos de literales y el idioma de la aplicación. Todo esto lo hacemos de la siguiente forma:

<noscript><pre><code>i18n.t('Lista_de_tareas')</code></pre></noscript>

Los archivos de literales son poco más que una relación de claves valor similar a los archivos properties de Java aunque en el caso de i18next se definen en archivos y con formato json. En este ejemplo la localización (l10n) que proporcionaré será para español (translation-dev.json, idioma por defecto) y para inglés (translation-en.json). Por cada idioma localizado necesitamos crea un archivo con los literales:

<noscript><pre><code>{ &quot;Lista_de_tareas&quot;: &quot;Lista de tareas&quot;, &quot;COMPLETADAS_tareas_completadas_de_TOTAL&quot;: &quot;__completadas__ tarea completada de __total__&quot;, &quot;COMPLETADAS_tareas_completadas_de_TOTAL_plural&quot;: &quot;__completadas__ tareas completadas de __total__&quot;, &quot;Muy_bien_has_completado_todas_las_tareas&quot;: &quot;¡Muy bien! has completado todas las tareas&quot;, &quot;Limpiar&quot;: &quot;Limpiar&quot;, &quot;Introduce_una_nueva_tarea&quot;: &quot;Introduce una nueva tarea&quot; }</code></pre></noscript>
<noscript><pre><code>{ &quot;Lista_de_tareas&quot;: &quot;Tasks List&quot;, &quot;COMPLETADAS_tareas_completadas_de_TOTAL&quot;: &quot;__completadas__ task completed of __total__&quot;, &quot;COMPLETADAS_tareas_completadas_de_TOTAL_plural&quot;: &quot;__completadas__ tasks completed of __total__&quot;, &quot;Muy_bien_has_completado_todas_las_tareas&quot;: &quot;¡Perfect! You have done all tasks&quot;, &quot;Limpiar&quot;: &quot;Clean&quot;, &quot;Introduce_una_nueva_tarea&quot;: &quot;Type a new task&quot; }</code></pre></noscript>

Los lenguajes tienen diferentes formas plurales, por ejemplo, en español hay dos formas plurales (1 y más de uno) pero dependiendo del número de elementos a los que hagamos referencia y el lenguaje puede variar el número de formas plurales. Si en una aplicación ves las típicas eses entre paréntesis, (s), es porque esa aplicación aunque esté internacionalizada no soporta las múltiples formas plurales de los lenguajes, para un usuario ver esos (s) crea confusión y dificulta la lectura del texto. Si nos encontramos con este caso el literal de la forma plural lo definiríamos y lo obtendríamos de la siguiente forma en el caso del español, el parámetro count se utiliza para determinada la forma plural a utilizar (en el caso de español, singular o plural) y los parámetros completadas y total como parématros del literal usando sus valores en la interpolación en la cadena:

<noscript><pre><code>i18n.t('COMPLETADAS_tareas_completadas_de_TOTAL', { count: 2, completadas: 2, total: 4 });</code></pre></noscript>

Para completar el ejemplo debemos inicializar la librería i18next con la configuración que queramos por lo menos para definir el locale y la disposición de los archivos de literales. Esta configuración en el ejemplo está antes de inicializar el componente de la lista de tareas:

<noscript><pre><code>define(['react', 'tareas', 'i18next'], function(React, tareas, i18n) { i18n.init({ lng: 'en', getAsync: false, resGetPath: 'js/locales/__lng__/__ns__.json' }); ... });</code></pre></noscript>

Cambiando el idioma preferido en el navegador podemos ver los textos de la aplicación según el mismo:

El texto que indica cuantas tareas están completadas usa las diferentes formas plurales del lenguaje, en el caso del español dos, singular y plural cuando se marca una o dos tareas completadas.

i18next se encarga de obtener los archivos de traducciones automáticamente según el idioma en que se deba mostrar la aplicación, para el caso de que el usuario tenga como idioma preferido es-ES se buscarán los archivos localizados es-ES, es y finalmente dev:

Una vez hechos los cambios y habiendo modificado las pruebas unitarias de javascript comprobamos que todos siguen pasando correctamente:

Eso es todo, este ejemplo aunque sencillo muestra bastantes cosas que se podrían utilizar como base para algo real, usa RequireJS, Mustache, Backbone, React, Jasmine, Grunt y ahora i18next por la parte cliente y RESTEasy y Apache Tapestry por la parte servidor, cada una de estas tecnologías las he comentado individualmente en varios artículos.

El código fuente completo de este ejemplo está en mi repositorio de GitHub, una vez descargado el código puedes probarlo en tu equipo con el siguiente comando:

<noscript><pre><code>$ ./gradlew tomcatRun</code></pre></noscript>

Referencia:
Internationalization in Javascript
Internacionalización a lenguajes con diferentes formas plurales en Java
Internacionalización (i18n) de campos con Hibernate

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

Blog Bitix

Generar URLs semánticas y amigables

January 31, 2015 12:00 AM

Java

En algunas web las urls incluyen el identificativo del objeto de la base de datos a partir de cual se muestra el contenido principal de la página, en Blog Stack esto podría ser un artículo pero en otras páginas webs podría ser un producto. Esto genera direcciones de páginas webs «feas» de cara al usuario y al SEO de los buscadores además de exponer cierta información de la base de datos que probablemente no interese a nadie excepto al desarrollador de la página. En este artículo voy a explicar una forma de generar urls semánticas, «bonitas» o amigables de cara al usuario y al SEO para los buscadores y como lo he implementado en un ejemplo real como es Blog Stack.

Lo primero que debemos conseguir es que las direcciones urls sean únicas para cualquier página de la web, por tanto, en la url deberemos incluir tanta información como sea necesaria pero al mismo tiempo la mínima para hacerlas únicas, sean cortas y que nos permitan identificar de forma unequívoca el contenido a mostrar o el objeto que nos permite obtener la información a visualizar en la página, esta información formará el denominado slug. En el caso de Blog Stack las direcciones «bonitas» se emplean en este momento en dos sitios, para los artículos y para las etiquetas. La información mínima para un artículo es el nombre de la fuente, el año, el mes y el título, para las etiquetas es simplemente el nombre de la etiqueta. Este es un desglose de las partes que forman una dirección url.

<noscript><pre><code>http://www.blogstack.info/post/blogbitix/2013/12/hola-nuevo-mundo/ ^ ^ ^ ^ ^ ^ Dominio Página Año Artículo Bitácora Mes </code></pre></noscript>

Pero eso no es todo además quizá queramos transliterar los caracteres de forma que las urls no tengan ciertos caracteres propios de cada idioma. La solución simple pero poco efectiva es hacer una serie de sustituciones como por ejemplo reemplazar á por a, ñ por n, etc… Esta solución aparte de tener que hacerla nosotros probablemente no seamos ni siquiera conscientes que deberíamos haber reemplazado algún carácter más, se complica más si hemos de hacer lo mismo con el resto de codificaciones de la que ni siquiera conocemos los caracteres. Una solución mejor es utilizar el comando iconv disponible en linux que hace precisamente lo que buscamos:

<noscript><pre><code>$ echo &quot;áéíóú&quot; | iconv -f UTF-8 -t ASCII//TRANSLIT aeiou</code></pre></noscript>

Para que la url sea más fácilmente legible es recomendable convertir las mayúsculas a minúsculas y sustituir los caracteres de espacio por un guión (–). En Blog Stack suponiendo un artículo de la fuente blogbitix publicado en diciembre de 2013 y de título «¡Hola nuevo mundo!» partiríamos de la siguiente url previamente a aplicar la transliteración de caracteres:

<noscript><pre><code>/blogbitix/2013/12/¡Hola nuevo mundo!</code></pre></noscript>

Convertida a minúsculas:

<noscript><pre><code>/blogbitix/2013/12/¡hola nuevo mundo!</code></pre></noscript>

Transliterada con iconv a ASCII:

<noscript><pre><code>/blogbitix/2013/12/?hola nuevo mundo!</code></pre></noscript>

Y finalmente sustituidos cualquier carácter que no esté entre en la siguiente expresión regular [^a-z1-9-] para eliminar por ejemplo signos de puntuación, múltiples guiones seguidos y si el resultado empieza o acaba por guión eliminándolo, al final tenemos el slug o parte de la url final a la que deberíamos añadir el protocolo y el dominio:

<noscript><pre><code>/blogbitix/2013/12/hola-nuevo-mundo</code></pre></noscript>

Todo esto en código java se traduce en:

<noscript><pre><code>package info.blogstack.misc; ... public class Utils { ... public static Object[] getContext(Post post) { String f = post.getSource().getAlias(); String y = String.valueOf(post.getConsolidatedPublishDate().getYear()); String m = StringUtils.leftPad(String.valueOf(post.getConsolidatedPublishDate().getMonthOfYear()), 2, &quot;0&quot;); String e = Utils.urlize(post.getTitle()); return new Object[] { f, y, m, e }; } public static Object[] getContext(Label label) { String l = Utils.urlize(label.getName()); return new Object[] { l }; } public static String urlize(String text) { return Utils.trasnliterate(text.toLowerCase()).replaceAll(&quot;[^a-z1-9-]&quot;, &quot;-&quot;).replaceAll(&quot;-+&quot;, &quot;-&quot;).replaceAll(&quot;^-+&quot;, &quot;&quot;).replaceAll(&quot;-+$&quot;, &quot;&quot;); } public static String trasnliterate(String s) { try { Process p = Runtime.getRuntime().exec(&quot;iconv -f UTF-8 -t ASCII//TRANSLIT&quot;); Writer w = new OutputStreamWriter(p.getOutputStream()); Reader r = new InputStreamReader(p.getInputStream()); IOUtils.copy(new StringReader(s), w); w.close(); Writer sw = new StringWriter(); IOUtils.copy(r, sw); r.close(); return sw.toString(); } catch (IOException e) { throw new RuntimeException(e); } } ... }</code></pre></noscript>

Pero ¿si el identificativo del artículo no está en la url como lo asociamos con el artículo? Nos queda proporcionar una solución a esta necesidad de como identificar esa dirección url semántica y más amigable con el objeto del artículo guardado en la base de datos para mostrarlo al visualizar la página solicitada.

La idea para asociar la url con un objeto de base de datos es crear un hash de la url y tenerlo precalculado en la base de datos, con el hash que generamos a partir de la url y su slug cuando recibimos la petición buscamos el objeto que en la base de datos tenga ese hash. ¿Por qué guardar el hash y no el slug? Un motivo es porque el hash tiene una longitud constante, probablemente mas corto que el slug además de mayor dispersión en el valor del dato que usando un índice de base de datos es beneficioso en la búsqueda. Si la url es única podemos suponer que el hash será único. Si en un futuro cambiásemos la información del slug para calcular el hash lógicamente deberíamos recalcular todos los hashs. Para calcular el hash podemos usar la función MD5 o SHA con el siguiente código en java.

<noscript><pre><code>package info.blogstack.misc; ... public class Utils { public static String getHash(Post post) { return Utils.getHash(Utils.getContext(post)); } public static String getHash(Object[] context) { try { String[] s = new String[context.length]; for (int i = 0; i &lt; s.length; ++i) { s[i] = &quot;%s&quot;; } String ss = String.format(StringUtils.join(s, &quot;/&quot;), context); byte[] h = MessageDigest.getInstance(&quot;MD5&quot;).digest(ss.getBytes()); return Base64.encodeBase64String(h); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } ... public static Object[] getContext(Post post) { String f = post.getSource().getAlias(); String y = String.valueOf(post.getConsolidatedPublishDate().getYear()); String m = StringUtils.leftPad(String.valueOf(post.getConsolidatedPublishDate().getMonthOfYear()), 2, &quot;0&quot;); String e = Utils.urlize(post.getTitle()); return new Object[] { f, y, m, e }; } ... }</code></pre></noscript>

Esta solo es una forma de crear las urls pero suficiente para el propósito de Blog Stack. Quizá en otro caso podríamos querer generar direcciones con caracteres que no solo sean ASCII o incluyan los propios de otra codificación como por ejemplo caracteres cirílicos, chinos o japoneses. También en vez de incluir en la url la referencia a un solo objeto con el slug incluir los slugs de varios objetos, sin esta solución deberíamos incluir un segundo identificativo de la base de datos y las direcciones serán aún más feas, menos amigables y peores en cuanto a SEO.

El código fuente completo de la clase Utils.java lo puedes encontrar en el repositorio de GitHub de Blog Stack.

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

Arragonán

Semana 346

January 28, 2015 10:27 AM

Viene tarde el resumen de esta semana, otra vez.

Nos juntamos a hacer la puesta a punto del local de Hispalinux para Senpai Devs. La semana pasada también dimos por cerradas las inscripciones y empezamos a trabajar en el primer corte de selección, que se apuntaron casi 30 personas para las 6 plazas que ofrecíamos.

Tuvimos un hangout a modo de kickoff para el Startup Open Space 2015, haciendo un poco de retrospectiva del año pasado y definiendo las primeras tareas en un tablero de trello. Por el momento está casi todo en el aire, más allá de que la intención es organizarlo en primavera.

Para rematar la semana, estuvimos trabajando con Guillermo en un sideproject, definiendo algunas cosas de la landing page y poniendo en común la visión del producto que vamos a desarrollar.

También se anunció Health Keeper de Axa, un proyecto en el que trabajé como contractor dentro de un equipo de Init Services. Vine contando algo por aquí en mis retros con el nombre en clave Nort.

Y bueno, además de tratar un par de posibles nuevas colaboraciones, sobre las actuales:

  • En besepa estuve mejorando algunos tests para el API e implementar cambios que venían de la aplicación principal y afectaban al servicio sobre el que ando trabajando.
  • Estuve haciendo algunos cambios en la web de OutreachBox, para ampliar los contenidos y dejar ya ActiveAdmin listo para la zona de administración.
  • En bichomanía dejé prácticamente finiquitada la parte de importación del catálogo, cosa que no fue trivial por ciertas diferencias en como están montados los modelos de datos.

Buena semana.

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

Poesía Binaria

[Bash script] Hacer un mirror de un servidor FTP

January 28, 2015 09:14 AM

Este script puede venir muy bien para copiar sitios enteros y sólo tengamos acceso por FTP. Sólo necesitáis tener lftp instalado.
Lo realmente interesante de este script es que podéis programarlo como tarea cron o correrlo remotamente.

El script no es mío, es uno de estos copia y pegas que tengo desde hace tiempo y seguro que encontráis por la red mil parecidos a este. Normalmente para cada sitio donde tengo que ejecutar esto modifico este script, pero es muy fácil hacer un entorno un poco más amigable, aceptando argumentos, notificando al terminar, etc.

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash    
HOST="ftp.servidor.remoto"
USER="usuario"
PASS="password"
FTPURL="ftp://$USER:$PASS@$HOST"
REMOTEPATH="/ruta/dentro/del/ftp"   # / o /www, por ejemplo
LOCALPATH="/ruta/local_donde/copiar"
lftp -c "set ftp:list-options -a;
open '$FTPURL';
cd $REMOTEPATH;
lcd $LOCALPATH;
mirror --verbose"

Como curiosidad, podemos utilizar junto con –verbose, la opción –delete y borrar todos los archivos del servidor remoto.

Foto: Steven Bratman (Flickr CC-by a 24/12/2014)

La entrada [Bash script] Hacer un mirror de un servidor FTP aparece primero en Poesía Binaria.

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

Variable not found

Normas de diseño y codificación de .NET framework

January 27, 2015 05:18 PM

Framework design guidelinesHace relativamente poco tiempo, y como parte del popular salto al open source del nuevo stack de Microsoft, se publicaron en Github las directrices o normas de codificación que deben seguirse para contribuir en el desarrollo de .NET Core. Se trata de un resumen simplificado del contenido del libro “Framework design guidelines” publicado por Krzysztof Cwalina y Brad Abrams en 2008.

Aunque creo que este mismo documento o versiones anteriores lo he leído en otras ocasiones, la verdad es que sigue resultándome muy interesante porque me recuerda normas y convenciones que conviene tener en cuenta al desarrollar marcos de trabajo y componentes. No hay que olvidar que estas directrices han sido refinadas y mejoradas con los años, acumulando ya la experiencia de muchos años y muchos desarrolladores que han trabajado en .NET framework, así que se trata de una base de conocimiento nada despreciable. De hecho, estas pautas son las bases del diseño de frameworks dentro de la propia Microsoft.

Y como a menudo me encuentro con equipos que no tienen guías de estilo ni convenciones de codificación formalizadas, he pensado que quizás sería interesante traducirlas para que puedan ser usadas como punto de partida para crear sus propias normas y, en cualquier caso, siempre dan buenas ideas que podemos aplicar en el día a día para hacer mejor nuestros componentes.

Es una lectura cortita, ¡que aproveche!

1. Principios generales de diseño

1.1. Diseño guiado por escenarios

Comienza el proceso de diseño de tu API público definiendo los escenarios más importantes de cada área funcional. Escribe el código que te gustaría que escribieran los usuarios finales cuando vayan a implementar esos escenarios usando tu API. Después, diseña tu API basándote en el código de ejemplo que escribiste.

Por ejemplo, si diseñas un API que permita tiempos, podrías escribir el siguiente código de ejemplo para los escenarios:
// Escenario #1 : medir el tiempo transcurrido
Stopwatch watch = Stopwatch.StartNew();
DoSomething();
Console.WriteLine(watch.Elapsed);

// Escenario #2 : reutilizar el cronómetro
Dim watch As Stopwatch = Stopwatch.StartNew()
DoSomething();
Console.WriteLine(watch.Elapsed)
watch.Reset();
watch.Start();
DoSomething()
Console.WriteLine(watch.Elapsed)

// Escenario #3: ...

1.2. Estudios de usabilidad

Realiza pruebas de usabilidad de tu API. Haz que desarrolladores que no estén familiarizados con tu API implementen los principales escenarios, e intenta identificar qué partes no son intuitivas.

1.3. API auto-documentada

Los desarrolladores que utilicen tu API deberían ser capaces de implementar los principales escenarios sin leer la documentación. Ayuda a los usuarios a descubrir qué tipos y métodos necesitan utilizar dándoles nombres intuitivos para los tipos y miembros más frecuentes. Hablad sobre la elección de los nombres durante las revisiones.

1.4. Entiende a tu cliente

Ten en cuenta que la mayoría de tus clientes no son como tú. Deberías diseñar el API para tus clientes, no para los desarrolladores más cercanos, que, a diferencia de tus clientes, son expertos en la tecnología que estás intentando exponer.

2. Reglas de nombrado

El uso de mayúsculas y minúsculas sólo deben ser tenidas en cuenta en identificadores public y protected, así como en implementaciones privadas de miembros de interfaz. Sin embargo, los equipos de trabajo pueden elegir libremente sus propio estilo para los identificadores internal y private.
  • Utiliza “PascalCasing” (primera letra de cada palabra en mayúsculas) para todos los identificadores excepto para los nombre de parámetro. Por ejemplo, usa TextColor en vez de Textcolor o Text color.

  • Utiliza “camelCasing” (primera letra de cada palabra excepto la primera en mayúsculas) para todos los nombres de parámetro. Precede los nombres de parámetros genéricos con la letra “T”:
    public interface ISessionChannel<TSession>
    where TSession : ISession
    {
    TSession Session { get; }
    }
  • Considera utilizar simplemente T como nombre de parámetro genérico de una única letra.

  • Utiliza “PascalCasing” o “camelCasing” para acrónimos con más de dos caracteres. Por ejemplo, utiliza HtmlButton en lugar de HTMLButton, pero System.IO en lugar de System.Io.

  • No uses acrónimos que no estén aceptados generalmente en el campo o contexto de la aplicación.

  • Utiliza acrónimos bien conocidos sólo cuando sean absolutamente necesarios. Por ejemplo, puedes utilizar UI para user interface (interfaz de usuario) o Html para Hyper-Text Markup Language (lenguaje de marcas hipertexto).
  • No uses contracciones como partes de nombres de identificador. Por ejemplo, usa GetWindow en lugar de GetWin.

  • No uses guiones, ni guiones bajos ni cualquier otro tipo de caracteres alfanuméricos. 

  • No uses la Notación Húngara.
     
  • Nombra tipos y propiedades usando sustantivos o frases nominales. 

  • Nombra métodos y eventos con verbos o frases verbales. Para los eventos, elije siempre nombres que indiquen si se ha lanzado antes o después de que la acción se produzca utilizando el gerundio y el pasado perfecto, respectivamente. Por ejemplo, si un evento es lanzado antes de cerrar un formulario, debería llamarse Closing; si es lanzado después de que sea cerrado, debería llamarse Closed.

  • No utilices prefijos “Before” o “After” en el nombre de los eventos para indicar si la acción se realizó o no (cíñete al punto anterior). 

  • Utiliza I como prefijo para todos los nombres de interfaz.

  • Utiliza las siguientes terminaciones:

    • Exception para tipos que hereden de System.Exception.
    • Collection para tipos que implementen IEnumerable.
    • Dictionary para tipos que implementen IDictionary o IDictionary<K,V>.
    • EventArgs para tipos que hereden de System.EventArgs.
    • EventHandler para tipos que hereden de System.Delegate.
    • Attribute para tipos que hereden de System.Attribute.

  • No utilices las terminaciones anteriores para ningún otro tipo. 

  • No uses como terminación de nombres las palabras Flags o Enum.

  • Utiliza nombres o frases nominales en plural para las enumeraciones de flags (las que soportan operaciones de bit) y en singular para las enumeraciones normales.

  • Utiliza el siguiente esquema para los espacios de nombres:
    <Company>.<Technology>[.<Feature>].
    Un ejemplo sería Microsoft.Office.ClipGallery. Sin embargo, los componentes de sistema operativo deberían usar espacios de nombres comenzando por System.

  • No utilices jerarquías de la organización para organizar los espacios de nombre. Éstos deben corresponder con escenarios, independientemente de los equipos que hayan creado las APIs.

3. Pautas generales de diseño

  • Usa el tipo más específico para los valores de retorno, y el menos específico para los parámetros de entrada. Por ejemplo, acepta IEnumerable como parámetro de entrada, pero retorna Collection<string>

  • Provee de un claro punto de entrada a tu API para cada escenario. Cada área funcional debería tener preferiblemente uno, aunque aunque a veces sean más, tipos que actúan como puntos de entrada para explorar la tecnología. Lo llamamos “componentes agregados”. La implementación de la gran mayoría de escenarios en una tecnología determinada deberían comenzar desde uno de esos componentes agregados.

  • Escribe código de ejemplo para los escenarios de uso más frecuentes. El primer tipo usado en esos ejemplos debería ser un componente agregado y el código debería ser trivial. Si el código va más allá de unas cuantas líneas, necesitas rediseñarlo. Por ejemplo, escribir a un log de eventos en el API Win32 tomaba alrededor de 100 líneas de código; en .NET, escribir al EventLog necesita una única línea de código.

  • Modela en componentes agregados los conceptos de mayor nivel (objetos físicos) en lugar de tareas a nivel de sistema. For example File, Directory o Drive son más sencillos de comprender y utilizar que Stream, Formatter o Comparer.

  • No obligues a que los usuarios de tus APIs instancien múltiples objetos en los principales escenarios. Las tareas simples deberían hacerse con un único new.

  • Permite que tus APIs sean usadas mediante el estilo “crear-asignar-llamar” en todos los componentes agregados. Debería ser posible instanciar todos los componentes con el constructor por defecto, establecer una o más propiedades y llamar a métodos o responder a eventos:
    var applicationLog = new EventLog();
    applicationLog.Source = "MySource";
    applicationLog.WriteEntry(exception.Message);
  • No requieras demasiadas inicializaciones antes de que los componentes agregados puedan ser utilizados. Si alguna inicialización es necesaria, la excepción lanzada cuando el componente no haya sido correctamente inicializado debería explicar claramente qué hay que hacer para que funcione.
  • Elije cuidadosamente los nombres para tus tipos, métodos y parámetros. Dedica tiempo a pensar cuál es el primer nombre que la gente intentará teclear cuando esté explorando tu API, y resérvalo para tu componente agregado. Un error común es usar el “mejor” nombre para un tipo base. Pasa FxCop a tus bibliotecas.

  • Asegúrate de que tu biblioteca es CLS compliant. Aplica CLSCompliantAttribute a tus ensamblados. 

  • Ten preferencia por usar clases en lugar de interfaces.

  • No crees tipos sellados a menos que tengas buenas razones para hacerlo.

  • No crees tipos valor mutables.

  • No proveas abstracciones como interfaces o clases abstractas sin proveer al menos de un tipo concreto que implemente cada abstracción. Esto ayudará a validar el diseño.

  • No proveas interfaces sin disponer al menos de un API que lo consuma, es decir, un método que requiera un parámetro del tipo del interfaz. Esto ayudará a validar el diseño del interfaz.

  • Evita crear tipos anidados públicos.

  • Aplica el atributo FlagsAttribute a enumeraciones de flags.

  • Utiliza principalmente colecciones en lugar de arrays en los APIs públicos.

  • No utilices ArrayList, List<T>, Hashtable, o Dictionary<K,V> in APIs públicas. Utiliza en su lugar Collection<T>, ReadOnlyCollection<T>, KeyedCollection<K,V>, o los subtipos de  CollectionBaseinstead. Ten en cuenta que las colecciones genéricas son sólo soportadas en .NET framework 2.0 o superior.

  • No utilices códigos de error para notificar fallos. Usa excepciones en su lugar. 

  • No lances excepciones de tipo Exception o SystemException.

  • Evita capturar excepciones del tipo base Exception.

  • Opta preferiblemente por lanzar excepciones ya existentes de propósito general como ArgumentNullException, ArgumentOutOfRangeException o InvalidOperationException en lugar de definir tus propias excepciones. Lanza siempre la excepción más específica posible.

  • Asegúrate de que los mensajes de excepción son claros y aplicables.

  • Utiliza EventHandler<T> para eventos en lugar de definir manualmente manejadores de delegados.

  • Usa preferiblemente APIs basadas en eventos en lugar de usar delegados.

  • Usa preferiblemente constructores en lugar de métodos de factoría.

  • No expongas directamente campos públicos. Utiliza propiedades en su lugar.

  • Usa preferiblemente propiedades para almacenamiento, pero utiliza métodos en los siguientes casos:

    • Cuando la operación sea una conversión (como en Object.ToString()) .
    • Cuando la operación puede ser costosa (órdenes de magnitud más lento de lo que podría ser el establecimiento de un campo).
    • Cuando el hecho de obtener el valor de una propiedad utilizando el getter tenga un efecto lateral observable.
    • Cuando llamar varias veces consecutivas al miembro pudiera retornar distintos resultados.
    • Cuando el miembro retorne un array. Nota: los miembros que retornen un array deberían retornar copias del array interno, no una referencia al mismo.

  • Permite que las propiedades sean establecidas en cualquier orden. Las propiedades deberían ser stateless respecto a otras propiedades.

  • No hagas que un miembro sea virtuales a menos que tengas razones de peso para hacerlo. 

  • Evita los finalizadores de clases.

  • Implementa IDisposable en todos los tipos que adquieran recursos nativos, así como en los que dispongan de finalizadores.

  • Sé consistente en el orden y nombrado de los parámetros de métodos. Es frecuente encontrar métodos sobrecargados con un número creciente de parámetros para permitir al desarrollador especificar el nivel de información que necesite.

  • Asegúrate de que todas las sobrecargas muestran parámetros consistentes en su orden (el mismo parámetro se encuentra en el mismo lugar en la signatura) y nombre. Entre las sobrecargas, el único método que debería ser virtual es el que tiene más parámetros y sólo cuando la extensibilidad es necesaria.
    public class Foo
    {
    private readonly string _defaultForA = "default value for a";
    private readonly int _defaultForB = 42;

    public void Bar()
    {
    Bar(_defaultForA, _defaultForB);
    }

    public void Bar(string a)
    {
    Bar(a, _defaultForB);
    }

    public void Bar(string a, int b)
    {
    // core implementation here
    }
    }
  • Evita el uso de parámetros out y ref.

¡Y eso es todo! Claramente hay algunas normas a las que se les nota el paso del tiempo, e incluso puede haber alguna discutible, pero espero que os resulten interesantes y os sean útiles como base si aún no tenéis directrices claras. Y si queréis contribuir al desarrollo de .NET, son las reglas a las que hay que ceñirse ;)

Publicado en Variable not found.

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

Variable not found

Enlaces interesantes 184

January 27, 2015 08:15 AM

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

.Net

ASP.NET

Azure / Cloud

Conceptos/Patrones/Buenas prácticas

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Otros

Publicado en Variable not found

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

Koalite

Retrospectiva de un proyecto con ReactJS

January 26, 2015 05:06 AM

Los que seguís este blog desde hace tiempo sabéis que me gusta ir comentando cómo evolucionan mis preferencias a la hora de desarrollar software y que no suelo tener problema en admitir cómo éstas cambian con el tiempo. Hace tiempo escribí sobre cómo había ido mi primer proyecto serio con AngularJS y, unos meses después, que era lo que empezaba a no gustarme de ese AngularJS.

Como era de esperar viendo todos los posts que he escrito sobre ReactJS recientemente, nuestra última aplicación web la hemos desarrollado con esta librería y, ahora que acabamos de liberar la primera versión, es el momento de hacer un pequeño balance.

Antes de entrar en materia, me gustaría dejar claras un par de cosas.

Este post trata sobre las experiencias de un equipo concreto desarrollando una aplicación concreta, por lo que puede que tu caso sea completamente diferente. Además, todavía es pronto para conocer las implicaciones a medio plazo del uso de ReactJS, por ejemplo a nivel de mantenimiento de la aplicación; ya llegará el momento de escribir ese post dentro de unos meses.

Puede parecer que esto se trata de un AngularJS vs ReactJS, y en cierto modo es así puesto que son los dos estilos que conozco de primera mano. Aunque ReactJS y AngularJS tengan objetivos distintos y no sean comparables, lo cierto es que el uso de uno u otro afecta directamente a la forma de trabajar y eso sí es comparable.

Los componentes básicos

Toda la aplicación la hemos organizado alrededor del uso de librerías independientes, en contraposición a usar un framework “todo incluido” como AngularJS o Durandal. La librería básica ha sido ReactJS, pero también hemos usado jQuery (muy poco, la verdad) y lodash para hacer más soportable el uso de Javascript.

Para orquestar la “compilación” de la aplicación, que sigue una organización basada en features, hemos utilizado grunt con browserify y las react-tools, además de algún minificador de css, mocha para tests unitarios y nightwatch para tests de extremo a extremo.

En el aspecto visual, acabamos descartando el uso de frameworks css porque necesitábamos un layout un poco extraño, basado en columnas css con scroll horizontal y, pese a nuestro escaso talento para el diseño gráfico, resultaba más fácil hacerlo a mano que convencer a Bootstrap o alguno de sus amigos de hacerlo por nosotros.

Las partes malas

Antes de empezar a glosar las bondades de nuestra solución y lo listos que somos por haberla empleado (ejem), creo que es más honesto ver los puntos que han resultado más complicados, incómodos, o costosos, que también los ha habido.

Lo primero que hay que tener en cuenta cuando se opta por una solución de estas características, basada en librerías independientes, es que vas a necesitar dedicarle algo de tiempo a coordinar todas estas librerías, decidir cómo “compilarlas”, “modularizarlas” y demás. En nuestro caso, eso supuso aproximadamente una semana de experimentos hasta que encontramos un flujo de trabajo que nos resultara cómodo.

La parte más complicada, sin duda, fue el montaje de los tests de extremo a extremo con nightwatch. Con AngularJS acabamos un poco hartos de karma y nos acabamos pasando a protractor, que tampoco es que fuera una maravilla, pero al menos el montaje fue mucho más sencillo que con nightwatch.

Otro factor a considerar es el uso de JSX para generar las vistas. Al quedar tan mezclado el JSX usado para generar el Virtual DOM con el código Javascript usado para coordinar los componentes, hay que ser cuidadoso para que aquello no acabe siendo un lío mezclando lógica de presentación y lógica de negocio.

Ha habido momentos en los que nos ha tocado refactorizar código que empezaba a ser demasiado complicado en algún componente, o en los que empezábamos a tener código duplicado en varios componentes sin darnos cuenta. Al ser tan sencillo añadir nuevo comportamiento a un componente, es fácil que se te vaya de las manos.

El uso de JSX tiene otro efecto, no tan importante, pero que también puede resultar molesto, y es el uso de herramientas para trabajar con él. Aunque sólo sea para colorear la sintaxis e indentarlo correctamente, hay que hacer algunos ajustes. Al final hemos acabado con distintas soluciones, algunos utilizando WebStorm, otros Sublime y otros emacs.

Las partes buenas

Sin duda, lo mejor de utilizar ReactJS es la naturalidad con la que se hace todo.

Seguramente sea por el uso de JSX, que sí, que como mencionaba antes tiene sus riesgos, pero permite una cohesión mucho mayor del código en los componentes. En AngularJS cuando querías reutilizar un componente usando una directiva o un controller, generalmente acababas saltando entre dos ficheros, el que contenía la plantilla de HTML y el que contenía el código en Javascript, y eso hacía que fuese mucho más incómodo trabajar.

La gestión del ciclo de vida del componente, con sus componentDidMount, componentWillUnmount, etc., resulta muy intuitiva y decidir dónde y cuándo hay que hacer las cosas suele ser bastante directo.

También ayuda mucho la separación entre información mutable e inmutable. Simplifica mucho la forma de razonar sobre los componentes, sobre todo si lo comparamos con el sistema de scopes anidados/aislados/clonados de AngularJS, que resultaba especialmente complejo.

Gracias a que es más sencillo razonar sobre los componentes, en parte por la mayor cohesión entre el código Javascript y el DOM (JSX), y en parte por la inmutabilidad, hemos podido partir la aplicación en componentes más pequeños, reutilizables y simples.

Los componentes nos han permitido aplicar un patrón más parecido a MVP que a MVVM. Sin entrar en flame wars, siempre me ha parecido que ese patrón aportaba una mejor separación de responsabilidades y, fundamentalmente, hacía que fuese más sencillo razonar sobre la aplicación.

Al final los componentes que representan “pantallas” de la aplicación acaban haciendo una labor “doble” de Vista y Presenter, siendo la vista el método render y el resto del código del componente haciendo las veces de Presenter.

Que no haya una separación mayor (todo está en el mismo objeto) es algo que reconozco que me pone un poco nervioso. Si lo piensas fríamente (y eres un poco disciplinado), al final no importa tanto en qué objeto se encuentre cada cosa sino la forma en que interactúan. De todas formas no descarto que en un futuro acabemos separándolo.

En cualquier caso, toda la lógica de negocio queda siempre fuera del componente en otros módulos o funciones, y que se acoplen vista y presenter tampoco es tan grave (en realidad siempre lo van a estar aunque no queramos aceptarlo).

Una parte que pensé que echaría más de menos es el sistema de módulos e inyección de dependencias de AngularJS, pero la verdad es que con browserify para poder modularizar la aplicación esto no ha sido nada problemático.

Supongo que si hubiésemos querido escribir más tests unitarios con mocks lo hubiéramos notado más, pero como nuestra política desde hace tiempo es aislar la lógica de la interacción para facilitar los tests, esto no ha sido un problema.

Una ventaja adicional de utilizar browserify es que facilita la experiencia de depuración. Puedes utilizar todas las versiones completas de las librerías (sin minificar) durante el desarrollo y, en la fase de compilación, browserificarlas junto con tu aplicación y minificarlo todo junto.

Eso se supone que ayudaría también al rendimiento porque tendrías automáticamente un bundle con todo tu Javascript, pero ahora mismo es algo que en nuestro caso no nos preocupa mucho. De hecho, una de las teóricas ventajas de ReactJS, su rendimiento, para nosotros es poco importante. Tampoco tuvimos problemas de rendimiento con AngularJS pese a la mala fama que tiene a veces.

Conclusiones

Utilizar ReactJS en una aplicación real requiere un esfuero adicional con respecto a otras soluciones porque necesitas buscar soluciones para todas las cosas que no cubre la librería.

Que esto merezca la pena o no, es una cuestión difícil de responder y depende mucho de las circunstancias de cada uno. A mi personalmente me deja más tranquilo tener más grados de libertad y elección en el futuro si quiero cambiar alguna parte, pero esto no es gratis.

Si tuviera que definir cómo ha sido la experiencia de trabajar con ReactJS en una sola palabra sería divertido. Está todo tan al alcance de la mano y es todo tan directo, sin tener que dar vueltas entre capas y capas de abstracción, que trabajar con ReactJS resulta muy placentero.

Lo que más me preocupa a medio plazo, y posiblemente venga derivado de eso, es que los componentes se puedan acabar convirtiendo en monstruos complejos llenas de casos límite para tratar con el DOM. Si llega ese punto, como decía antes, mi plan consiste en extraer más lógica de los componentes (lo que sería el Presenter) para generar una separación mayor.

Posts relacionados:

  1. Rutas en ReactJS con React Router
  2. ReactJS: un enfoque diferente
  3. Crear un componente con ReactJS

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

El blog de Adrián Arroyo

La experiencia GCI 2014 con Haiku

January 22, 2015 11:00 PM

El día 1 de diciembre comenzaba el Google Code-In 2014 y hasta el 19 de enero pude trabajar en la organización que había elegido, en este caso Haiku, como el año anterior.

HaikuToDo

HaikuToDo 1
La tarea consistía en reusar cierto código de una aplicación de tareas para crear un frontend en Haiku usando la BeAPI. Sin embargo ese código no funcionaba. No tenía sistema de compilación y más tarde descubrí que carecía de punto de entrada y ciertas headers no coincidían con la implementación. Así que lo hice de 0. En primera instancia usé SQlite para almacenar las tareas. Sin embargo me pidieron que mejorara mucho más la interfaz. Eso hice y en el camino tuvo que inventarme el sistema de categorías. La siguiente tarea consistía en reemplazar SQlite por algo específico de Haiku y BeOS. Hablo de BeFS y su sistema de Queries. Gracias a C++ solo tuve que crear un objeto que implementase las operaciones de escritura con BeFS y pude mantener el de SQlite (hay que activarlo en tiempo de compilación). La siguiente tarea consistía en añadirle el soporte online. Valía cualquiera pero elegí Google Tasks porque ya tenía cuenta. Toda la gestión de HTTP se debía realizar por las APIs nativas de Haiku. Estas son APIs que BeOS no llegó a incorporar nunca. Además el procesado de JSON corría a cargo de las APIs de Haiku que al igual que las de HTTP están indocumentadas. Obtener la información de Google puede parecer lioso pero una vez lo entiendes es bastante sencillo. Para la autenticación, HaikuToDo abre WebPositive para que te registres con Google y recibes un código. Ese código lo pones en la aplicación y se descargarán tus tareas de Google. El soporte actual es de solo lectura. La aplicación tiene licencia MIT y se puede descargar
HaikuToDo 1

SuperFreeCell

HaikuToDo 1
¿Quién no ha jugado al solitario de Windows? ¿Y al Carta Blanca también conocido como FreeCell? Seguro que alguno más pero también muchos. La tarea consistía en hacer el clon de FreeCell para Haiku. Por supuesto usando la BeAPI, en concreto la gran flexibilidad de BView para estas tareas. Para ello tomé como referencia BeSpider, el clon del solitario spider en Haiku. Luego comprendí que no entendía mucho el código y lo empecé a hacer a mi manera. Se me ocurrió hacer las cartas un objeto que se tenía que dibujar. Error. La interación con el resto del mundo se hecha en falta. Luego pensé en que heredasen BView. Error. El número de glitches gráficos era digno de mencionar. Finalmente las cartas pasaron a ser estructuras simplemente e hice toda la lógica en la BView del tablero. El resultado era mucho mejor. Cambié el algoritmo de ordenación de cartas (barajar, si alguien no se enterá) para ganar en velocidad. Antes usé uno con bucles muy simple pero lentísimo. Otros detalles fue que use DragMessage para mover las cartas y que las cartas son PNGs de BeSpider integrados dentro del ejecutable (una cosa que siempre he hechado en falta a Linux). Obviamente al hacer un clon tuve que jugar mucho a otras implementaciones de FreeCell. Jugué a la de Windows 7, Ubuntu 14.04 y Android. Todo sea por SuperFreeCell. La aplicación tiene licencia MIT y se puede descargar
HaikuToDo 1

Haiku EGL

EGL es una API del Khronos Group para definir superficies sobre las que operar con otras APIs de Khronos Group, entre ellas OpenGL y OpenVG. EGL se ha usado sobre todo en móviles pero el salto a escritorio es inminente (Wayland y Mir dependen de EGL para funcionar). La API es teóricamente multiplataforma aunque en la práctica hay que modificar el código si usamos las X11 o Wayland o en este caso Haiku. La tarea consiste en portar EGL de manera que funcione en Haiku como wrapper de BGLView. La tarea requería modificar código de Mesa 10. Tuve muchos problemas en esta tarea: documentación nula, características exclusivas de C99 (y que no están en C++), desconocimiento de parte del sistema gráfico tanto en Linux como en Haiku, desconocimiento de SCons, etc. Esto me llevó a implementar EGL en un principio como un driver DRM2. Pero luego descubrí que DRM2 solo funciona en Linux. Así que tuve que escribir un driver desde 0. Este crea una configuración placebo y realiza operaciones básicas como crear una ventana y hacer el intercambio de búferes.

Haikuports

El resto de tareas consistían en portar software normal y corriente a Haiku. He portado con más o menos dificultad:
- OpenSceneGraph
- EntropiaEngine++
- libuv

Quería haber portado Node.js pero dependía de libuv que no estaba portado. Después comprobé que nuestra versión del motor V8 estaba desactualizada para Node.js así que no tuve tiempo para terminarla.

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

Blog Bitix

Conferencia BilboStack 2015

January 22, 2015 04:00 PM

BilboStack

Un año más una de las primeras conferencias del año se ha celebrado en Bilbao, la BilboStack 2015. Esta edición del 2015 ha sido la cuarta entrega donde varios profesionales del sector de las tecnologías han hablado de diversos temas, desde programación hasta metodologías de desarrollo y algunas otras cosas relacionadas con la tecnología y el desarrollo. Cada año la BilboStack acoge a más asistentes en la Universidad de Deusto dando lugar este año a un cambio de ubicación dentro de la propia universidad para poder dar cabida a todos de forma más cómoda. Como en ediciones anteriores este año ha seguido manteniéndose gratuita, lo único necesario ha sido el registro para adquirir la entrada.

Hasta el momento el formato de la conferencia ha sido presentaciones de 45 minutos en dos tracks simultáneos en horario únicamente de mañana y durante un día, siendo la agenda de este 2015 la siguiente:

Hora Track 1
9:00 - 9:45 Desarrollo de aplicaciones web con .NET en MAC: open source, multiplataforma e incluso gratuito por Ibon Landa
10:00 - 10:45 Google es ciego por Oihana Alberdi
11:15 - 12:00 Descubriendo los Beacons por Borja Reinares
12:15 - 13:00 ¿Qué es eso de IoT? por Quique Martinez
13:15 - 14:00 Bomberos pirómanos por Ujue Agudo y Aritz Suescun
Hora Track 2
9:00 - 9:45 Errores comunes en la visualización de datos y algunas soluciones por Pablo Garaizar
10:00 - 10:45 ReactJS: un enfoque distinto a la UI en JavaScript por Eduard Tomás
11:15 - 12:00 Creando directivas para AngularJs por Hugo Biarge
12:15 - 13:00 WordPress al limite por Asier Marqués
13:15 - 14:00 Arquitectura frontend de CartoDB por Javi Santana

Como cada año no puede faltar alguna presentación del ubicuo Javascript y en las presentaciones de años anteriores ha habido de PHP, Python, Groovy y .NET pero aún no ha habido ninguna de Java (a pesar de que será uno de los más usados por los asistentes). Después de revisar la agenda de este año he asistido únicamente y a todas a las presentaciones del track 1. Del track 2 me llamaban la atención la de ReactJS, pero es una herramienta que ya conozco y que me parece de lo mejor para su propósito aún así intuía que iba a conocer poco nuevo después de escribir el artículo Ejemplo lista de tareas con Backbone y React y usarlo en el ejemplo simple pero ilustrativo mostrado. También me llamaba la atención Wordpress al límite y Arquitectura frontend de CartoDB. A continuación un resumen breve de cada una de las presentaciones a las que he asistido.


Desarrollo de aplicaciones web con .NET en MAC: open source, multiplataforma e incluso gratuito por Ibon Landa

Yo me muevo alrededor de la plataforma Java en vez de .NET pero parece que Microsoft está dando un giro a su plataforma para dar cabida a opciones como Linux o Mac y hacerla un poco más abierta tanto en su desarrollo como en su comunidad. Creo que más bien por necesidad que por ser buenos, en el ámbito empresarial y de servidores Java está mucho más establecido y tiene algunas comunidades y projectos más cerca del software libre y del código abierto como Apache, Spring o JBoss que además proporcionan proyectos de gran calidad y utilidad sin costes de licencias. El software libre, el código abierto y el coste de las licencias son argumentos de venta y se toman en consideración, si Microsoft no quiere dejar aislado a .NET en su propia plataforma Windows que aún con una gran cuota en el escritorio, en un futuro probablemente disminuya y mucha menos cuota en los servidores, no le queda más remedio que abrirse. Pero esta solo es mi opinión, en cualquier caso me parece un buen paso y bienvenido es.

La nueva plataforma de .NET comentada en la presentación aparte de ser agnóstico en el sistema operativo trata de ser agnóstico y quizá por facilidad de implementación cualquiera de ellos en las herramientas de desarrollo, de este modo, en esta nueva versión para el desarrollo no será necesario Microsoft Visual Studio y podrá hacerse con cualquier editor de texto (Sublime, vim, emacs o notepad) y desde la terminal. Esta nueva visión agnóstica de las herramientas hace que puedan ser utilizadas las que más adecuadas consideremos para una tarea aparte de las que ofrezca la propia Microsoft como Grunt, Bower, Karma, Jasmine.

Después de la presentación me planteo aprender algo de .NET porque siendo pragmático hay una buena cantidad de ofertas de trabajo solicitando conocimientos en esta plataforma y algunas aparentemente interesantes.

Google es ciego por Oihana Alberdi

El título de la presentación viene motivado porque Google procesa el contenido no como lo vemos nosotros en el navegador sino por ejemplo sin estilos, de modo que dando importancia como está definido el contenido en el html de una página y haciendo que sea accesible mejoraremos como es indexada la página por Google y por tanto su posicionamiento en el buscador, pero también mejorando la accesibilidad de una página ayudaremos a que las personas con algún tipo de impedimento pueda acceder el contenido de forma más cómoda.

En la mejora de la accesibilidad de una página intervienen tanto diseñadores (tipografía, colores, estilos externalizados) como desarrolladores (código html limpio, javascript no intrusivo) y pueden ayudarse de herramientas como validadores de HTML, validadores de CSS, validadores de accesibilidad. También podemos comprobar como se ve una página sin estilos (como es accedida por google), con javascript deshabilitado, añadiendo atributos alt (como a imágenes), añadiendo teclas de acceso, … algunas de estas cosas pueden probarse rápidamente con el plugin web developer de Firefox.

Descubriendo los Beacons por Borja Reinares

La verdad es que no conocía de nada que eran en el mundo tecnológico los beacons salvo por lo poco que puede proporcionar su nombre, en la descripción de la charla no aparecía ningún texto de descripción. Mediante algún artículo he podido conocer algo sobre ellos y por donde podía ir la charla. La alternativa era la presentación de AngularJS y personalmente estando más convencido de la opción Backbone y ReactJS prefería conocer algo de los beacons.

Como su nombre indica un beacon o baliza es un dispositivo que emite una señal identificable, por bluethooth (Bluethooth Low Energy, BLE). Posteriormente, un dispositivo como un teléfono inteligente (Android, iPhone o Windows Phone) con una aplicación instalada permite procesar esa señal para ofrecer alguna función útil para el usuario en base a la distancia hasta la baliza (0,5 metros, 2m, 30m), estas sol algunas aplicaciones de los beacons con BLE. Algunos usos que se están dando a esta tecnología es en las Apple Store o en algunas tienda de ropa de EEUU.

BLE es distinto de NFC, BLE es una comunicación de 1:N, consume batería y el usuario no tiene que hacer nada, por el contrario, NFC es una comunicación 1:1, no consume energía (considerable) y necesita la intervención del usuario. Entre los retos de los beacons que debe resolver es el consumo de energía, necesita una aplicación instalada en el dispositivo, la reticencia del usuario a perder privacidad o problemas legales de protección de datos.

Los beacons y BLE puede ser un nuevo campo tecnológico, veremos si realmente se convierte en útil y se implanta su uso o si finalmente desaparece y posteriormente resurge como un nuevo concepto basado en el anterior que finalmente sea usado.

¿Qué es eso de IoT? por Quique Martinez

El internet de las cosas (IoT) es otro palabro que aprender, salvo que ahora tiene un nombre molón es la consecuencia de la evolución de la tecnología, no es más que encontrar una aplicación útil a los dispositivos que tienen tendencia a ser cada vez más pequeños, baratos, que pueden usar múltiples sensores y con la posibilidad de estar conectados a internet.

El número de estos dispositivos aumentará rápidamente en los próximos años tratando de ofrecer funciones útiles tanto para las empresas como para las personas. Por ejemplo, quizá en un futuro un seguro requiera que el vehículo asegurado disponga un dispositivo de estos con sensores como acelerómetro, velocímetro u otros datos cuantificables que puedan ser utilizados para determinar sin en un accidente se circulaba a más de 120 km/h o hacer una llamada de emergencia en su caso.

Otro nuevo área tecnológico en el que descubrir aplicaciones útiles y con gran potencial.

Bomberos pirómanos por Ujue Agudo y Aritz Suescun

Durante el desarrollo de un proyecto de software en algún momento alguien (cliente, usuario, desarrollador, consultor, jefe de proyecto, diseñador, …) involucrado puede tener la sensación o certeza de que el producto que se está desarrollando no resuelve en alguna medida las necesidades del cliente y los usuarios y/o no es motivo de orgullo de los que lo realizan. El concepto de bombero pirómano trata de identificar estos problemas y hacerlos visibles para todos los involucrados y “prender un fuego” con ellos como haría un pirómano. Sin embargo, estos fuegos pueden presentar peligros para el proyecto en el momento que no son tomadas medidas para apagarlos o resolverlos como haría un bombero. De esta forma se presenta el concepto de bombero pirómano formado por estos dos opuestos.

En Biko siguen tres ideas para mantener estos fuegos controlados:

  1. Quemar cuanto antes. Cuanto antes se prenda el fuego más margen de maniobra habrá en el proyecto haciendo con más garantías de que cumpla su objetivo y evitará malgastar tiempo, dinero y esfuerzo en el desarrollo.
  2. Todo el equipo comparte la misma visión del proyecto. El esfuerzo es compartido por todos los involucrados evitando sorpresas cuando un fuego obliga a cambiar las funcionalidades según las restricciones que presenten los involucrados como prioridades o el mismo proyecto en tiempo o coste.
  3. Mantener equilibrio constante. En el momento que aparece un fuego hay que tomar medidas para apagarlo evitando así perder el control del proyecto.

Por desgracia este año no ha sido posible grabar en vídeo las presentaciones pero pasados unos días seguro que se publican las diapositivas, sin embargo, con únicamente las diapositivas pierde mucho del contenido respecto a la presentación dada en vivo. En algunas presentaciones al menos se ha recogido el audio:

  • Desarrollo de aplicaciones web con .NET en MAC: open source, multiplataforma e incluso gratuito por Ibon Landa Diapositivas
  • Errores comunes en la visualización de datos y algunas soluciones por Pablo Garaizar Diapositivas Audio
  • Creando directivas para AngularJs por Hugo Biarge Diapositivas y demos
  • ReactJS: un enfoque distinto a la UI en JavaScript por Eduard Tomás Diapositivas
  • Wordpress al límite por Asier Marqués Audio
  • Arquitectura de CartoDB por Javi Santana Audio

También en una lista de reproducción de YouTube de elComite están disponibles casi todas las presentaciones de las ediciones 2012, 2013 y 2014 con las que saciar tu curiosidad. Para el año que viene si tienes posibilidad de ofrecerte para grabar las presentaciones con una cámara para poder publicarlas más tarde casi seguro que los organizadores estarían agradecidos y dispuestos a darte facilidades para ello.

Nuevamente esta edición de la BilbaoStack ha sido excelente gracias a sus organizadores, ponentes, Universidad de Deusto y asistentes, esperemos que en el 2016 continuemos disfrutando de esta gran conferencia.

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

El blog de Adrián Arroyo

Post Mortem de Torre Utopía

January 21, 2015 11:00 PM

Torre Utopía

Image http://adrianarroyocalle.github.io/torre-utopia 1.0 html5
Adrián Arroyo Calle
2014

Torre Utopía fue un juego diseñado con el objetivo de ser creado en menos de un mes usando solo mis ratos libres. Para facilitar el trabajo había diseñado un conjunto de librerías y scripts en lo que denomino esqueleto. Este esqueleto es open-source y lo podeis encontrar en GitHub.

Desarrollo

Elevator Action
Torre Utopía esta fuertemente inspirado en Elevator Action. Inicialmente iba a ser un clon del juego pero según avanzó el desarrollo del juego vi partes que no eran fáciles de implementar y que requerirían un rediseño. Estoy hablando sobre todo del scrolling. Torre Utopía inicialmente fue pensado para ser programado en TypeScript que es como el esqueleto lo admite por defecto. Sin embargo terminé usando muy poco las características de TypeScript. Creo que porque no tengo soltura suficiente todavía en TypeScript como para usarlo correctamente. Aun así la inclusión fue positiva en cierto punto porque el compilador era capaz de avisarme de variables no definidas, un error que en JavaScript corriente es tedioso de solucionar pues debes mirar la consola del navegador.

Un acierto, creo yo, fue usar gráficos pre-generados para ir probando las mecánicas. Esto facilita mucho desde el principio saber como va a quedar cada cosa. Sin embargo, este arte pregenerado no fue sustituido al final enteramente dando una mala imagen al espectador. Realmente se cambiarón muchos gráficos pero la falta de tiempo hizo que tuviesen poco nivel de detalle. Una cosa que no me gustó fue que el personaje se moviera mirándote a ti. Y me cabrea más cuando pienso que hacerlo bien es muy sencillo de implementar.

La música era repetitiva y sin copyright pero quizá debería haber un botón para acabar con el dolor de oídos que genera escuchar una y otra vez lo mismo durante varias horas. Aunque el tema del audio lo implementé casi al final. Sin embargo no fue difícil alterar el resto del código para que al subir el ascensor sonase (aunque es posible que con algo de retardo).

La fuente usada quería que fuese estilo pixel para que encajase mejor; fue más difícil de lo que esperaba. Al final encontré una que encajaba con el estilo que quería dar y era gratuita.

TorreUtopia

Distribución

Una vez di por terminado el juego empezó la distribución. Estaba un poco impaciente porque era la primera vez que iba a publicar en tantos sitios a la vez. Sin embargo el tema de crearse cuentas en tantos sitios hizo que me decantase solo por 5 distribuidoras. Estas han sido:

Kongregate

Kongregate

Simple y directo. Me publicaron el juego en poco tiempo y recibí comentarios de usuarios en el juego. Cuando miré por primera vez había generado 4 céntimos de euro. Lo más molesto de Kongregate es el tema fiscal. Ellos insisten en que lo cumplimentes todo aunque no es necesario. Esto es porque se pueden ahorrar impuestos (y tú ganar más) si lo cumplimentas. Para los que no lo conozcan en Kongregate ganas dinero por la publicidad que se ve en Kongregate cuando gente juega a tu juego. Es un portal de juegos pero con mucho tráfico.

FGL

Originalmente diseñado para juegos Flash se ha adaptado y ofrece ahora también para HTML5 y Unity. FGL tiene muchas opciones de distribución y para un principiante puede ser confuso. Por suerte, FGL tiene ayudas en los márgenes muy útiles. En FGL ganamos dinero si nos compran el juego para publicarlo en portales de juegos. Todavía no he recibido ninguna oferta (tampoco espero, es mi primera vez) y se encargan de hacerte una valoración con nota en diferentes aspectos. En mi corta experiencia con FGL puedo decir que los administradores ayudan mucho (me enviaron correos varias veces para comunicarme fallos y como podría mejorar ciertas cosas)

MarketJS

MarketJS es como FGL pero centrado exclusivamente en HTML5. Mal. Creí que por estar centrados en HTML5 (y obviamente más nuevos en el mundillo) tendrían algo más de simpatía. No sé si será la plataforma (mucho más verde en todos los aspectos) pero no recibí respuesta al publicar el juego. Semanas más tarde les envié un correo personalmente. Su respuesta fue que cambiase la imagen de la descripción. La cambié. Volví a publicar. Y ya está. Ninguna respuesta.

Clay.io

Ya les conocía y el proceso es el habitual, algo mejor que de costumbre y todo. En Clay.io ganamos dinero por anuncios como Kongregate, pero también nos pueden comprar el juego como FGL y tiene un tercer modo que es dejar a los portales de juegos el juego tal cual y por los anuncios de Clay.io recibiremos dinero como si fuera en el propio sitio. Puse un anuncio de vídeo al principio y nada más. Y todavía no he ganado nada pero es más sospechoso si pensamos que Clay.io ha añadido mi juego a más portales con el tercer sistema como html5games.club

Firefox Marketplace

Firefox OS
Una tienda al estilo Google Play o App Store pero para Firefox OS. Fue aprobado y está disponible pero en esta versión no he añadido anuncios. Comentar que en Firefox Marketplace obtienes los certificados PEGI, ESRB y parecidos de manera gratuita, aunque solo valen para Firefox OS. Las certificaciones en principio te las dan según rellenas unas preguntas sobre el juego. Además hacen pruebas aleatorias cada institución y por ello pueden cambiarte la calificación. En mi caso ESRB me daba T y PEGI me daba +7. Pero en diferentes análisis (llegaron en diferentes meses) me dijeron que al estar los gráficos muy pixelados la violencia que contiene el juego es mínima, por ello actualmente tengo en ESRB la E y en PEGI +3.

Recepción

Vamos a ver las críticas del juego a día de hoy:

  • Firefox Marketplace: Es como wrecking cree pero más chafa 4/5
  • FGL: Definitely not my type of game, but could be fun. You need to think about touch controls (how will one play it on a mobile browser) and also improve graphics, like game over screen for example.
  • FGL: I like the concept for the game! Although the graphics needs some serious improvment but I think that the game could be fun with new graphics and some polish!
  • FGL, la review oficial: _
    Intuitiveness: 5 Needs Improvement
    Fun: 6 Average
    Graphics: 5 Needs Improvement
    Sound: 6 Average
    Quality: 6 Average
    Overall: 6 Average
    Comments:
    Instructions should be included in game. No-one will understand what’s going on without them.Graphics are poor. They’re programmer’s art, not professional finished product. They’re basic and very static(lack of animations). Need to be changed. Music is little low-quality. Also, there should be mute button on every screen. It’s very frustrating for players if they can’t mute music, especially if it’s annoying. There should be always a way back to main menu(Home button or something like that). Policemans are staying in the same place as player and they can’t shoot him if you don’t move. There should be some text on main menu saying “Press anything to play”._
  • Firefox Marketplace, un comentario oficial: The game doesn’t cover large screens.
  • Kongregate: Nice game, i recomend adding a menu, and make AI on the enemies.

Conclusión

Hay que mejorar el esqueleto npm, el audio, los sprites (aunque seguiré usando gráficos pre-diseñados al principio). También creo que debe haber un menú, un sistema de anuncios integrados fácilmente desactivables via parámetros GET, integración con Google Analytics, ajustes para quitar el sonido, etc. Espero mejorar todos estos (y más aspectos que seguro que me olvido) para futuros juegos.

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

Arragonán

Semana 345

January 19, 2015 03:55 PM

Esta semana movidita, en la que tocó invertir tiempo en posibles nuevos proyectos, además de irse a Bilbao el fin de semana por doble razón: tener una sesión de trabajo conjunta con Nagore y asistir de nuevo a la BilboStack. La verdad que últimamente siempre vuelvo encantado con la gente de Bilbao, nos tratan genial.

Respecto a los nuevos proyectos, tuve que rechazar una oferta de colaboración como contractor para una startup madrileña. Le di bastantes vueltas, ya que aún siendo un proyecto a priori bastante bonito y que por algunos aspectos me atraía, había otras cuestiones que no terminaban de encajarme y finalmente decidí descartar trabajar en ese proyecto. Por otro lado, seguí en conversaciones para terminar de valorar otro para el que me contactaron a finales de año.

Y además de tener que hacer la recopilación trimestral, estos fueron los proyectos a los que dediqué mi tiempo:

  • Durante mi estancia en Bilbao trabajamos sobre Outreach Box. Tanto de lo que va a haber en el próximo par de semanas en la nueva web, como en la versión inicial del software que empezará a dar soporte a la parte de definición de estrategias de comunicación.
  • En Bichomanía estuve dedicando algo más de tiempo en conocer spree y en ver la actual tienda online para empezar a pensar en la importación de datos, cosa con la que espero empezar esta semana.
  • Con Besepa dejé cerca de terminar la extracción del servicio que empecé la semana previa y ya sólo quedan algunos flecos para darlo por finalizado.

Buena semana.

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

Variable not found

Enlaces interesantes 183

January 19, 2015 12:54 PM

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

Eventos

.Net

ASP.NET

Azure / Cloud

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

Especificación de tipos en ReactJS con propTypes

January 19, 2015 05:06 AM

En las últimas semanas he dedicado bastante tiempo a desarrollar una aplicación real con ReactJS y eso me ha permitido ver cómo se comporta la librería en un proyecto más complejo que los típicos tutoriales.

Entre mixins, funciones ligadas al ciclo de vida del componente y demás particularidades de ReactJS (de las que seguro que acabaré escribiendo algo), hay una funcionalidad que me ha resultado especialmente útil: la validación de propiedades usando propTypes.

En este post vamos a ver qué es propTypes, pero además veremos cómo podemos mejorar lo que nos ofrece ReactJS de serie y qué otras ventajas nos aporta el uso de propTypes.

Pero vayamos por partes…

Qué es eso de propTypes

Cuando hace un tiempo explicaba cómo crear un componente en ReactJS, veíamos que necesitamos definir una función render que se encargase de devolver el (Virtual) DOM asociado al componente, y que el componente podía recibir información inmutable de su componente padre a través del objeto this.props. Si todo esto te suena a chino, puedes revisar cómo funciona ReactJS.

La propiedad propTypes podemos incluirla en el objeto que usamos para definir nuestro componente de ReactJS y nos permite establecer una serie de validaciones que se realizarán sobre las propiedades recibidas por el componente en el momento de su creación.

Podemos realizar validaciones de distinto tipo. Lo más sencillo es validar el tipo de la propiedad, por ejemplo si es un number, o un string o un array. Podemos también indicar si la propiedad es opcional o es obligatoria. Podemos definir la “forma” que tendrá la propiedad, es decir, podemos por ejemplo definir que será un objeto que contendrá una propiedad id de tipo number y una propiedad name de tipo string. Incluso podemos añadir una función de validación con lógica personalizada para validar la propiedad.

Como ejemplo, podríamos pensar en un componente que muestra los datos de un usuario (id, nombre y rol) y permite guardarlo o eliminarlo. El uso de ese componente sería algo así:

<UserEditor user={theUser} onSave={saveUser} onDelete={deleteUser} />

El componente recibe a través del objeto props los datos actuales del usuario y las funciones que deberá invocar para guardar y eliminar el usuario. Esto podemos validarlo de la siguiente forma:

var UserEditor = React.createClass({
  propTypes: {
    user: React.PropTypes.shape({
      id: React.PropTypes.number.isRequired,
      name: React.PropTypes.string.isRequired,
      role: React.PropTypes.oneOf(['admin', 'power user', 'user'])
    }).isRequired,
    onSave: React.PropTypes.func.isRequired,
    onDelete: React.PropTypes.func.isRequired
  }
});

En ese código se pueden ver unas cuantas de las opciones existentes para definir la validación de las propiedades, como el uso de shape para definir estructuras más complejas (el “tipo” user) o el oneOf para definir “tipos” enumerados. En la documentación de ReactJS.propTypes podéis ver todas las opciones existentes.

Aumentando el efecto de la validación

Con esto hemos definido el aspecto que deberían tener las propiedades que recibe un componente pero, ¿qué pasa cuando hay algún error?

Si estamos ejecutando la versión de producción de ReactJS, no pasa absolutamente nada. ReactJS desactiva la validación de propiedades cuando ejecutamos la versión de producción de la librería por motivos de rendimiento.

Si estamos usando la versión de desarrollo de ReactJS, cuando se produzca un error de validación se mostrará un warning en la consola. Sí, sólo eso, un triste warning en la consola de Javascript del navegador que, probablemente no lleguemos a ver.

Para mejorar esto y utilizar la validación de propiedades de una forma más cercana a lo que serían precondiciones en diseño por contrato podemos aprovecharnos de que Javacript es un lenguaje dinámico y aplicar un poco de monkey patching sobre el objeto console:

function setReactWarnsAsErrors() {
  var warn = window.console.warn;

  window.console.warn = function() {
    if (arguments && arguments[0].match(/(^Warning: )|(react)/)) {
      throw Error(arguments[0]);
    }
    warn.apply(window.console, arguments);
  };
}

window.onError = function(error) {
  window.alert('Unexpected Error: ' + error);
}

setReactWarnsAsErrors();

No es que sea una solución muy limpia (más bien todo lo contrario), pero al menos mientras estamos desarrollando los avisos nos saltarán como errores y podremos detectar problemas más fácilmente.

Ventajas adicionales

El uso de los propTypes tiene algunas ventajas adicionales que hace que sean especialemente interesantes desde mi punto de vista.

Por una parte, nos permite identificar el API del componente de una forma más cómoda.

Un problema que existe al definir un componente en ReactJS es que lo único obligatorio es definir su método render, y éste no recibe ningún parámetro. Esto hace que si queremos saber qué propiedades debemos pasarle al componente tengamos que leer todo el código del método render para saber qué propiedades son necesarias.

Al definir la validación de las propiedades con propTypes tendremos documentado en un punto todo lo que necesita el componente para trabajar y nos ayudará a utilizarlo en el futuro. Es una buena forma de ahorrarnos un comentario de documentación.

Por otro lado, en aplicaciones Javascript es muy frecuente que trabajemos con un modelo de datos que está definido de forma externa a nuestra aplicación. En lugar de definir mediante funciones contructoras los objetos con los que vamos a trabajar, estos objetos llegan serializados en JSON desde APIs externas y, si queremos saber el contenido de esos objetos tenemos que saltar a otro proyecto o a consultar la documentación del servicio que estamos consumiendo.

Podemos utilizar propTypes para documentar el modelo de objetos dentro de la aplicación Javascript, pero con la ventaja de que no hace falta realizar una conversión entre el objeto JSON y el objeto construido, ya que sólo definimos la forma, no el “tipo”. Duck Typing en estado puro.

Además, podemos organizar la definición de estos objetos de manera que sea fácil de reutilizar en lugar de definirlos inline en cada componente. Así, en el ejemplo anterior del usuario podríamos tener:

// Fichero: AppTypes.js
var AppTypes = {};

AppTypes.role = React.PropTypes.oneOf(['admin', 'power user', 'user']);
AppTypes.user = React.PropTypes.shape({
  id: React.PropTypes.number.isRequired,
  name: React.PropTypes.string.isRequired,
  role: AppTypes.role.isRequired
});

// Fichero UserEditor.jsx
var UserEditor = React.createClass({
  propTypes: {
    user: AppTypes.user.isRequired,
    onSave: React.PropTypes.func.isRequired,
    onDelete: React.PropTypes.func.isRequired
  }
});

De esta forma, podemos organizar la definición de los “modelos” usados por los componentes de la manera que queramos, por ejemplo en un único fichero si la aplicación es lo bastante simple, y también podemos reutilizar esa definición de “tipos” en todos los componentes que vayan a trabajar con ellos.

Conclusiones

Hacer aplicaciones de juguete está muy bien para familiarizarse con una tecnología, pero hasta que no desarrollas una aplicación de un cierta complejidad, hay partes que no llegas a apreciar.

El uso de PropTypes no es algo a lo que se le dé mucha importancia en los típicos tutoriales y presentaciones sobre ReactJS, pero para nosotros ha sido extremadamente útil en la vida real.

Las ventajas que aporta en cuanto a validación de precondiciones, documentación del API de los componentes y documentación del modelo de la aplicación son lo bastante grandes como para que merezca la pena su uso.

Seguro que alguno de vosotros estará pensando que todo esto es necesario únicamente porque Javascript es un lenguaje de tipado dinámico. Tiene toda la razón del mundo. Si usásemos otro lenguaje con tipado estático y un sistema de tipos medianamente decente, todo esto no sería necesario (y tendríamos alguna ventaja más), pero esa es otra discusión distinta.

Posts relacionados:

  1. Crear un componente con ReactJS
  2. Cómo utilizar ReactJS con Browserify
  3. Rutas en ReactJS con React Router

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

Blog Bitix

Cómo hacer un substring de una cadena HTML

January 16, 2015 12:03 PM

Java

Una de las cosas que he tenido que resolver en Blog Stack es como conseguir un extracto del contenido completo de una cadena que es HTML. Esto lo he usado en los diferentes feeds de Blog Stack donde solo se muestra el extracto de cada artículo y no el texto completo. A primera vista puede parecer fácil pero no lo es tanto, cortar una cadena que es html haciendo un substring puede ocasionar problemas si se hace en un mal punto de la cadena y luego esa cadena cortada se inserta como contenido de nuevo el una página web. Lo más probable que ocurra es una desmaquetación de la página o que los estilos aparezcan mal pero puede dejar estropeada la página completa.

Por ejemplo, si tenemos la siguiente cadena y la cortamos en un mal punto y luego insertamos en una página html ese contenido lo que ocurrirá es que todo el texto a continuación de él aparecerá en negrita.

<noscript><pre><code>&lt;strong&gt;Lorem ipsum ad his scripta blandit partiendo, eum fastidii accumsan euripidis in, eum liber hendrerit an.&lt;/strong&gt;</code></pre></noscript>

<noscript><pre><code>&lt;strong&gt;Lorem ipsum ad his scripta blandit partiendo, eum fastidii</code></pre></noscript>

Usar una expresión regular tampoco es solución, con alguna puede parecer que en algún caso funciona pero posiblemente para cada expresión regular podamos encontrar un html para el que no sirva. La expresión regular puede ser complicada.

Para dar solución a este problema podemos emplear jsoup. Jsoup es una librería Java que nos permite manipular el html, desde extraer en forma de texto plano el contenido hasta modificar el html empleando una API. Empleando esta librería podemos ir extrayendo el contenido para contar cuantos caracteres de texto contiene el html y a la vez crear un extracto del documento html.

<noscript><pre><code>public String getContentExcerpt() { Document document = Jsoup.parse(getContent()); final StringBuffer excerpt = new StringBuffer(); final List&lt;Node&gt; nodes = new ArrayList&lt;&gt;(); document.traverse(new NodeVisitor() { @Override public void tail(Node node, int depth) { } @Override public void head(Node node, int depth) { if (excerpt.length() &gt; Globals.POST_EXCERPT_LENGHT) { nodes.add(node); } if (node instanceof TextNode) { TextNode textNode = (TextNode) node; excerpt.append(textNode.text()); } } }); for (Node node : nodes) { node.remove(); } return document.body().html(); }</code></pre></noscript>

Empleando esta librería la cadena del ejemplo anterior podría quedar:

<noscript><pre><code>&lt;strong&gt;Lorem ipsum ad his scripta blandit partiendo, eum fastidii&lt;/strong&gt;</code></pre></noscript>

El resultado aplicando está solución puede verse en el feed de la portada de Blog Stack donde se muestra una entradilla o extracto del inicio del contenido de cada uno de los artículos.

El código fuente de Blog Stack está disponible en un repositorio de GitHub donde puede verse el código completo.

Referencia:
Qué es y cómo hacer «web scraping» en Java
Cómo filtrar contenido HTML de forma segura

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

Blog Bitix

Qué es y cómo hacer «web scraping» en Java

January 16, 2015 11:00 AM

Java

Algunas aplicaciones en internet necesitan intercambiar información para hacer algún tipo de integración. La tendencia actual es proporcionar una API REST o algún tipo de archivo descargable con cierto formato que permita procesarlo de forma automatizada y a las aplicaciones obtener la información de forma sencilla y precisa. Sin embargo, hay ocasiones en las que las aplicaciones de las que necesitamos extraer la información no proporcionan ni una API REST ni un archivo descargable con lo que no nos queda más remedio que extraer los datos de la propias páginas web inspeccionando el código HTML, esto en inglés se le conoce como «web scraping».

En este artículo explicaré como hacer web «scraping» usando la librería jsoup y usando el lenguaje de programación Java. jsoup proporciona una API para poder extraer la información que necesitemos, ya sean las URLs de los enlaces, determinado texto que contiene una valor, imágenes, … . A través de los selectores similares a los usados en jquery podemos llegar a los elementos que queremos de forma simple sin tener que hacer complicados algoritmos.

Dada la URL, archivo o String con contenido HTML podemos extraer los enlaces de imágenes, enlaces, hojas de estilos, iconos como se muestra en el siguiente ejemplo:

http://jsoup.org/cookbook/extracting-data/example-list-links

Un ejemplo práctico en el que podríamos hacer «scraping» es por ejemplo para extraer los enlaces torrent de descarga de todos los libros de un determinado autor o determinada serie de la página epublibre, esto nos ahorraría tener que hacerlo manualmente. Además si usamos transmission a través de su API podríamos automatizar la descarga.

El algoritmo o algoritmos que necesitemos para extraer la información será específico según la estructura HTML de cada página web, si esta cambia deberemos cambiar el algoritmo o los selectores, en cualquier caso es mejor que tener que hacer la tarea manualmente constantemente que al cabo de un tiempo será tediosa, aburrida y repetitiva.

Pero hay que tener cuidado con el contenido «scrapeado» y se debe tratar como una fuente de datos no segura. Por seguridad hay que tener especial cuidado con los scripts del contenido importado que podrían hacer que nuestra aplicación al mostrarlos tuviese algún problema de seguridad. La siguiente semana explicaré como «scrapear» contenido de forma segura en un ejemplo real como es el agregador de bitácoras Blog Stack donde solo se permiten los scripts de fuentes consideradas seguras como presentaciones de Speakerdeck, Gist de GitHub, YouTube, Vimeo o publicidad del programa de afiliados de Amazon.

Referencia:
Cómo filtrar contenido HTML de forma segura
Como hacer un substring de una cadena html

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

Variable not found

Top posts 2014 en Variable not found

January 12, 2015 07:47 AM

imageComo de costumbre, aprovecho estas primeras palabras del año para desearos de todo corazón un 2015 fabuloso en todos los aspectos. A ver si el oráculo empieza a tener razón, las cosas mejoran un poco y podemos acabar este año recién estrenado siendo un poco más felices.

Y también como parte de la tradición, dedicaremos este post a repasar qué entradas fueron las diez más visitadas en el pasado año, que más o menos da una idea de los intereses que nos han movido a todos durante la pasada temporada.


Y en la primera posición se encuentra la entrada “vNext”. Un conciso título para un gran mensaje de fondo: “iros agarrando los machos” ;) En este post se sobrevolaba a vista de pájaro las novedades anunciadas en el TechEd Norte América para la próxima versión de ASP.NET, y que parece ser que interesó bastante entre los seguidores del blog.

En segundo lugar está “El operador “-.” en C# y VB.NET, más cerca”, un post que adelantaba que el operador de navegación segura se estaba postulando como firme candidato para las siguientes versiones de C# y VB.NET, como después hemos podido confirmar.

En tercer lugar, una prueba de que los desarrolladores queremos hacer mejor las cosas. “TempData sin variables de sesión en MVC” describía cómo modificar la forma en que MVC almacena por defecto el contenido de la colección TempData, implementando esta característica sobre las cookies del navegador. En el fondo, era también una buena excusa para volver a revisar el interior del framework MVC y sus posibilidades de extensión.

A continuación, tenemos un post muy rápido en el que simplemente anunciaba la disponibilidad de un documento oficial en PDF con una minuciosa descripción del Ciclo de vida de una aplicación ASPNET MVC 5. Un documento imprescindible si queréis conocer cómo funcionan las cosas por dentro, y cuya buena acogida dejó claro que es un tema que tiene tirón.

Seguimos con el post “Ejecutar tareas en segundo plano en ASP.NET 4.5.2”, la solución a un problema clásico en el mundo del desarrollo sobre ASP.NET, gracias a la introducción de nuevas características en la última actualización del marco de trabajo.
SignalR book in japanese
En sexto lugar, probablemente por las visitas de mi familia y amigos ;), el post donde anunciaba oficialmente la publicación de mi libro “Ya está aquí- SignalR Programming in Microsoft ASPNET”.

Y ya que habéis sacado el tema, os contaré que las críticas, aunque escasas, han sido muy buenas hasta el momento: 4.7 sobre 5 en Goodreads y 4.5 sobre 5 en Amazon, Todo un orgullo y una satisfacción, como diría aquél ;)

Pero no acaban aquí las sorpresas con el libro: hace poco me avisaban mi amigos de Krasis, coprotagonistas en estas andanzas literarias, que ha sido traducido y publicado en idioma japonés :-) Así que ya sabéis: si con la versión en inglés no os quedó algo claro, aún podéis haceros con esta, a ver qué tal.

Bueno, seguimos, que me despisto O:)

En séptima y octava posición encontramos, respectivamente, el primer y segundo artículo de una serie de tres sobre “Attribute routing en ASPNET MVC y Web API (I)” en la que vimos detalladamente este mecanismo introducido en MVC 5 y Web API con objeto de ayudarnos a configurar más fácilmente las rutas de acceso a nuestras acciones en aplicaciones o servicios.

Sidewaffle, gran pack de plantillas para Visual Studio es el post que encontramos en novena posición. Esta extensión de Visual Studio, básicamente un pack de plantillas de proyectos y otros artefactos, me pareció muy útil por su amplitud y el trabajo que podía ahorrar en muchos escenarios. Y dado que está en el top ten, parece que a vosotros también os interesó el tema.

Por último, cerrando esta lista, y como todos los años suele pasar, se coló a última hora el tradicional post del día de los inocentes, que esta vez dedicaba a dar la noticia de que “Visual Studio 2015 considerará las faltas de ortografía como errores de compilación”. Por los comentarios recibidos a través de distintos medios, estoy por proponerlo en User Voice, a ver si se tiene en cuenta… :-DDD

Aparte de estos posts, publicados todos ellos a lo largo de 2014, Variable not found sigue atrayendo bastantes amigos gracias a artículos de años anteriores, entre los que destacan:
¡Y esto es todo! Espero que os haya resultado interesante para conocer algún artículo que os perdisteis en su momento o para rememorar viejas glorias ;)

Publicado en Variable not found.

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

Koalite

¿Adios .NET, hola Java?

January 12, 2015 05:06 AM

Hace ya unos cuantos meses que llevo dándole vueltas a la posibilidad de migrar parte de las aplicaciones que desarrollamos profesionalmente a entornos Linux.

Hasta hace poco esto era algo impensable, ya que desarrollábamos aplicaciones de escritorio basadas en .NET y aplicaciones para dispositivos móviles con Windows Mobile, pero últimamente cada vez son más las aplicaciones basadas en HTML5 que forman parte de nuestro software para punto de venta.

Ese paso a aplicaciones HTML5 ha permitido que muchos de los clientes que se conectan al servidor central (desplegado localmente o on-premises, para los modernos) sean dispositivos con Android, iOS o incluso Linux.

¿El motivo fundamental? El coste del hardware y el coste de la licencia. Cuando tienes un equipo dedicado en exclusiva a realizar una tarea profesional, muchas veces el sistema operativo importa muy poco puesto que el usuario sólo utiliza una aplicación, y el coste de una tablet malucha con Android es mucho más bajo que el de cualquier PC con pantalla táctil y su correspondiente licencia de Windows.

Todavía tenemos una parte importante de aplicaciones que son aplicaciones de escritorio, pero parece plausible que a medio plazo éstas sean reemplazadas por sus equivalentes HTML5.

En un escenario así, lo único que seguiría dependiendo de Windows sería el servidor central, y la idea de poder desplegarlo en Linux resulta muy atractiva.

Por una parte, está el ahorro directo del coste de licencia, que para nuestros clientes es importante. Estamos hablando de licencias de menos de 100€, que para los que estáis en mundos enterprise os parecerá algo ridículo, pero la realidad es que en mi sector, ese coste se nota.

Por otra, evitaríamos depender de la estrategia de negocio de Microsoft y tendríamos más libertad a la hora de decidir qué versiones de sistema operativo utilizar (el fin de soporte para Windows XP ha sido incómodo en nuestro sector).

.NET Core como solución

Llegado a este punto, la opción más “lógica” para dar el paso a Linux sería aprovechar .NET Core. A fin de cuentas, una de las cosas que está “vendiendo” Microsoft de su nueva versión de .NET es que será multiplataforma.

Viéndolo así, no hay mucho que pensar. Seguiríamos utilizando .NET, con las herramientas que conocemos de hace mucho tiempo, el lenguaje que llevamos utilizando más de diez años y un framework con el que estamos familiarizados, pero además ganaríamos soporte multiplataforma. Todo perfecto, ¿no?

Pues no tanto, la verdad. Resulta que .NET Core no es realmente compatible hacia atrás y no es tan sencillo migrar una aplicación compleja realizada con, por ejemplo, .NET Framework 3.5 a .NET Core. Frans Bouma escribía sobre ello hace unos meses cuando evaluaba la posibilidad de migrar su ORM (LLBLGen) a .NET Core.

En ese sentido, incluso desde Microsoft hay quien recomienda actualizar las aplicaciones ya existentes a .NET Framework 4.6 en lugar de a .NET Core:

My personal advice? if you’re going to migrate an application, bet for ASP.NET 5 running on the regular CLR.

Para los que no estéis familiarizados con las nuevas versiones del Framework, al hablar del regular CLR se está refiriendo a .NET Framework 4.6, que será la evolución del actual .NET Framework 4.5 y que sólo tendrá soporte para Windows.

En el fondo, es razonable. Una de las partes buenas de .NET Core es que pretende “limpiar” el kipple acumulado en el framework durante todos estos años para hacerlo más modular y liviano, y además existen partes del framework que están íntimamente ligadas a Windows, por lo que es necesario hacer algo con ellas para poder utilizarlo en otras plataformas.

El hecho es que hay partes que para nosotros son importantes, como el caso de ORMs potentes, contenedores de inversión de control o soporte para determinadas bases de datos que, actualmente, no están soportados en .NET Core y no está muy claro que lo vayan a estar en el futuro.

Cuando empiezas a considerar todo esto y te das cuenta de que la transición no es directa, en parte por las características (yo no lo llamaría limitaciones) de .NET Core, y en parte por las propias dependencias que tiene nuestra aplicación sobre Windows (uso del registro de Windows, ejecución como servicio, etc.) y determinadas librerías, resulta que tal vez el esfuerzo sea lo bastante grande como para poder plantearse el paso a otras plataformas.

Aquí podríamos empezar a culpar a nuestra aplicación por estar acoplada a Windows, a un ORM o a lo que queramos. La realidad es que en su momento esas decisiones parecían razonables, nos han permitido obtener muy buenos resultados de negocio y, en cualquier caso, ahora simplemente es lo que hay y forman parte del escenario del que partimos. Tampoco creo que se trate de algo tan extraño dentro del mundo de .NET.

La JVM como alternativa a .NET Core

Decir esto en este blog es casi una herejía, pero lo cierto es que después de pensar un poco sobre el tema, cada vez me parece una alternativa más razonable para conseguir mi objetivo, que es acabar ejecutando nuestro servidor sobre Linux.

Dos de las cosas que ofrece .NET Core y que más se están publicitando en círculos afines a Microsoft, el ser open source y el ser multiplataforma, son algo que tiene Java desde hace mucho, mucho tiempo. La parte de open source, aun siendo importante, me importa algo menos en este momento, pero el multiplataforma, Linux first (o al menos Linux first-class), sí es crítica para lo que estoy buscando.

Al llevar tanto tiempo disponible para plataformas Linux, la estabilidad de la JVM está mucho más contrastada que la que tendrá .NET Core cuando por fin esté disponible para Linux (hoy en día se está usando Mono, cuya estabilidad y rendimiento no es comparable al de la JVM).

El esfuerzo de convertir una aplicación desarrollada en C# a Java (o posiblemente otro lenguaje sobre la JVM como Scala) no es despreciable, pero tampoco se trata de una tarea imposible. Además, viendo las limitaciones actuales en cuanto a disponibilidad de librerías para .NET Core, tal vez no fuese mucho mayor que el de convertir una aplicación de .NET Framework 3.5 a .NET Core. Sólo prescindir de NHibernate para utilizar Entify Framework 7, con todas sus limitaciones iniciales, ya supondría un trabajo considerable.

Precisamente muchas de las librerías que utilizamos actualmente, como NHibernate, NUnit o log4net son ports casi directos de sus equivalentes Java, por lo que ya estamos familiarizados con sus APIs y su funcionamiento general. Además, el paso a la JVM nos permitiría explorar otras vías que parecen interesantes, como el uso de Akka o Play.

En resumen

No pretendo convertir este post en un alegato sobre por qué Java es mucho mejor que .NET, porque sinceramente no creo que sea así. Cada uno tiene sus puntos fuertes y sus puntos débiles, y ambos han demostrado que son alternativas viables para desarrollar casi cualquier tipo de aplicación.

En mi caso, se trata simplemente de analizar dos alternativas para evolucionar a medio plazo un proyecto concreto, buscando un equilibrio entre estabilidad, coste de desarrollo y proyección de futuro. Cada escenario es diferente y merece una consideración aparte.

Lo que me resulta más curioso es que, hasta hace poco tiempo, para mi el mero hecho de plantearme cambiar .NET por la JVM era algo impensable, y sin embargo ahora me parece una alternativa razonable.

Por suerte no es una decisión que necesite tomar inmediatamente y eso me va a permitir ver cómo avanza .NET Core y cómo van resolviendo parte de los problemas que he descrito, por lo que cuando llegue el momento podré tomar una decisión basada en hechos más tangibles.

En cualquier caso, reescribir un sistema, ya sea para migrar a una plataforma o a otra, no deja de ser una decisión arriesgada y, posiblemente, errónea, por lo que es una decisión que no debe tomarse a la ligera. Veremos cómo acaba todo dentro de un tiempo.

Estoy seguro de que hay muchas cosas que se me escapan tanto de un entorno como del otro, y estaré eternamente agradecido al que lo indique en los comentarios.

Posts relacionados:

  1. Adios, Mocks

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

Navegapolis

Scrum funciona con capacidad, trabajo y compromiso.

January 11, 2015 04:17 PM

triadaEs posible que en determinados trabajos se necesiten personas con una de estas fortalezas:

Su capacidad de trabajo:
"Dame gente trabajadora, dispuesta a echar horas o fines de semana".

Su talento:
"No necesito gente para calentar la silla; quiero brain time, no body time".

O su nivel de compromiso:
"Quiero gente que sienta los colores, que se sienta empresa".

Sin embargo un equipo Scrum no funciona por su dedicación, talento o compromiso, sino por la combinación equilibrada de los tres. De hecho no es otro el motor de Scrum: gente capaz, comprometida y laboriosa, trabajando en equipo.

 

perfil equipo scrum

 

 

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

Arragonán

Semanas 343 y 344

January 08, 2015 02:18 PM

Con tanto festivo entre medio toca hacer resumen de las 2 semanas previas. La semana de nochevieja no fue apenas productiva, salvo algunas reuniones y ratos que me dediqué a desarrollar o a analizar posibles proyectos. En cambio en la siguiente hubo vuelta a la normalidad con fuerzas renovadas y saqué bastante trabajo adelante.

Además de por aquello de que se partía con un festivo en medio, la semana del cambio de año habíamos convocado desde Cachirulo Valley una quedada de fin de año, donde nos reunimos un buen puñado de gente del sector a tomar unas cervezas y cenar algo.

Esos días también tuve una reunión en remoto para un posible proyecto en el que se debería rehacer una aplicación web, se mantendría todo el frontend pero empezaría desde cero el backend.

Anunciamos Senpai Devs, algo en lo que llevamos trabajando un tiempo que se podría definir como una mentorización para desarrolladores a los que podamos ayudar que iniciaremos el mes de Febrero.

Entre resacas y días festivos estuve dedicando un tiempo a pensar y programar en un sideproject que me resulta útil a mi. Es un sideproject en el que estoy pensando invertir un poco más para tratar de darle más entidad y lanzarlo de forma en que me pueda dar un poco de rentabilidad.

Cerrando la semana pasada estuve dándole una vuelta a cómo plantear la posibilidad de colaborar como asesor técnico con una startup, sin entrar en el día a día del desarrollo. En ello sigo, ya que es la primera vez que se me presenta una colaboración de este tipo.

Mientras tanto en proyectos en los que trabajé este par de semanas:

  • Empecé a trabajar en investigar la migración de Bichomanía de su actual plataforma a una basada en Spree.
  • Pusimos en marcha la primera colaboración con Besepa, empezar a extraer parte del software que ya tienen desarrollado como un servicio independiente.
  • Tuve varias reuniones en torno a OutreachBox, relacionado con la versión que queremos lanzar inicialmente.

Buena semana.

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

Ingenieria de Software / Software Engineering / Project Management / Business Process Management

Empezando año 2015

January 05, 2015 02:14 PM

El año pasado tuve muy descuidado el Blog pero espero este 2015 retomarlo con mayor continuidad. Me encuentro con buen artículo sobre Business Analyst, que habla sobre las tendencias en el campo de Business Analysis, Este seguira siendo un factor de cambio en las empresas pero habrá que atender varios puntos como : Cloud, Project Management, skills, IIBA

http://www.modernanalyst.com/Resources/Articles/tabid/115/ID/3146/The-Top-10-Business-Analysis-Trends-for-2015.aspx

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

Picando Código

Arreglar una MacBook Pro horneándola

January 05, 2015 01:30 PM

Mac on Fire

La única Mac que ilumina es la que arde

Puede parecer una broma, pero no… Leí en Slashdot que el usuario de una MacBook Pro la pudo arreglar horneándola.

La computadora tuvo problemas de sobrecalenatimento por meses, alcanzando temperaturas superiores a los 100°C. Se podía calentar agua para el mate en esa computadora.

Al dejar de funcionar, un poco de investigación sugirió que la temperatura extrema hacía que la placa madre se flexionara y rompiera las conexiones soldadas.

La solución: soldadura por refusión, pero es demasiado complicado de hacer en una Mac Book Pro (así dice el artículo…).

Por lo tanto el usuario arregló su laptop Apple en el horno.

En vez de eso, abrí a la fuerza la parte de atrás de mi laptop, desconecté los once conectores y los tres disipadores de calor de la placa, y prendí el horno a 340 Grados Fahrenheit (~171°C). Puse mi parte de $ 900 en una bandeja de horno y la horneé por siete minutos enfermo de los nervios. Tras enfriarla, volví a aplicar la pasta térmica, armé todo de nuevo, y festejé cuando booteó. Anduvo bien por los próximos ocho meses.

Después de eso la laptop falló de nuevo y volvió a recuperarse con otro toque de horno. Si leen el artículo original enlazado en Slashdot, verán que además terminó haciéndole agujeros a la laptop con un taladro para que el aire circulara mejor y no se calentara tanto.

Personalmente recomendaría a los usuarios de Apple por lo menos probarlo, aunque sus dispositivos estén funcionando, seguramente van a estar mejor así. Y recuerden que también pueden cargar la batería de su iPhone en el microondas y quitar las marcas de dedos de las pantallas de sus iPads poniéndolo en la lavadora…

Hablando en serio, me imagino otra noticia en breve en los medios de comunicación: Usuarios de Apple indignados porque tras leer esa noticia intentaron arreglar sus computadoras metiéndolas en el horno y agujereándolas con un taladro. Terminaron con un ladrillo carbonizado muy caro en sus manos :D

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

Arragonán

Un repaso a mi 2014

January 02, 2015 03:56 PM

Aunque por aquí publico mis retros semanales, posiblemente no venga mal pegar un vistazo de un modo más global. Con el año nuevo me he reservado al fin un rato para parar, mirar atrás y escribir un pequeño resumen de lo que ha dado de sí el 2014. Año en el que he empezado a trabajar más como Biera Solutions SLU que como autónomo, aunque en realidad eso a mis clientes creo que les da un poco igual por el momento.

Lo primero en lo que me fijé, es que este año se ha agudizado todavía más una tendencia que empezó a ser muy visible el año pasado, mi facturación en Aragón es casi residual (no ha alcanzado el 10% del total). Tampoco es que me haya preocupado mucho en cambiar esa tendencia, porque tampoco es que haya hecho muchos presupuestos por mi tierra.

También en cuanto a facturación, algo de lo que era muy consciente, es que habría bajado respecto al año anterior. He dedicado bastante tiempo a proyectos propios y a temporadas decidí centrarme en ellos.

Mi colaboración con mhop siguió, a primeros de año aún como freelance, pero al poco tiempo entré como socio con una pequeña participación. Durante ese tiempo me he responsabilizado a llevar el apartado técnico y con ello sigo, aunque los últimos meses han sido más que nada cuestiones de mantenimiento y soporte. Un poco en paralelo, surgió OutreachBox, en el que también me he involucrado y del que ya iré escribiendo.

Durante el año resurgía y desaparecía el proyectoSinNombre, que venía arrastrándose desde final de 2013 y aún no ha visto la luz, aunque hace ya un par de meses que lo dejamos listo en un entorno de producción. Si no lo borro de mi memoria, quizás un día publique algo sobre el devenir de este proyecto. Una pena con lo bien que pintaba en sus inicios.

Casi hasta mediados de año continué trabajando con ShuttleCloud, ayudando a mantener o desarrollar algún nuevo scraper. Y aunque fuera un poco de rebote, mola haber participado en un proyecto para Google. Un placer que hubieran contado conmigo, son una de esas empresas de las que da gusto ser proveedor.

Más scraping dentro del pequeño proyecto doc, en el que tuve que hacer también un importador de contenidos para un wordpress.

Justo a inicio de verano comencé mi colaboración en Nort, un proyecto para en el que me integré en el día a día de un equipo de desarrollo como contractor, aunque trabajando en remoto. Era un proyecto bastante interesante para una multinacional en la que había desarrollo web y móvil, y del que me llevé mi primera experiencia desarrollando aplicaciones móviles híbridas.

Además de un puñado de pequeños sideprojects, a los que en algún momento quizás les dedique algo más de tiempo para probar hasta donde pueden llegar. Minchador recuperó cierto protagonismo, pero no el suficiente hasta el último trimestre en el que incluso estrenamos nuevo diseño.

Con CachiruloValley bajamos mucho el nivel de actividad. Aunque montamos nuestros primer “gran” evento: el Startup Open Space. Que para mi fue una buena paliza y gran acumulo de estrés, supongo que no supe delegar en muchas cosas de la organización… No digo más que al terminar el evento estaba convencido de no volver a participar en su organización, pero la perspectiva del paso del tiempo me hizo cambiar de opinión.

Otras comunidades o grupos en los que participé fue en Zaragozarb ayudando en temas organizativos y con un par de mini charlas, en un Betabeers Zaragoza y en el 2º Encuentro de Valleys. Y también asistí a unos cuantos saraos: BilboStack, Greach, UX Spain, Agile Open Space, UX Zaragoza, Jacathon Open Data, PyConES… además de ser habitual asistente en eventos de varios grupos locales, claro.

En fin, que desde luego que parados no hemos estado y, aún habiendo bastantes cosas en las que mejorar, no ha sido un mal año.

Feliz an nou!.

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

Picando Código

Cool Retro Term – aplicación que emula terminales antiguas

December 30, 2014 01:00 PM

cool-retro-term es un emulador de terminal con la apariencia y sensación de las antiguas pantallas de tubos de rayos catódicos. Está diseñada para ser visualmente atractiva, personalizable y relativamente liviana.

Cool Retro Term

No tiene mucho más funcionalidad que el aspecto retro de la terminal, pero está muy bien logrado. Cuenta con varios perfiles clásicos que podemos cambiar mientras la ejecutamos.

La instalación está bastante documentada en el Readme del proyecto. Por ahora hay paquetes para Fedora y openSUSE (desde Open Build Service), ArchLinux (en AUR) y Gentoo. También se puede instalar en Mac OS X. La documentación incluye las dependencias a instalar para usuarios de Debian, Ubuntu, Fedora, ArchLinux y OpenSUSE. Instalar en Debian Jesse fue bastante sencillo:

$ sudo apt-get install build-essential qmlscene qt5-qmake qt5-default qtdeclarative5-dev qml-module-qtquick-controls qml-module-qtgraphicaleffects qml-module-qtquick-dialogs qml-module-qtquick-localstorage qml-module-qtquick-window2
$ git clone --recursive https://github.com/Swordfish90/cool-retro-term.git
$ cd cool-retro-term/
$ qmake &amp;&amp; make
$ ./cool-retro-term

Y con la info de agregar aplicaciones al lanzador del sistema, puedo ejecutarlo fácilmente desde el lanzador.

Cool Retro Term

Cool Retro Term

Una vez ejecutado el programa, podemos esconder o mostrar la barra de menú con Ctrl + Shift + M y alternar la pantalla completa con Alt + F11.

Es un proyectito bastante interesante. Con el tiempo seguramente se vayan agregando más perfiles y con suerte eventualmente haya un paquete .deb para distribuciones basadas en Debian :)

» 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