Noticias Weblogs Foros Wiki Código

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

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

Microsoft Dynamics CRM Service Update

Enero 31st, 2012 - [Enlace local]

Me da gusto saber que en el próximo Service Update de CRM se podrá accesar a Dynamics CRM con los Navegadores Safari, Firefox y Chrome

En el siguiente link lo nuevo que se presento en el Service Update de Noviembre

http://blog.sonomapartners.com/2012/01/whats-new-in-the-microsoft-dynamics-crm-november-2011-service-update.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+typepad%2Fsonoma+%28Sonoma+Partners+Microsoft+CRM+Blog%29&utm_content=Bloglines

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

Bitácora de Javier Gutiérrez Chamorro (Guti) » Programación

Avances en la informática personal (I)

Enero 31st, 2012 - [Enlace local]

La informática es la disciplina con avance más rápido que ha existido, tanto es así que todos aquellos que seáis de mi generación, habréis podido ser testigos en primera persona de sus orígenes a principios de los años 80, hasta nuestra situación actual en 2012. Bien es cierto que a simple vista la cosa no [...]

Artículos relacionados:
Avances con SMETAR
Informática y coches
Record personal en Operation Wolf

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

xailer.info (esp)

CheckMenu

Enero 31st, 2012 - [Enlace local]

El control TCheckMenu representa un control tipo menú utilizando botones Checkbox y es prácticamente idéntico en funcionalidad al control TRadioMenu nativo del IDE con la diferencia que aquí podemos seleccionar varias opciones.

CheckMenu

Las únicas diferencias a tener en cuenta son dos:

En el ZIP se incluye la DLL y la librería para Xailer 2.5

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

Variable not found

Enlaces interesantes 69

Enero 31st, 2012 - [Enlace local]

Enlaces interesantesEstos son los enlaces publicados en Variable not found en Facebook y Twitter del 16 al 29 de enero de 2012. Espero que os resulten interesantes. :-)



.Net

Asp.net

Azure / Cloud

Conceptos

Data access

Html/Css/Javascript

Visual Studio/Complementos

Otros

Y no olvidéis que podéis seguir esta información en vivo y en directo desde Variable not found en Facebook, o a través de Twitter.



Publicado en Variable not found



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

Koalite's blog

Tutorial jQuery Mobile + Knockout (I): Sentando las bases

Enero 30th, 2012 - [Enlace local]

Tras la buena acogida que tuvo el tutorial de nodejs y express, me he decidido a preparar otro tutorial que sirva de introducción para un par de librerías con las que he estado jugando últimamente.

Igual que en el anterior tutorial, quiero dejar claro que esto es sólo una pequeña introducción a dos librerías que me parecen útiles. No se trata de un catálogo de buenas prácticas y habrá muchos puntos que puedan (y deban) ser mejorados.

En este caso vamos a crear una pequeña aplicación web para dispositivos móviles usando jQuery Mobile y Knockout. Como creo que es importante conocer las bases para poder entender lo que estamos haciendo, antes de empezar a implementar nada vamos a presentar a nuestros nuevos amigos.

jQuery Mobile

jQuery Mobile es un framework que nos permite crear aplicaciones para dispositivos móviles. Por tanto, está optimizado para su uso con pantallas de pequeño tamaño e interfaces táctiles encargándose de ajustar el interfaz de usuario de los controles estándar html para que sean más atractivos y manejables en un entorno móvil.

Se ejecuta por completo en el lado cliente, en este caso, el browser del dispositivo. Para emplearlo, debemos añadir lo siguiente a nuestra página web:

	
	
	

Podemos usar la versión descargada o enlazar directamente a una versión online, tal y como explican en la su página de descarga.

jQuery Mobile se basa en la asignación de roles a los distintos elementos html para atribuirles determinadas funciones dentro de la aplicación. A partir de estos roles, se ajusta el aspecto del elemento. Para asignar los roles a los elementos se usa el atributo data-role:

	

Una aplicación desarrollada con jQuery Mobile se estructura alrededor del concepto de página. Una página no es más que un div que tiene asignado el rol page, como en el ejemplo anterior. En un único documento html podremos tener varias páginas simplemente añadiendo varios divs con el atributo data-role="page", y jQueryMobile se encargará de mostrar en cada momento únicamente el div correspondiente a la página que esté activa.

Además del rol usado para marcar las páginas, existen otros roles muy útiles como header, footer, etc. que permiten representar otros elementos dentro de la página, o listview, button, etc. que se usan para crear controles con los que el usuario puede interactuar.

Si quieres conocer en profundidad las opciones que ofrece jQuery Mobile, te recomiendo que consultes su documentación.

Knockout

Knockout es una librería diseñada para aplicar cómodamente el patrón MVVM en aplicaciones javascript. Al igual que jQuery Mobile se ejecuta por completo en el browser por lo que deberemos incluirla en el código de nuestras páginas:

	

Para poder trabajar con Knockout es fundamental conocer el patrón Model-View-ViewModel. Resumiéndolo (mucho) podríamos decir que se basa en organizar la aplicación en torno a 3 conceptos:

Knockout nos ofrece una manera muy sencilla de enlazar View y ViewModel a través de data binding. Este data binding se hace de forma declarativa usando atributos data-bind:

    

Las posibilidades que ofrece Knockout para realizar el data binding son de lo más variado y podéis consultarlas en la documentación de Knockout.

Para que funcione esto del data binding es fundamental poder detectar los cambios en los valores de los controles para propagarlos al ViewModel, pero también es necesario poder detectar los cambios en el ViewModel para propagarlos a la vista. En este aspecto Knockout cuenta con su propia implementación del patrón observer, a través de funciones como ko.observable.

¿Cuándo empezamos?

En el siguiente post veremos cómo es la aplicación de ejemplo que vamos a hacer en este tutorial y prepararemos la estructura de páginas de jQuery Mobile que vamos a tener.




Compartir enlace:
Facebook Twitter Email

Posts relacionados:

  1. Tutorial node.js + express + jquery (III): Usando jQuery
  2. Tutorial node.js + express + jquery (IV): Conclusiones y próximos pasos
  3. Tutorial node.js + express + jquery (I): Creando la aplicación

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

Escuela De Codigo

CoffeeScript, El primer paso

Enero 30th, 2012 - [Enlace local]

En esta era de la web2.0, en la que toda actividad y aplicación es llevada a la internet, la nube, un lenguaje antes subestimado, se convirtió para sorpresa de algunos, alegría de otros y desdicha de pocos en un fuerte aliado para los desarrolladores, no hablo de HTML ni CSS sino del tercer componente del triunvirato de la web actual: Javascript.

Javascript un lenguaje interpretado, del lado de cliente, que en sus inicios se usaba en las paginas web para crear efectos de copos de nieve y tonterías de ese tipo. Ahora es el lenguaje sin el cual Gmail no fuera posible, facebook solo seria una galería de fotos aburrida y un twitt seguiria siendo el sonido que algunos creen que hacen los pájaros. Javascript se convirtió en un lenguaje muy importante. Pero, sigue manteniendo muchas cosas que aun no se ajustan al nuevo capricho de los desarrolladores actuales:Syntactic Sugar.

Syntactic Sugar se ha hecho muy popular sobre todo (según como lo veo) gracias a Ruby, y es que eso de escribir código sin puntos y coma, corchetes, llaves y paréntesis innecesarios es una buena idea y hay muchos que piensan que esas ideas es bueno llevarlas a otros lados.

y así fue como nació CoffeeScript,un lenguaje de programación que se escribe bonito y genera Javascript de toda la vida.

Instalación

Para instalar Coffeescript, necesitamos primeramente instalar Node.js y npm, una vez ya lo hallas hecho solo ejecuta en tu terminal favorita

npm install -g coffee-script

(El parametro -g es para indicar que es una instalación global que estara disponible para todos los usuarios de tu sistema operativo)

Hola Mundo

Hagamos una prueba para identificar que todo esta instalado correctamente, y de paso explicar como compilar javascript, abre un editor de texto de tu eleccion y escribe.

square = (x) -> x * x

Guarda tu archivo como hola.coffee (Si, .coffee es la extensión de los script CoffeeScript)

y luego ejecuta

coffee -c 'hola.coffee'

Inmediatamente veras un archivo javascript que se genero con el siguiente código

square = function(x) { return x * x; };

y ya tienes un archivo .js de toda la vida que puedes usar sin problema en tus aplicaciones web.

Ahora bien el comando -c es el que nos sirve para compilar nuestros archivos .coffee y convertirlos en Javascript, claro que se vuelve tedioso estar corriendo ese comando por cada vez que escribo y/o modifico en mi archivo, asi que para evitarnos la fatiga de esa tarea, ejecuta

coffee --watch --compile hola.coffee

Y ahora cada vez que modifiques tu programa Coffeescript, este auto-mágicamente generara el compilado.

Un ejemplo practico

Tengo un archivo javascript de un viejo bookmarklet que hice hace un tiempo, como en ese momento no conocia CoffeeScript pues lo hice a Javascript duro y maduro. ¿Porque no lo migramos a algo mas elegante y comentamos las partes mas interesantes? Nada como un ejemplo practico para aprender mejor las cosas, o alguien aprendio a andar en bicicleta por internet?? ;)

(Que hace el bookmarklet?…elimina el teclado virtual de la siguiente pagina y permite al usuario utilizar nuevamente el teclado convencional, un banco de mi país penso que era buena idea, a mi me pareció incomodo, así que lo quite :D )

El código original lo puedes encontrar aquí

var ifr = false;

var formName = 'loginForm';
#Comentarios

ifr = off

formName = 'loginForm'

Variables

El script empieza definiendo unas cuantas variables,en CoffeeScript para definir variables no es necesario usar la palabra reservada var y en terminos generales los punto y coma no son requeridos.

Comentarios

Los comentarios no son compilados a javascript y se escriben anteponiendo #

Booleanos

Ademas cuando tenemos alguna variable de tipo booleana, podemos utilizar alguno de los alias que el lenguaje nos ofrece para este caso podemos sustituir el false con off o no, para true se utilizan yes o on.

var $ = function(idname) {
var doc = ifr ? window.frames.working.document : document;
return doc.getElementById(idname) ||
doc.getElementsByName(idname)[0] || '';
};

$ = (idname) ->
doc = if ifr then window.frames.working.document else document
doc.getElementById(idname) or
doc.getElementsByName(idname)[0] or ''

Funciones

Las funciones se definen siguiendo la estructura nombre = (parametros entre parentesis) -> [cuerpo de la funcion] sino existen parametros se omiten los parentesis, la palabra reservada return se omite, al igual que en Ruby, la ultima sentencia que se ejecuta es el valor que la funcion devuelve. Los parametros pueden tener valores por defecto parametro='valor'.

Sentencias condicionales

Para definir un if corto (condicion?true:false) se utiliza un lenguaje mas natural if condicion then true else false. Es de notar que las llaves y paréntesis tampoco son necesarios.

Operadores Lógicos

Los operadores logicos tambien tienen alias, para el caso de || se puede sustituir con or

for (var i=0; i<usuario.length; i++){
var caracter = usuario[i];
k = k + $(caracter).value;
}

var letras = new Array();

for (var i=32; i<170; i++){

letras[i] = String.fromCharCode(i);

}

for caracter in usuario
k = k + $(caracter).value

letras = (String.fromCharCode(i) for i in [32..169])

 

 

 

Sentencias repetitivas

El clasico de toda la vida for se abrevia, ya no necesitamos conocer la longitud del arreglo a iterar, ni definir alguna variable auxiliar,CoffeeScript se encarga de todo eso.

Arreglos

Para crear un arreglo basta utilizar nombre = [] aunque para el ejemplo que tenemos creamos un arreglo a partir de una sentencia for y un rango.

Rangos

En el código del bookmarklet necesitaba obtener todas las letras del alfabeto, para lograr eso lo hice con la funcion fromCharCode, que me pide un numero para devolverme el carácter que le corresponde, la opcion en Javascript es crear un loop (for) que inicie en 32 y termine en 169, en CoffeeScript podemos hacer eso haciendo uso de los rangos [inicio..final] . Los rangos son utilizados en las sentencias repetitivas y en la definición de arreglos. Es de notar que si existen dos puntos consecutivos entre los valores de inicio y final significa que el valor inicial es incluido dentro del rango, si vemos tres puntos consecutivos (…) significa que el extremo final del rango es excluido.

El resultado final

Y finalmente!! mi Javascript bookmarklet migrado a CoffeeScript

#declaracion de variables
ifr = no;
formName = 'loginForm';
#funciones
iisIframe = ->
window.location.href=='https://www.pcbac.com/PotalaPersonal/home.do';
window.iisIframe = iisIframe

#Ojo con los espacios es importante!!!
$ = (idname) ->
doc = if ifr then window.frames.working.document else document #if else
doc.getElementById(idname) or
doc.getElementsByName(idname)[0] or ''

window.$ = $;

createHTMLElement = (id,type) ->
_parent = $(id).parentNode
_parent.innerHTML = ''
_input = document.createElement 'input'
_input.setAttribute 'type', type
_input.setAttribute 'id', id
_input.setAttribute 'name', id
_input.setAttribute 'size', '32'
_input.setAttribute 'autocomplete', 'off' #los parentesis no son necesarios
_input.setAttribute 'class', 'notfocussed'
_input.setAttribute 'onblur', if ifr then 'parent.copyText(this);' else 'copyText(this);'
_parent.appendChild _input
return #coloco esto para que mi funcion no retorne nada

window.createHTMLElement = createHTMLElement

copyText = (caja) ->
usuario = caja.value
k = ''
for caracter in usuario
k = k + $(caracter).value

if caja.id=='usernameA' or caja.id=='claveActual' then $('Field1ValueHidden').value = k
if caja.id=='passwordA' or caja.id=='nuevaClave' then $('Field2ValueHidden').value = k
if caja.id=='confirmacionNuevaClave' then $('Field3ValueHidden').value = k

return

window.copyText = copyText;

ifr=iisIframe()
if ifr then formName='cambioClaveForm'
firstRowSplit = $(formName).charFirstRowhidden.value
secondRowSplit = $(formName).charSecondRowhidden.value
thirdRowSplit = $(formName).charThirdRowhidden.value
firstRowSplitMi = $(formName).charFirstRowhiddenHMi.value
secondRowSplitMi = $(formName).charSecondRowhiddenHMi.value
thirdRowSplitMi = $(formName).charThirdRowhiddenHMi.value
firstRowSplitMa = $(formName).charFirstRowhiddenHMa.value
secondRowSplitMa = $(formName).charSecondRowhiddenHMa.value
thirdRowSplitMa = $(formName).charThirdRowhiddenHMa.value

firstRow = firstRowSplit.split '|'
firstRowMi = firstRowSplitMi.split '|'
firstRowMa = firstRowSplitMa.split '|'
secondRow = secondRowSplit.split '|'
secondRowMi = secondRowSplitMi.split '|'
secondRowMa = secondRowSplitMa.split '|'
thirdRow = thirdRowSplit.split '|'
thirdRowMi = thirdRowSplitMi.split '|'
thirdRowMa = thirdRowSplitMa.split '|'
todo = []
for i in [firstRow.length - 1..0] by -1 #empezar en -1
todo[firstRow[i].toLowerCase()] = firstRowMi[i];todo[firstRow[i]] = firstRowMa[i];
for i in [secondRow.length - 1..0] by -1
todo[secondRow[i].toLowerCase()] = secondRowMi[i];todo[secondRow[i]] = secondRowMa[i];
for i in [thirdRow.length - 1..0] by -1
todo[thirdRow[i].toLowerCase()] = thirdRowMi[i];todo[thirdRow[i]] = thirdRowMa[i];

for m in [0..2]
todo[$(formName).number1[m].value] = $(formName).number1[m].alt;
todo[$(formName).number2[m].value] = $(formName).number2[m].alt;
todo[$(formName).number3[m].value] = $(formName).number3[m].alt;

todo[$(formName).number4.value] = $(formName).number4.alt;

for m in [0..9]
todo[$(formName).button4[m].value] = $(formName).button4[m].alt;

for m in [0..10]
todo[$(formName).button5[m].value] = $(formName).button5[m].alt;
todo[$(formName).button10[m].value] = $(formName).button10[m].alt;

letras = (String.fromCharCode(i) for i in [32..169])

for letra in letras
input = document.createElement 'input'
input.setAttribute 'type', 'hidden'
input.setAttribute 'id', letra
input.setAttribute 'value', todo[letra]
$(formName).appendChild input

if !ifr
createHTMLElement('usernameA','text')
createHTMLElement('passwordA','password')
else
createHTMLElement('claveActual','password')
createHTMLElement('nuevaClave','password')
createHTMLElement('confirmacionNuevaClave','password')

$(if ifr then formName else 'forma1').getElementsByTagName("table")[0].getElementsByTagName("tr")

[if ifr then 14 else 8].style.display = 'none'

 

CoffeeScript es mucho mas

Lo que utilice de CoffeeScript para migrar mi bookmarklet no es ni la décima parte de todo lo que este lenguaje nos ofrece, hay mas temas que tratar pero, no caben en un articulo introductorio, espero haber logrado inculcar un poco de curiosidad para que sigas adelante en el estudio de CoffeeScript. Si ese es tu caso, dejo a tu disposición documentación para dar el siguiente paso

Un curso de CoffeeScript en EscueladeCodigo, completamente gratis, ¿te parece buena idea?

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

Picando Código

¿Y si juntamos a la comunidad de usuarios ArchLinux del Uruguay?

Enero 26th, 2012 - [Enlace local]

ArchLinux

ArchLinux

Lo que dice el título, ¿y si juntamos un grupo de usuarios ArchLinux en un mismo espacio física esporádicamente y nos unimos a trabajar con algun(os) objetivo(s) en común?

En un principio pensé que la mejor forma de convocar a los usuarios a unirse en grupo era crear una lista de correo, un blog, o algo así. Pero eso son solo herramientas, preferí empezar sin mucha ambición con este post (gracias al principio de KISS). Los invito a dejar un comentario si quieren sumarse a la iniciativa. Hay que ver si hay más interesados, y después entre los que seamos vemos qué se arma :)

Se me ocurren varias razones de por qué esto es una buena idea. Una buena parte de lo positivo de ir a una reunión de personas técnicas (hackatón, conferencias y demás) es conocer a otras personas con los mismo intereses. Ni que hablar que las charlas suelen ser bastante interesantes. Si nos entretenemos leyéndonos por foros, redes sociales y blogs, mejor la vamos a pasar conversando mientras tomamos alguna cerveza y comemos alguna pizza.

A continuación listo algunos objetivos/ideas/razones más que me vienen en la cabeza sin caer en nada muy ambicioso.

Si hay convocatoria, coordinamos una fecha y me comprometo a conseguir un lugar para reunirnos por primera vez y ver qué sale. No hay mucha idea o compromiso, simplemente juntarse a ver qué sale.

Para finalizar el post, los dejo con un texto de la wiki:

En Biología, mutualismo es una interacción entre dos organismos en que ambos organismos obtienen beneficio. Este principio puede también ser aplicado a miembros proactivos y motivados de la comunidad de ARCH que quieren estar involucrados y contribuir a su distribución favorita GNU/Linux. Esta participación beneficia no solo a los miembros de la comunidad y sus compañeros Arches, pero también a todos los fans potenciales de Software libre y de codigo abierto

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

Koalite's blog

Diseño Web Sensible y Grids CSS

Enero 26th, 2012 - [Enlace local]

Ya he dicho en alguna ocasión que me interesa bastante el tema de la experiencia de usuario, aunque luego la parte de diseño gráfico que suele llevar asociada no sea mi fuerte y acabe basándome más en la teoría que en el talento.

En el mundo del diseño web últimamente está muy de moda el Responsive Web Design, que podríamos traducir como diseño sensible o más bien como “diseño que responde bien”. Se trata de intentar diseñar las páginas web para que se adapten correctamente a distintas resoluciones y formatos de pantalla, y es algo que hoy en día cobra una importancia especial con la gran variedad de dispositivos que se usan para navegar por internet.

Para conseguir esto, siempre existe la opción de desarrollar distintas versiones del sitio web adaptadas a cada formato que queramos soportar, pero eso implica un trabajo adicional que no siempre merece la pena y además supone un problema cuando aparecen nuevos formatos que no teníamos previsto.

El responsive design aprovecha las características de CSS3 y media queries para aplicar distintos formatos en función de las características del dispositivo que está accediendo a la página.

Una forma muy extendida de implementar esto es estructurar la página a partir de un grid y maquetar la información ajustándola a ese grid:

Estructura de una página basada en un grid

Estructura de una página basada en un grid de 7 columnas

Una vez que tenemos la información estructurada, aplicando las técnicas CSS adecuadas es relativamente fácil conseguir adaptarlo al tamaño de pantalla del dispositivo:

Ejemplo de web adaptada a distintas resoluciones

Ejemplo de web adaptada a distintas resoluciones

En este ejemplo se ve como al reducir el ancho de la pantalla, el contenido se reformatea reduciendo el tamaño de las columnas del grid, llegando incluso a apilar las columnas para pasar a un formato completamente vertical apto para teléfonos móviles. Se puede comprobar fácilmente accediendo a la página y redimensionando la ventana del navegador.

Para ayudarnos a implementar esto, existen muchos frameworks CSS para responsive design que nos facilitan bastante la vida. Algunos están basados en grids fluidos, en los cuales la anchura de las columnas se ajusta automáticamente al tamaño de la pantalla, y otros en grids fijos, que mantienen constante la anchura de las columnas pero varían el número de columnas en función del tamaño de la pantalla. Entre los frameworks más conocidos están:

Personalmente me parece una idea bastante buena, pero hay puntos que no acaban de gustarme. Me parece que se sacrifica parte del contenido semántico del documento en favor de la maquetación, algo que ya ocurría hace unos cuantos años con el abuso de las tablas. Ahora parece que, mientras se usen divs en lugar de tablas, todo vale.

Por otra parte, casi todos estos sistemas utilizan clases CSS que no tiene valor semántico, sólo tienen valor para formatear la información. En un mundo ideal, las clases CSS que aparecen en el documento HTML no deberían definir el cómo (formato) sino el qué (intención), deberían ser algo declarativo.

Por ejemplo, si en una página queremos marcar el importe total de una compra, deberíamos marcarlo como y luego asignar en la hoja de estilo a la clase total-amount una fuente negrita, más grande o lo que queramos. Con este tipo de frameworks se fomenta más usar algo de la forma , penalizando la estructura semántica del documento. Es lo mismo que ocurre al utilizar otros frameworks de diseño web como jquery-ui o jquery-mobile.

Una excepción a esto es Semantic Grid System, que intenta no manchar el documento html con sus clases CSS. Para ello, aplica sus estilos mediante mixins con LESS, SCSS o Stylus.

En cualquier caso, las ventajas que aportan el uso de este tipo de frameworks son considerables, por lo que a veces resulta mejor ser más pragmático y aprovecharlos. A fin de cuentas, lo que realmente importa es aportar valor al usuario/negocio, y para ello estos frameworks pueden ser de mucha ayuda.




Compartir enlace:
Facebook Twitter Email

No hay posts relacionados.

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

Arragonán

Don’t Censor Me!

Enero 26th, 2012 - [Enlace local]

Don’t Censor Me!

Via Pablo Jimeno

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

xailer.info (esp)

Error.log

Enero 25th, 2012 - [Enlace local]

Cuando lanzamos una aplicación desde el IDE y aparece un error en tiempo de ejecución sucede que, por motivos que van desde el cansancio o la falta de concentración hasta directamente porque se ha producido un error no recuperable (recursión, GPF, etc.), se cierra la aplicación sin darnos tiempo a anotar en qué lugar del código estaba el error.


ErrorLogError

Para evitar tener que reproducir otra vez cada uno de los pasos para llegar al error usaremos este plugin que añade una nueva opción al menú Ver del IDE que permite mostrar la información de error completa o resumida así como borrar el archivo del disco cuando ya no es necesario.

ErrorLogMenu

Desde la vista error.log es posible copiar la información del error al portapapeles en el mismo formato en que se está mostrando, completa o resumida, para, por ejemplo, enviarla por correo:

ErrorLogView

El archivo para descargar: ErrorLog

El plugin sólo funciona con Xailer 2.5 y Xailer 2.5.1

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

Picando Código

Disponible Oil Rush 1.00 :)

Enero 25th, 2012 - [Enlace local]

Oil Rush

Oil Rush

El excelente juego de estrategia naval en tiempo real Oil Rush (clic en el enlace para leer mi reseña) está disponible en su versión 1.00. Aquellos que lo preordenamos lo podemos descargar ya desde Unigine Online Store.

Se está trabajando en versiones para Steam, Desura y Ubuntu Software. Éstas estarán disponibles en uno o dos días.

La versión 1.00 nos trae el tan esperado modo de campaña para un jugador. Pre ordené el juego en marzo del año pasado, y desde entonces he ido viendo cómo evoluciona poco a poco con cada nueva versión. Ahora me toca el turno de hacer la campaña y ver qué han estado preparando los desarrolladores para nosotros…

Es un juego bastante importante en lo que respecta al mundillo de videojuegos en plataformas GNU/Linux. Fue construido sobre el motor Unigine que da la oportunidad de realizar unos gráficos 3D impresionantes, corriendo de forma nativa en nuestro querido sistema.

Con suerte el juego tenga éxito, así lo espero. Esto abriría más el mercado de videojuegos en GNU/Linux, dándole la publicidad necesaria a su motor para que otras compañías lo tengan en cuenta a la hora de desarrollar sus juegos.

Ya estoy descargando esta nueva versión, y más tarde tendré la oportunidad de probarlo. Ahí les contaré qué me pareció. Mientras les dejo algunas fotos de versiones anteriores para que se hagan una idea de los excelentes gráficos del juego:

Oil Rush 0.66

Oil Rush 0.82

 

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

Variable not found

Libro: Dependency injection in .NET

Enero 25th, 2012 - [Enlace local]

La inyección de dependencias es uno de esos conceptos rodeados de misterio que parecen reservados a gurús, arquitectos, y otros profesionales de gama alta, y aplicables exclusivamente en proyectos mastodóndicos.



Y nada más lejos de la realidad: DI se basa en principios relativamente simples, e incluso diría intuitivos, para lograr evitar el acoplamiento entre componentes, es aplicable en todo tipo y tamaño de aplicaciones, y por tanto todas ellas pueden beneficiarse de las ventajas que aporta, como la simplicidad, mantenibilidad, extensibilidad, o facilidad para la realización de pruebas unitarias.



Dependency Injection in .NET. Manning.Pero, sinceramente, jamás pensé que el tema que pudiera dar tanto de sí como para escribir un libro. Por eso me ha sorprendido la lectura, por cortesía de Auges, del libro “Dependency Injection in .NET”, escrito por por Mark Seemann y publicado por la editorial Manning, donde he podido comprobar que mis conocimientos sobre inyección de dependencias, aunque válidos, eran bastante superficiales.



El libro se estructura en cuatro grandes bloques a través de los cuales se realiza un completo recorrido guiado por los conceptos, utilización y herramientas para aplicar DI:

En definitiva, se trata una lectura recomendable para desarrolladores .NET, tanto para aquellos que no hayan tenido experiencia previa con la Inyección de Dependencias y anden buscando fórmulas para reducir el acoplamiento entre componentes, como para los que ya se han enfrentado a ella y desean conocer en mayor profundidad las bases que la sustentan.



Como puntos negativos, que está disponible exclusivamente en inglés, y que algunos capítulos se hacen algo densos y requieren varias pasadas para poder asimilar las ideas transmitidas.



Enlace: http://www.manning.com/seemann/



Publicado en: Variable not found.



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

Arragonán

Taller Spring I/O 2012: Modulariza tus aplicaciones Grails

Enero 25th, 2012 - [Enlace local]

Este año volveré a estar por el Spring I/O (16 y 17 de Febrero 2012 en Madrid), en esta ocasión dirigiendo el taller Modulariza tus aplicaciones Grails :

Gracias a los plugins de grails liberados a la comunidad, podemos aprovechar el esfuerzo hecho por otros desarrolladores y reutilizar el trabajo que han hecho. El sistema de plugins de grails da múltiples puntos de extensión para la plataforma: permite añadir comandos nuevos a la CLI, servicios, clases de dominio, extender dinámicamente algunos comportamientos… En el taller sacaremos partido del sistema de plugins de grails para reutilizar trabajo entre distintas de nuestras aplicaciones, veremos algunos ejemplos y desarrollaremos un plugin a modo de ejemplo.

Básicamente, mostraremos de forma práctica como reutilizar código en nuestros proyectos del día a día, más allá de liberar plugins que sólo tengan sentido ser liberados para el resto de la comunidad.

Este año volverán a ser 2 días de charlas y talleres, un eventazo a un precio de risa. Como podéis ver en la agenda, hay buena cantidad y calidad de ponentes, incluida alguna rockstar internacional entre ellos.

Cualquiera que trabaje o le interesen tecnologías alrededor de los ecosistemas Spring, Grails o Groovy debería asistir a este evento; o también a quienes les interesan cosas relacionadas con Mongodb, Scala, ElasticSearch, RabbitMQ o incluso temas de cloud computing.

Pero seguro que lo mejor está por los pasillos, durante los cafés y las comidas… o, por descontado, en la fiestaca del jueves :) .

Nos vemos en el Spring I/O!

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

Variable not found

SignalR (II): Conexiones persistentes

Enero 24th, 2012 - [Enlace local]

Hace poco estuvimos viendo por aquí conceptos básicos sobre SignalR, el componente que nos permite crear espectaculares aplicaciones en las que múltiples usuarios pueden estar colaborando de forma simultánea, asíncrona, y en tiempo real.



Entre otras cosas, comentábamos que SignalR  crea una capa de abstracciones sobre una conexión virtual permanente entre cliente y servidor, sobre la que podemos trabajar de diferentes formas:

En este post estudiaremos la primera opción, conexiones persistentes. Los hubs los veremos en un artículo posterior de la serie, aunque si sois impacientes ya podéis ir leyendo el fantástico post del amigo Marc Rubiño sobre el tema, “Push con SignalR”.



Demo de conexiones persistentesBueno, pues vamos al tema: emplearemos esta vía para implementar una funcionalidad bastante simple, pero nada trivial utilizando las herramientas habituales de ASP.NET: mostrar en una página, en tiempo real, información sobre los usuarios que están llegando a ella, los que la abandonan y el número de usuarios que hay conectados justo en ese momento, en tiempo real.



Para ello haremos lo siguiente:

  1. En el lado servidor, implementaremos un servicio (endpoint) SignalR, que es el que procesará las conexiones y desconexiones de clientes, y enviará información actualizada por las conexiones abiertas.
  2. Registraremos este endpoint durante la inicialización de la aplicación, asociándole una URL de acceso a las funcionalidades del servicio.
  3. En el lado cliente implementaremos la conexión con el servicio, capturaremos la información que nos vaya enviando y la mostraremos en la página en forma de log.
El resultado lucirá tal y como se muestra en la captura de pantalla adjunta. Aunque si lo preferís, podéis verlo en vivo y en directo descargando y ejecutando el proyecto de demostración que encontraréis al final de este artículo.



Ya en el post anterior de la serie vimos cómo descargar e instalar SignalR en un proyecto, así que vamos a suponer que ese paso ya lo hemos realizado previamente.

1. Implementación del endpoint

El endpoint, o servicio SignalR, que vamos a implementar utilizando el enfoque de conexión persistente es simplemente una clase que hereda de SignalR.PersistentConnection, en la que podemos sobrescribir los métodos que necesitemos para implementar nuestras funcionalidades. En ella encontramos métodos como OnConnected(), OnDisconnect(), OnReceived(), y bastantes más, que nos permiten tomar el control cuando se producen determinados eventos de interés en la conexión:

    public class VisitorsService : PersistentConnection
    {
        protected override void  OnConnected(HttpContextBase context, string clientId) { ... }
        protected override void  OnDisconnect(string clientId) { ... }
        protected override void  OnReceived(string clientId, string data) { ... }
        // [...]
    }
Observad que el interfaz es bastante similar a la que encontramos al trabajar directamente con sockets: podemos introducir lógica cuando un nuevo cliente se conecte sobrescribiendo el método OnConnected(),  cuando se desconecte, haciendo lo propio con OnDisconnect(), o cuando el cliente envíe algún tipo de mensaje al servidor, que ejecutará la funcionalidad implementada en OnReceived().



De la misma forma, la clase base PersistentConnection ofrece mecanismos para enviar mensajes directos a un cliente, a grupos de ellos, o a todos los clientes conectados.



Volviendo al sistema que estamos desarrollando, básicamente para alcanzar nuestros objetivos necesitamos:

1.1. Notificando a los clientes las nuevas conexiones

Cuando se realiza una nueva conexión al servicio, es decir, la llegada de un nuevo cliente, SignalR invocará al método OnConnected() del endpoint suministrándole el contexto de la petición HTTP actual, y un “ClientId”. El primero nos puede ser muy interesante para acceder a información de la petición (como el navegador, IP, cookies, información de autenticación, etc.), y el segundo es un identificador único generado por SignalR para realizar el seguimiento de la conexión.



Implementamos nuestro método y lo comentamos justo a continuación:

    protected override void OnConnected(HttpContextBase context, string clientId)
    {
        var clientDescription = getClientDescription(context);
        _clients.TryAdd(clientId, clientDescription);
 
        string text = clientDescription + " arrived.";
        var msg = new NotificationMessage(text, _clients.Count);
        Connection.Broadcast(msg);
    }
Lo primero que hacemos en la implementación del método es obtener una descripción textual del cliente (que puede ser el nombre del usuario autenticado, o su IP), utilizando el método getClientDescription(), que veremos más adelante. Esta descripción, asociada al ClientId, es almacenada en el diccionario estático _clients, lo que nos permitirá conocer en todo momento los clientes conectados.



Justo después componemos el mensaje y realizamos el envío a todos los usuarios conectados invocando el método Broadcast() de la propiedad de instancia Connection, que nos da acceso al canal virtual abierto entre clientes y servidor. El parámetro que recibe este método es de tipo object, y viajará serializado en formato JSON hasta cada uno de los clientes conectados; en este caso, hemos creado una clase llamada NotificationMessage que contiene toda la información que necesitamos suministrarles:

public class NotificationMessage
{
    public NotificationMessage(string message, int onlineUsers)
    {
        OnlineUsers = onlineUsers;
        Message = message;
    }
 
    public string Date
    {
        get { return System.DateTime.Now.ToLongTimeString(); }
    }
    public string Message { get; set; }
    public int OnlineUsers { get; set; }
}
Es conveniente tener en cuenta, sin embargo, que es posible enviar cualquier tipo de objeto: tipos propios (como en el ejemplo anterior), objetos anónimos, primitivos, o lo que se nos ocurra. Simplemente será serializado como JSON y llegará al cliente de forma directa (más adelante veremos cómo).



Los miembros auxiliares utilizados en el código anterior son los siguientes:

    private static ConcurrentDictionary<string, string> _clients =
        new ConcurrentDictionary<string, string>();
 
    private static string getClientDescription(HttpContextBase context)
    {
        var browser = context.Request.Browser.Browser + " " +
                        context.Request.Browser.Version;
        var name = context.Request.IsAuthenticated ?
                    "User " + context.User.Identity.Name :
                    "IP " + context.Request.UserHostAddress;
        return name + " (" + browser + ")";
    }
Observad que el diccionario donde almacenamos la información sobre las conexiones ha sido definido como ConcurrentDictionary para evitar problemas de concurrencia durante las actualizaciones, y es estático para que su información sea compartida entre todas las instancias del servicio.

1.2. Notificando a los clientes las desconexiones

Cuando SignalR detecta que un cliente se ha desconectado, invocará al método virtual OnDisconnect() del endpoint, lo cual nos permite introducir lógica de gestión del evento. En nuestro caso, simplemente necesitamos eliminar al cliente del diccionario donde los estamos almacenando,



De la misma forma, debemos controlar las desconexiones para notificar este hecho a los clientes aún conectados, para lo que sobrescribimos el método OnDisconnect():

    protected override void OnDisconnect(string clientId)
    {
        string text, clientDescription;
 
        if (_clients.TryRemove(clientId, out clientDescription))
            text = clientDescription + " is leaving.";
        else
            text = "Unknown user leaving.";
 
        var msg = new NotificationMessage(text, _clients.Count);
        Connection.Broadcast(msg);
    }
En este método recibimos el ClientId que SignalR asignó al cliente en el momento de iniciar la conexión; lo único que hacemos es buscarlo en el diccionario de clientes donde los estamos almacenando, eliminarlo, y enviar un mensaje broadcast al resto de usuarios indicando la desconexión que se ha producido.



Cuando implementéis funcionalidades en la desconexión, tened en cuenta que SignalR tarda unos segundos en darse cuenta de las desconexiones (recordad que con el transporte utilizado por defecto se trata de una conexión persistente virtual) por lo que puede aparecer un leve retraso en las notificaciones. Estos tiempos, en cualquier caso, pueden ser configurados (en el proyecto de demostración podéis ver cómo hacerlo).



[Actualización]: como bien indica Arturo en un comentario del post, para que las desconexiones sean notificadas correctamente es necesario utilizar IIS o IIS Express. Con Cassini (el servidor web integrado en VS) no funcionará bien este mecanismo.

1.3. Algunas observaciones adicionales

Al principio de comenzar a jugar con conexiones persistentes de SignalR, una de las cosas que pueden llamar la atención es que si en la implementación del método OnConnected() enviamos un broadcast a todos los usuarios conectados,  el usuario actual (el que ha provocado la llamada a OnConnected) no recibirá el mensaje; o en otras palabras, el broadcast llegará a todos los clientes excepto al que acaba de realizar la conexión.



Desconozco si se trata de un comportamiento por diseño, si es algo que se modificará en posteriores revisiones de SignalR (recordemos que en estos momentos es todavía una versión preliminar), o si simplemente se trata de un nombre para el método poco afortunado, pues en mi opinión da a entender que la conexión ya ha sido realizada y, por tanto, el broadcast debería llegarle también.



Pero en cualquier caso, en la implementación del proyecto de pruebas que podéis descargar al final de este post veréis cómo lo he solucionado incluyendo una llamada explícita (“ping”) desde el cliente al servidor para forzar el envío de un mensaje de actualización justo después de completarse la conexión. Conceptualmente, lo que se hace es:

Más adelante, cuando tratemos la parte cliente del servicio, veremos cómo está implementado el envío desde el cliente de este “ping”.

2. Registro de ruta

Una vez tenemos el servicio implementado, debemos registrar en el sistema de routing de ASP.NET una URL a través de la cual será posible acceder al mismo. El lugar idóneo para hacerlo, como siempre que se trata de cargar la tabla de rutas, es en el global.asax, para que se ejecute durante la inicialización de la aplicación.



Por ejemplo, en una aplicación ASP.NET MVC podría ser algo así:

    public static void RegisterSignalrConnections(RouteCollection routes)
    {
        routes.MapConnection<VisitorsService>("Visitors", "VisitorsService/{*operation}");
    }
 
    protected void Application_Start()
    {
        RegisterSignalrConnections(RouteTable.Routes);
        [...]
    }
Observad que lo único que estamos haciendo es añadir a la tabla de rutas una entrada en la que asociamos el servicio, en este caso nuestra clase VisitorsService, a la dirección “VisitorsService/{*operation}”, que será la URL de acceso al mismo.



El primer parámetro que enviamos al método MapConnection() es simplemente el nombre de la entrada en la tabla de rutas, no tiene demasiada importancia.

3. Implementación del cliente web

La implementación de clientes web para las conexiones persistentes desarrolladas con SignalR es bastante simple, y comienza incluyendo en la página o vista una referencia hacia la biblioteca cliente de este componente:

<script src="@Url.Content("~/Scripts/jquery.signalR.js")" type="text/javascript"></script>
Como siempre, esta inclusión puede realizarse a nivel de página, o bien en la Master o Layout si queremos aplicarlo a todas las vistas del sistema.

Nota: si queremos dar soporte a clientes antiguos que no soportan deserialización JSON de forma nativa (por ejemplo, IE7), será necesario descargar desde Nuget la biblioteca de scripts json2.js y referenciarla en la página antes de la carga de SignalR.js. En caso contrario, se lanzará una excepción con el error:



“SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8” 
Centrándonos en nuestra aplicación, el marcado HTML será tan simple como el que se muestra a continuación, lo único que hacemos es dejar un “hueco” en el que introduciremos los mensajes que se vayan recibiendo del servidor:

<h2>Log</h2>
<div id="log"></div>
A continuación, necesitamos implementar el código de script que realice las siguientes tareas:

Y el código de script tampoco puede ser más sencillo:

<script type="text/javascript">
    $(function () {
        var conn = $.connection("VisitorsService");
        conn.received(function (data) {
            var text = data.Date + " - " + data.Message + " " +
                data.OnlineUsers + " users online.";
            
            $('#log').prepend("<div>" + text + "</div>");
        });
 
        conn.start(function () {
            conn.send("ping");
        });
    });
</script>
Lo comentamos muy rápidamente:

Y ¡esto es todo!



Si tenéis un ratillo, no dejéis de descargar el proyecto de prueba y jugar un rato con él. Y sobre todo, observad las pocas líneas de código que hemos tenido que emplear para resolver esta funcionalidad y comparadlo con lo que supondría implementarla de forma artesana, con las técnicas tradicionales.

Descargar proyecto de prueba.



En el próximo post de la serie veremos cómo utilizar los Hubs de SignalR, un planteamiento con una abstracción aún mayor sobre la conexión y una integración entre cliente y servidor simplemente espectacular.



Publicado en Variable not found.



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

Najaraba.com: Software libre, metodologías ágiles y más.

Nueva etapa profesional: la inspiración

Enero 23rd, 2012 - [Enlace local]

No sería capaz de reflejar mejor estos últimos cinco años trabajando en Biko de cómo ya los ha reflejado Jessi en su blog. Va de personas que son felices en su trabajo. Porque el desarrollo de software no es trabajar con ordenadores y picar código. El desarrollo de software es mucho más: son personas haciendo cosas grandes que disfrutan con lo que hacen, y sobre todo, con quien lo hacen. Este

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

Koalite's blog

Demasiada abstracción

Enero 23rd, 2012 - [Enlace local]

Hay veces que llegamos a un punto en que intentamos abstraer demasiado las cosas y acabamos teniendo lo que se suele llamar una leaky abstraction. Se trata de casos en los cuales el mecanismo de abstracción no es efectivo, aquello que queremos abstraer acaba traspasando la capa de abstración y lo único que conseguimos es una complicación innecesaria.

Recientemente he padecido un caso claro de esto usando la API de consultas QueryOver de NHibernate. QueryOver está diseñado como una implementación del patrón Query Object aprovechando expresiones lambda para hacer static reflection y conseguir así que el API sea type-safe y refactor friendly.

QueryOver intenta abstraer el acceso a la base datos, pero a la vez trata de mantener toda la potencia del SQL, por lo que en cuanto las consultas se complicando un poco acaba siendo un lío y la ganancia que tenemos por ser type-safe y refactor friendly no compensa la pérdida de legibilidad.

Veamos un ejemplo concreto bastante simpe. Supongamos que tenemos el típico modelo de clientes y pedidos y queremos lanzar una consulta para obtener el número de pedidos y el importe total pedido por cada cliente. La implementación con QueryOver es algo así:

Customer customer = null;
var stats = s.QueryOver()
    .JoinAlias(x => x.Customer, () => customer)
    .SelectList(lst => lst
                            .SelectGroup(() => customer.Id)
                            .SelectGroup(() => customer.Name)
                            .SelectSum(x => x.Total)
                            .SelectCount(x => x.Id))
    .List();

El resultado es bastante feo. Para poder hacer el equivalente al inner join de forma type-safe, tenemos que declarar una variable de tipo Customer que usamos únicamente como alias para usarla luego en las expresiones lambda. Además, para construir la lista de columnas a devolver se usa un builder (lst) que simplifica un poco las cosas pero no acaba de resultar claro.

Si la misma consulta la lanzamos con el equivalente HQL, el lenguaje de consultas de NHibernate, tenemos:

var stats = s.CreateQuery(@"select c.Id, c.Name, sum(o.Total), count(o.Id)
                            from Order o right join o.Customer c
                            group by c.Id, c.Name")
             .List();

Para cualquiera que esté acostumbrado a manejar SQL, está claro que la consulta resulta mucho más legible. Es cierto que no es type-safe no refactor friendly, pero en mi opinión la legibilidad lo compensa.

Parece que nuestra tendencia natural como desarrolladores es siempre abstraerlo todo, pero a veces hay que tener cuidado porque puede que estemos causando más problemas de los que solucionamos.




Compartir enlace:
Facebook Twitter Email

No hay posts relacionados.

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

Escuela De Codigo

GitHub, para el que empieza con Git

Enero 23rd, 2012 - [Enlace local]

La semana pasada vimos una corta y puntual introducción a Git, solo lo necesario para el que no sabe nada de control de versiones deje de vivir en la era del oscurantismo y pase a ser parte del cada dia mas grande, grupo de iluminados que hacen de su vida de desarrollador mas facil, utilizando Git. Pues bien hoy en dia no se puede mencionar Git sin decir GitHub. ¿Que es? ¿Como se sirve? ¿Con que lo aderezo? En este articulo conoceremos GitHub y lo mucho que nos puede ayudar.

¿Que es GitHub?

GitHub es un sitio web para alojar proyectos utilizando el sistema de control de versiones Git.

¿Necesitas alojar tu proyecto en algun repositorio Git que no sea en tu computadora? ¿No quieres perder tu tiempo configurando un servidor remoto como repositorio de Git? Entonces GitHub es para ti, un sitio web donde todos tus proyectos que utilicen Git estaran bien resguardados.

Seria muy injusto decir que GitHub solo es un simple sitio web para guardar repositorios Git. Porque la verdad es que es mucho mas que eso,es una “red social” donde los desarrolladores compartimos nuestro codigo fuente con otros. Todos los repositorios en GitHub son open source (todos los que no son de pago) asi que podemos descargarlos, clonarlos,enviar parches, corregir el codigo de otro, que otros nos envien sus cambios, etc, etc.

De esa forma no solo compartimos nuestro código, sino que lo exponemos a una audiencia de profesionales (como nosotros) para que lo puedan evaluar, corregir y mejorar :)

Para empezar, registrate en GitHub

Ingresa a https://github.com/plans , elige el plan gratuito, llena el formulario (bastante simple no tendras problemas) y ya estas registrado!

Mi primer repositorio

Vamos a estrenarnos dentro de GitHub, para eso ya debemos tener correctamente configurado Git, ¿No lo has hecho?? Tomate unos minutos para leer este articulo antes de continuar

Crea un nuevo repositorio

GitHub es tan bueno con nosotros, que inmediatamente despues de crear el repositorio nos indica como debemos proceder, asi que hagamos lo que dice

Sube el código

Antes que nada, crea en tu computadora la carpeta donde tendras el código fuente, abre una terminal y escribe

 mkdir Hola-Gato

y muevete dentro de la carpeta recien creada

 cd Hola-Gato

inicializa el repositorio Git

 git init

Los repositorios en GitHub tienen un archivo muy importante, el README, dentro de este archivo se colocan instrucciones que quieres que los desarrolladores lean desde que entran a ver tu repositorio, asi que no olvidemos crearlo. Utiliza Markdown para escribir en el.

touch README

Ahora que ya tienes un archivo en tu repositorio, lo agregamos

git add README

y ejecutamos nuestro primer commit

git commit -m “Primer commit en el proyecto”

Hasta este momento todo lo que hemos hecho, seria como cualquier proyecto en el que usemos Git, todo local, para relacionar nuestro código fuente con el repositorio remoto que recien hemos creado en GitHub debemos ejecutar lo siguiente

git remote add origin git@github.com:escueladecodigo/Hola-Gato.git

y finalmente subimos el codigo a GitHub

git push -u origin master

Ahora cuando demos en el enlace Continue veremos algo como lo siguiente

Ahora ya tienes tu primer repositorio en GitHub, listo para que cualquiera lo vea, lo clone, haga forks, te envié mejoras, etc, etc. Solo llénalo un poco con tu código, no creo que un repositorio con un solo archivo README sea muy llamativo para otros desarrolladores ;)

GitHub cuenta con tantas funcionalidades; resaltado de sintaxis, seguir desarrolladores, clonar repositorios, etc, etc. Por el momento dejare que tu curiosidad trabaje un poco y explores todo lo que Git junto con GitHub puede ofrecerte. En artículos posteriores iremos desglosando cada una de esas opciones, conociéndolas bien y sacandoles el máximo provecho posible. Así que no te pierdas los próximos artículos, te ayudaran no solo a conocer Git sino a usarlo como un ninja!

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

xperiments.es

(English) i5hare project launched.

Enero 22nd, 2012 - [Enlace local]

Disculpa, pero esta entrada está disponible sólo en English.

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

xperiments.es

(English) StageWebViewBridge Update

Enero 22nd, 2012 - [Enlace local]

Disculpa, pero esta entrada está disponible sólo en English.

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

El blog de pico.dev

Errores de precisión, redondeo y representación con float y double

Enero 21st, 2012 - [Enlace local]

Java
Los tipos de datos float y double aunque muy usados y útiles tienen defectos, como que no son capaces de representar el resultado de ciertas operaciones ariméticas entre números reales con total precisión, en algunos casos solo son capaces de representar aproximaciones a ellos y que las operaciones las realizan en base dos. Al igual que nosotros no podemos repsentar 1/3 con números en base diez con total exactitud (solo una aproximación 0,333333333... con treses hasta el infinito) a las computadoras les pasa otro tanto de lo mismo, aunque estas guardan los números en base dos. Por tanto usarlos para hacer ciertas operaciones aritméticas, y siendo acumuladas varias de ellas, puede dar lugar a errores de redondeo y precisión en el resultado final. Por estos motivos usar estos tipos de datos no son los más adecuados para trabajar en una aplicación que calcule precios. Veámoslo con un ejemplo.



Supongamos que tenemos una cantidad de dinero tal que 100,05 a la que aplicamos un 10% de descuento y posteriormente un 5% en concepto de impuestos. Las líneas de código que calculan esto son:



import java.text.NumberFormat;



double amount = 100.05;

double discount = amount * 0.10;

double total = amount - discount;

double tax = total * 0.05;

double taxedTotal = tax + total;



NumberFormat money = NumberFormat.getCurrencyInstance();

System.out.println("Subtotal: "+ money.format(amount));

System.out.println("Discount: " + money.format(discount));

System.out.println("Total: " + money.format(total));

System.out.println("Tax: " + money.format(tax));

System.out.println("Tax+Total: " + money.format(taxedTotal));


Y el resultado es:



Subtotal: 100,05 €

Discount: 10,00 €

Total: 90,04 €

Tax: 4,50 €

Tax+Total: 94,55 €



Si nos fijamos en la suma de total más impuestos hay una diferencia de 0.01 y si presentamos un desglose de precios como este a un usuario puede que este piense que hay algún error en el cálculo, le genere desconfianza y no haga la compra en el peor de los casos. Viendo los valores sin los redondeos que hace NumberFormat tenemos:



Subtotal: 100.05

Discount: 10.005

Total: 90.045

Tax: 4.50225

Tax+Total: 94.54725



Los redondeos que hace NumberFormat es HALF_EVEN por defecto, de modo que cuando un decimal está equidistante a las dos partes se redondea a la parte par por lo que con una precisión de dos decimales:



Discount: 10.005 se redondea a 10.00

Total: 90.045 se redondea a 90.04

Tax: 4.50225  se redondea a 4.50

Tax+Total: 94.54725 se redondea a 94.55



En este caso se trata de un problema de redondeo pero ahora supongamos que tenemos una cantidad de 0,70 céntimos a la que no aplicamos un descuento pero si el procentaje de impuestos del 5%. Tendríamos:



import java.text.NumberFormat;

double amount = 0.70;

double tax = amount * 0.05;

double taxedTotal = tax + amount;



NumberFormat money = NumberFormat.getCurrencyInstance();

System.out.println("Subtotal: "+ money.format(amount));

System.out.println("Tax: " + money.format(tax));

System.out.println("Tax+Total: " + money.format(taxedTotal));


Subtotal: 0,70 €

Tax: 0,03 €

Tax+Total: 0,74 €



Nos encontramos otra vez con la diferencia de 0.01. Vemos los valores sin redondear por NumberFormat:



Subtotal: 0.7

Tax: 0.034999999999999996

Tax+Total: 0.735



Aquí se ve que el resultado de ciertas operaciones aritméticas entre datos double (o float) son almacenadas por una computadora con errores de precisión, 0.70 * 0.05 (debería ser 0.035).



Para evitar estos errores debemos utilizar la clase BigDecimal que pemite almacenar números con una precisión en la práctica infinita en base 10, realizar los cálculos como los humanos esperan, en base diez, y hacer los redondeos de precisión. Aplicando una precisión de dos decimales a los números y usando BigDecimal tenemos:



import java.math.BigDecimal;

import java.math.RoundingMode;

import java.text.NumberFormat;



RoundingMode RM = RoundingMode.HALF_EVEN;

BigDecimal amount = new BigDecimal("100.05");

BigDecimal discountPercent = new BigDecimal("0.10");

BigDecimal discount = amount.multiply(discountPercent).setScale(2, RM);

BigDecimal total = amount.subtract(discount).setScale(2, RM);

BigDecimal taxPercent = new BigDecimal("0.05");

BigDecimal tax = total.multiply(taxPercent).setScale(2, RM);

BigDecimal taxedTotal = total.add(tax).setScale(2, RM);

NumberFormat money = NumberFormat.getCurrencyInstance();

System.out.println("Subtotal : " + money.format(amount));

System.out.println("Discount : " + money.format(discount));

System.out.println("Total : " + money.format(total));

System.out.println("Tax : " + money.format(tax));

System.out.println("Tax+Total: " + money.format(taxedTotal));


Ahora los precios si están correctos:



Subtotal : 100,05 €

Discount : 10,00 €

Total : 90,05 €

Tax : 4,50 €

Tax+Total: 94,55 €



Para el otro caso en el que teníamos un error de precisión:



import java.math.BigDecimal;

import java.math.RoundingMode;

import java.text.NumberFormat;



RoundingMode RM = RoundingMode.HALF_EVEN;

BigDecimal amount = new BigDecimal("0.70");

BigDecimal taxPercent = new BigDecimal("0.05");

BigDecimal tax = amount.multiply(taxPercent).setScale(2, RM);

BigDecimal taxedTotal = tax.add(amount).setScale(2, RM);



NumberFormat money = NumberFormat.getCurrencyInstance();

System.out.println("Subtotal: "+ money.format(amount));

System.out.println("Tax: " + money.format(tax));

System.out.println("Tax+Total: " + money.format(taxedTotal));


Subtotal: 0,70 €

Tax: 0,04 €

Tax+Total: 0,74 €



Referencia:

http://www.javamexico.org/blogs/luxspes/por_que_usar_bigdecimal_y_no_double_para_calculos_aritmeticos_financieros

http://speleotrove.com/decimal/decifaq1.html#tzeros

http://www.mkyong.com/java/how-do-calculate-monetary-values-in-java-double-vs-bigdecimal/

http://blogs.oracle.com/CoreJavaTechTips/entry/the_need_for_bigdecimal

http://stackoverflow.com/questions/7539/please-explain-the-use-of-java-math-mathcontext/7561#7561

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

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

Bitácora de Javier Gutiérrez Chamorro (Guti) » Programación

Código nativo y dispositivos móviles

Enero 21st, 2012 - [Enlace local]

El panorama actual de dispositivos móviles, ha quedado, podríamos decir que reducido a iOS de Apple, Android de Google, y Windows Phone de Microsoft (con el permiso del marginal TabletOS de RIM). La evolución ha llevado a que el código bytecode sea el que domine estas plataformas. Java para Android, y .NET para Windows Phone. [...]

Artículos relacionados:
Rendimiento de dispositivos móviles
Office 2007 no es nativo x64
Código automodificable en PHP

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

Javier Pérez

¿Eres inteligente? Relación entre el cociente intelectual y comportamientos e ideas del ser humano

Enero 20th, 2012 - [Enlace local]

Tendencia al suicidio = Menos inteligente

Un estudio realizado por investigadores de varias universidades del mundo, sobre informes médicos de 24 años referentes a más de un millón de hombres, relaciona el cociente intelectual con la falta de tendencia al suicidio. Es decir, que las personas con más tendencias suicidas suelen tener menor cociente intelectual, sin capacidad para enfrentarse a los problemas o eventos traumáticos.

Conservador y religioso = Menos inteligente

Los más inteligentes suelen tender a probar cosas nuevas. 14.000 adolescentes norteamericanos evaluados en 2001 y 2002 dan como resultado esta relación entre ser conservador y la falta de inteligencia.

Usar Internet Explorer = Menos inteligente

Un estudio muy controvertido y cuya veracidad o autoridad está en entredicho, relaciona el uso del navegador de Microsoft, Internet Explorer, y la falta de cociente intelectual.

Consumir drogas = Más inteligente

El estudio sobre esta relación comenzó en 1970, del Estudio Británico de Cohorte, realizando un seguimiento a miles de niños (5-16 años) durante décadas hasta que cumplieron los 30 años.  Este estudio venía a demostrar también que los más inteligentes son más propensos a probar y experimentar cosas nuevas.

Hermano mayor = Más inteligente

Este estudio revelaría que los hermanos mayores son estadística y significativamente más inteligentes que sus hermanos pequeños (análisis de 241.310 hombres de 18-19 años). Se concluye además que por ese motivo los hermanos pequeños suelen ser más simpáticos, porque tratan de competir con su hermano mayor por otras vías.

Te gusta música clásica = Más inteligente

Un estudiante de doctorado del Instituto de Tecnología de California ideó un sistema para calcular una estadística que relacionara los gustos musicales con el nivel intelectual, en base a los datos de Facebook de estudiantes de diferentes universidades americanas, contrastándolos con sus notas académicas. El resultado fue que los que decían que Beethoven era su músico preferido eran los más inteligentes, y los menos inteligentes los que les gustaba el RAP o el reguetón.

Hombre fiel y ateo = Más inteligente

Este estudio también hace incapié en la falta de fé religiosa, además de en la fidelidad en la pareja, como síntoma de más inteligencia, estadísticamente hablando.

Cerebro en desarrollo = ???

Y si aún no ha terminado la edad de desarrollo cerebral (hasta los 18-20 años), ten en cuenta que tu cociente intelectual aún puede variar, y no necesariamente a más inteligente…

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

Bitácora de Javier Gutiérrez Chamorro (Guti) » Programación

Java 8, Eclipse 4.2 y Netbeans 7.1

Enero 19th, 2012 - [Enlace local]

Sin ser un gran defensor de Java a pesar de haberlo tocado bastante durante sus comienzos, debo reconocer que a día de hoy, Java es una plataforma madura, que le ha llevado a tener un rendimiento aceptable (teniendo en cuenta que es bytecode), y un nivel de estabilidad elevado. El garbage collector funciona correctamente, podría [...]

Artículos relacionados:
Eclipse solar
Sieve en Java
La historia de Java se parece al descubrimiento de América

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

Koalite's blog

EventHandlers con jQuery 1.7: on() vs click()

Enero 19th, 2012 - [Enlace local]

En la última versión de jQuery han intentado unificar las APIs de manejo de eventos en los métodos on y off. Estos métodos sustituyen a los antiguos bind(), delegate() y live().

Si comparamos el uso de on() con el de atajos que ya existían, como click(), tenemos el siguiente código:

// Asignar un manejador de eventos usando click
$("#header a").click(function() {
    // manejar el evento
});

// Asignar un manejador de eventos usando on
$("#header a").on("click", function() {
    // manejar el evento
});

Estas dos construcciones son equivalentes, pero on() permite hacer muchas más cosas. Una de las cosas que más me gusta es que permite usar un mismo manejador de eventos para múltiples elementos html suscribiendo el manejador a un elemento padre. Para ver lo que significa este lío de frase, es mejor ver un ejemplo. Supongamos que tenemos este código:


Si por algún oscuro motivo queremos asignar el mismo manejador de eventos a todos los elementos , podemos hacerlo de la siguiente forma:

$("#content").click("click", "a", function() {
    // manejar el evento
    // $(this) apunta al  que ha generado el evento
});

Esto tiene varias ventajas:

Nota para los que usamos demasiado C#

Si, al igual que yo, usas mucho C# u otro lenguaje estático, es posible que se te haga raro este tipo de API. En C#, la diferencia entre usar un API como element.click() y otra como element.on("click",...) es que la primera es type-safe y refactor-friendly, mientas que la segunda se basa en el uso de un magic string.

Sin embargo, no hay que olvidarse que esto es Javascript y es dinámico. Es igual de “seguro” (o inseguro, según se mire), escribir person.name que person["name"], por lo que el uso de magic strings es algo normal, frecuente y que hay que ver como una característica del lenguaje de la que aprovecharnos, no como una limitación.




Compartir enlace:
Facebook Twitter Email

Posts relacionados:

  1. Tutorial node.js + express + jquery (III): Usando jQuery

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

Escuela De Codigo

Side Project, es bueno trabajar en algo propio.

Enero 19th, 2012 - [Enlace local]

Un Side Project, es en palabras simples, un proyecto, invento, experimento que hago sencillamente porque tengo las ganas y el tiempo para hacerlo. ¿Porque trabajar en algo que aparentemente no nos dara ningún beneficio ya que nadie nos paga por hacerlo? Es lo que descubriremos en este articulo. 

La rutina matara tu pasión por programar

Llega un momento en la vida de todo desarrollador, que se levanta una mañana y se da cuenta que esta haciendo exactamente lo mismo que el día anterior, y que el día siguiente hara lo mismo, y la siguiente semana sera igual y peor aun es posible que el siguiente mes la mayor variación con la que se encuentre sera…posiblemente nada. Los programadores también caemos en rutinas, y para mi al menos, no hay peor rutina que la que implica: programar en el mismo lenguaje, en la misma plataforma, en el mismo IDE, en el mismo sistema operativo, resolviendo los mismos problemas con las mismas soluciones. Es un completo fastidio!!! Asi como la rutina mata el amor entre una pareja, también matara tu amor por tu trabajo, por programar. Y no queremos eso ¿cierto?

Vuelve al primer amor, trabaja en un Side Project

Si en tu trabajo son como autómatas siguiendo un manual escrito en piedra, sin ninguna posibilidad de cambiar algo, y si ahí se programa en Java así se hara toda la vida hasta que un nuevo profeta diga que hay que usar otra cosa. Dejame decirte que la única posibilidad para romper tu rutina, es creando, uno o varios Side Project, tu sabes, pequeños proyectos en paralelo que llevas por diversión, por curiosidad, cosas que programas solo para experimentar, para probar ese nuevo framework, esa nueva librería, ser atrevido.

La esencia de un Side Project es básicamente crear una pieza de software con el único proposito de ser el amo y señor de nuestro minúsculo universo, hacer las cosas como yo digo, como yo creo que es correcto, como yo quisiera que fuera correcto. Hacer algo con mis propias manos, sin que nadie me diga como hacerlo, sin cumplir requerimientos, sin seguir ordenes!! mas que las que me dicta mi propia mente.

¿Quieres probar esa nueva librería que en el trabajo y en los proyectos de la universidad no te dejan? Hazlo!!! Es TU proyecto ¿Quien te va a decir que no?

¿Quieres probar esa nueva metodología de desarrollo que tanto lees en sitios web y blogs? Hazlo!!! Es TU proyecto. Recuerda eres el amo y maestro.

Cuando tenemos una fin de semana espectacular, el lunes que regresamos a trabajar no se siente tan mal. Lo mismo es cuando has trabajado en un proyecto propio. Regresar a la rutina se hace mas llevadero.

¿Y que gano con hacer un Side Project?

Básicamente:

Ahora ya lo sabes, olvídate por un segundo de tus clientes, de tu trabajo. Deja de pelear guerras ajenas por un momento y construye algo propio. Diviértete, experimenta, aprende y quien sabe si lo que hagas sea el siguiente Twitter, uno nunca lo sabe.

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

Información legal y técnica