Consejos para la Depuración

Comentario Personal:
Cuando uno estudia y aprende a programar en cualquier lenguaje sin ayuda de un material debidamente estructurado y sin ayuda de algún mentor, es normal que en ocasiones se utilice un código extenso o poco limpio debido a la falta de conocimiento de técnicas o metodologías bien estudiadas y desarrolladas.
Pero es importante el buscar y desarrollar sistemas limpios, que optimicen el código y den un resultado mas limpio y profesional.
Al leer este libro de C++ eh descubierto muchos aciertos y errores que mi camino de desarrollador me han dejado, y muchas técnicas y soluciones simples que de haber conocido antes, habrían resuelto muchos de los problemas a los cuales eh enfrentado con anterioridad de manera mucho mas sencilla y cómoda, como lo es el tema de esta ocasión.
Por lo cual invito a cualquier persona que se encuentre en una situación similar, que el programar haya surgido de un gusto nato, y no contase con algún estudio debido del tema, a leer materiales técnicos y de gran valor que den un sentido profesional y bases fuertes para este hobby xP... Digo yo puee xP

Consejos para la depuración.

En ocasiones no contaremos con un buen depurador de nuestro lado que haga al programa trasparente y poder descubrir errores de manera fácil y rápida. O puede que se trabaje con sistemas embebidos (empotrados) donde no hay depuradores y exista una retroalimentación muy limitada, como un led o pantalla lcd de 1 o 2 lineas.

A continuación se explicaran algunas buenas sugerencias para esto.

Banderas para la depuración.

En ocasiones tendremos que agregar código que nos ayudara en el proceso de depuración, y luego este código sera un estorbo (en memoria o en lectura) y sera borrado, después surgirá de nuevo algún error y volverá  teniendo esto en un ciclo vicioso y estorboso en tiempo en agregar y quitar este código.
Una solución a esto es utilizar algunas banderas que permitan separa el código de depuración y activarlo o desactivarlo, y para esto tenemos 2 opciones.


  • Banderas de pre-procesador.
Usando el pre-procesador para definir (#define) una o mas banderas de depuración puede así separa el código de depuración con las sentencias #ifdef y #endif. Condicionando el código de depuración a una bandera de pre-procesador.
Cuando crea que la depuración ah terminado utilice #undef con esa bandera y el código quedara eliminado automáticamente (con esto reducirá el tamaño y sobrecarga del ejecutable).
"Las banderas de pre-procesador tradicionalmente se distinguen de las variables porque se escriben todas en mayúscula".

#define DEBUG
.......
#ifdef DEBUG
//Codigo de depuración....
....
#endif //end of debugging

  • Banderas en Tiempo Real.


En ocasiones es mas conveniente utilizar banderas en tiempo de ejecución que puedan modificarse sin la necesidad de re-compilar el código (esto es esencialmente importante en sistemas muy grandes, que nos permitirán ahorrar todo el proceso de compilación).
Para esto se utilizan banderas booleanas.

bool debug = false;
....
if(debug){
     //codigo ....
}

En ocasiones también puede ser conveniente que la bandera de depuración se active como un argumento de inicio de la aplicación (--debung=on), permitiendo así activar los programas en este modo cuando sean requeridos.


Salutaciones Finales xP
Esta misma técnica del pre-procesador puede ser muy útil (y es utilizada) para la habilitación y negación de bloques de código en la compilación, permitiendo activar módulos de sistemas muy grandes, o dejarlos fuera para ciertas empaquetados o para la prueba en partes del mismo :)

0 comentarios:

Primer Programa en C++

Primer Programa en C++

En este programa simple se emplea un objeto que es muy común en C++, el objeto stream (flujo) para imprimir un mensaje en pantalla.
#include <iostream>

El paquete iostream define una variable (un objeto) llamado cout de forma automática que es capaz de enviar todo tipo de datos a la salida estándar.
El operador << esta sobrecargado en C++ (por lo que no significa el desplazamiento a la izquierda únicamente como en C) y significa algo así como “enviar a”.
cout << “Que tal todos?”;

  • Espacio de Nombres
C++ incluye la posibilidad de agrupar y separar funcionalidades de diferentes fuentes, y con esto evitarnos problemas de usar un mismo nombre en una función o variable.
Para esto se agrego la palabra reservada namespace. Cada conjunto de definiciones de una libreria o programa se <<envuelve>> en un espacio de nombres y si otra definición tiene el mismo nombre, entonces no se produce colisión.

using namespaces std;
Es la directiva que indica al compilador que se utilizara el espacio de nombres indicado, como en este caso el estándar (que utilizan librerías comunes como iostream).

  • Fundamentos de la estructura en C++

Una definición de función consiste en un valor de retorno (que debe estar especificado obligatoriamente en C++), un nombre de función, una lista de argumentos y el código de la función encerrado en llaves.

int funcion(){
//Código de la función
}

En C++ main() siempre devuelve un valor tipo int (entero).
C y C++ son lenguajes de formato libre. Con un par de excepciones, el compilador ignora los espacios en blanco y los saltos de linea, por lo que que hay que determinar el final de una sentencia con ; (punto y coma).

<<Ejemplo HolaMundo.cpp>>
#include <iostream>
using namespace std;

int main(){
cout << “Hola Mundo!!! Hoy es ”
<< 7 << “ de octubre. By Aero”
<< endl;
}

Una vez que tengamos el código en un archivo de texto plano con extensión cpp (por ejemplo Hola.cpp) es momento de compilarlo.
En el caso del compilador GNU C++ (que es distribuido libre y gratuitamente por internet) solo debemos teclear en la consola:
g++ Hola.cpp
Esto nos devolverá cualquier error en la sintaxis del programa, en caso contrario termina el proceso y ejecutamos el resultado. En Linux se ejecuta tecleando ./a.out y en Windows solo debemos escribir a.exe y observar los resultados.

  • Más sobre iostream.

A continuación veremos algunas de las propiedades con las que se cuenta al mostrar informacion en la pantalla.

Manipuladores: No imprimen nada en pantalla, pero cambien el estado del flujo de salida.

<< dec << 8 //muestra en la pantalla el valor en decimal
<< oct << 89 //Devuelve el valor octal del numero
<< hex << 12 //Hexadecimal
<< char(20) //devuelve el carecter correspondiente al numero indicado.

Concatenar vectores de carácter: El precompilador concatena cadenas de la forma:

cout << “Hola esta cadena es “
“demasiada larga para estar en”
“ una sola fila”;

Leer entrada de teclado: En C++ esto se realiza de una manera muy sencilla con el objeto cin, y solo debemos indicar la variable a la que enviaremos el resultado de la entrada por teclado y limitamos el tipo de dato que esperamos del usuario.

int number;
cin >> number;

Introducción a las cadenas

La clase string es un objeto de C++ diseñado para que se encargue y oculte las manipulaciones de bajo nivel que antes tenia que realizar el programador en C.
Gracias a la sobrecarga de operaciones la sintaxis del uso de las cadenas es muy intuitiva:
#include <string>
#include <iostream>

int main(){
string s1, s2;
string s3 = “Hola mundo”;
s2 = “Today”;
s1 = s3 + “ “ + s4;
cout << s1 + s2 << endl;
}


Lectura y Escritura de Ficheros

En C++ la librería que se utiliza para ficheros es fstream, aunque eso implica la inclusión automática de iostream, es prudente incluirla si se piensa utilizar cin o cout.
Para la lectura de un archivo se utiliza el objeto ifstream. Para un de escritura, se utiliza ofstream. Estos se comportan como cin y cout respectivamente.
Código de copia de ficheros en C++.

#include <string>
#include <fstream>
using namespace std;

int main(){
ifstream in('file.txt');
ofstream out('filecopied.txt')
string s;
while(getline(in, s))
out << s << “\n”;
}

Vectores

En C++ se ah implementado una librería de contenedores (lo cual es un tema un tanto mas avanzado) que nos permite el objeto Vector. Este objeto permite tener una lista de cualquier tipo no delimitada que incrementa su tamaño dinámicamente. Esto nos permite ir agregando y recuperando elementos sin tener que saber de antemano con cuantos de ellos trabajaremos.

#include <string>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

int main(){
vector<string> v;
ifstream in('file.cpp');
string s;
while(getline(in, s))
v.push_back(s);
for(int i=0; i<v.size; i++)
cout << i << “: ” << v[i] << endl;
}

Capitulo 3 (Lenguaje C y C++)

Este capitulo contiene un extenso material sobre cuestiones basicas de C y algunas implementaciones sobre C++ por lo que solo comentare 2 cuestiones que me parecen de interes para esta publicacion, si tu aun no conoces bien el lenguaje C es recomendable que leas bien este capitulo entero.

  • Paso por referencia.

Void f(int& r){ //el caracter & indica el paso por referencia sin utilizar punteros
r=5;
}

int main(){
int x=3;
f(x); //paso por referencia
}

  • Definición de Variables al Vuelo.

C++ permite definir variables en cualquier citio dentro de un ambito({}), de modo que se puede declarar una variable justo antes de usarla.

0 comentarios:

Principios de Tratamientos de imagen en MatLab

Funciones básicas sobre MatLab:


  • Lectura de Imagen: A =  imread('archivo.ext');

Para leer una imagen desde un archivo, si el archivo esta en el directorio actual, solo debemos color el nombre con su extención, si no es así, se requiere colorar el Path completo del archivo.
Si la imagen es a color, nos devolverá 3 matrices de tamaño del ancho y alto de la imagen, una por cada color del sistema de colores RGB.
El punto y coma al final de la instrucción indica a MatLab que no requerimos que nos muestre los valores obtenidos en pantalla, esto es importante, porque de lo contrario el programa tarda demasiado tiempo, mostrando estos valores.

El tamaño lo podemos determinar con el comando: [M, N] = size(A) 'en el caso de imágenes en blanco y negro o tomando solo una matriz de color del RGB.

  • Mostrar una imagen desde un arreglo: imshow(A)


Este comando genera y muestra en una ventana la imagen resultante de una matriz dada.
Con este comando poder hacer visibles los cambios que hagamos al trabajar sobre la matriz de datos anteriormente obtenida desde una imagen o de algún dispositivo de captura de imagen.

  • Guardar una imagen como archivo en disco: imwrite(B, 'nombre.ext')
Este comando permite crear un archivo de imagen y almacenarlo en el path que le indiquemos, y el formato de imagen que indiquemos (entre los soportados por MatLab), solo requiere como parámetros las matriz con los datos de la imagen y que indiquemos el nombre y la extensión de la imagen en una cadena de texto.

  • Conversión de tipos de datos: B = tipodedato(A)
Algunas veces para manipular y trabajar sobre las matrices de imagen, requeriremos que estas estén definidas por un tipo de dato especifico, y con esto limitadas entre un rango especifico de números.
Por ejemplo si nosotros utilizamos im2uint8(A) nos devuelve una matriz de datos con valores que van del 0 - 254, y si nosotros usamos mat2gray(A) esto resultara en una matriz con valores de 0.0 - 1.0 (flotante) los cambios de dimensión numérica los realiza MatLab por si solo.

  • Indexado:
Una parte importante a comprender en MatLab es  la forma en la que se realiza el indexado, indexado es la forma en la que se llama un elemento especifico de un arreglo de datos (vector, matiz, etc).
Suponiendo que tenemos un arreglo de la siguiente manera (donde los espacios son la separación entre elementos):
v = [1 2 3 4 5]
Si nosotros queremos obtener el segundo valor del arreglo utilizaremos v(2) y esto nos devolverá el valor 2.
Suponiendo una matriz de 2 dimensiones dadá por (donde los espacios son divisiones en columnas y el carácter ; divide las filas):
A = [1 2 3;4 5 6;7 8 9]
1  2  3
4  5  6
7  8  9
Podemos requerir elementos de este arreglo con 2 parámetros el primero son las filas y el segundo columnas de la manera A(Filas,Columnas):
A(3,2) ----------> 8
A(2,:)------------> 4 5 6 (utilizando el carácter : como comodín que indica todas)
A(:,1)------------>1
                           4
                           7

  • Ejemplo básico de uso:
//leemos una imagen cualquiera
A = imread('test.jpg')
//guardamos cada matriz de intensidad de color por separado (RGB) en archivos individuales.
imwrite(A(:,:,1), 'rTest.jpg')
imwrite(A(:,:,2), 'gTest.jpg')
imwrite(A(:,:,3), 'bTest.jpg')
//con esto obtenemos las intensidades de cada canal, demostradas en imagenes a escala de grises.


Referencia: MATLAB Y SIMULINK Procesamiento digital de imagenes. Erick Cuevas.

0 comentarios: