domingo, 30 de diciembre de 2012

Punteros y arreglos en C que se unen.

Cuando trabajamos en C/C++ usamos punteros debido a que son una herramienta muy buena para facilitarnos la vida, pero un detalle interesante de estos que no siempre funcionan como uno quiere.

Como sabemos los punteros son direcciones de memoria y utilizar estos puede ocasionar que la aplicación colapse por acceso de memoria no autorizado, pero los utilizamos porque reducen el código y nos ayudan muchísimo.

Aquí un ejemplo de punteros que nos dan problemas cuando iniciamos y no sabemos por que. Para sorpresa del profesor se encuentra raro cuando nos revelamos a utilizar C y optamos por un lenguaje de alto nivel.


#include <stdio.h>

int *a, *b, *c;

void f(int x) {
  int i[3];
  i[0] = x;
  i[1] = x + 1;
  i[2] = x + 2;
  a = i;
}

void g(int x) {
  int i[3];
  i[0] = x;
  i[1] = x + 1;
  i[2] = x + 2;
  b = i;
}

void h(int x) {
  int i[3];
  i[0] = x;
  i[1] = x + 1;
  i[2] = x + 2;
  c = i;
}

int main() {
  f(1);
  printf("a = {%d,%d,%d}\n", a[0], a[1], a[2]);
  g(2);
  printf("a = {%d,%d,%d}\n", a[0], a[1], a[2]);
  h(3);
  printf("a = {%d,%d,%d}\n", a[0], a[1], a[2]);
}

Noten que imprimo siempre a[0], a[1] y a[2] siempre, pero después de llamar a una de mis funciones para asignar valores a otro puntero.


domingo, 23 de diciembre de 2012

Una función que retorna FALSE, pero es TRUE

Muchas veces en la programación habituamos a usar los booleanos y por alguna razón aveces empleamos el sistema de ellos en base a lo que necesitamos, dígase "1" para verdadero y "0" para falso y según nos acostumbramos a hacer estas asociaciones ligamos dicha sintaxis a nuestros software principalmente en ciclos que ejecutan una determinada acción u/o ciclos que son servicios o demonios que escuchan en espera de un evento específico.

Algunos ejemplos de estos son en los juegos con el ciclo principal, hilos que escuchan puertos en espera de conexiones u otro caso similar y se ven linea como "while(1)" en vez de "while(true)" y de vez en cuando cuando tenemos una función que retorna un booleano le ponemos al final "return 0" o "return 1" y el lenguaje no los acepta, ya que simbólicamente para el lenguaje estos representan lo mismo, pero ¿es en su totalidad cierto?

Aquí les muestro un código que rompe con cualquier lógica de aquellos que trabajamos con booleanos:

#include <stdio.h>

#define TRUE  1
#define FALSE 0

int function_returning_false() {
  return FALSE;
}

int main() {
    if(function_returning_false) {
printf("La funcion retorna True.\n");
    }else {
        printf("La funcion retorna false.\n");
    }
}

Más adelante seguiré publicando más comportamientos extraños de los código, cualquier pregunta o sugerencia no dudar en preguntar.

viernes, 21 de diciembre de 2012

Time Analysis Tool Android (Proyecto)

Aquí les presento un pequeño proyecto que estoy desarrollando en Android para el departamento de industrial de la Pontificia Universidad Católica Madre y Maestra (PUCMM).

Aunque todavía esta en su fase prototipo y se continua su desarrollo este podrá ser la siguiente herramienta que ayudará a los estudiantes de ingeniería industrial en sus prácticas del análisis y estudio del tiempo.

Aquí os presento el logo, aunque simple, pero simpático:


Según se continué el proyecto su interfaz cambiará, pero así es que se encuentra actualmente. A continuación algunas capturas de la aplicación corriendo en Android.


Mostrar/Ocultar Fotos
Seleccionar lugar para salvar los archivos.
                                                                                                         


Presentación vacía de la pantalla.

Presentación de como se capturan los datos.

Funcionamiento del menú.

Detalle del botón acerca del menú.

lunes, 17 de diciembre de 2012

Algunos Comandos De Git


Siempre que desarrollamos proyectos que requieren más de 1 persona necesitaremos compartir código y siempre que no conocemos las herramientas hacemos un caos con el código y se nos dificulta trabajar en equipo, pero tenemos los SCM (Software Configuration Manager) y que son herramientas que controlan el caos en los proyectos de equipos.

Existen diferentes software para controlar el código que se desarrolla con varias personas como son: Git, SubVersion (con este existen variantes, pero solo conozco la versión apache), Microsoft Team Foundation Server 2010, y otros más. Estos software se conocen como controladores de versiones y es más o menos una descripción de lo que hacen.

Controladores de versiones?, como es eso?, es el proceso tal y cual lo indica el nombre, pero es más complejo de lo que parece en los mecanismos sin embargo su uso es bien simple y nos permite trabajar con mucha flexibilidad, con esta herramienta podemos subir código a un proyecto y hacer que todo el grupo de trabajo tenga los cambios realizados reflejados inmediatamente.

En caso de que la aplicación tenga un rumbo erróneo y exista código que no debe estar es posible retroceder en el árbol de cambios y regresar al código a un punto exacto donde empezaron los cambios que no iban.

También estos SCM pueden controlar cuales archivos son subidos para evitar que se suban archivos compilados al repositorio si lo único que se quiere son los archivos de source existen los [.ignore].

Después de explicar un poco el proceso entonces podemos proceder a explicar algunos comandos de un SCM, el cual será el que le doy uso (GIT).

Comandos básicos de git

  1. Comando git init: Este inicia el proyecto de git y habilita para enviar cambios.
  2. Comando git add: Adiciona elementos al árbol del repositorio. Cuando se quieren adicionar todos los cambios sin tener que hacerlo uno a uno si alteramos muchos archivos y no sabemos cuales cambiaron usamos el comando (git add -A) y este le agrega todos los cambios y respeta el [.gitignore] que puedes crear.
  3. Comando git rm: Remueve elementos del árbol del repositorio.
  4. Comando git commit -m "comentario": Crea un punto de envío de datos y le asigna un nombre.
  5. Comando git push: Este subo los cambios al repositorio oficial.
Existen más comandos para crear brach, pero como es un manual básico no los expongo o explico, pero más adelante se hará la parte 2 explicando lo demás.

Para aquellos que le gusta indagar más aquí hay un libro sobre git donde se explica en mucho detalle la forma de administración de git.

http://git-scm.com/book/es

jueves, 13 de diciembre de 2012

Como buscaban en los 60?

Curioseando se encuentran cosas interesantes y más ahora que es muy fácil buscar y encontrar información acerca de algo que estas interesado, pero antes de que estos sistemas estuvieran tan avanzados ¿como se buscaba información en los años 60?, la respuesta es simple y es como están pensando, haciendo uso de un computador y tarjetas perforadas con un gran tiempo de procesamiento, pero por suerte tenemos la posibilidad de experimentar esa experiencia usando la tecnología de hoy día.

Para aquellos que quieren probar dicha experiencia podrán ver el método de búsqueda  pero con la información actualizada de hoy día en el siguiente enlace.

http://www.masswerk.at/google60/

miércoles, 5 de diciembre de 2012

Que es lo que necesita un ingeniero para ser un ingeniero como tal?

Según obtengo experiencia y avanzo más en lo que es la carrera y el ámbito profesional me doy cuenta de que los ingenieros necesitamos de un elemento crucial para poder hacer uso de ese título que se nos entrega y es algo que perdemos con el paso del tiempo, debido a que la misma sociedad se encarga de destruir toda forma de curiosidad que tiene el ser humano, tal y como dijo Albert Einstein "cada flor de curiosidad es aplastada por la sociedad en sí misma".

La naturaleza del hombre es ser un ente sociable y este nace con características muy particulares, pero desde el momento en que nacemos buscamos e indagamos para saber como funcionan las cosas y según crecemos esta cualidad se pierde igual e inclusive llega a casi desaparecer en el individuo, pero que es lo que hace que la curiosidad desaparezca de aquel que nace con ella?, la respuesta radica en lo que afirmó Albert Einstein y es la sociedad, ya que los cursos que hacemos según nos desarrollamos, dígase escuela primaria y secundaria solo se nos enseñar a memorizar y cada vez que un estudiante presenta cualidades de innovación y curiosidad este es instigado por el sistema obligando a este a solo memorizar y no a razonar y entender el por que de la cosas.

Un ejemplo claro es la deficiencia de matemática y física que existe en la República Dominicana, debido a que solo nos muestran a como sustituir variables en ecuaciones y a realizar la operación que obtiene el resultado. Es por esto que si se nos quita una variable y se nos obliga a buscar la manera de encontrarla usando otras formulas y despejes simplemente no podemos ver la solución y realizar el problema, ya que no entendemos, sino que memorizamos y repetimos.

Aquí les comparto un video muy relacionado al tema y que es de uno de los más grandes físicos del siglo Michio Kaku.
http://www.youtube.com/watch?v=fjkVoW4Y3x0


jueves, 29 de noviembre de 2012

Que tan perfectos son los cálculos matemáticos en la Computación?

Nota: El código se puede compilar y ver su salida en linea usando uno de los links en http://aluismarte.blogspot.com/p/herramientas-en-linea.html

Cuando empezamos a programar utilizamos los tipos de datos numéricos  con los cuales se nos enseñan las lógicas básicas para crear algoritmos y tener una mente ordenada, pero aveces aparecen casos muy particulares cuando trabajamos con los números; dígase cuando aplicamos un algoritmo de redondeo a números flotantes o cuando necesitamos más precisión en los cálculos de lo normal, pero a que me refiero explícitamente , es simple, cuando usamos datos numéricos flotantes estos carecen en sí mismos de precisión, aunque suene algo ilógico estos los usamos para tener más precisión, pero que hace que un numero flotante carezca de precisión?

Para responder a esa pregunta solo tenemos que entender que la computación es un gran puñado de bits (no bytes) en orden secuencial y lógico ordenado que permite tener diferentes opciones, pero recordando que estos bits solo pueden tener 2 estados consistentes y 1 no consistente, dígase 0 o 1 y en el estado no consistente sería que este carezca de existencia.

Como ya sabemos los bits tienen solo 2 valores, por lo que si no es 1 es cero, y los datos se guardan con una agrupación de estos, pero en los números tenemos singularidades en los flotantes, ya que estos tienen datos de 1 entero y datos para precisión (serían los números después del punto), por lo que entenderíamos que estos no tendrían un margen de error, pero si lo tienen!, si trabajamos con números que no son potencias de 2 estos generan un residuo importante lo cual puede hacer fallar un programa con una lógica impecable, pero me dejo de explicaciones y les muestro un ejemplo:

Este ejemplo es aplicable a todos los lenguajes que trabajo (C, C++, Java, C#, Python), aunque seguiré buscando aprender más lenguajes para probar estos casos.

#include <iostream>
using namespace std;

int main() {
    for(double i = 0.0 ; i < 2.0 ; i+=0.1) {
        if(i == 1.0) {
            cout << "Se supone que termino aqui." << endl;
            break;
        }
        cout << i << endl;
    }
    return 0;
}


Cuando corran este programa observaran algo curioso, pero si cambian el factor de suma de la variable i verán un efecto diferente, aunque este efecto es un caso raro, pero nos ayuda a hacer conciencia para que cada vez que trabajemos con flotantes usemos rango y no igualdades.

#include <iostream>
using namespace std;

int main() {
    for(double i = 0.0 ; i < 2.0 ; i+=0.125) {
        if(i == 1.0) {
            cout << "Se supone que termino aqui." << endl;
            break;
        }
        cout << i << endl;
    }
    return 0;
}

Aquí vemos el comportamiento de los flotantes, pero existen casos en los cuales se hallan perdido recursos debido a este error que no se contempla?, pues aquí hay unos ligeros ejemplos.

MIM-104 Patriot (1991): Es un misil antiaéreo que se utilizan también para la intercepción de misiles balísticos a modo de defensa. Durante la Guerra del Golfo en 1991 un Scud iraquí mató a 28 soldados al alcanzar un cuartel norteamericano ya que estos misiles fallaron. Se dictaminó que fue un error de software en el reloj del sistema que se había retrasado un tercio de segundo por haber estado activado 100 horas.

Ariane-5 (1996): Esta fue una misión ESA en el que el vuelo 501 la lanzadera se desvió y se partió durando únicamente 40 segundos en vuelo. El problema fue que el sistema de referencia inercial tratado con datos de punto flotante de 64 bits lo convertía a 16 bits con valores enteros. En una de esas operaciones el valor era demasiado grande provocando un desbordamiento aritmético en el hardware.

Chips Pentium (1994): Un error en el juego de instrucciones en los chip Pentium repercutió en la empresa $475 millones de dólares de costes en recogida y reenvío de procesadores. El error se reproducía al realizar una división con coma flotante en el que a partir del cuarto dígito decimal no daba valores correctos. Este fallo empezó a llamarse “bug de FDIV“.

Este ultimo caso fue un error de el chip, pero el problema fue que no controlaba correctamente un margen de precisión aceptable, lo cual provocó un error crítico y perdidas de dinero enormes.

Como conclusión, podemos afirmar que los números flotantes tienen error, pero que estos son controlados hasta un cierto punto para evitar problemas, y que si no se tiene conciencia de ello podemos crear un error lógico.

Descarga de código

Un solo link, con todos los códigos de los 5 lenguajes que trabajo.
http://adf.ly/FQO9f

martes, 27 de noviembre de 2012

Un arreglo curioso de tamaño cero.

Arreglo [0]

Nota: El código se puede compilar y ver su salida en linea usando uno de los links en http://aluismarte.blogspot.com/p/herramientas-en-linea.html

Como programadores siempre haremos uso de los arreglos para manejar datos, pero que pasa cuando rompemos la lógica y buscamos crear algo con dimensiones cero?.

Pues verá que los compiladores de C, C++, Python y Java permiten la creación de arreglos declarados en 0, así como su manipulación pero en C# esto solo permite su creación, pero no da la posibilidad de entrar 1 datos sin que de error de indice. La manipulación de este arreglo es curiosa y varía según el lenguaje al igual que su comportamiento.

Por ejemplo en C++ la salida de este arreglo singular da números que no son siquiera cercanos a los insertados en el mismo. Estos números sin sentido que nos ofrece la salida del programa podríamos buscarle algo de lógica si nos hacemos la idea de que eso sería acceso a ram del programa. Aunque esto no lo he podido probar, pero es una posibilidad existente que intentaré probar más adelante.


#include <iostream>
using namespace std;

int main() {
int arr[0];
int i,j, p;
cout << "Inserte el numero de datos a introducir en el arreglo" << endl;
cin >> p;
//Introducimos algunos datos en nuestro arreglo.
for(i = 0 ; i < p ; i++) {
arr[i] = i + 10;
}
cout << "Imprimimos a ver que sale" << endl;
//Imprimimos nuestros valores guardados.
for(j = 0 ; j < p ; j++) {
cout << arr[j] << endl;
}
return 0;
}


Después de correr este curioso programa, podría interesarle ver como se comportan estos en otros lenguajes y con el fin de facilitar la prueba podrán descargar los códigos para sus respectivos lenguajes a probar.

Links de descarga del código.

Lenguaje C
http://adf.ly/FL2Bh

Lenguaje C++
http://adf.ly/FL2Hp

Lenguaje C#
http://adf.ly/FL2J5

Lenguaje Python
http://adf.ly/FL2Mg

Lenguaje Java
http://adf.ly/FL2Ka

sábado, 16 de junio de 2012

Como crear un menú con gráficos acelerados en 2 dimensiones


Unos de los problemas que se presentan al programar juegos en 2 dimensiones es que el menú no tiende a ser muy sutil a los cambios y el tiempo que se dedica a este es muy alto siendo solo una presentación con poca complejidad de funcionamiento de las opciones del juego.

Entender un menú es parte fundamental para poder simplificarlo y hacerlo fácil de modificar y es por eso que dividiremos el menú en las siguiente partes: botones, eventos, animación y estética.

Comencemos con la elaboración del menú!

Nota: Este ejemplo y concepto se basa en la utilización de SDL, pero el concepto es manejable en otros métodos de gráficos 2D y lenguajes tanto Top-Down como POO.

1: hacemos un bosquejo de como se verá el menú:

Es un bosquejo, por lo que no lleva detalles de estética y tampoco planeamiento de efectos visuales, por lo que es solo una plantilla base para tenerlo definido, donde luego los detalles se agregan a los códigos correspondientes.

2: identificamos las partes que componen nuestro menú:

  • Titulo
  • Botón
  • Marcador

3: Determinamos si nuestros componentes tienen más componentes dentro:

En el Botón: texto, evento o función y un marcador según la posición del ratón o uso de las teclas.
En el Marcador: Posición de apunte y textura.

4: Determinamos si manejaremos diferentes tamaños de resolución de pantalla y ajustamos la ubicación mediante un algoritmo de posicionamiento intrínseco en el comportamiento del menú.

5: Empezamos la codificación!

Para codificar tendremos lo siguiente:

Si es en un lenguaje POO (C#, C++,python,etc) podremos usar objetos, por lo que es más sencillo crear los componentes, en caso de que sea un lenguaje Top-Down (C, PASCAL,etc), entonces el mecanismo es diferente

En base a un POO como python, se hace de la siguiente manera:

Codificación de Botón

class Boton:

    Texto = ""
    FuncionLlama = None
    #Separacion del boton con los demas objetos.
    Posx = 0
    Posy = 0

    PosxResolucion = 0
    PosyResolucion = 0


    def __init__(self,texto,funcion,posx,posy):
        self.Posx = posx
        self.Posy = posy
        self.FuncionLlama = funcion
        self.Texto = texto

    def EjecucionEvento(self):
        #Aqui usando el nombre que envio puede llamar la funcion deseada.
        #El nombre de la funcion se pasa sin comillas.
        #Ejemplo (boton = new Boton('hi',Render,15,15))
        #Render sin comillas es el nombre de la función a ejecutar
        self.FuncionLlama()
        #Al agregar () a la variable la ejecutamos

    def NuevaUbicacion(self,x,y):
        self.Posx = x
        self.Posy = y

    def AjusteUbicacionResolucion(self):
        #Ajusto la ubicacion del menu con el tamaño de resolucion.
        #Las coordenadas de Posx y Posy solo son la separación entre Botones.
        print "Aqui se busca ajustar las coordenadas"

    def Render(self):
        #Aqui va el algoritmo de renderizado
        print "Mi algoritmo renderiza"

Se añaden las características deseadas y se ajusta el algoritmo.

Codificación de Marcador


class Marcador:

    Textura = None
    Posx = 0
    Posy = 0
    PosxResolucion = 0
    PosyResolucion = 0
 
    def __init__(self,x,y):
        self.Posx = x
        self.Posy = y

    def NuevaUbicacion(self,x,y):
        self.Posx = x
        self.Posy = y

    def AjusteUbicacionResolucion(self):
        #Ajusto la ubicacion del menu con el tamaño de resolucion.
        #Las coordenadas de Posx y Posy solo son la separación entre Botones.
        print "Aqui se busca ajustar las coordenadas"

    def CambioPosPuntero():
        #El puntero se mueve a la opcion de click
        print "Aqui se ubica el puntero."

    def Render(self):
        #Aqui va el algoritmo de renderizado
        print "Mi algoritmo renderiza"


Se añaden las características deseadas y se ajusta el algoritmo.

Codificación de Titulo?

La clase titulo no es necesaria, por lo que se puede trabajar con una imagen o tipos de letras y lo manejamos directamente sin necesidad de crear un objeto, a menos de que exista dicha necesidad.

Podemos construir el menú!

Con esto tenemos todos los elementos de nuestro menú y lo que nos falta es adicionarlo en una clase que llamaremos menú o simplemente usaremos esto es un esquema Top-Down. Esto es decisión del programador.

En base quedan algunos algoritmos no mostrados como: detección de resolución, ubicación de elementos en base a la resolución, etc, pero como es un esquema de trabajo para simplificar el menú eso concierne a el programador.

Para lenguajes Top-Down, el esquema no varía, sino que en vez de clases trabajamos con funciones y la forma de instanciar el menú es algo más tediosa y necesita más lineas, pero al fin y al cabo es un menú rápido, sencillo y fácil de modificar.