IT Unicorns

Trevor Pott said that unicorns are “those smart people [that] everyone wants but no one has ever seen one.” They typically have experience managing large amounts of infrastructure and have a background in data center administration and suffer no fools gladly.

 

Polyfill

En términos de desarrollo web, un polyfiller es una pieza de código descargable el cual provee capacidades esperadas nativamente dentro de un explorador web. Por ejemplo, muchas características de HTML5 no son soportadas por antiguas versiones de Internet Explorer, pero pueden ser usadas por paginas web siempre y cuando cuenten con algún polyfiller el cual ayude con dichas carencias.

Dicho termino fue creado por Remy Sharp, quien buscaba una palabra que significara el replicar una API, usando Javascript, en el caso de que el explorador no contara con ella. Poly del griego πολύ = muchos, el cual refiere a dar una solución usando cualquier numero de técnicas, sin estar limitarlo a Javascript y fill cuya traducción significa llenar, refiriendo al rellenar aquellas carencias del explorador donde tecnología necesaria debe estar presente.

Por ultimo, también refiere al nombre del producto ingles Polyfilla, el cual es una pasta que ayuda a cubrir hoyos en las paredes, siendo una forma visual para Sharp de representar el como es corregido las carencias del explorador.

Polyfilla

Para conocer una coleccion de shims, fallbacks y polyfills visita la siguiente pagina.

 

A que se refiere la cultura de DevOps?

Durante el ciclo de vida de una aplicación de software, y mas en especifico, durante sus fases de implementación y mantenimiento, los equipos de desarrollo y operaciones tienen metas e incentivos que pueden llegar divergir y resultar en conflictos. Por un lado se tiene el equipo de desarrollo el cual es medido en base a su velocidad para la creación de nuevas capacidades de una aplicación, y por otro lado se tiene a el equipo de operaciones, los cuales son juzgados y medidos en base a la disponibilidad que se tiene en los servidores y el tiempo de respuesta de una o varias aplicaciones. En términos generales, mientras un departamento se esfuerza por aplicar cambios, el otro intenta mantenerlo lo mas estable posible. Y por si fuera poco, en lugar de optimizar el ciclo de vida completo de la aplicación, los equipos se dedican a mejorar sus procesos individualmente para poder lograr sus objetivos, dando como resultado una serie de culpas entre ellos.

Es por esto, que es necesario cambiar esa forma de pensar y actuar entre los equipos de trabajo. Recientemente fue acuñado el termino de DevOps(una abreviación entre las palabras Developers y Operations), para referirse a la respuesta para la creciente preocupación que hay en esa desconexión entre lo que tradicionalmente se considera una actividad de desarrollo y una de operaciones. Ademas de centrarse en describir patrones para la colaboración entre equipos, implementación de procesos y herramientas de trabajo.

La base del éxito de DevOps ha sido su cultura de confianza y sentimiento de fraternidad, todo parte de como se percibe el uno al otro, en lugar de pensar en lo “nuestro contra suyo”, se busca pensar en “nosotros” como equipo. Sus ventajas radican en el uso constante de la automatización de procesos, resulta evidente que automatizando se puede llegar a eliminar la discrepancia que existe entre procesos y minimizar errores humanos. La medición es necesaria para la cultura DevOps, ya que para poder mejorar algo es indispensable poder contar con métricas. Por ultimo, DevOps se enfoca en el concepto de compartir: compartir ideas, problemas, procesos, herramientas y metas. Mejorando la comunicación entre los equipos de desarrollo y operaciones se puede llegar resolver problemas críticos de forma inmediata. Como se observa la cultura de DevOps es mas una actitud que una tarea especifica.

Cabe remarcar que DevOps no es un termino de mercadeo o negocio, tampoco es permitir a los desarrolladores trabajar directamente en ambientes de producción, mucho menos un nuevo departamento en una empresa ni un titulo de una posición de trabajo.

Mas informacion : http://www.youtube.com/watch?v=_I94-tJlovg

 

Duck typing

Su nombre viene de la frase “Si se ve como pato y suena como pato, entonces es un pato”.

Y se basa en la premisa de que un objeto no tiene porque soportar todos los métodos y propiedades una clase o interfaz especifica para poder ser pasado como argumento de un método. El objeto solo tiene que soportar aquellos métodos y propiedades que sean necesarios por el método.

Algunas características de C# han soportado duck typing desde hace tiempo, como es el caso del operador foreach, ya que solo se necesita que el objeto tenga implementado un método publico llamado GetEnumerator, el cual no reciba argumentos y retorne un tipo que tenga dos cosas, un método llamado MoveNext que no reciba argumentos y regrese un tipo Boolean y una propiedad Current que regrese un objeto.

Para el caso de C#, el chequeo de tipo de clases se realiza en tiempo de ejecución en lugar de compilación, esto permite gozar de sus beneficios con una penalización en el tiempo de compilación. Por otra parte Python determina el tipo de un objeto mediante la inspección de sus métodos o conjunto de atributos.

class Persona:
    def hablar(self):
        print("Hola!")
 
class Pato:
    def hablar(self):
        print("Quaaaaaack!")
 
class AlguienMas:
    pass
 
def EnElBosque(cosa):
    cosa.hablar()
 
donald = Pato()
john = Persona()
who = AlguienMas()
 
for cosa in [donald, john, who]:
    try:
        EnElBosque(cosa)
    except AttributeError:
        print 'Meeowww!'

Para duck typing se prefiere el estilo de programación en el que “Es mas fácil pedir perdón que pedir permiso”, por lo que se intenta ejecutar algún método o leer una propiedad y si no funciona se tiene un comportamiento alternativo.

 

Instalacion de Python, Pip y Virtualenv en Windows

La instalación de python y sus herramientas de trabajo en una maquina con Windows podría ser llegar a complicarse dependiendo del nivel de personalización deseado.

Una forma tradicional de instalar python seria descargando el instalador desde la pagina oficial e instalarlo manualmente, completando los pasos del asistente y agregando el directorio de los binarios en la variable de ambiente global “Path”. Pero quizá una forma mas eficiente de hacerlo seria a través de chocolatey, el cual nos permite automatizar su instalación y controlar sus dependencias, así como facilitar su actualización.

Instalación de python con Chocolatey

C:\Users\electrocucaracha>cinst python

Completada la instalación de python, se recomienda tener un manejador de paquetes como es el caso de pip, el cual nos ayuda con instalación y administración de paquetes. Para poder instalar pip, es necesario tener instalado setuptools o distribute. La elección estara basada en la versión de python que estemos utilizando, ya que para versiones 3.x es obligatoria la instalación de distribute. Ambas herramientas tienen scripts que facilitan su instalación, puede optarse por utilizar el archivo “distribute_setup.py” o ez_setup.py, una vez descargado alguno de los archivos sera necesario ejecutarlos desde la consola.

Distribute

C:\Users\electrocucaracha>python.exe Downloads\distribute_setup.py

Setuptools

C:\Users\electrocucaracha>python.exe Downloads\ez_setup.py

Teniendo instalado alguna de estas herramientas, podemos proceder con la instalación de pip a través de su archivo de instalación get-pip.py y de igual manera ejecutarlo.

C:\Users\electrocucaracha>python.exe Downloads\get-pip.py

También se recomienda agregar la ruta de C:\<Ruta de instalación de python>\Scripts en la variable de ambiente global “Path”.

Por ultimo y no menos importante esta la instalación de virtualenv, el cual permite la creación de ambientes de python aislados. Para ello haremos uso de pip mediante el siguiente comando.

C:\Users\electrocucaracha>pip.exe install virtualenv

Recordemos que python es una interfaz y quizá al intentar instalar algún modulo este nos arroje el mensaje de error “unable to find vcvarsall.” por lo que sera necesario contar con algún compilador de C. Básicamente, existen dos alternativas para ello, una seria a través del compilador que Visual Studio 2008 Express Edition tiene o y la otra utilizar el compilador gcc de MinGW.

Instalación de MinGW con Chocolatey

C:\Users\electrocucaracha>cinst mingw

Una vez instalado MinGW, junto con el compilador gcc, solamente necesitaremos configurar python para poder utilizarlo. Podremos configurarlo de manera global o para cada uno de nuestros ambientes virtuales. Para ambos casos modificaremos o crearemos el archivo distutils.cfg agregando la siguiente información:

C:\Python27\Lib\distutils\distutils.cfg

[build]
compiler=mingw32
 

Hot swapping

El termino de “hot swapping” se refiere al remplazo de componentes sin la necesidad de reiniciar el sistema. El ejemplo mas claro, es en el caso de las memorias USB, ya que para su extracción no se requiere reiniciar el sistema operativo.

“Hot swapping” dentro del argot de desarrollo de sistemas se refiere a la habilidad de alterar un programa en ejecución para reducir su tiempo de desarrollo. Solo pocos lenguajes de programación soportan dicha habilidad como lo son Pike, Lisp, Erlang, Smalltalk, and Java. Para el caso de lenguajes en la plataforma de .Net el IDE tiene una opcion llamada “Editar y Continuar” lo cual permite hacer pequeños cambios.

En el caso de Django(Framework web para Python) los cambios en los modulos son detectados y se elimina el cache para actualizar los cambios al vuelo.

 

Visual Studio 2012 Product-Launch event

Visual Studio 2012 esta a la vuelta de la esquina, para ser el primero en conocer las nuevas capacidades y caracteristicas que este producto contiene visite el sitio oficial:

http://www.visualstudiolaunch.com/vs2012vle/Home

 

Configurar VS 2010 para poder debuguear en .NET Framework codigo fuente.

Hace tiempo Microsoft anuncio la liberacion del codigo fuente del .Net Framework ademas de habilitar el soporte a la depuracion a traves de Visual Studio. A continuacion tratare de enlistar los pasos a realizar para poder configurar dicho soporte en Visual Studio 2010.

Pasos a realizar:

1. Como paso inicial es necesario descargar e instalar Visual Studio 2010 QFE. El cual al ser instalado habilitara las opciones necesarias.

2. Una vez instalado el parche, dentro de Visual Studio 2010, en el Menu Tools -> Options… -> Debugging -> General, deseleccionar la opcion “Enable Just My Code(Managed only)” y seleccionar la opcion “Enable source server support”.



3. Por ultimo, es necesario especificar la localicacion de los fuentes, en la opcion Symbols, dentro de Debuggin se selecciona el Servidor, en caso de que no aparezca algun servidor se puede agregar http://referencesource.microsoft.com/symbols, ademas es necesario especificar la ruta para el cache la cual podria ser “C:UserselectrocucarachaSymbols”.

 

Implementacion de suma de cadenas parte II

Como mejora de la implementacion anterior y estudio de C#, sobretodo en las mejoras incoorporadas en la version 4, me decidi a implementar una nueva version de esta suma. Basicamente los cambios agregados fue la suma por bloques y la suma de ceros, que pienso yo que reduce la cantidad de operaciones, por lo menos unas 19 veces ya que es el bloque de numeros que toma.

Habria que hacer un profundo analisis en revisar la cantidad de codigo usado si este mejora el performance del algoritmo.

StringInteger.cs

...
        public static readonly int MAX_ULONG_LENGTH = ulong.MaxValue.ToString().Length;
...
        public static StringInteger operator +(StringInteger lhs, StringInteger rhs)
        {
            //Validaciones
 
            String tmpX = lhs.Container, tmpY = rhs.Container;
            ulong x, y, result = 0;
            int limit = lhs.Container.Length > rhs.Container.Length ? lhs.Container.Length : rhs.Container.Length;
            StringBuilder tmp = new StringBuilder(limit);
            do
            {
                if (IsTheOnlyOperand(ref tmpX, ref tmpY, (int)result))
                {
                    result = 0;
                    tmp.Insert(0, tmpX + tmpY);
                }
                else
                {
                    x = RetrieveNextNumber(ref tmpX);
                    y = RetrieveNextNumber(ref tmpY);
 
                    result += x + y;
                    if (result.ToString().Length == MAX_ULONG_LENGTH)
                    {
                        tmp.Insert(0, result.ToString().Substring(1));
                        result = 1;
                    }
                    else
                    {
                        tmp.Insert(0, result);
                        result = 0;
                    }
                }
            } while (!(string.IsNullOrEmpty(tmpX) && string.IsNullOrEmpty(tmpY)));
            tmp.Insert(0, result);
 
            return new StringInteger(tmp.ToString());
        }//operator+
 
        private static bool IsTheOnlyOperand(ref string firstOperand, ref string secondOperand, int carry)
        {
            bool response = false;
            firstOperand = SanitizeStringInput(firstOperand);
            secondOperand = SanitizeStringInput(secondOperand);
 
            if (string.IsNullOrEmpty(firstOperand) && !string.IsNullOrEmpty(secondOperand))
            {
 
                secondOperand = secondOperand.Substring(0, secondOperand.Length - 1) +
                    Convert.ToChar(Convert.ToInt32(secondOperand[secondOperand.Length - 1]) + carry);
                response = true;
            }
            else if (string.IsNullOrEmpty(secondOperand) && !string.IsNullOrEmpty(firstOperand))
            {
                firstOperand = firstOperand.Substring(0, firstOperand.Length - 1) +
                    Convert.ToChar(Convert.ToInt32(firstOperand[firstOperand.Length - 1]) + carry);
                response = true;
            }
 
            return response;
        }//IsTheOnlyOperand
 
        private static string SanitizeStringInput(string input)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }
 
            input = input.TrimStart('0').Trim();
            if ("".Equals(input))
            {
                input = "0";
            }
 
            Regex pattern = new Regex(@"^d+$");
            if (!pattern.IsMatch(input))
            {
                throw new ArgumentException("The string value " + input + " is not a integer value");
            }
 
            return input;
        }//SanitizeStringInput
 
        private static ulong RetrieveNextNumber(ref string stringNumber)
        {
            int length = stringNumber.Length > MAX_ULONG_LENGTH - 1 ? MAX_ULONG_LENGTH - 1 : stringNumber.Length;
            int index = stringNumber.Length - length;
            ulong number = length > 0 ? ulong.Parse(stringNumber.Substring(index, length)) : 0;
            stringNumber = stringNumber.Remove(index, length);
 
            return number;
        }//RetrieveNextNumber
 

Implementacion de suma de cadenas

Continuando con la serie de operaciones con numeros grandes, desarrollo la implementacion de una suma de valores contenidos en una cadena, la cual nos puede evitar el desboramiento de bufer. Realizando un ligero analisis encontramos que seguimos limitados por el manejo de indices de arreglos, ya que solo nos permite indexarlos con numeros enteros.

Suma.java

...
	private static String sumar(String a, String b) {
		//Validaciones
...
		int x, y, result = 0;
		int limite = a.length() > b.length() ? a.length() : b.length();
		char[] tmp = new char[limite + 1];
		for (int i = 1; i <= limite; i++){
			x = i <= a.length() ? a.charAt(a.length() - i) - '0' : 0;
			y = i <= b.length() ? b.charAt(b.length() - i) - '0' : 0;
			result += x + y;
			tmp[tmp.length - i] = (char) ((result % 10) + '0');
			result /= 10;
		}
 
		if ( result > 0){
			tmp[0] = (char) ((result % 10) + '0');
			return String.valueOf(tmp);
		}
		return String.valueOf(tmp, 1, tmp.length -1);
	}
 
 
 
Resources