Link del día: Un poquito sobre el email
EPH o “Extra Pair of Hands” es el nombre de un servicio de tercerización de atención telefónica, que se supone nos brinda la posibilidad de sacarnos un peso de encima si es que eso toma mucho del tiempo de nuestra estadía en la oficina. Pero eso no es lo interesante de hoy, sino un FAQ que publicaron sobre el tamaño de direcciones de email. El pequeño informe está bastante completo para tratar de un tema tan específico, llegando a hablar incluso de cuánto en memoria se reserva por los programadores en general y cuánto requerirían los estándares. Algo curioso de conocer.
Como extra, les dejo el blog de Cellular Obscura, que es la forma en que este fotógrafo (Shawn Rocco) sigue el mundo. No sé si tenga algo de especial, pero me gustaron las fotos que tiene.
Soy un zorrinito reservado.
Link del día: IPInfoDB
Aquellos que no están mucho en el tema de la geolocalización, lo que más cerca habrán estado de encontrar el link del día de hoy útil es preguntarse algo como: ¿Puedo saber de qué ciudad se mandó un email? ¿Puedo saber en qué parte del mundo está alguien?
Para aquellos que están un poco más adentro, saben que un determinado rango de IPs está asignado a determinadas empresas, que por lo general lo utilizan en cierta parte del mundo, y no sólo eso, sino que también distribuyen sus redes en subredes (valga la redundancia) utilizando rangos menores, de forma tal que a veces es posible, con el IP de una determinada computadora, saber desde qué parte del mundo está conectada.
Para eso el día de hoy tenemos a IPInfoDB, un servicio de geolocalización gratuito que tiene dos variantes muy interesantes.
La primera de ellas es la versión web, en donde podemos verificar nuestra localización o la localización de algún IP o dominio.
La segunda de ellas es la posibilidad de bajar una base de datos IP-localización, a nivel de país o a nivel de ciudad. Sí, sí, y no sólo eso, sino que, según prometen ellos, la base de datos se actualiza todos los meses. Nos permiten bajar la versión grande o chica, según lo que nos convenga más. Por último, interesante para aquellos que quisieran agregar esto a sus aplicaciones: no hace falta tener la base de datos localmente, ya que ellos ofrecen una API gratuita utilizable para propósitos de consulta.
Soy un zorrinito geolocalizado.
Seminario ASP.NET con VS 2008
El día de hoy tuve el gusto de poder participar como disertante en un seminario que se dio en la Universidad FASTA, junto a Adrián Cura, presidente de MUG Argentina, quién se encargó de explicar la parte teórica, y yo dando demostraciones en vivo y en directo de cómo funcionan muchas de las características o fundamentos mencionados.
Si bien el tema de la charla, en lo que se publicó originalmente, trataba del nuevo modelo de programación de ASP.NET con .NET Framework 3.0 o 3.5, ASP.NET AJAX y Windows Communication Foundation, en realidad el temario fue un poco más extenso.
Comenzamos a las 9.15 de la mañana, presentándonos y mostrando un video, la publicidad de Proyecto Natal de Microsoft. Hablamos de la experiencia del usuario, y cómo las nuevas tecnologías apuntan a mejorar esa experiencia y tratar de naturalizar la interacción del usuario con los sistemas, en lugar de adaptar el usuario a los paradigmas de programación. Esto se enlazó con la facilidad que el programador debe tener para poder tener una buena experiencia como desarrollador y las herramientas que posee. Esto a la vez se enlazó y comenzó la exposición sobre .NET Framework 2.0, 3.0 y 3.5 y se explicó qué tiene de nuevo y en qué nos beneficia.
Entre estas cosas, se mencionó ASP.NET AJAX y la gran diferencia que genera en la experiencia del usuario la presencia de AJAX, y la gran diferencia de desarrollo que genera que todo esto esté presente en una herramienta existente, sin necesidad de reinventar la rueda. Tras una breve pausa para tomar un café, se hizo una exposición en vivo de algunos pequeños ejemplos mostrando el funcionamiento de ASP.NET AJAX, explicando cómo funcionaban internamente y cómo hacían transparente al desarrollador y al usuario un montón de cuestiones que siempre fueron necesarias tener en cuenta para el desarrollo web.
Pasamos a una segunda sección, que fue WCF (Windows Communication Foundation). Se habló del paradigma de programación orientado a servicios brevemente, y cómo este pilar de la arquitectura .NET nos provee de herramientas para poder afrontar dicho paradigma. Se habló de los servicios, sus características, y tras haber refrescado todo eso, una breve demostración en donde se podía ver un servicio funcionando, y la manera en que este era implementado a través de las herramientas que Visual Studio 2008 provee.
Finalmente, se pasó a una explicación introductoria a Silverlight y Windows Presentation Foundation, otro pilar de la arquitectura .NET, que se basa en enriquecer la experiencia del usuario y generar una interfaz amigable para cualquier tipo de aplicación, y de qué forma Microsoft provee nuevas herramientas y estándares para no hacer de esto una tarea imposible para los desarrolladores y los diseñadores.
La charla terminó a las 13:00 como se encontraba previsto, aunque nos quedamos un rato más hablando sobre ciertas inquietudes particulares de alguna gente, tras lo cual efectivamente nos retiramos.
Soy un zorrinito ASP.NET.
Link del día: Genetic Algorithms
Recuerdan que en algún caso publiqué una introducción a algoritmos genéticos (que incluía visualizaciones gráficas y todo)? Bueno, varios luego de ver eso me preguntaron “Y esto para qué sirve?” y aparte de la chorrera de palabras que habré largado, poco convincentes, hoy publico también 15 Real-World Applications of Genetic Algorithms.
Por si fuera poco, me animo a publicar otra introducción más al tema, llamada Genetic Algorithms: Cool Name & Damn Simple y otra más: Introduction to Genetic Algorithms, y a republicar el autito generado con algoritmos genéticos, o la evolución de la Mona Lisa.
Soy un zorrinito genético.
Testing Flexible | Flexible Testing
Español:
Estos días estuve trabajando en desarrollar un proceso de testing adaptable a empresas que pueden querer tener un ciclo de testing completo (con todo el ciclo de vida del mismo que eso implica) como también tener simplemente un par de días y un par de recursos libres para poder testear. Ante tanta variabilidad, es necesario generar un modelo de testing que sea adaptable y particionable según las necesidades del momento, o según lo planificado con anterioridad.
Para casos planificados, pueden anticiparse testings que comienzan a trabajarse desde los requerimientos del sistema en desarrollo, y pueden incluso seguir el ciclo de vida de desarrollo del software a lo largo del mismo y en paralelo. Este es el famoso modelo en V del ciclo de vida de testing, pero este es el que presenta una gran deficiencia, que es la misma dependencia entre todas sus etapas. Este modelo se ajusta perfectamente a desarrollos con ciclos de vida de cascada, y si bien es fácilmente adaptable a otros ciclos de vida definidos, qué ocurre cuando nuestras etapas no son del todo claras? O peor aún, qué pasa cuando diferentes etapas se mezclan entre sí?
Por supuesto, esta situación no es deseable, pero al momento de darse, también sería deseable que nuestro modelo de testing no sea un contra más en esta situación, sino que permita ser utilizado también para aportar calidad, que es – al fin y al cabo – la finalidad del mismo.
Nuestro acercamiento a dicha tarea fue definir distintos tipos de testing, que variarían según los requisitos que estos tuvieran (documentos en qué basarse, cantidad de recursos necesarios proporcionalmente al tamaño del sistema, tiempo invertido, nivel de capacitación necesaria para los recursos, etc.), y para cada nivel de este tipo de testing, una variante que permitiera evaluar cierto aspecto de un sistema. De esta forma, logramos tener testing que puede ser hasta casi improvisado por los mismos desarrolladores, dejando documentación útil para el futuro del desarrollo del sistema, como a la vez también tenemos testing que puede planificarse desde el comienzo del proyecto y comenzar a trabajarse desde los requerimientos.
Por supuesto, creemos que mientras más haya, mejor, pero esto no es siempre posible, y es una realidad a la que tenemos que mantenernos atentos, porque negarla es condenarnos al fracaso.
Desafortunadamente, no puedo detallar información sobre los tipos de testing que hemos definido (ya que estos son propiedad e información de la empresa), pero los mismos también han sido planeado de un estilo y estructural totalmente formal, de manera que fácilmente puede tercerizarse el trabajo, o realizar testing para terceros de ser necesario o de surgir la oportunidad.
Soy un zorrinito adaptable.
English:
These days I’ve been working on developing a testing process which would be adaptable to companies having a large testing cicle (including the whole life-cycle for testing it implies) as well as companies having just a couples of days they can use for testing and few resources available. On such variability, it was necesary to generate a testing model which would be adaptable and partitionable acording to particular necesities, or according to what can be planned in the project.
For cases where the testing is a planed part of the whole development cycle, testing itself may begin from the requirement specification and may even follow the whole development life-cycle at the same time. This is the famous V-model of testing life-cycles, but this model presents a great deficiency, and it is the same dependency between all of its internal stages. This model adjusts perfectly to developments with waterfall life-cycles and, it is even adaptable to other well-defined life-cycles. But what happens when these life-cycles do not have well-defined stages? Or, even worse, when this stages are sometimes mixed-up?
Of course, this situation is not desirable at all for a project, but, when it is found, it would be desirable that our testing model does not fall with it, but should allow us to be used also to give more quality – i.e., the purpose of it.
Our approach to this task was defining several different types of testing, which would vary from the requirements they had (documents on which to be based on, resources needed according to project size, time invested, knowledge level required for resources, etc.), and for each of these levels of testing, different variants which would allow us to evaluate a certain aspect of a system. This way, we achieved having testing processes which could be improvised by the developers themselves leaving useful documentation for future developments, as well as it could be also used for being planned and start being analyzed by a testing team from the very beggining of the development proces.
Of course, we belive that as more testing, best quality can be achieved, but this is not always posible, and this is a fact we should take into account, as deying it is condemn ourselves to failure.
Unfortunately, I’m not allowed to go into details on about the different types of testing we’ve defined – as they are our company’s property – but these types of testing had been designed with a formal structure and style, so that they can be also used to be outsourced to other testing companies, or that, needed the case, we could be testing another’s company code.
I’m an adaptable little skunk.
Link del día: Un poquito de Encodings
El otro día, leyendo un post de I know the answer (it’s 42) hablando sobre cuál es el post del blog por el que te conocen (cosa que generalmente suele ocurrir), me desvíe leyendo otro de los artículos que él linkea, llamado The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) […la frotó sobre una piedra, la colgó de un abedul…]. Dicho post en particular habla de toda la historia que hay detrás de las distintas representaciones de los caracteres y la forma de codificarlos. Muy fácil de leer y hasta muy didáctica. Importante para los desarrolladores y buen dato para los curiosos (notesé que tiene fecha del 2003… y aún aplica muy bien).
Por ahí también anda el link a la página oficial de Unicode, que es actualmente el repositorio más grande de información que hay sobre símbolos utilizados para la transmisión de información, desde letras latinas y números hasta símbolos matemáticos y caracteres ideográficos.
Como extra también tenemos una página para testear distintos encodings en nuestro navegador (aunque a mí no me anduvo del todo bien), o una que tiene varios elementos todos juntitos, acá o acá.
Soy un zorrinito latin-1.
Testing como parte del proceso de calidad de software
Jobeet - symfony en 24 horas
Capacitación VS2008 & Framework .NET 3.5
Code review guidelines
En estos días mientras anduve haciendo los code reviews se me ocurrió estandarizar de alguna forma cómo podrían estos hacerse y de qué forma podría “puntuarse” al código evaluado en cuestión. Por ahora, eso último queda pendiente (ya que es lo más difícil de determinar y no lo más útil), pero lo primero se convirtió en un conjunto de categorías y puntos que pueden ser muy interesantes tener en cuenta al momento de ver el código y ver qué se puede mejorar de él.
Seguro que esta lista que viene a continuación está lejos de estar completa, y que se podrían agregar y quitar un montón de cosas, pero lo tiro como una introducción a esto que quiero (queremos?) terminar de formar, que nos puede llegar a ser muy útil.
PD: No creo que nada de esto sea “requerido” para que un sistema esté “bien”, sino que partiendo de que funciona, podemos decir “qué tan bien” o “qué tan mal” estamos.
Estandarización / Legibilidad de código
¿El código está comentado explicativamente?
El código debería estar acompañado de comentarios que expliquen qué es lo que se está haciendo y por qué más allá de explicar el cómo. A la vez, el código debería ser lo suficientemente claro como para que se entienda cómo es que se está resolviendo un problema en particular.
¿Los nombres son significativos?
Debería entenderse qué función tiene una variable, un método o una clase cuando se lee el nombre que se le dio.
¿El código de una clase accede a la información que necesita de forma correcta?
Si una clase necesita información de otras debería pedirla en los parámetros de sus métodos o en su constructor. Las propiedades también son una buena opción.
¿El código se encuentra correctamente modularizado?
El código de un método no debería excederse en tamaño, y debería ser explicativo en unas pocas líneas de código sobre qué es lo que está haciendo. De ser compleja su acción, debería repartirse en varios pasos que se desdoblen en todo lo que deban hacer.
Arquitectura
¿Se respeta el concepto de la arquitectura propuesta?
Sea cual sea la arquitectura propuesta para la aplicación, debería respetarse el esquema que esta propone, poniendo la lógica de la aplicación en donde esta debería estar, el acceso a datos en otro lado, etc.
¿Se encuentran separadas las capas de la misma lo suficiente?
De existir distintas capas en la arquitectura, estas deberían encontrarse lo suficientamente separadas como para depender de cada otra sólo como distintos módulos de un sistema y nunca según su implementación.
¿Qué tan fácil sería camiar alguna de las capas por una implementación distinta?
Como medición de la independencia de las capas, el acto de crear una nueva implementación para una de ellas debería ser tan costoso como la implementación misma y no más que eso. De ser de otra forma, existe dependencia en la implementación de las capas.
Code-coverage
¿Existe un testing definido para el código escrito?
Debería existir alguna forma de probar el código escrito, cualquiera sea su metodología.
¿Las pruebas testean que el código devuelva resultados correctos en escenarios esperados?
Las pruebas deberían testear, como caso esencial, que el sistema se comporte correctamente ante determinados escenarios.
¿Las pruebas testean el comportamiento del código en escenarios no esperados?
Las pruebas deberian testear, como caso adicional, determinadas situaciones no comunes, o incluso situaciones que no deberían darse, para poder probar la forma en la que el sistema responde al mismo.
¿Ocurre esto último con cada uno de los datos de entrada?
Las pruebas con elementos erróneos o inesperados deberían variarse para cada uno de los datos de entrada, pudiendo evaluar qué tan sensible es el sistema a la variación de cada uno de estos.
¿Ocurre esto último con combinaciones de los datos de entrada?
La misma situación es aplicable a la combinación de distintos datos de entrada. A veces la variación de los datos de entrada de forma individual no genera problemas, pero una determinada combinación de los mismos, sí. Así también puede evaluarse la correlación que tienen estos datos de entrada respecto del funcionamiento del sistema.
Estabilidad
¿Qué parte del código se encuentra atrapando excepciones o situaciones no esperadas?
El sistema debería programarse considerando que pueden darse situaciones adversas que puedan afectar el correcto funcionamiento de los bloques sobre los que depende. Si bien un extremo de esto llevaría a la reescritura de todo el código en cada capa superior (lo cual no sólo es imposible sino indeseable), debe considerarse que un bloque del que dependemos, cuanto menos, no esté disponible.
¿Cómo se comporta la lógica de tratamiento de errores?
Un sistema debería tener al menos una rutina de tratamiento de errores, que controle la situación o alerte al usuario.
¿Puede una situación imprevista alterar el funcionamiento del sistema?
La ocurrencia de un error o una situación no esperada no debería generar comportamientos no esperados del sistema. Posiblemente resultados erróneos, pero el comportamiento del sistema debería mantenerse estable.
Flexibilidad
¿Cuánta información utilizada es parametrizable, versus la que se encuentra codificada en el sistema?
La información que se considera “fija” para el sistema debería poderse parametrizar, para otorgar más flexibilidad en casos especiales en donde la misma se viera sujeta a cambios.
¿Es extensible el funcionamiento del sistema o sus funcionalidades?
En caso de no poderse alterar el código de la aplicación, debería existir cierta posibilidad de agregarle funcionalidad desde la entrada o la salida de datos.
¿Qué tanto afecta al sistema agregar una funcionalidad?
En caso de tener que agregar una funcionalidad al sistema, la menor cantidad de módulos deberían verse afectados, y nunca debería verse afectado el código de otras funcionalidades.
¿Qué tanto afecta al sistema quitar una funcionalidad?
En caso de tener que quitar o deshabilitar una funcionalidad al sistema, el código de las demás funcionalidades no debería verse afectado.
¿Qué tanto afecta al sistema el modificar la implementación de una funcionalidad?
En caso de tener que alterar una funcionalidad del sistema, el código de las demás funcionalidades no debería verse afectado.
¿Cuánto afecta al sistema que cambien las reglas de negocios?
Si las reglas de negocio que definen el comportamiento del sistema cambiaran, sería deseable que la menor parte del sistema se volvería obsoleto, y que el resto pudiera ser reusado para la implementación de las nuevas reglas de negocios.
Recursos
¿Qué recursos requiere el sistema para su funcionamiento?
Sería deseable que un sistema requiera la menor cantidad de recursos posibles. Estos incluyen tanto la utilización de procesador, memoria, tiempo de ejecución, sistemas sobre los que depende, bases de datos, archivos en disco, etc.
¿Cuánto tiempo hace uso de los recursos versus cuánto tiempo los retiene ociosos?
Sería deseable que en el momento mismo en que el sistema ya no hace uso de un recurso, lo libere. A veces esto puede ser contraproducente por cuestiones de performance, pero de todos modos sería deseable que lo haga.
Performance
¿Cuánto tiempo requiere el más pesado de los procesos que efectúa el sistema?
Los procesos que requieren mucho tiempo de ejecución deberían ser optimizados al máximo posible, ya que en ellos se encuentra el peor de los casos que el sistema puede encontrar.
¿Cuántos cuellos de botella se identifican en el flujo de información / acciones del sistema?
Sería deseable que existan alternativas para que un punto en particular no sea determinante de no poder utilizar el sistema. A veces las reglas de negocios requieren que así sea, pero de no ser necesario, es deseable que existan vías alternativas de continuar con el flujo de utilización del mismo.
Seguridad
¿Cuántos datos de entrada son validados por el sistema en cuanto a su tipo de datos?
Los datos que entran al sistema deberían controlarse si son válidos para el tipo de datos que deben representar. Ejemplo típico es el de los datos numéricos, o de fecha, que muchas veces se leen simplemente como cadenas.
¿Cuántos datos de entrada son validades en cuanto a sus restricciones según su uso?
Los datos también deberían validarse según su contenido, es decir, que contengan un valor que tenga sentido en el ámbito en el que se necesita usar. Ejemplo, una fecha de nacimiento del 1/1/0001.
¿Qué medidas toma el sistema para la protección de los distintos recursos que utiliza?
Algunos datos alteran el funcionamiento del sistema (recursos tiempo de ejecución, memoria, etc) y otros se envían a ser almacenados en determinados recursos del sistema (recursos de bases de datos, archivos, etc). Todos estos recursos deben verse protegidos de datos que hagan al sistema abusar de ellos, como ser por ejemplo los loops infinitos, el escalado de prioridades, SQL Injection, XSS, etc.
¿Qué usuarios tienen acceso a la utilización del sistema y cuáles no?
Es deseable que el sistema restrinja el acceso a los usuarios que efectivamente deben hacer uso de él y tienen permitido acceder a la información que el sistema maneja.
¿Qué usuarios tienen acceso a la administración o configuración del sistema y cuáles no?
De la misma manera, el sistema debería restringir el acceso solo a determinados usuarios que puedan modificar su configuración o comportamiento. A veces es incluso deseable que este perfil de usuarios no puedan tener acceso al resto de la información que el sistema utiliza, sino solo a la información de configuración en sí.