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.

Instalación de Python, Pip y Virtualenv en Windows 10

La instalación de Python, Pip y Virtualenv en una maquina con Microsoft Windows 10 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 para hacerlo seria a través de chocolatey, el cual nos permite administrar los paquetes instalados.

Para ello necesitamos abrir una consola de PowerShell en modo administrador:

Run as Administrator
Instalación de Chocolatey(powershell.exe) y python

PS C:\windows\system32> Set-ExecutionPolicy AllSigned
PS C:\windows\system32> iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
PS C:\windows\system32> choco install -y python

Una vez completada la instalación de Chocolatey y Python podemos cerrar la consola de PowerShell que hemos abierto con permisos de administrador y abrir otra con permisos de usuario. Python cuenta con un manejador de paquetes como es el caso de pip, el cual nos ayuda con instalación y administración de paquetes. Su instalación se puede realizar mediante la descarga del script get-pip.py y ejecutarlo con python.

PS C:\Users\electrocucaracha> Invoke-WebRequest -Uri https://raw.githubusercontent.com/pypa/get-pip/master/get-pip.py -OutFile get-pip.py
PS C:\Users\electrocucaracha> python.exe .\get-pip.py

Por ultimo y no menos importante se encuentra 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.

PS C:\Users\electrocucaracha> pip 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:\windows\system32>choco install -y mingw

Una vez instalado MinGW, solamente necesitaremos configurar distutils para que utilize el compidor gcc. 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:\Python36\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.

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);
	}

Implementacion de multiplicacion ultizando arreglos

Esta implementacion surgio de la necesidad de implementar una solucion para la multiplicacion de numeros grandes, me refiero a numeros que su resultado causaran el desboramiento de bufer. Mi propuesta se baso en la utilizacion de cadenas para su representacion y manejo de datos, pienso que la solucion que encontre es relativamente buena y quizas tenga muchos puntos a mejorar, lo cual se aceptan sugerencias.

Quiza una de las mayores limitantes que tengo es que el tipo de valor para el indice de los arreglos solo puede ser entero, esto reduce la cantidad de digitos con los cuales puedo trabajar.

Multiplicacion.java

...
	private static String multiplicar(String a, String b) {
		//Validaciones
...		
		StringBuffer result = new StringBuffer();
		int x = a.length();
		int y = b.length();
		int i;
		int j;
		long[][] results = new long[x][y];
		List sum = new LinkedList();
		long tmp;

		for (i = 0; i < x; i++) {
			for (j = 0; j < y; j++) {
				results[i][j] = (a.charAt(i) - '0') * (b.charAt(j) - '0');
			}
		}

		x--;
		y--;
		tmp = 0;

		while (true) {
			j = y;
			i = x;
			while (j >= 0 && i < a.length()) {
				tmp += results[i][j];
				i++;
				j--;
			}
			sum.add(tmp % 10);
			tmp /= 10;

			if (x > 0) {
				x--;
			} else if (y > 0) {
				y--;
			} else {
				if(tmp > 0){
					sum.add(tmp);
				}
				break;
			}
		}
		Collections.reverse(sum);
		for (long l : sum) {
			result.append(l);
		}

		return result.toString();
	}

Memristor

Simbolo Electrico
Simbolo Electrico

Es un elemento de circuito pasivo. Ha sido descrito como el cuarto elemento de los circuitos pasivos, junto con el capacitor, la resistencia y el inductor; su nombre es una palabra compuesta de memory resistor (resistencia-memoria). Y se cree que puede llevar a la creación de circuitos analógicos que podrían pensar como el cerebro humano.

El memristor fue predicho y descrito en 1971 por Leon Chua, de la Universidad de California, Berkeley. Durante 37 años, fue un dispositivo hipotético, hasta que en abril de 2008, una implementación física fue divulgada por un equipo de investigadores de HP Labs.

El concepto general es una matriz de cables (conductores), entre cada par de conductores de toda la matriz, existen llaves (interruptores) que en primera instancia se encuentran abiertos. Si conectamos una fuente de alimentación entre un par de conductores, al principio esta disposición no almacena o posee información alguna, pero si empezamos a cerrar algunos de estos interruptores podemos programar la matriz para que contenga una cantidad impresionante de información. Se puede abrir o cerrar cualquier interruptor particular, si queremos manejar otro interruptor solo debemos cambiar la conexión de la fuente.

Teóricamente se puede reemplazar 10 transistores con tan solo 1 memristor, las implicancias de esto son abismales, en modo simplista podríamos decir que aumentaríamos en 10 veces la capacidad de todos los circuitos electrónicos, y con ello las PC, celulares, tablets, etc

Los memristors de estado sólido de Williams pueden ser combinados para formar transistores, aunque son mucho más pequeños. Pueden también ser formados como memoria de estado sólido no volátil, que permitiría una mayor densidad de datos que los discos duros con tiempos de acceso similares a la DRAM, sustituyendo ambos componentes. Además, al ser un dispositivo analógico, no solo podría almacenar bits («1″s y «0»s), sino bytes o cadenas de bytes en el mismo espacio, solamente mejorando el dispositivo de control del memristor. Esto ofrece un futuro muy prometedor a largo plazo.

Hewlett Packard presenta los chips del futuro

RESTful (REpresentational State Transfer)

La Transferencia de Estado Representacional o REST, termino publicado por de Roy Fielding (uno de los principales autores de la especificación del protocolo HTTP) en el año 2000, el termino por si solo no define una arquitectura, sino una serie de reglas o restricciones que, cuando son aplicadas al diseño de un sistema, este crea un estilo de arquitectura. Despues de evaluar todos los recursos en la red y tecnologias disponibles para crear sistemas distribuidos y viendo que sin alguna restriccion, era dificil el mantenimiento y desarrollo de aplicaciones; Fielding definio una serie de restricciones definiendo el sistema RESTful:

  • Debe ser un sistema cliente-servidor
  • Debe ser stateless, es decir, cada peticion debe ser independiente de las otras.
  • Tiene que soportar un sistema de caching.
  • Debe ser accesible uniformemente, cada recurso debe tener una unica direccion y un punto de acceso valido.
  • Debe estar diseñado en capas para soportar escabilidad.
  • Debe proveer codigo bajo demanda, esta es una restriccion opcional.

Estas restricciones no dictan que tipo de tecnologia usar, solo definen como los datos son transferidos entre componentes y sus beneficios. Actualmente contamos con un ejemplo claro de un sistema RESTful funcionando, la Web. Antes que nada debemos puntualizar que significa que la Web sea RESTful, mas particularmente la web estatica, dicha web se apega a las restricciones de RESTful, su infraestructura web actual ofrece sistemas de cacheo, conexion stateless, y unicos hyperlinks para obtener recursos, donde los recursos son todos los documentos disponibles en cada sitio, siendo sus representaciones legibles por el explorador; por lo tanto la web estatica esta construida sobre la arquitectura de REST.

Por otra parte las aplicaciones web dinamicas no siempre son RESTful, porque pueden no cumplir con alguna restriccion.

Para conocer mas acerca de la arquitectura de RESTful necesitamos comprender que son los recursos y sus representaciones, definiendo un recurso como cualquier cosa direccionable sobre la web, entendiendo por direccionable, como aquellos recursos que pueden ser accedidos y trasferidos entre cliente y servidor. Siendo el mapeo de un recurso unico, diferentes peticiones sobre el mismo pueden regresar la misma representacion binaria guardada en el servidor. Por otra parte, la representacion de un recurso, es el estado temporal de la informacion actual que es enviado de vuelta hacia los clientes, por lo tanto una representacion puede tomar varias formas, como una imagen, un archivo de texto, o un stream de XML o JSON, pero todos deben estar disponibles bajo la misma URI.