viernes, 31 de diciembre de 2010

Ordenamiento externo: Mezcla Natural (Natural Merge Sort)

Entre los métodos de ordenamiento externos más comunes se encuentran el de Mezcla Directa (o Merge Sort) y el de Mezcla Natural (o Natural Merge Sort). El método de Mezcla Natural consiste en aprovechar la existencia de secuencias ya ordenadas dentro de los datos de los archivos. A partir de las secuencias ordenadas existentes en el archivo, se obtienen particiones que se almacenan en dos archivos o ficheros auxiliares. Las particiones almacenadas en estos archivos auxiliares se fusionan posteriormente para crear secuencias ordenadas cuya longitud se incrementa arbitrariamente hasta conseguir la total ordenación de los datos contenidos en el archivo original.

Para ilustrar la Mezcla Natural es muy conveniente utilizar números enteros como los datos almacenados en un archivo, de tal manera que este método funciona como se ilustra en el siguiente ejemplo (se utilizan corchetes o paréntesis cuadrados para separar las secuencias en las particiones):

Nombre del archivo original: Origen
Archivos auxiliares: Auxiliar1 y Auxiliar2

Origen: [10,17],[5,8,9],[3,22,50],[4],[2,20,30],[11,16,19],[6,21,23]

Primera Iteración: Las secuencias que se encuentren dentro del archivo origen se almacenan de forma alternada en los archivos auxiliares:
Partición
Auxiliar1: [10,17],[3,22,50],[2,20,30],[6,21,23]
Auxiliar2: [5,8,9],[4,11,16,19]

Aquí vale la pena resaltar lo que sucede con la secuencia [4] del archivo origen: cuando se realizan las particiones (aún sin entrar al proceso de fusión) los elementos 11, 16 y 19 se convierten en una sola secuencia junto con el 4.

La fusión se realiza por pares de secuencias de manera ordenada, así, la primer nueva secuencia está formada por los elementos de la primera secuencia en el archivo Auxiliar 1 y los elementos de la primera secuencia en el archivo Auxiliar2. Si uno de los archivos auxiliares llega a su fin, las secuencias que se encuentren en el otro archivo sin terminar se vacían directamente después de las nuevas secuencias:
Fusión en el archivo original
Origen: [5,8,9,10,17],[3,4,11,16,19,22,50],[2,20,30],[6,21,23]

Segunda Iteración: Se repite el proceso de partición con las nuevas secuencias:
Partición
Auxiliar1: [5,8,9,10,17],[2,20,30]
Auxiliar2: [3,4,11,16,19,22,50],[6,21,23]

Cuando al comparar un par de secuencias en los archivos auxiliares una de ellas llega a su fin, entonces simplemente se vacía el resto de la secuencia que aún contiene elementos en la nueva secuencia. Este caso se observa claramente en el par de secuencias azules: cuando se llega al elemento 17 del archivo Auxiliar1, la nueva secuencia en la fusión simplemente incluye los elementos 19, 22 y 50 del archivo Auxiliar2 al final.
Fusión en el archivo original
Origen: [3,4,5,8,9,10,11,16,17,19,22,50],[2,6,20,21,23,30]

Tercera Iteración: En este punto se cuenta ya con sólo un par de secuencias. La fusión de éstas da como resultado una secuencia que contiene todos los elementos del archivo Origen en orden ascendente.
Partición
Auxiliar 1: [3,4,5,8,9,10,11,16,17,19,22,50]
Auxiliar 2: [2,6,20,21,23,30]

Fusión
Origen:  [2,3,4,5,6,8,9,10,11,16,17,19,20,21,22,23,30,50]

En este último paso, los datos contenidos en el archivo origen se encuentran ordenados de manera ascendente. En la Mezcla Natural se comparan pares de secuencias contenidas en los archivos auxiliares con el objetivo de formar nuevas secuencias durante el proceso de fusión.

En el archivo adjunto se encuentra el código que implementa la Mezcla Natural utilizando nombres de personas como datos de los archivos, por lo que las comparaciones que se llevan a cabo a la hora de realizar las particiones y fusiones utilizan el método "compareTo" propio de la clase String.

NOTA: Este código maneja archivos de tipo binario, para probarlo se puede utilizar el archivo de prueba que se encuentra en el post Archivo para probar algoritmos de Ordenamiento Externo.


MezclaNatural.java

jueves, 16 de diciembre de 2010

Desarrollo de Software dirigido por Pruebas: árboles binarios (Parte 1)

Te encuentras en la primera parte de la serie "Desarrollo de Software dirigido por Pruebas":
  1. Diseño de las pruebas
  2. Implementación
  3. Refactoring
  4. Conclusiones y código
El Desarrollo de Software dirigido por Pruebas (Test Driven Development, en inglés) es una técnica que se basa en la elaboración de pruebas para el software previas a la implementación del código. Puede parecer extraño, ya que normalmente estamos acostumbrados a implementar un código y después probar que funcione. Sin embargo, esto tiene sentido ya que antes de la implementación, ya conocemos el funcionamiento del programa y podemos estar seguros de cuál o cuáles son los resultados esperados a la hora de correr dicho programa.

El desarrollo de las pruebas antes del desarrollo del software es muy útil para comprender a profundidad la funcionalidad y el comportamiento del mismo. Realizar test cases utilizando JUnit es muy conveniente ya que a la hora de probar la aplicación, se puede estar seguro de que cumple con el objetivo establecido desde un principio si pasa todas las pruebas y además, es posible realizar cambios con mayor seguridad ya que al correr nuevamente las pruebas, si éstas fallan, se puede tener una muy buena idea de dónde está el error para corregirlo rápidamente. Una vez que las pruebas han pasado satisfactoriamente, aún con la implementación de cambios, es muy probable que dicha aplicación esté desarrollada correctamente. Además, si se desarrollan pruebas de forma creativa, tal y como se explica en el post Prueba Unitaria (Unit Testing) con Netbeans, es muy posible que se estén cubriendo escenarios que quizá no se consideren al realizar las pruebas manualmente.

En esta ocasión, voy a ilustrar el proceso de desarrollo dirigido por pruebas utilizando un conjunto de clases que servirán para implementar árboles binarios. Dos de las operaciones básicas para un árbol binario son la inserción y el borrado de nodos. En esta serie, utilicé valores enteros como el tipo de dato que almacenan los árboles, pero esta información puede ser de cualquier otro tipo.

En este punto, aún no he implementado los cuerpos de los métodos, solamente he creado los esqueletos de las clases, ya que comenzaré por implementar las pruebas. Por ejemplo, para probar el método de inserción (al que llamé insertion), utilizaré los tres recorridos por profundidad de un árbol básicos: recorrido preorden, recorrido inorden y recorrido postorden. Realizaré tres pruebas dentro de las cuales insertaré valores de manera que las estructuras de los árboles sean lo más distintas posibles. Una vez instanciado un objeto árbol, "insertaré" (es decir, haré varias llamadas al método de inserción) ciertos valores, llamaré a los métodos que realizan los recorridos y que devuelven un arreglo con los resultados y los compararé con otro arreglo que contiene esos mismos valores pero que yo ordené de acuerdo con lo que espero obtener de cada recorrido. Un primer caso de prueba para la inserción podría ser insertar los siguientes valores: 10, 6, 7, 5, 4, 11, 13, 12, 15, 3. El árbol binario que se obtiene como resultado es el siguiente:


De acuerdo con esta información, la implementación de esta primera prueba luciría de la siguiente manera:

@Test
    public void insertion01() {
        //Crea una instancia de tipo SimpleBinaryTree para el test
        SimpleBinaryTree simpleTree = new SimpleBinaryTree();

        //Verificar que el arbol esta vacio al inicio
        assertTrue(simpleTree.isEmpty());

        //Insertar elementos al arbol
        simpleTree.insertion(10);
        simpleTree.insertion(6);
        simpleTree.insertion(7);
        simpleTree.insertion(5);
        simpleTree.insertion(4);
        simpleTree.insertion(11);
        simpleTree.insertion(13);
        simpleTree.insertion(12);
        simpleTree.insertion(15);
        simpleTree.insertion(3);

        //Corroborar que todos los datos se hayan insertado
        assertArrayEquals(simpleTree.preOrder(),
                     new int[]{10, 6, 5, 4, 3, 7, 11, 13, 12, 15});
        assertArrayEquals(simpleTree.inOrder(),
                     new int[]{3, 4, 5, 6, 7, 10, 11, 12, 13, 15});
        assertArrayEquals(simpleTree.postOrder(),
                     new int[]{3, 4, 5, 7, 6, 12, 15, 13, 11, 10});
    }

El método de borrado (al que llamé deletion)  se probará de manera muy similar: primero se "insertarán" algunos valores, después se hará una llamada al método de borrado y finalmente se comparará el resultado obtenido de los recorridos contra arreglos que contienen los valores esperados.

El proyecto que estoy utilizando para demostrar el desarrollo de software dirigido por pruebas consta de cinco clases: BinaryTree, TreeNode, SimpleBinaryTree, AVLTree y RedBlackTree. Esta estructura y los resultados de las pruebas se discutirán con mayor detalle en el siguiente post.

sábado, 11 de diciembre de 2010

Cómo evaluar integrales múltiples utilizando Wolfram Alpha

Wolfram Alpha es una herramienta muy versátil. Además de poder evaluar derivadas e integrales simples, también permite conocer el resultado de integrales múltiples. Solamente hay que acostumbrarse a la notación utilizada para poder introducir una de estas integrales. Por ejemplo, si queremos conocer el resultado de evaluar la siguiente integral en Wolfram Alpha:

Debemos introducirla en el recuadro naranja donde se llevan a cabo las consultas y cálculos de la siguiente manera:

int (z) dz dx dy, z = 0 to sqrt(4 - x - y^2), x=0 to sqrt(1 - y^2), y=0 to 1

Donde "int" representa la operación de integración, el argumento entre paréntesis siguiente al operando int es el integrando (si es que lo hay), seguido por las diferenciales de las variables (en este caso x, y, y z) y finalmente los límites para cada variable comenzando con aquélla cuya diferencial aparezca enseguida del integrando. Los límites para cada variable se separan por comas.

El resultado en la página de Wolfram Alpha luciría de la siguiente manera:

Porción de la página de Wolfram Alpha que contiene la operación realizada




En ocasiones es posible obtener un procedimiento y una gráfica, sin embargo, cuando esto no es posible, aún podemos utilizar Wolfram Alpha para corroborar los resultados obtenidos en nuestros cálculos al aplicar técnicas conocidas de integración. Si das click en el letrero "More digits", Wolfram Alpha te proporcionará varias decenas de los dígitos que corresponden al resultado si es que éste es un número irracional.

Dentro de las funciones que también podemos utilizar se encuentran las trigonométricas (como el seno que se  escribe sin), las exponenciales (únicamente introduciendo la letra "e" seguida del símbolo de exponente y lo que se desea que constituya el exponente para la base e), las logarítmicas (Wolfram Alpha utiliza el símbolo "log" para identificar al logaritmo natural) e inclusive las hiperbólicas (ejemplo: sinh es el seno hiperbólico).

Para poder introducir una integral fácilmente, es posible utilizar como plantillas los ejemplos que ya proporciona Wolfram Alpha, para ello, hay que dirigirse desde la página principal al enlace que dice "Examples by Topic", de ahí a "Mathematics" -> "Calculus" -> "Integrals" y en el apartado de "Multiple Integrals", utiliza la plantilla que más se parezca al ejemplo que deseas evaluar.

¿Qué hacer si Wolfram Alpha no muestra los pasos intermedios para llegar a un resultado?

Ahora bien, en ocasiones Wolfram Alpha no despliega los pasos intermedios que sigue para obtener un resultado. Esto puede deberse a que utiliza técnicas que quizá desde el punto de vista de una computadora son más sencillas (por ejemplo a través de aproximaciones), mientras que nosotros obtenemos el resultado de la operación de manera simbólica (a través de identidades, fórmulas, despejes sencillos).

Sea cual sea el caso, si no existen pasos intermedios, podemos utilizar Wolfram Alpha para verificar el resultado de nuestros cálculos. Independientemente de la técnica que utilicemos o las operaciones intermedias que realicemos para obtener una respuesta, podemos comparar nuestros resultados con los que nos ofrece Wolfram Alpha para verificarlos.

Por ejemplo, podemos descomponer la integral múltiple que se planteó al principio y utilizar Wolfram Alpha para calcular la más interna de la siguiente manera:

int (z) dz, z = 0 to sqrt(4 - x - y^2)

El resultado es el siguiente:

En esta ocasión Wolfram Alpha no muestra los pasos intermedios porque se trata de un caso básico de integracion. Lo que podemos hacer es realizar la integral y verificar que obtengamos el mismo resultado. Una vez que verificamos esta parte, podemos ahora sustituir este resultado para encontrar la integral siguiente en la integral múltiple original:

int (1/2(-x - y^2 + 4)) dx, x=0 to sqrt(1 - y^2)

Para obtener:

Y finalmente, el resultado de esta integral utilizarlo para resolver la última integral con respecto a y:

int (1/4((1 - 2*sqrt(1 - y^2))y^2 + 8*sqrt(1 - y^2) - 1)) dy, y=0 to 1

Y así verificar el resultado final:

De esta manera, si existe alguna duda acerca del resultado de una integral múltiple como esta, puede ser de más ayuda el observar cómo se van resolviendo cada una de las integrales mediante la sustitución del resultado de cada una de ellas desde la más interna hasta la última o más externa.

Cómo utilizar el cambio de ejes para resolver una integral múltiple (ejemplo)

Supongamos que se pide evaluar la siguiente integral:

Tal parece que para esta integral es inútil recurrir a la sustitución simple, la sustitución trigonométrica, las fórmulas de integración contenidas en los formularios más usuales y por supuesto, es virtualmente imposible realizarla de manera directa, así que, ¿Qué podemos hacer para simplificar la tarea de evaluar una integral semejante? La respuesta es muy simple: realizar un cambio de ejes. 

Primero debemos reconocer que al tratarse de una integral doble que posee un integrando, en realidad estamos ante una integral triple, es decir, debemos pensar en tres dimensiones. La gráfica de las curvas en cuestión se obtiene mediante el análisis de la expresión, observándola en términos de las dimensiones x y y, podemos apreciar que y está delimitada por una línea recta en y = 1 y cero y  x está delimitada por la curva "raíz de y" y la recta x = 1. La curva que representa el integrando se levanta sobre el eje z a partir de z = 1. De modo que si nos situamos hipotéticamente sobre el eje z y observamos la base de estas gráficas, este sería el resultado:



Gráfica realizada con ayuda de Wolfram Alpha


La base del volumen que se pretende evaluar por medio de esta integral está marcada en azul. Ahora bien, si observamos la integral tal y como está, nos encontraremos en serios problemas a la hora de encontrar una solución apropiada, sin embargo, podemos invertir el orden en el que están evaluando las variables x y y y obtener como resultado la siguiente expresión:


Ahora, el diferencial de x se evalúa desde cero hasta 1, por lo tanto, para poder obtener la expresión que corresponde a los límites del diferencial de y, es necesario despejar a y. Despejando la raíz de y obtenemos y = x^2, por lo que éste es el nuevo límite aplicable a y.


Esta expresión resulta muy sencilla de evaluar, ya que el integrando se encuentra en términos de x y la variable respecto de la que hay que integrar es y, por lo tanto, el integrando se convierte en una constante y se puede integrar como tal. El resultado es el siguiente:




miércoles, 8 de diciembre de 2010

Prueba Unitaria (Unit Testing) con Netbeans

¿Cómo pruebo mis programas de Estructura de Datos? ¿Existe algo mejor que imprimir resultados en la consola y analizar visualmente si el programa funcionó bien?

Por supuesto, desarrollando pruebas unitarias para tu código aseguras que tu implementación se comporta como esperas y mejor aún, si realizas algún cambio en el código, puedes correr tu prueba nuevamente para validar que todo siga funcionando correctamente. En resumen, una prueba unitaria es código que evalúa partes específicas de otro programa.

Suena como trabajo doble ¿Aparte de mi implementación tengo que hacer otro programa para probarlo?

Realmente no, ya que existen librerías que te ayudan a desarrollar las pruebas rápidamente. Es más, IDE´s como Netbeans incluyen atajos y opciones para generar y ejecutar las pruebas. La siguiente imagen muestra cómo el proyecto por default de Neatbeans ya incluye folders y librerías para desarrollar pruebas.

¿Cómo puedo probar una lista que tiene como tipo de datos enteros e inserta los valores en orden?

Supongamos que los métodos iniciales de la lista son los siguientes:

public class ListaDoble {
   public void insertar(int n){...}
   public NodoDoble remover(int valor){...}
   public boolean isEmpty(){...}
   public static void main(String args[]){...}
}

Primero, borrar el método main, ya que eso está fuera de las responsabilidades de la clase. Vamos hacer dos cambios a la clase:

  1. Agregar una variable privada que mantenga el número de elementos en la lista: numElementos. Se incrementará cuando se inserte un elemento y se drecrementará en el método remover.
  2. Adicionar un método que nos retorne la lista como un arreglo de enteros. Esta es una posible implementación:
        public int[] toArray(){
           int[] array = new int[numElementos];
           int i = 0;
           NodoDoble auxiliar = inicio;
           while (auxiliar != null) {
               array[i] = auxiliar.getDatos();
               auxiliar = auxiliar.getSiguienteNodo();
               i++;
           }
           return array;
       }

Ahora veamos lo rápido y fácil que es agregar una prueba.

  1. Da clic derecho en la clase que queremos probar, selecciona la opcion Tools (Herramientas) > Create JUnit Tests
  2. Aparece un diálogo con opciones para crear la clase que ejecutará las pruebas. Para esta prueba seleccioné lo mínimo, como puedes ver en la figura.
  3. Borra el método por default que genera Netbeans y agrega el siguiente método.
        @Test
       public void testEscenario01() {
           ListaDoble lista = new ListaDoble();
           // La lista debe estar vacia al inicio
           assertTrue(lista.isEmpty());
    
           // Insertemos 5 elementos
           lista.insertar(100);
           lista.insertar(50);
           lista.insertar(200);
           lista.insertar(-50);
           lista.insertar(0);
           assertArrayEquals(lista.toArray(),
                   new int[]{-50,0,50,100,200});
       }
    Como puedes ver, este método crea una instancia de ListaDoble. Los métodos assert son parte de la librería JUnit, y sirven para verificar si cierta condición se cumple. Por ejemplo, recién creada la lista, se espera que esté vacía, esto lo logramos con assertTrue(lista.isEmpty()). Después insertamos 5 elementos y verificamos con assertArrayEquals que el contenido de la lista sea igual al arreglo que pasamos como segundo parámetro. Nota que el segundo arreglo está ordenado, ya que es lo que esperamos de la lista.
  4. Para ejecutar la prueba, simplemente da clic derecho en el archivo de prueba (en este caso ListaDobleTest) y selecciona Test File
    Si tu implementación es correcta, aparecerá un mensaje como el siguiente.
    Para la siguiente imagen, introduje un error en la prueba para ver la salida de JUnit.

NOTA

Esto nos lleva a reflexionar, que pueden existir errores tanto en la implementación como en la prueba. Pero es importante notar que sin pruebas confiamos ciegamente en la implementación. Si hay un error al correr las pruebas, el error puede estar en la implementación o en las pruebas. Si las pruebas corrieron exitosamente, entonces la implementación cumple con los casos presentados en las pruebas; en otras palabras, puede que tanto la implementación como las pruebas estén mal. Obviamente, es más difícil equivocarse en dos lugares (implementación y pruebas) que sólo en uno (implementación).

También es importante mencionar que las pruebas sólo garantizan que nuestro programa cumple con los escenarios mencionados, más no que está 100% libre de errores.

¿Con una sola prueba basta para la clase ListaDoble?

El objetivo no es crear tantas pruebas como sea posible. Más bien, es crear el mínimo número de pruebas que cubran el mayor número de casos o escenarios de nuestra implementación. Por ejemplo, supongamos que en la prueba uno insertamos 20,19, 18, 17, 16 y en la prueba dos insertamos 10,9,8,7,6. Realmente, en las dos pruebas estamos insertando elementos en orden descendente; es decir, las dos cubren el mismo escenario (son redundantes).

Con esto en mente, recomiendo crear escenarios que se complementen. Para el caso de la inserción en la lista doble: 1) insertar elementos en order ascendente, 2) insertar elementos en orden descendente, 3) insertar elementos tal que un elemento se inserte al inicio de la lista, el siguiente elemento al final de lista, y otro elemento en un punto medio de la lista y así sucesivamente, 4) insertar sólo elementos iguales.

Observa que estos casos son para la inserción, casos similares deben ser creados para el borrado. Y por último recomendaría un conjunto de casos que mezclaran operaciones de inserción y borrado.

Veo que al comparar la lista en forma de arreglo usamos un arreglo que nosotros calculamos new int[]{-50,0,50,100,200}, ¿cómo difiere esto de imprimirlo en la consola e inspeccionarlo visualmente?

Quizá las primeras dos o tres veces de inspeccionar el resultado visualmente resulte práctico, pero después de un buen rato de estar desarrollando verás que resulta demasiado tedioso y propenso a errores. Imagina que tienes una lista de 100 números, no suena muy divertido inspeccionar visualmente los 100 números cada vez que realices un cambio a la lista.

Además, como menciono en el punto anterior, es necesario probar varios escenarios. Si creas tus pruebas unitarias, entonces cada vez que las ejecutes estarás evaluando todos los escenarios en un abrir y cerrar de ojos. Esto te ayuda a tener más confianza al realizar cambios o mejoras en tu implementación, ya que puedes ir probando continuamente para validar si algo deja de funcionar o si algo ya está funcionando.

miércoles, 1 de diciembre de 2010

Fundamentos de Bases de Datos: Bases de Datos Orientadas a Objetos (apuntes)

He aquí una breve introducción a las Bases de Datos Orientadas a Objetos para el curso de Fundamentos de Bases de Datos del Instituto Tecnológico de Toluca. La práctica la pueden descargar en el link que se encuentra al final de la misma.

A las Bases de Datos Orientadas a Objetos también se les conoce como Sistemas de Manejo de Bases de Datos de Objetos (ODBMS, por sus siglas en inglés: Object Database Management Systems). Este tipo de bases de datos almacenan objetos en lugar de datos como enteros, cadenas o números reales. Los objetos ss utilizan en lenguajes de programación orientados a objetos tales como C++, Java y otros. Los objetos consisten básicamente en lo siguiente:

  • Atributos. Es la información que define las características de un objeto. Puede ser de tipo simple como por ejemplo enteros, booleanos o caracteres o puede hacer referencia a otros objetos.
  • Métodos. Los métodos definen el comportamiento de un objeto, son el equivalente a lo que se conoce como funciones o procedimientos en C, por ejemplo.
Otro término que vale la pena considerar es el de Clases. Las clases se utilizan en lenguajes de programación orientados a objetos para definir los datos y los métodos (características y comportamientos) que los objetos posean. Una clase es como una plantilla para crear un objeto y es usada para crear (instanciar) el objeto. Las clases pueden ser empleadas en bases de datos orientadas a objetos para re-crear partes de un objeto que puedan no estar almacenadas dentro de la base de datos como por ejemplo, los métodos.

Existen ventajas y desventajas de las Bases de Datos Orientadas a Objetos sobre las Bases de Datos de tipo Relacional, entre las ventajas cabe mencionar el hecho de que la navegación a través de la información en las primeras es más fácil que en las segundas, además de que el modelo de datos en las Orientadas a Objetos está basado y se ajusta mejor al mundo real. Entre las desventajas de las Orientadas a Objetos se encuentran la existencia de más herramientas para las Relacionales, la mayor estabilidad de los estándares de las Relacionales y una eficiencia más baja cuando se presentan datos y relaciones simples.

Fuente:
Object Oriented Databases
http://www.comptechdoc.org/independent/database/basicdb/dataobject.html 


DESCARGA LOS APUNTES DE LA PRÁCTICA DE LA CLASE AQUÍ!!!

martes, 30 de noviembre de 2010

Archivo para probar algoritmos de Ordenamiento Externo

En esta ocasión me gustaría proporcionarles a través de este medio, un archivo en formato binario que contiene más de 5000 nombres y con el cual se puede realizar una prueba confiable de los algoritmos de ordenamiento externo Mezcla natural y Mezcla directa o de intercalación que hemos revisado en la clase de Estructuras de Datos en el Instituto Tecnológico de Toluca.

Dicho archivo proviene de un proyecto denominado "Project Euler", que es un proyecto donde se convoca a la comunidad apasionada de la programación a resolver acertijos de distinto nivel con el fin divertirse por medio de la programación. El proyecto se nombró en honor al matemático Leonard Euler. En uno de los problemas (concretamente, en el problema 22) se proporciona un archivo con los más de 5000 nombres pero en formato de archivo de texto. Para nuestros proyectos, lo convertí a archivo binario.

Dicho archivo contiene los nombres en completo desorden, de modo que se pueda apreciar el buen funcionamiento de los métodos de ordenamiento de los que nos hemos encontrado.

Aquí puedes descargar el archivo.

Aquí puedes encontrar el código de la mezcla natural.

Si desean más información acerca del Proyecto Euler, pueden visitar su página web: http://projecteuler.net/

domingo, 28 de noviembre de 2010

SQL: Filtrar por Columna Resultado de Agrupado

Nota: Para poder seguir mejor este ejemplo y poder ejecutar las consultas, te recomiendo seguir las instrucciones para configurar el ambiente de trabajo en la parte 1 del tutorial de SQL.

En este post analizaremos una pregunta que recibí en la parte 3 (Consultas con agrupados) del tutorial de SQL. La siguiente consulta obtiene lo que ha gastado en total cada cliente en la renta de films.

SELECT customer.customer_id, first_name, last_name, SUM(amount) 
FROM customer 
INNER JOIN payment ON (customer.customer_id=payment.customer_id) 
GROUP BY customer.customer_id, first_name, last_name;

Pero, ¿cómo podemos filtrar por columnas que son resultado de agrupados? Específicamente, en la consulta anterior, ¿cómo desplegamos sólo los clientes que hayan gastado 100 o más? Este dato es resultado de usar una función de agrupado; es decir, no es una columna directa de la tabla. Por ello, no lo podemos usar directamente en la cláusula where. Lo que vamos a usar son consultas anidadas. La consulta original servirá como la tabla de otra consulta. Veamos la consulta que obtiene el resultado deseado:

SELECT *
FROM
(
   SELECT customer.customer_id, first_name, last_name, 
          SUM(amount) AS gasto_total
   FROM customer
   INNER JOIN payment ON (customer.customer_id=payment.customer_id)
   GROUP BY customer.customer_id, first_name, last_name
) ClientesConPagoTotal
WHERE gasto_total >= 100;

Como puedes observar, el resultado de la consulta original se usa como la tabla fuente de la consulta externa - nota que asignamos un nombre a esta tabla interna: ClientesConPagoTotal. También nombramos la columna que contiene el resultado agregado: gasto_total. Ahora, todos las columnas de la tabla temporal ClientesConPagoTotal son visibles en la consulta externa y las podemos usar para realizar filtros, como en: WHERE gasto_total >= 100.

Saludos,
Toño.

jueves, 25 de noviembre de 2010

Apuntes Circuitos Eléctricos Unidad3

Hola,

En los siguientes links encontrarán los apuntes de la unidad 3 para la materia de Circuitos Eléctricos y Electrónicos impartida para Ingeniería en Sistemas Computacionales aquí en el Instituto Tecnológico de Toluca.

Apuntes parte1 (aquí está incluida la tabla de los teoremas de álgebra booleana)
Apuntes parte 2 (comienza con los mapas de Karnaugh)

Saludos y suerte mañana en el examen.

domingo, 21 de noviembre de 2010

Boliche Magnético

Se acerca el fin de semestre, y con ello la carga de trabajo aumenta. Cuando tomes un descanso, te recomiendo que juegues Boliche Magnético. En este juego, la bola de boliche es un protón, el objetivo es colocar cables con corriente para crear campos magnéticos que guíen a la bola. Cuando activas el switch, puedes dar clic en el área del juego para ver los campos magnéticos que se han creado. Si necesitas ajustar los cables, sólo baja el switch y realiza los cambios. Si sientes que ya lograste una buena combinación, activa el switch y lanza la bola. La siguiente imagen muestra la configuración que logré en mi primer intento en el nivel 3. Con esta configuración sólo quedó un pino de pie. La segunda imagen muestra cómo aumenté la carga del cable que está más cerca de la esquina superior derecha para poder tirar el último pino.

El juego lo pueden encontrar en la siguiente dirección:

¿Qué les parece el juego? ¿A qué nivel llegaron?

jueves, 4 de noviembre de 2010

Test ADempiere en línea

Como sistema ERP, ADempiere es una herramienta muy completa y versátil. Sin embargo, para quien desee utilizarla ya sea desde la computadora personal o desde un negocio, la instalación puede resultar un tanto tardada a pesar de que existen interfaces de usuario e instaladores que realizan el proceso semiautomáticamente.

Para quienes desean comprobar los múltiples beneficios que este sistema trae consigo, sin embarcarse en el proceso de instalación, existe una versión en línea totalmente gratuita que puede ser utilizada y cumple con toda la funcionalidad de ADempiere. Esta versión fue lanzada por una empresa llamada Italica y la dirección en la que se encuentra es la siguiente:


La primera vez que se ingresa en el sitio, se pide al usuario algunos datos de tipo personal con el fin de que pueda ser identificado y se determine el propósito de la visita (Nota: es importante llenar todos los campos solicitados, ya que de lo contrario, no se puede avanzar a la siguiente página de login). En la siguiente imagen se muestra dicha pantalla:


Una vez que se ha completado la información solicitada, se procede a la página de login. El usuario y el password o contraseña (GardenAdmin y GardenAdmin respectivamente), se encuentran en la tabla a la izquierda:



También se puede seleccionar el idioma:


Cuando se completa el proceso para acceder a la aplicación, y una vez seleccionado el idioma, se presenta la interfaz para poder utilizar ADempiere:


Después de estos sencillos pasos, se puede disfrutar del uso de ADempiere sin pasar por la instalación.

domingo, 31 de octubre de 2010

Revista Comunicados de la ACM (Octubre 2010)

Parte del desarrollo de un Ingeniero en Sistemas Computaciones, es mantenerse informado no sólo desde el punto de vista de usuario sino también desde el punto de vista científico. Por ejemplo, además de saber que Microsoft acaba de liberar Windows 7 Mobile o que Google ha estado realizando pruebas reales con un automóvil autónomo; es bueno saber cómo algunas compañías están explotando la información en Internet para poder predecir el futuro (ver artículo).

Mejor aún es mantenerse informado de avances científicos. Una buena fuente de información es la revista Comunicados de la ACM. La ACM (Association for Computing Machinery) es una sociedad cuyo objetivo es ayudar a compartir recursos (artículos, conferencias, bolsa de trabajo) que promuevan el progreso de las ciencias de la computación. La revista es mensual y la pueden descargar en pdf (Comunicados de la ACM).

El artículo que ocupa la portada del mes de octubre es acerca de sistemas P2P. La tecnología P2P no se utiliza sólo para distribuir archivos (ej. torrents); es usada también en aplicaciones científicas para donar ciclos de CPU en la investigación de enfermedades, el calentamiento global, entre otros. El artículo menciona estrategias empleadas para encontrar y distribuir contenido en un sistema P2P. Además habla de los retos y oportunidades relacionados a esta tecnología.

Comparte en los comentarios tu opinión acerca de los artículos de la Revista Comunicados de la ACM (Octubre 2010).

Nota: ya se encuentra también disponible la versión del mes de noviembre.

martes, 19 de octubre de 2010

Fallece Benoit Mandelbrot

 Hace algun tiempo cuando actualicé la imagen de mi avatar, publiqué un artículo acerca de fractales. Pues bien, el padre de los fractales, Benoit Mandelbrot, falleció el pasado 14 de Octubre víctima de cáncer en un hospital en Cambridge, Massachusetts a la edad de 85 años.

Mandelbrot era un genio de las matemáticas que descubrió la propiedad que tienen algunas figuras de estar compuestas por partes que son idénticas al todo pero en una escala menor que se prolonga hasta el infinito. De familia judía, emigró a París para escapar de los Nazis. Trabajó durante mucho tiempo para IBM y después se convirtió en profesor de ciencias matemáticas en la universidad de Yale.

El concepto de fractales ha permitido a los científicos medir figuras que se consideraban demasiado difíciles de medir debido a su aspecto aparentemente irregular. Las matemáticas de los fractales también han hecho contribuciones importantes en las áreas de la música digital y la compresión de imágenes. Además, el uso de fractales se ha extendido significativamente en forma de arte moderno a través de la creación de hermosos diseños que siguen el comportamiento típico de los fractales descubierto por Mandelbrot.

Pocos son los grandes genios que viven una vida tan larga y fructífera como lo fue la vida de Benoit Mandelbrot. Recientemente, apareció dando una plática dentro de las famosas TED Talks (Technology, Entertainment, Design Talks, por sus siglas en inglés) demostrando una vitalidad y una frescura de ideas impresionantes. A continuación se muestra el video de dicha plática. Merece la pena verla.

domingo, 17 de octubre de 2010

Practicando SQL (Parte 4)

Te encuentras en la cuarta parte de la serie "Practicando SQL":
  1. Configurando ambiente de trabajo y consultas básicas
  2. Consultas con más de una tabla
  3. Consultas con agrupados
  4. Consultas anidadas

Supongamos que deseamos saber con cuáles actores han trabajado con cierto actor (en este ejemplo usaremos al actor Christopher West que tiene como actor_id = 163). Para ello, primero debemos obtener una lista de todos los films en los que ha trabajado Christopher. De esta lista de films, obtendremos todos los actores que han trabajado en esos films (y por lo tanto han trabajado con Christopher). Un detalle que hay que cuidar, es que un actor puede aparecer más de una vez, por lo que sólo hay que mostrarlo una vez.

La siguiente consulta regresa todos los films en los que ha trabajado Christopher:

mysql> SELECT film_id
  -> FROM film_actor
  -> WHERE actor_id=163;

Ahora podemos obtener los actores que han trabajado en esas películas con:

mysql> SELECT actor.actor_id, first_name, last_name
  -> FROM actor
  ->   INNER JOIN film_actor ON (actor.actor_id=film_actor.actor_id)
  -> WHERE film_id IN
  -> (SELECT film_id FROM film_actor WHERE actor_id=163);

Como pueden ver las primeras tres filas de la consulta ya son familiares: obtienen en qué películas han trabajado todos los actores. La última fila (consulta anidada) es igual a la primer consulta mostrada arriba. El truco es que usamos los resultados de la consulta anidada para mostrar sólo los actores que hayan participado en esos films. También noten que usamos la palabra clave IN, ya que podemos tener más de una película. Podemos leer las últimas dos líneas de la consulta como: si el film_id de la fila de la consulta externa se encuentra en la lista de films regresados por la consulta interna, entonces esa fila pertenece al resultado final.

Como Christopher pudo haber trabajado en más de una película con el mismo actor, esto causa actores repetidos en el resultado. Eso lo podemos solucionar fácilmente usando la palabra clave DISTINCT. Además, la siguiente consulta también excluye al mismo Christopher.

mysql> SELECT DISTINCT actor.actor_id, first_name, last_name
   -> FROM actor
   ->   INNER JOIN film_actor ON (actor.actor_id=film_actor.actor_id)
   -> WHERE actor.actor_id<>163 AND film_id IN
   -> (SELECT film_id FROM film_actor WHERE actor_id=163);

Muy bien! Con esto cerramos esta introducción a SQL. Sin embargo, de vez en cuando publicaré alguna consulta que resulte interesante. Por último los dejo con una trivia.

Trivia

Requisitos para participar

  1. Ser seguidor de este blog
  2. Ser estudiante del Instituto Tecnológico de Toluca (credencial vigente)
  3. Poner la respuesta en los comentarios de este post
  4. Fecha límite: 31 de Octubre de 2010 a las 23:59:59

Premio

Un mouse que se encuentra en muy buenas condiciones. Es similar al que pueden ver aquí. El ganador será el primer comentario con la respuesta correcta.

Pregunta

Mostrar la consulta y el resultado que obtenga el par de actores que han trabajado en más films juntos. Por ejemplo, quizá Cristopher y Bela Walken han trabajado en 50 films. La consulta debe regresar a los dos actores y el número de films. NOTA: Cristopher no es necesariamente parte de la respuesta, puede ser cualquier par de actores.

La respuesta a la trivia la puedes encontrar en el siguiente post.

domingo, 10 de octubre de 2010

Practicando SQL (Parte 3)

Te encuentras en la tercer parte de la serie "Practicando SQL":
  1. Configurando ambiente de trabajo y consultas básicas
  2. Consultas con más de una tabla
  3. Consultas con agrupados
  4. Consultas anidadas

Continuemos esta serie. Ahora veremos como generar resultados que tengan agrupados. La siguiente consulta obtiene en cuántos films ha participado cada actor:

mysql> SELECT actor.actor_id, first_name, last_name, COUNT(*)
    -> FROM actor
    ->   INNER JOIN film_actor ON (actor.actor_id=film_actor.actor_id)
    -> GROUP BY actor.actor_id, first_name, last_name;

El resultado tiene 200 filas:

Lo relacionado a la cláusula FROM ... INNER JOIN ... ON lo revisamos en la parte 2, esto nos regresa todos los actores con los ids de sus films. NOTA: en la parte 2, usamos tres tablas actor, film_actor, film porque queríamos desplegar el nombre de la película; en este caso sólo necesitamos saber si participó en una película (pero no el nombre de la misma) por ello sólo usamos actor y film_actor.

La claúsula GROUP BY junta todos las filas que tengan el mismo valor en las columnas especificadas. En este caso junta todas las filas que tengan el mismo id del actor, nombre y apellido. Ahora, en conjunto con GROUP BY estamos usando COUNT(*) que cuenta todas las filas que fueron agrupadas en una sóla fila.

Veamos esto con un poco más de detalle. Como pueden ver en la figura de arriba el actor con id=1 tiene 19 films. Sin usar GROUP BY podemos ver los ids de sus 19 films.

mysql> SELECT actor.actor_id, first_name, last_name, film_id
    -> FROM actor
    ->   INNER JOIN film_actor ON (actor.actor_id=film_actor.actor_id)
    -> WHERE actor.actor_id=1;

Cuando usamos GROUP BY en la consulta de arriba, las 19 filas se consolidan en una sola, pero COUNT(*) nos permite saber cuántas filas fueron agrupadas en una sola.

Junto con la cláusula GROUP BY podemos usar otras operaciones como SUM o AVG (promedio). Para calcular cuánto ha gastado un cliente en renta de películas podemos usar SUM: primero relacionamos un cliente con todos sus pagos; después agrupamos las filas por cliente; y finalmente sumamos todas las cantidades (amount) para cada cliente.

mysql> SELECT customer.customer_id, first_name, last_name, SUM(amount)
    -> FROM customer
    ->  INNER JOIN payment ON (customer.customer_id=payment.customer_id)
    -> GROUP BY customer.customer_id, first_name, last_name;

Preguntas

¿Por qué usamos customer.customer_id en la lista de columnas de SELECT, en lugar de sólo customer_id?

Cuando unimos dos o más tablas en FROM, existe la posibilidad que haya columnas con el mismo nombre entre las tablas. En caso de haber más de una columna con el mismo nombre, debemos especificar la tabla para evitar ambigüedades. Por ejemplo, si en el último ejemplo cambiamos customer.customer_id por sólo customer_id en el SELECT, obtendremos el siguiente error:

ERROR 1052 (23000): Column 'customer_id' in field list is ambiguous

En el resultado de la primera consulta, la última columna tiene como nombre COUNT(*), ¿puedo cambiarle el nombre a num_films?

Para renombrar el nombre de una columna puedes usar la palabra clave AS. En este ejemplo, en la primer consulta puedes cambiar el primer renglón por:

SELECT actor.actor_id, first_name, last_name, COUNT(*) AS num_films

Siguiente post...

Cerraremos esta serie con un ejemplo de consulta anidada.

jueves, 7 de octubre de 2010

Instalando ADempiere para Windows con PostgreSQL


ADempiere es un proyecto desarrollado gracias a la participación colectiva y cuya organización estructural dista de los proyectos tradicionales. El uso del Internet juega un papel primordial en los avances de este sistema ERP.

   Para poder comenzar a utilizar un sistema como ADempiere es necesario conocer algunas definiciones básicas, entre ellas el concepto de ERP. Un ERP (Enterprise Resource Planning, por sus siglas en inglés) es un sistema de cómputo integrado utilizado para administrar los recursos de una empresa (tanto internos como externos) entre los cuales se pueden incluir los recursos financieros, materiales y humanos. Es un software cuya arquitectura permite facilitar el flujo de información entre todas las funciones que lleva a cabo un negocio dentro de los límites de una organización y permite además, administrar las conexiones con accionistas externos. Un ERP está constituido típicamente por una base de datos centralizada, es decir, que la información se concentra en una ubicación geográfica específica dentro de un servidor y normalmente utiliza una plataforma de cómputo común. Los sistemas ERP facilitan las tareas que provienen de las operaciones de negocios dentro de una organización.

   Ahora bien, ¿qué es ADempiere?. ADempiere es un sistema ERP de código abierto (open source) que permite la contribución de sus usuarios a fin de que el proyecto (que se originó en el 2006) siga creciendo y fortaleciéndose. La palabra "adempiere" proviene del italiano y significa entre otras cosas "completar, alcanzar, realizar tareas, practicar, honrar y respetar". Existe mucha información relativa a ADempiere, sin embargo, para esta serie de posts, utilizaré como principal referencia la Wiki de ADempiere.

   La instalación que estaré manejando es la instalación para Windows que utiliza como base de datos a la base PostgreSQL.  PostgreSQL es una base de datos relacional de código abierto muy poderosa y personalizable. Tiene más de 15 años de haberse comenzado a desarrollar y es capaz de correr bajo todos los sistemas operativos de mayor importancia (Windows, Linux, UNIX, MacOs, etc). También puede utilizarse la base de datos de Oracle XE, sin embargo, en este tutorial, me enfocaré en la utilización de PostreSQL.

   Existen básicamente dos maneras de instalar ADempiere en Windows: la instalación automática (utilizando un instalador que provee una interfaz gráfica similar a la que estamos acostumbrados a utilizar en la mayoría del software) y la instalación manual. Cabe aclarar que yo realicé la instalación manual.

   A continuación se muestran los enlaces a las posts que componen este tutorial. Es importante que lo enriquezcan con comentarios y sugerencias a fin de que se mejore su contenido y sea lo más didáctico posible. Conforme vaya terminando los posts, iré activando los links a ellos:

*Cómo familiarizarse con ADempiere antes de su instalación (ADempiere en línea)
1. Instalando ADempiere para Windows con PostgreSQL: instalador de Windows
2. Instalando ADempiere para Windows con PostgreSQL: introducción a la instalación manual
3. Instalando ADempiere para Windows con PostgreSQL: Instalación de PostgreSQL
4. Instalando ADempiere para Windows con PostgreSQL: Instalación y configuración de ADempiere
5. Instalando ADempiere para Windows con PostgreSQL: Instalación de los datos de ADempiere
6. Instalando ADempiere para Windows con PostgreSQL: Ejecutando la aplicación

domingo, 3 de octubre de 2010

Tabs en Firefox

BarTab y Tab Mix Plus son mis plugins favoritos para el manejo de tabs en Firefox. Tab Mix Plus ofrece varias opciones para personalizar el comportamiento de los tabs, las dos características por las que lo uso son: A) Firefox (al menos hasta 3.6) abre un tab en blanco cuando creamos un nuevo tab. Tab Mix Plus permite configurar lo que queremos en un nuevo tab: tab en blanco, la página de inicio del navegador, una página en específico, entre otros. Yo lo configuré para que abra la página de búsqueda de Google, ya que la mayor parte del tiempo requiero esa página en un nuevo tab. Podría usar la barra de búsqueda de Firefox, pero he notado que las recomendaciones de búsqueda son más completas en la página principal de Google. Además, con el lanzamiento de búsqueda instantánea tengo un motivo más para ir a esta página. B) La lista de tabs cerrados recientemente de Tab Mix Plus es muy útil cuando por accidente cerramos uno o cuando nos damos cuenta de que necesitábamos más información de un sitio a los 5 minutos de haber cerrado el tab. Por último, lo que NO uso de Tab Mix Plus es el administrador de sesiones porque tiene conflictos con BarTab, así que uso el administrador default de sesiones de Firefox. Veamos ahora a BarTab. Frecuentemente dejo algunas páginas abiertas para revisarlas después - las podría poner en los bookmarks, pero una vez ahí es muy fácil que no les ponga atención y las olvide. Cuando reinicio Firefox normalmente cargaría todos los tabs que deje abiertos la última vez, lo cual puede ser muy tardado dependiendo del número de tabs y de su contenido. Aquí es donde BarTab entra, este plugin sólo carga los tabs cuando los visitamos; al inicio sólo carga el tab que estaba activo cuando cerramos el navegador. Como pueden ver en la imagen, la última vez dejé 5 tabs abiertos, pero al reiniciar Firefox sólo un tab fue cargado. Los otros 4 tabs aparecen semi-transparentes, y serán cargados hasta que los seleccione. Eso es todo por el momento, compartan en los comentarios qué plugins usan para el manejo de tabs y cómo los ayudan en sus tareas diarias.

domingo, 26 de septiembre de 2010

Practicando SQL (Parte 2)

Te encuentras en la segunda parte de la serie "Practicando SQL":
  1. Configurando ambiente de trabajo y consultas básicas
  2. Consultas con más de una tabla
  3. Consultas con agrupados
  4. Consultas anidadas
En el post anterior configuramos el ambiente en el que estaremos trabajando. Ahora veamos algunas partes del comando SELECT con la siguiente consulta que muestra los films con rating R que duren entre 90 y 120 minutos inclusive.

SELECT title, rating, length
FROM film
WHERE rating="R" AND length>=90 and length<=120 ORDER BY length DESC;

Después de la palabra clave SELECT especificamos las columnas que queremos en nuestro resultado. La palabra clave FROM nos permite especificar la tabla de donde obtendremos los resultados. WHERE es seguido de las condiciones que deben cumplir las filas o registros que formarán parte del resultado. Por último, especificamos el orden de las filas en el resultado final usando ORDER BY; después de especificar la columna por la que queremos ordenar podemos poner la dirección ASC (ascendente, que es la default) o DESC (descendente). Ahora, despleguemos todas las ciudades con el país al que pertenecen. Recuerden que el comando describe nos ayuda a ver los campos o columnas de una tabla. La tabla city tiene un id (city_id), nombre (city) y una llave foránea (country_id) que nos permite conocer el país al que pertenece. La tabla country tiene un id (country_id) y nombre(city). La siguiente imagen muestra un ejemplo del resultado final.


Como pueden observar, necesitamos información de dos tablas (city y country). Si intentamos la siguiente consulta:

SELECT city, country
FROM city, country;

Obtendremos un resultado incorrecto (65400 filas en el resultado), ya que al especificar más de una tabla en FROM lo que se calcula es el producto cartesiano de las dos tablas; es decir, el resultado combina todas las ciudades (600) con todos los países (109) (600*109=65400). Nosotros sólo estamos interesados en las combinaciones ciudad-país que comparten el id del país. Para ello podemos especificar esa condición, como en la siguiente consulta:

SELECT city, country
FROM city, country
WHERE city.country_id = country.country_id;

Cuando especificamos más de una tabla en FROM, le llamamos JOIN. En este caso como estamos relacionando tablas donde una fila de la primer tabla se relacionan con una fila de la segunda tabla, le llamamos INNER JOIN.

Un pequeño detalle de la última consulta, es que si queremos especificar más filtros en WHERE, estaremos mezclando nuestro filtros con la condición que nos ayuda a relacionar las tablas. La siguiente consulta nos retorna todas las ciudades cuyo nombre empieza con T, acompañadas del país al que pertenecen. Noten que en WHERE sólo especificamos que la ciudad empiece con T, y con la clausula INNER JOIN ... ON especificamos como se relacionan las dos tablas:

SELECT city, country
FROM city
INNER JOIN country ON (city.country_id=country.country_id) WHERE city LIKE "T%";

Ahora veamos una consulta que regresa todos los films que duran 2 horas junto con los actores que participaron en cada film. En este caso ya estamos usando tres tablas.

SELECT title, first_name, last_name
FROM film
INNER JOIN film_actor ON (film.film_id=film_actor.film_id)
INNER JOIN actor ON (film_actor.actor_id=actor.actor_id)
WHERE length=120
ORDER BY title;

Siguiente post...
Veremos consultas que involucran agrupados, por ejemplo saber cuántos films ha realizado un actor.

viernes, 24 de septiembre de 2010

Esculturas de origami y las matemáticas

Natural Cycles, página de Erik Demaine

Erik Demaine es un profesor del área de Ciencias de la Computación en el Instituto Tecnológico de Massachusetts (MIT). Pero sobretodo es un genio de los que muy pocas veces escuchamos. Durante su infancia su educación corrió a cargo de su padre (se educó en casa) y logró ingresar a Universidad de Dalhousie en Canadá a los 12 años, completando su carrera y posteriormente culminó su doctorado en el 2003. En el año de 2001 se incorporó como profesor en el MIT a los 20 años de edad, convirtiéndose en el profesor más joven en la historia de este prestigiado Instituto.

Su tesis doctoral la realizó acerca del Origami Computacional. En términos muy simples, se trata del estudio del arte creado a partir de las matemáticas. De acuerdo con Erik Demaine, si se logra doblar un pedazo de papel circular realizando muchas crestas ya sea con la ayuda de un compás o de un rayo láser, la figura tomará una forma que le permite lograr el equilibrio perfecto.


En la imagen se muestra una de las esculturas que forman parte de la colección de Erik Demaine y una de las figuras que él estudia desde el punto de vista matemático. Las curvas, que hemos estado estudiando a lo largo de esta unidad en Matemáticas 3, tienen una parte importante dentro del arte moderno. Aunque las figuras que hemos estudiado son las más básicas, vale la pena echar un vistazo a la belleza que surge de la aplicación de las matemáticas dentro de una actividad artística muy interesante como lo es el origami.

Para descargar los ejercicios de Matemáticas 3 en el Instituto Tecnológico de Toluca para la especialidad de Ingeniería en Sistemas Computacionales, correspondientes a la Unidad 2 del programa, basta con que DES CLIC AQUÍ.

miércoles, 22 de septiembre de 2010

Crocodile Physics

Hola,

En esta sección se encuentra el documento con la información pertinente al programa de simulación de Crocodile Clips que se presentó en la clase de Circuitos Eléctricos y Electrónicos para Ingeniería en Sistemas Computacionales en el Instituto Tecnológico de Toluca.

Más abajo se encuentran los enlaces tanto de la página de los desarrolladores de este programa como de la página para adquirir una licencia.

Página de inicio de Crocodile Clips: http://www.yenka.com/

Página para descargar el paquete de aplicaciones de Yenka: http://www.yenka.com/en/Downloads/

Documento de información presentado en español: Yenka

martes, 21 de septiembre de 2010

Practicando SQL (Parte 1)

Te encuentras en la primer parte de la serie "Practicando SQL":
  1. Configurando ambiente de trabajo y consultas básicas
  2. Consultas con más de una tabla
  3. Consultas con agrupados
  4. Consultas anidadas
Este es el inicio de una serie de posts para practicar SQL. Primero, vamos a configurar todo el ambiente que usaremos, utilizaremos MySQL como nuestro manejador de bases de datos (BD). Pueden descargarlo de la siguiente liga:

http://www.mysql.com/downloads/mysql/

La instalación es bastante sencilla, con la versión MSI Installer Essentials es suficiente para los ejercicios de este tutorial. Al final de la instalación ofrece la opción de configurar el servidor, durante la configuración también puedes dejar todos los valores por default, lo mínimo que tienes que configurar es el password para el servidor.

Podríamos crear nuestras propias tablas e insertar nuestros datos, pero eso nos puede consumir tiempo y es muy aburrido. Es más práctico si usamos una BD existente, como la que pueden encontrar en:

http://downloads.mysql.com/docs/sakila-db.zip

Esta BD tiene alrededor de 15 tablas, por ejemplo: film, actor, categoría, tienda, inventario, cliente. En la siguiente liga, puedes ver el diagrama entidad-relación:

http://forge.mysql.com/w/images/2/23/SakilaSampleDB-0.8.png

Para crear la BD en nuestra instalación:
  1. Inicia la línea de comandos de MySQL, la puedes encontrar en Inicio de Windows> Todos los Programas> MySQL> MySQL Sever 5.1> MySQL Command Line Client. Te pedirá el password que proporcionaste durante la configuración. Y después aparecerá el cursor:
    mysql>
  2. Extrae los archivos de sakila-db.zip, y en la línea de comandos, ejecuta los siguientes dos scripts (nota: en widows usar / para separar directorios), por ejemplo:
    mysql> SOURCE d:/sql/sakila-db/sakila-schema.sql
    mysql> SOURCE d:/sql/sakila-db/sakila-data.sql
  3. Veamos si la instalación correcta, selecciona la BD con:
    mysql> USE sakila
  4. Y veamos que campos contiene la tabla film:
    mysql> describe film;



Nota: las instrucciones terminan con un punto y coma (;). Si por alguna razón olvidas el punto y coma, el cursor continuará en la siguiente línea, ahí puedes poner el punto y coma y volver a dar enter para ejecutar la instrucción.

El comando describe es de gran ayuda para ir conociendo las tablas de esta BD.

Bueno, en este punto ya tenemos configurado nuestro ambiente y ahora podemos a empezar con la parte divertida. Cuando escuchamos BD, una de las primeras tareas que nos vienen a la mente es el realizar consultas a la BD. En SQL, el comando para realizar consultas es SELECT. Veamos una serie de ejemplos.

Mostrar toda la información de la tabla film (despliega 1000 films):
SELECT * FROM film;

Mostrar sólo el título y el rating de todos los films
SELECT title, rating FROM film;

Mostrar sólo los films con rating R
SELECT title, rating FROM film WHERE rating="R";

Siguiente post...
En el siguiente post, veremos algunas consultas más elaboradas. Por el momento dejo una idea de consulta para ir practicando:

Mostrar sólo los films con rating R que duren entre 90 y 120 minutos inclusive.

viernes, 17 de septiembre de 2010

AutoHotkey

Durante algún tiempo estuve buscando una solución que me permitiera automatizar tareas con el teclado. Algunos programas tienen algunas funciones de autocompletar, por ejemplo, Netbeans detecta cuando abrimos un paréntesis y pone el otro paréntesis por nosotros. Sin embargo, yo buscaba una solución que no dependiera de la aplicación que estuviera usando. Esta necesidad nació cuando estuve realizando pruebas manuales de software hace un par de años. Muchas veces tenía que teclear el mismo usuario y contraseña para probar distintas funciones de la aplicación, lo cual era muy tedioso. Esto me llevó a descubrir AutoHotkey, esta aplicación permite automatizar tareas con el teclado mediante la creación de scripts. Un uso curioso, es que puede ayudar a crear atajos para secuencias de teclas de un videojuego o para insertar frases que usamos comúnmente en correos o chats. Actualmente lo uso para automatizar 4 tareas, debajo de cada tarea muestro algunos ejemplos: A) Las tareas de salvar, copiar y pegar son muy frecuentes. Las combinaciones con la tecla Ctrl no son muy cómodas para mí. Por lo que las reemplacé por las teclas F1, F2, F3. *F1::Send {Ctrl down}s{Ctrl up} *F2::Send {Ctrl down}c{Ctrl up} *F3::Send {Ctrl down}v{Ctrl up} B) Como les comentaba en el post anterior, uso cuatro perfiles en Firefox y tengo asociadas combinaciones para iniciar el perfil que necesite. Por ejemplo para abrir el perfil de desarrollo presiono la tecla de windows + v #f::Run "c:\Program Files (x86)\Mozilla Firefox\firefox.exe" -P full #t::Run "c:\Program Files (x86)\Mozilla Firefox\firefox.exe" -P test #s::Run "c:\Program Files (x86)\Mozilla Firefox\firefox.exe" -P sec #v::Run "c:\Program Files (x86)\Mozilla Firefox\firefox.exe" -P dev C) También lo utilizo para abrir folders comunes. #a::Run "D:\scja\01_jdk-6u21-docs\api" D) Y por último para abrir aplicaciones que ocupo cada sesión. Después de unos días se nota que es más rápido presionar la combinación de teclas, que usar el mouse para dar click en un icono. #k::Run "D:\winsw\KeePass\KeePass.exe" #n::Run "D:\winsw\Notepad++Portable\Notepad++Portable.exe" #u::Run "D:\winsw\Aptana Studio 2.0\AptanaStudio.exe" #c::Run "C:\Program Files (x86)\Cool Timer\ct.exe" Al ejecutarse por primera vez AutoHotkey, ofrece crear un script de ejemplo, yo usé ese script para iniciar con mi configuración (el script es creado en el folder "Mis Documentos"). Una vez instalado y en ejecución, el icono de la aplicación aparece en el área de notificaciones, dando clic derecho, permite editar el script "Edit This Script". Al editar el script y salvarlo, debes volver a cargarlo dando clic derecho en el icono y seleccionando "Reload This Script". Por último, te recomiendo poner el script (archivo ahk) en las tareas de inicio para que lo tengas siempre disponible. ¿Qué tipo de tareas o acciones frecuentes consideras que AutoHotkey podría ayudarte a automatizar?

jueves, 16 de septiembre de 2010

Ejercicios de Circuitos Eléctricos y Electrónicos (kickYouTube)

En este post pueden descargar los ejercicios de Circuitos Eléctricos y Electrónicos para el primer parcial en el Instituto Tecnológico de Toluca (carrera: Ing. en Sistemas Computacionales).

¿Qué significa "kickYouTube"? Es una aplicación que permite bajar videos de YouTube sin necesidad de descargar algún tipo de aplicación. Por ejemplo, al buscar videos acerca del funcionamiento del osciloscopio o la fuente generadora de modelos parecidos a aquéllos con que contamos en el laboratorio de Electrónica del Instituto Tecnológico de Toluca, sólo tenemos que dirigir el cursor a la barra de la dirección electrónica que aparece cuando elegimos tocar un video en YouTube y donde aparece la dirección de la página correspondiente a ese video, anteponer la palabra "kick" justo antes de "youtube" y dar "enter", como se muestra en estas figuras,






. A continuación esto nos redirigirá a otra página que corre un script el cual se encarga de desplegar una barra en la parte superior y el video que estamos viendo en la parte media. En dicha barra se puede elegir el formato y la calidad con la que deseamos bajar el video. Al dar click sobre la barra en la opción elegida, se inicia la descarga del video.

Esta es la página en cuestión y un ejemplo:

Porción de la página de kickyoutube con la barra para bajar el video encerrada en azul

Papel para graficar coordenadas polares

Antes de que comenzara todo el frenesí de las celebraciones en esta fecha tan especial para México, me di a la tarea de buscar en algunas papelerías hojas para poder graficar coordenadas polares. Sin embargo, en ninguna papelería me dieron una respuesta positiva así que recurrí entonces a internet para buscar una plantilla que pudiera ser útil. Afortunadamente encontré un sitio que genera no solamente plantillas para coordenadas polares sino también rectangulares y muchas otras. Este sitio se llama "incompetech" y además de proveer plantillas gratuitas en formato *.pdf, permite personalizar la plantilla según nuestras necesidades. A continuación muestro una imagen del menú que aparece al seleccionar la plantilla para las coordenadas polares.
Menú presentado en la página de incompetech para personalizar la plantilla de coordenadas polares
 Para ir directamente a esta página y comenzar a bajar sus plantillas para realizar gráficas en el sistema deseado pueden dirigirse al siguiente link: