viernes, 26 de diciembre de 2014

Antonio Recio, no pico código

Antonio Recio, no pico código

Hace semanas, escuche la frase "no, pero yo ya no pico código". Es como sí el picar código, estuviera en la más bajo del escalafón de la programación, y de hecho, en España, se percibe de esta manera. Solo hay que echar un vistazo a las ofertas de empleo cuando ofertan un puesto de programador, o analista/programador, y ver el rango de retribución económica que ofrecen.

Y tener está visión, ¿que consecuencias tiene?. Primeramente, yo no soy muy indicado para hablar de esto, y lo hago desde mi experiencia personal. Además, escribiendo este post, hago una reflexión interna sobre este asunto.

Cuando una empresa busca el kilo de programador a lo más barato, la verdad, no sé lo que está pensando sobre lo que hace o deja de hacer un programador. Solo alcanzo a imaginar que piensan que es escribir lineas de código para añadir/modificar/arreglar un software. Si esto es así, bien, la verdad que no están tampoco equivocados, pero bajemos unos niveles más.

Cuando un programador (llamo programador a todo a quién pica código, desde un programador junior a un project leader, que pica las partes clave de programa) esta escribiendo código, también esta diseñando, está definiendo una arquitectura. Pero como será esta arquitectura, ¿compleja o habría otro método más fácil? ¿la está documentando para que sea entendible por otro programador?

Y aquí, es donde se ve la diferencia entre un programador bueno y otro menos bueno.

Un código escribo por un menos bueno programador a la larga, será:
 - Más difícil de añadir nuevas funcionalidades,
- De encontrar bugs y reproducirlos.
- Más propenso a tener futuros bugs.

Esto hace que se extienda el tiempo haciendo más caro el software, y que el cliente este más descontento. Y si el cliente está descontento, mala cosa. ¿De quién es la culpa? todos lo sabemos, del programador! solo y exclusivamente. No de quién (una parte claro) no alcanza a ver la diferencia entre un buen programador y uno menos bueno.

Pero que sucede si hace está diferencia. Si en un equipo hay un buen programador y otro menos bueno, el bueno ayudará y guiará al menos bueno, el menos bueno se sentirá motivado para aprender más. El código será más mantenible, antes de programador algo nuevo, harán pruebas y luego las incorporaran, y además será menos propenso a errores, acortando tiempos de desarrollo y reparaciones de bugs. Con lo cual,el cliente estará más contento.

Entonces, desde este punto de vista, uno puede decir con orgullo: "Soy Félix, y pico código".

Aunque, me he referido aquí a programadores, al final, todos tendemos o queremos ser un buen ingeniero software. Que lo mismo, el problema, es que todavía no se ve el desarrollo de software como una ingeniería, donde convergen o se tocan diferentes disciplinas,  y se piensa que es 'solo' picar código.

Está imagen, me resulta muy ilustrativa.



¿Y que visión hay en otros países?
Una de las primeras diferencias, por lo menos, lo que yo ví en UK, es que, en la mayoría de las empresas IT, antes de hacer una entrevista cara a cara (ya previamente pasada la del telefono...), es que te envían un ejercicio de programación, te dan un tiempo, y tienes que enviarlo de vuelta con el código fuente. Si es verdad, que en España, me he encontrado con dos empresas, una de juegos y otra una IT.

Y para contestar a está pregunta, hay personas que dan una respuesta muy ilustrativa.

Los Reyes del Mambo: los programadores mejor pagados

"Lo que más llamó su atención fue que, al contrario que aquí en España, ser programador era una profesión que no estaba asociada a un rango bajo ni a salarios vergonzosos."

"Existe una enorme confusión sobre lo que es o no es un programador. En España, la programación se considera un primer nivel: programador, analista, jefe de proyecto, y gerente. Una actividad mal pagada. En la universidad, muchos profesores recomiendan a sus alumnos huir de la programación. En Estados Unidos, en cambio, hay un auténtico culto al programador: muchos de los grandes emprendedores tecnológicos lo son gracias al hecho de saber programar."

"La falacia del Programador Perdido"
"Es cierto que en España es difícil encontrar buenos programadores. Difícil, pero no imposible. Si quieres encontrar un buen programador, básicamente sólo tienes que hacer una cosa: pagarlo. "


Ahora, leyendo las siguientes noticias, creo necesario que no solamente se tenga en cuenta a los buenos programadores y su importancia, sino a todos los que componen el equipo de un desarrollo software. Y solo son noticias de los pasados 4 meses...y de los cuales nos hemos enterado por la prensa...¿Y de los que no nos enteramos?

24/11/2014
Un fallo en el sistema informático de la DGT impide el pago de tasas y multas a los ciudadanos

30/08/2014
Retrasos de hasta una hora en Barajas por un fallo en el sistema de radares

22/12/2014
Un fallo informático ha impedido pagar esta tarde los billetes premiados

18/12/2104
El Portal de la Transparencia arrastra desde su inauguración un grave problema de seguridad


Un saludo

Félix Romo

felix.romo.sanchezseco@gmail.com

domingo, 23 de noviembre de 2014


Personalizar el DataGridView


Introducción


Algunas veces, en un datagrid, queremos visualizar diferentes informaciones en una celda y no simplemente un valor por celda.

Por ejemplo, un ejemplo, sería un grid donde con una cierta frecuencia, el contenido numérico va a variar, pero, ¿qué sucede si para el usuario es importante no solamente la nueva cifra sino el incremento?




Suponiendo que tenemos una aplicación donde lleva el saldo de los Pitufos. Para el usuario de la aplicación, lo mismo sería interesante, no solamente ver el nuevo saldo, sino el tanto por ciento que ha variado.

Con los controles que nos ofrece .Net, una de las formas, sería añadir una nueva columna "% Balance", donde refleje la variación. Pero otra forma, sería, que en la misma celda, en letra más pequeña y con una flecha (hacía arriba para incrementos positivos y hacía abajo para incrementos negativos) para mostrar esta información.

Quedaría como:






Personalizar la celda del data Grid


Paso 1:

Crear una clase que derive de alguna de las siguientes clases, 

      System.Windows.Forms.DataGridViewButtonCell
      System.Windows.Forms.DataGridViewCheckBoxCell
      System.Windows.Forms.DataGridViewComboBoxCell
      System.Windows.Forms.DataGridViewHeaderCell
      System.Windows.Forms.DataGridViewImageCell
      System.Windows.Forms.DataGridViewLinkCell
      System.Windows.Forms.DataGridViewTextBoxCell

En este ejemplo, se eligio derivar de DataGridViewTextBoxCell, ya que era la clase que más acercaba a lo que queríamos representar. Dependiendo de lo que contendrá la celda, asi será la clase elegida para derivar.

class DataGridViewCellDoubleIncrement : System.Windows.Forms.DataGridViewTextBoxCell


Paso 2:

Sobreescribimos el método Paint. Este método será llamado siempre que la celda vaya a ser pintada. Aquí estará el código donde dibujaremos la información del incremento del %.

protected override void Paint(System.Drawing.Graphics graphics, System.Drawing.Rectangle clipBounds, System.Drawing.Rectangle cellBounds, int rowIndex, System.Windows.Forms.DataGridViewElementStates cellState, object value, object formattedValue, string errorText, 
            System.Windows.Forms.DataGridViewCellStyle cellStyle, System.Windows.Forms.DataGridViewAdvancedBorderStyle advancedBorderStyle, System.Windows.Forms.DataGridViewPaintParts paintParts)
        

Paso 3:

Sobre escribimos el método:

protected override System.Drawing.Size GetPreferredSize(System.Drawing.Graphics graphics, System.Windows.Forms.DataGridViewCellStyle cellStyle, int rowIndex, System.Drawing.Size constraintSize)


Este método será llamada para cuando se necesite saber el tamaño que tendrá la celda. Como vamos a añadir más información a la celda, necesitará más espacio. Entonces, aquí es donde se añada ese espacio extra para mostrar la información del %.

Paso 4:

Crear una clase que derive de .DataGridViewColumn, y está clase representará la columna que contendrá nuestro nuevo tipo de celda para visualizar el incremento del %.

 public class DataGridViewColumnDoubleIncrement : System.Windows.Forms.DataGridViewColumn


Paso 5:
Para que la columna sepa DataGridViewColumnDoubleIncrement  que tipo de celdas debe de crear, en el constructor se añade la línea:

this.CellTemplate = new DataGridViewCellDoubleIncrement();

Con lo anterior, ya tendríamos lo básico para personalizar la forma en que queremos visualizar los datos en cada celda.

Como ver el código, es más explicativo que párrafos y párrafos, en este link está el código fuente.

Conclusión

Como se ha visto, con un poco de trabajo, puede resultar de gran efecto visual en el interface de usuario y además, que el usuario, vea la información más cercana a su modelo mental, creando una mejor experiencia de usuario.

Félix Romo
felix.romo.sanchezseco@gmail.com



miércoles, 5 de noviembre de 2014


La API de tu interfaz (UserControls)


Introducción


Cuando uno desarrolla una aplicación de escritorio, piensa que el interfaz será estable, que una vez que se implemente, no se modificará y si se modifica son algunos detalles. Si se sigue este principio durante el desarrollo del UI, tendremos un problema. Ya que al cabo de una año o dos, por razones comerciales, de un cliente especial, de un nuevo jefe, se modifique gran parte del UI.

Un ejemplo, supongamos que estamos desarrollando un software para la gestión del video club, y en una parte del interfaz tenemos un ListView con el titulo de la pelicula, director, etc. Esta ListView se rellena desde una base de datos. Creo que el típico error aquí, es hacer visible la ListView con el resto de la aplicación. Es decir, seguir estos pasos:

- Leer información de las peliculas de la base de datos
- Añadir información a la ListView.



Pero vamos a complicar un poco la cosa. Ahora, una vez que se la información principal de la película, queremos que en otra parte de la pantalla, se muestre el argumento de la película.
Con lo cual, lo más normal es capturar el evento de selección de la ListView para actualizar y visualizar el argumento de la película seleccionada.



private void ON_lvFilms_SelectedIndexChanged(object sender, EventArgs e)
        {
            showPlotFromFilm();
        }



Así, el método showPlotFromFilm accederá al control listview, para obtener el titulo de la película y asi buscar en la base de datos o en memoria y mostrar el argumento. Aquí, hemos introducido un acoplamiento de miedo.

El problema viene cuando al cabo de un mes o un año, por el motivo que sea, hay que cambiar la listview por un treeview, ya que se ha decidido ver las películas por géneros y el treeview es por el momento el que más se ajusta.

Entonces, si hay que cambiarlo, habría que mirar todo el programa, desde donde es visible el listview para ahora engancharlo a un treeview. Podría llevar mucho tiempo, más luego los posibles bugs por un cambio que afecta tanto.

¿Cómo disminuir este riesgo?

Crear la API del UI para tu Aplicación


Para disminuir este riesgo, una opción (la verdad que otra de momento no alcanzo a verla) es crear un control de interfaz de usuario que su responsabilidad sea la de visualizar películas.

Al igual que existen los controles para visualizar texto (TextBox) o un fichero .jpg (PictureBox), nos creamos un control para representar un objeto del dominio del problema, en este caso, una conjunto de película (no escribo 'lista' para no sugerir que en la implementación que sea una lista).

El control que visualizará la lista de películas será FilmControl.cs (deriva de UserControl)

Y tendrá una propiedad:

public List<Kernel.Film> Films

Que de hay el control rellenará la lista de las peliculas en la lista que tiene interna, pero si en el futuro se cambia a un arbol, no afectaría externamente, es decir, fuera del ámbito del control.

Y luego tendría el evento:


[Description("Se selecciono una pelicula en el control.")]
public event selectFilmHandle ONselectFilm;




Que se dispara cuando el usuario seleccione una película en la listview. Si en el futuro fuese una arbol, la implementación por dentro, detectaría la selección en el arbol y lanzará despues el evento ONselectFilm.



Esta ha sido una forma algo simple de intentar explicar la buena practica de crear partes del interfaz de usuario que manejen directamente conceptos a nivel del dominio del problema y no de implementación.

En este ejemplo se ve por ejemplo en ONselectFilm, donde es un evento que se lanza cuando se selecciona una pelicula, pero por el contrario si fuese ON__lvFilms_SelectedIndexChanged, es un evento que se lanza cuando se selecciona un elemento de la lista, y lista es ya un elemento de la implementación, y sin embargo en ONselectFilm, no se hace referencia a ningún elemento de implementación del interfaz, sino que solamente se ha selecionado, ya sea por un ListView o un TreeView o cualquier otro UI más extraño. Así, hemos reducido el acoplamiento entre partes del programa enormemente.

Para descargar el código fuente de videoClub aquí.

Conclusión


Como experiencia, esta forma de trabajar me ha ahorrado bastantes horas de trabajo, ya que se intento crear una api UI para los objetos del dominio del problema (en la carpeta Kernel del ejemplo), de esta forma si una parte del interfaz se quiere llevar a otro sitio del interfaz, o recolocar la interfaz, será más rápido y menos propenso a errores (que los habrá claro).

Félix Romo

felix.romo.sanchezseco@gmail.com









miércoles, 28 de agosto de 2013

Detectar noticias interesantes con un clasificador Naive Bayes


Detectar noticias interesantes con un clasificador Naive Bayes

Hace mucho tiempo, cuando empezo el auge de internet y solo tenía acceso a las redes desde el trabajo, me ví que no podía acaparar toda información a la que tenía acceso. ¿Qué solución me podría proporcionar?
ChotaWeb, una aplicación que tuviese todas las páginas web en las cuales estuviese interesado y luego el programa detectase si en alguna página habría alguna noticia interesante. Y si fuese así, avisarme por mensaje o por un correo.

El sistema que idee en aquella época era de los más simple: por palabras clave. Aún el interfaz de usuario conserva sus reminiscencias.



Pero hasta que hace poco, retome esté proyecto personal y mejorarlo de forma que de verdad detectara las noticias que me interesasen. Entonces, me tope con el clasificador Naive Bayes.

Encontre este tutorial en pdf el cual me sirvio para implementar un proyecto de prueba en C#, Bayes.sln

Tutorial on Naive Bayes Classification


El cual cuando se ejecuta para comprar que da los mismos resultados que el tutorial, tiene este aspecto:



Este proyecto se puede descargar el código fuente aquí

Una vez, desarrollado el algoritmo núcleo que determinará si una noticia es interesante o no, habrá que codificar el algoritmo anterior de C# a c++, ya que ChotaWeb está en c++ con MFC.


El formato que usa ChotaWeb en el fihero .cht es:

9    <numero de páginas>
http://elpais.com/tag/astronomia/a/ 
http://www.expansion.com/ 
http://www.noticias.com 
http://www.elmundo.es 
http://www.elmundo.es/navegante 
http://www.newscientist.com/news/ 
http://news.bbc.co.uk/ 
http://news.bbc.co.uk/2/hi/technology/default.stm 
http://news.bbc.co.uk/2/hi/health/default.stm 

03:00   <tiempo que se activa automáticamente para inspeccionar cada página>
1  <1 para que cada vez que se inicie windows se ejecute chotaweb. Aunque no funciona muy bien por el tema del directorio que tiene por defecto. Bug conocido>


El aspecto que tiene es el siguiente y donde se muestra una página que habla sobre los planetas extrasolares y como se ha entrenado al clasificador de Bayes con un documento que habla sobre los planetas extrasolares. Entonces, si todo va bien, en la inspección, debería de avisaros de que en dicha página hay una noticia que nos interesa.



Para su descarga el ejecutable del ChotaWeb y ver un poco mejor como funciona, aquí.

Necesitará que el fichero TrainingDocuments.xml contenga más documentos para que así, de unos resultados más precisos. Esos resultados, una vez mostrados el usuario, se guardan en disco para no volverlos a mostrar.

Creo que el crear otro proyecto en C# para investigar, probar un algoritmo, es bastante útil, ya que uno no 'guarrea' el código del proyecto en el que está trabajando. Además, el diseño del algoritmo se verá menos condicionado al proyecto en curso, y solo se centrará en el algoritmo.

Un saludo
Félix





lunes, 10 de diciembre de 2012

Patrón de software - Visitor


Patrón de software - Visitor


Muchas veces, cuando queremos mostrar un ejemplo de programación orientada a objetos, se sale con el ejemplo de dibujar en pantalla diferentes figuras, como triangulos, cuadros y circulos. Que si estamos programando en C# pasaremos un objeto Graphics para su dibujado y ya está, ya que cada objeto tendrá su posición. Y de esta forma, usaríamos el poliformismo.

En este ejemplo, tendremos, como todos sabemos, una clase abstracta Figura y las clases hijas, Triangle, Square y Circle.

Pero, ¿qué pasa cuando el rectangulo representa una zona de una ciudad, es decir, sus medidas están en metros?. Ya no se podrá dibujar un rectangulo de 100x100 metros, habrá que escalar las medidas a pixeles.
¿pero donde se hace esa transformación? ¿en las clases hijas?¿la del padre?

Creo que una forma sería tener una clase, en este caso, FigureView, donde tendría la responsabilidad de dibujar y de guardar todas las figuras. Y el metodo dibujar sería


void Draw(Graphcis g)
{
foreach(Figure figure in _figures)
{
       f.Draw(g,this);
}
}

aquí le pasamos el this, el objeto a un objeto FigureView que será el Visitor del patrón de diseño.

ya que luego el metodo Draw de Triangle será:

void Draw(Graphics g,FigureView view)
{
     view.Draw(g,this);
}

Y aquí, viene la importante, las clases hijas llamaran a los siguientes métodos sobrecargados de FigureView:

void Draw(Grapchis, Triangle t);
void Draw(Grapchis, Circle c);
void Draw(Grapchis, Square s);

así, se deja en FigureView la responsabilidad de dibujar, y hacer los cálculos en la escala que precise.

y también importante, en un solo bucle, podemos dibujar las distintas figuras que conforman la vista.

saludos y happy coding!


miércoles, 28 de noviembre de 2012

Arquitectura - removiendo las bases

Arquitectura - removiendo las bases

En muchas ocasiones, he visto o he estado en aplicaciones donde una modificación de los requisitos, te puede trastocar o simplemente no poder implementarse con la arquitectura con la que ha sido construida la aplicación.

Siempre que ha querido hacer una analogía entre la construcción de un edificio con la construcción software. Vamos a intentar hacer lo mismo para el caso de "remover la arquitectura por los requisitos de usuario".

Imaginemos que estamos desarrollando una aplicación 3d, donde el terreno 3d, se forma através de un fichero .jpg o .bmp donde el código de color es una altura. La arquitectura tiene encuenta este hecho y se construye la malla de del terreno, conforme al grid del .jpg. Es decir, internamente se trabajo con coordenadas del tipo grid [i][j]  para acceder a la altura. Y todo funciona a la perfección!!!

Hasta que el cliente llega y dice..."Vamos a trabajar con una empresa donde tiene archivos con curvas de nivel en vez de con .jpg. Entonces, la aplicación nos gustaría que importase y trabajase con archivos de curva de nivel".

Y va el ing. sw, o el desarrollador y se queda a cuadros. Y se queda por que sabe que tendrá que modificar toda la arquitectura de la aplicación, pero ¿cómo explicarlo?

Imaginemos que estamos construyendo un bloque (esto le paso a un arquitecto que realizo un diseño para un cliente. Eran un bloque de pisos en una pequeña ladera).

El arquitecto empezo por diseñar los pilares, los cuales sustentaran todo el peso y de hay subir pisos. Es decir, con los pilares hizo el esquelo del edificio, la arquitectura.
Cuando termino los planos, se los enseño al cliente:
- "bien..bien..pero...yo quería garaje.."
El arquitecto se quedo a cuadros también, claro esta. Y se quedo por que como el garaje va debajo de los pisos, tendría que haber una separación entre los pilares para crear las plazas de garaje, con lo cual, tendría que modificar la arquitectura de los pilares para encajar las plazas de garaje.



Aquí, en este ejemplo, se ve claramente como se modifica la arquitectura.
En el caso del software, la dependencia de que cada i,j tiene su altura, hizo que cuando este supuesto no es cierto, todo se cae a bajo, como un castillo de naipes.
Algo como, hallar el dato de altura más cercano a punto i,j podría haber sido una arquitectura más resistente los cambios de requisitos.

Como punto final, la diferencia entre el aquitecto del garaje y el arquitecto del terreno 3d, es que el primero, solo tuvo que hacer las modificaciones en un papel, el otro es sobre código, sobre algo ya construido.
Es como si el arquitecto del edificio, despues de haber consstruido los pilares, según la distrubición que le ha marco un programa de calculo de estructuras, llega el arquitecto y manda a los albañiles a mover los pilares para dejar espacio a las plazas de garaje. Da miedo, no?.

happy coding!


domingo, 8 de abril de 2012

Interprete de Ecuaciones

Desde hacía mucho tiempo, tiempos donde compilaba con el borland c++, me llamaba mucho la atención en poder representar gráficamente una fórmula matemática:

y = x*x+5
y= x*cos(x/2)

Pero tenía un problema, una vez escribía la función:

double eq1(double x)
{
    return (x*x+5)
}

Ya no podía cambiar. El usuario, no podía escribir la ecuación que quisiera ver representada en la pantalla.

Hasta que me decidí a investigar este campo un poco y también a arrepentirme un poco más de no haber elegido la asignatura de libre elección "compiladores e interpretes" en segundo de la carrera. A si qué, empeze a mirar libros como "Engineering a Compiler" y "Modern Compiler Implementation in C". Ahí ví las gramáticas por la izquierda, que son las gramáticas más facil de implementar, con lo cual, mejor empezar por algo fácil. Y implemente está gramática:


S => E$
E => TERMINAL Eprima
Eprima => +TERMINAL Eprima
Eprima => -TERMINAL Eprima
Eprima => cos(E)
Eprima =>


TERMINAL => FACTOR Tprima
Tprima =>*FACTOR Tprima
Tprima =>/FACTOR Tprima
Tprima =>


FACTOR => NUM
FACTOR => ( E )
FACTOR => VARIABLE
FACTOR => cos( E )
FACTOR => sin( E )


Como se puede ver en el video, se pueden escribir variables (x, a,...) que a la hora de realizar la gráfica el programa, las va dando valores de un rango de -50 a 50 para realizar la gráfica.
Admite ecuaciones de dos variables, pero esto sería ya para realizar una visualización en tres dimensiones.




La implementación de este tipo de algoritmos, permite al usuario obrar con más libertad a la hora de interactuar con cualquier aplicación. En este por ejemplo, se permite experimentar con visualizar casi todo tipo de equaciones (que permita este simple gramática), pero en aplicaciones grandes, se podría por medio de comandos variables...es decir,..un mini-lenguaje, hacer más productiva una aplicación.