jueves, 17 de noviembre de 2011

Ley Lleras

Preocupante...


viernes, 4 de noviembre de 2011

Pilas C++ !!

Pilas en C++:
Hace poco me llego una "barbacha" (Barbacha: dicese del trabajo freelance, pequeño, temporal en donde el precio es mas regateado que una película en San Bazar..), esta consistía en realizar un programa en C++ que determinara si una palabra es palindrome (palabra que se lee igual al derecho y al revés).
Para desarrollarlo use code::blocks (http://www.codeblocks.org/), un ide para C++ que me ha parecido excelente, ademas de ser multiplataforma.

Una pila es un tipo especial de lista enlazada de la cual solo se puede insertar y eliminar elementos en uno de los extremos de la lista. Imaginemos una lista enlazada como un tren, en donde cada vagón lleva su carga y tiene un enlace al siguiente vagón. Por lo tanto un nodo de la lista tendria un campo de valor y en C++ un puntero hacia el siguiente nodo(vagón).



class nodo{
// metodos publicos: son los que se acceden desde otros objetos
    public:
// inicializamos el constructor del objeto
        nodo(char v, nodo *sig = NULL){
            valor = v;
            siguiente = sig;
        }
    private:
        char valor; // el dato que guardamos en el nodo
        nodo *siguiente; // puntero hacia el siguiente nodo


    friend class pila; // definimos que la clase pila tiene acceso a los metodos
};


typedef nodo *pnodo; // definimos un tipo de dato


Estos nodos irían encapsulados en una clase llamada pila, que es la encargada de aplicar la lógica de sacar y meter datos. Esta clase deberá llevar un contador para saber cuando la pila esta vacia, con el fin de evitar punteros a campos nulos,


/*
Definimos la clase pila que manejara los metodos de sacar y meter
nodos dentro de la pila
*/
class pila{
    public:
        pila() : ultimo(NULL){ contador=0;}
        ~pila();


        void Push(char v); // con Push se ingresa un nuevo nodo con valor
        char Pop(); // con Pop se extrae el ultimo nodo ingresado
        int contador; // contador nos permite determinar si la pila esta vacia o
 // todavia tiene algun dato


    private:
        pnodo ultimo; // nodo que nos indica cual es el ultimo de la pila
};

Para insertar un valor usamos la función Agregar(char), esta funciona de la siguiente manera:

  1. Incrementamos el contador al crear un nodo
  2. Recibimos el valor por parámetro
  3. Guardamos el nuevo nodo como el ultimo de la pila.
void pila::Agregar(char v){
    this->contador++;
    pnodo nuevo;
    // crea nodo nuevo
    nuevo = new nodo(v, ultimo);
    // apuntar el comienzo de la pila alnuevo nodo
    ultimo = nuevo;
    if(!primero) primero = nuevo;
}


Para sacar un valor usamos la función Leer, esta funciona así:


  1. Decrementamos el contador de items
  2. Creamos un nodo auxiliar y una variable para retornar el valor del nodo que vamos a sacar
  3. Guardamos el ultimo nodo en el nodo auxiliar
  4. En el ultimo nodo, guardamos el siguiente del auxiliar
  5. Guardamos en la variable el valor del nodo actual
  6. Borramos el nodo con la función delete
  7. Retornamos el valor del nuevo nodo




char pila::Leer(){
    this->contador--;
    pnodo nodo; // variable auxiliar para manupular el nodo
    char v; // variable auxiliar para retorno
    if(!ultimo) return ' '; // si no hay nodos retorna vacio
    //el nodo apunta al primer elemento de la pila
    nodo = ultimo;
    // asignamos a pila toda la pila menos el primero
    ultimo = nodo->siguiente;
    //guardar el valor a retornar
    v = nodo->valor;
    delete nodo;


// si la cola quedo vacia, el ultimo debe ser NULL tambien
    if (!primero) ultimo = NULL;


    return v;
}


El destructor en C++ es una función que se encarga de limpiar la memoria del sistema cuando el objeto ya no se va a utilizar. Lo único que hace es recorrer toda la lista e ir borrando item por item.


/*
El destructor sirve para finalizar el objeto pila
recorre cada item de la pila y lo elimina con delete
*/
pila::~pila(){
    pnodo aux;


    while(ultimo){
        aux = ultimo;
        ultimo = ultimo->siguiente;
        delete aux;
    }
}

Ahora la lógica para determinar si una palabra es palindrome es sencilla, solamente tienes que comparar la primera letra con la ultima y así sucesivamente hasta comprobar toda la palabra letra por letra. Si alguna letra es diferente a su equivalente ya no es una palindrome.


int main(){


    cola Cola;
char palabra[256];
int i =0;
int longitud = 0;
bool palindrome = true;


cout << "Digite la palabra" << endl;
cin >> palabra;


/*
La idea es ingresar la palabra a la pila, despues recorrer el vector
que contiene la palabra de forma inversa comparandola con la pila
de forma normal; asi comparamos el ultimo termino de la palabra en
el vector contra el primer termino de la pila.
Si llega a existir alguna letra diferente, ya no es palindrome
*/


for (i=0; palabra[i] != '.'; i++){
Cola.Agregar(palabra[i]);
longitud++;
}


for (i=longitud-1; i>0; i--){
char caracter;
char caracter_pila;
caracter = palabra[i];
caracter_pila = Cola.Leer();
if (caracter != caracter_pila || caracter == ' '){
palindrome = false;
break;
}
}
if (palindrome){
        cout << " Es palindrome" << endl;
}else{
        cout << " No es palindrome" << endl;
}


    return 0;
}


No es el mejor algoritmo, pero es para aprender Pilas, ademas mi lenguaje es Java, y este ya trae estas funciones y estructuras de serie. C++ también con templates, pero es un lenguaje que hasta ahora estoy tomando en serio.
Se reciben comentarios de optimizacion y correcciones.

Fuente:
http://c.conclase.net/edd/index.php?cap=002#inicio

miércoles, 26 de octubre de 2011

Comprimir en linux [Terminal]

Estoy usando Ubuntu 11.10, vengo usándolo desde la 10.04, y lo cambie porque cuando compre mi portátil Vostro 1500 venia solamente con 1Gb de Ram y la tortura de Windows Vista, con ese sistema operativo y esa memoria solamente podía ejecutar notepad, y eso que parte se va para la virtual... pero en otra entrada daré mi análisis sobre esta versión de Ubuntu, por ahora voy a colocar como comprimir desde linux. Creo que esto aplica a casi todas las distribuciones. 


Es interesante ver cual es el mejor comprimiendo una carpeta de 450 megas entre archivos comprimidos, paginas jsp, js, imagenes, y clases:


Para comprimir un directorio en (*.tar.gz):
Comprimir: tar -cvf archivo.tar.gz /directorio/
Descomprimir: tar -xvf archivo.tar.gz


-c : indica a tar que cree un archivo.
-v : indica a tar que muestre lo que va empaquetando.
-f : indica a tar que el siguiente argumento es el nombre del archivo comprimido
-x : indica a tar que descomprima


Tamaño comprimido: 254.243.613 bytes




Comprimir y empaquetar archivo o directorio en (*.tar.bz2)
Comprimir: tar -c directorio | bzip2 > archivo.tar.bz2
Descomprimir: bzip2 -dc archivo.tar.bz2 | tar -xv

Tamaño comprimido: 242.879.874


Comprimir y empaquetar archivo o directorio  en (*.zip)
Comprimir: zip archivo.zip directorio
Descomprimir: unzip archivo.zip

Tamaño comprimido: 259.243.905


Comprimir y empaquetar archivo o directorio  en (*.lha)
Comprimir: lha -a archivo.lha directorio
Descomprimir: lha -x archivo.lha

Tamaño comprimido: 256.172.988


Comprimir y empaquetar archivo o directorio  en (*.arj)
Comprimir: arj a -r archivo.arj directorio
Descomprimir: arj -x archivo.arj

Tamaño comprimido: 257.450.957


Comprimir y empaquetar archivo en (*.rar)
Comprimir: rar -r archivo.rar directorio
Descomprimir: rar -x archivo.rar

Tamaño comprimido: 253.781.737






jueves, 20 de octubre de 2011

Cargue de un archivo a FTP con Java

Continuando con el tema de FTP y Java tratado en el articulo anterior, ahora vamos a cargar un archivo al FTP con la misma librería commons.net


try {
String ls_directorio = "archivos";
ftp.connect(IP_FTP);
if (!ps_usuario.equals("") && !ps_password.equals("")){
ftp.login(USUARIO_FTPPASSWORD_FTP);
respuesta = ftp.getReplyCode();
if (respuesta == 230){
ftp.setFileType(FTP.BINARY_FILE_TYPE);
ftp.changeWorkingDirectory(ls_directorio);
respuesta = ftp.getReplyCode();
if (FTPReply.isPositiveCompletion(respuesta) ){
File archivo = new File("Ruta del archivo a cargar");
boolean ret_cargue = ftp.storeFile(archivo.getName(), new FileInputStream(archivo));
b_retorno = ret_cargue;
}
}
}
} catch (Exception ex) {

} finally {
try {
ftp.disconnect();
} catch (IOException ex) {
}
}

He agregado varias comprobaciones, como que la contraseña no sea vacia y dos especiales :


respuesta = ftp.getReplyCode();
if (respuesta == 230){


esta significa que pudo hacer login en el servidor y:



ftp.changeWorkingDirectory(ls_directorio);
respuesta = ftp.getReplyCode();
if (FTPReply.isPositiveCompletion(respuesta) ){



Significa que pudo cambiar de directorio dentro del servidor. La comprobación de cambio de directorio no necesita de un codigo porque ya esta parametrizado dentro de la clase FTPReply en isPositiveCompletion



martes, 18 de octubre de 2011

Descarga FTP desde Java

Hoy vamos a ver como descargar un archivo de un servidor FTP desde Java. El proceso requiere de la libreria apache commons .net (no crean que es el .net de microsoft...)  se descarga de la direccion: http://commons.apache.org/net/download_net.cgi . Lo que se descarga es una librería que tiene varios paquetes, entre ellos vamos a usar org.apache.commons.net.ftp.FTPorg.apache.commons.net.ftp.FTPClientorg.apache.commons.net.ftp.FTPFile. La descarga del archivo se hace de la siguiente manera:





public File getArchivoFTP(String nombreArchivo) {
File f_retorno = null;
FTPClient ftp = new FTPClient();
int respuesta;
String ps_ip = this.IP_FTP;
String ps_archivo = nombreArchivo;
String ps_usuario = this.USUARIO_FTP;
String ps_password = this.PASSWORD_FTP;
try {
// establecer conexion
String ruta_pdf_local = this.RUTA_DESTINO;

ftp.connect(ps_ip);
if (!ps_usuario.equals("") && !ps_password.equals("")) {
ftp.login(ps_usuario, ps_password);
respuesta = ftp.getReplyCode();
if (respuesta == 230) {
ftp.setFileType(FTP.BINARY_FILE_TYPE);
ftp.changeWorkingDirectory(this.RUTA_FUENTE);
respuesta = ftp.getReplyCode();
if (FTPReply.isPositiveCompletion(respuesta)) {
FTPFile archivosFTP[] = ftp.listFiles();
respuesta = ftp.getReplyCode();
if (FTPReply.isPositiveCompletion(respuesta)) {
if (archivosFTP.length > 0) {
        for(int i=0; i< archivosFTP.length; i++){
String nombre = archivosFTP[i].getName();
if (nombre.equals(ps_archivo)) {
String archivo_salida = ruta_pdf_local
+ File.separator
+ archivosFTP[i].getName();
boolean retorno_download = ftp
.retrieveFile(archivosFTP[i]
.getName(),
new FileOutputStream(
archivo_salida));
if (retorno_download) {
f_retorno = new File(archivo_salida);
if (!(f_retorno.length() > 0)) {
System.out
.println("Advertencia: Archivo con longitud 0");
f_retorno = null;
}
} else {
System.out
.println("No se pudo descargar en: "
+ archivo_salida);
}
         }
if (f_retorno != null) {
break;
}
}
if (f_retorno == null) {
System.out
.println("No se pudo descargar el archivo: "
+ ps_archivo);
}
} else {
System.out
.println("Listado de archivos de longitud invalida -"
+ archivosFTP.length);
}
} else {
System.out
.println("No se pudo listar el directorio -");
}
} else {
System.out
.println("No se pudo cambiar de directorio -");
}
} else {
System.out.println("No se pudo autenticar -");
}
} else {
System.out.println("Login y password invalidos -");
}
} catch (SocketException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
ftp.disconnect();
} catch (IOException ex) {
ex.printStackTrace();
}
}

return f_retorno;



Después de ubicarte en el directorio que deseas en el FTP, también puedes listar el contenido de un directorio FTP, de esta forma:


FTPFile[] archivosFTP = ftp.listFiles();
if (archivosFTP.length > 0){
for(FTPFile arch : archivosFTP){
String ls_nombre_archivo = arch.getName();
System.out.println(ls_nombre_archivo);
}
}





viernes, 14 de octubre de 2011

SOA... Una arquitectura orientada al servicio


He empezado a hacer una recopilación de la arquitectura SOA, para al final hacer una implementación en la empresa que trabajo; prometo compartir la experiencia a medida que la misma vaya evolucionando. Por ahora llevo esto:
Definición:
SOA es un concepto de arquitectura de software que define la utilización de servicios para dar soporte a los requisitos del negocio.
La Arquitectura Orientada a Servicios es un soporte arquitectónico de tecnologías de información que ayudan en la transformación de la empresa en un conjunto de servicios vinculados que pueden ser accedidos a través de una red. La combinación de una implementación SOA y los objetivos empresariales estratégicos aseguran los siguientes beneficios:

  • Alineación de la TI (Tecnología de la Información) a los negocios
  • Re utilización máxima de los activos de TI
Beneficios de la implementación de una arquitectura SOA:
Se clasifican en cinco puntos de entrada de los beneficios.

  • Personas: SOA enfoca al usuario a ver la empresa como un conjunto de servicios que le ayudan a interactuar con otras personas y procesos; esto genera un aumento en la productividad.
  • Procesos: al utilizar SOA la empresa puede transformar los procesos empresariales en servicios reutilizables y flexibles, que le permita mejorarlos y optimizarlos.
  • Información: una arquitectura orientada a servicios, provee un entorno de datos consistente y confiable para todas las áreas de la empresa, habilitándola para poder competir con mas eficiencia.
  • Conectividad: con SOA puede conectar los servicios y procesos de la empresa de forma eficiente, incluso se puede llegar a ofrecerlos como un nuevo servicio a futuros clientes o nuevos nichos de mercado.
  • Reutilización: la reutilización de servicios permite agilizar los desarrollos de nuevas características en los proyectos actuales y disminuye el tiempo de desarrollo en nuevos productos; al estar la estrategia de la empresa alineada con las TI, dar un paso adelante es mas sencillo.
Estandares SOA:
Para que un servicio pueda adaptarse a la arquitectura SOA y un conjunto de servicios pueda definirse globalmente como una arquitectura SOA implementada, debe cumplir con los siguientes requerimientos:

  • Debe corresponder a una funcionalidad de negocio bien establecida y acotada, asi sea necesario involucrar diferentes sistemas.
  • Debe ser re utilizable: un servicio que no se pueda reutilizar en cualquier medida, no debe ser un servicio sino una caracteristica propia interna del sistema.
  • Deben proveer un contrato formal sobre el cual se define la forma de acceso, funcionalidades, datos de entrada y salida.
  • Bajo acoplamiento: esto se logra accediendo al webservice a traves del contrato.
  • Permitir la composición: los servicios deben poder ser utilizado por otros servicios de mas alto nivel
  • Autónomos: los servicios deben tener su propia plataforma de ejecución, asegurando así la ejecucion de la funcionalidad y reutilizacion por parte de otros servicios.
  • No deben tener estado: un servicio solo debe tener la lógica de la funcionalidad
  • Debe poder ser descubierto: un servicio que esta escondido o nadie conoce, no es servicio, debe poder ser publicado en un directorio UDDI o algun otro medio de publicacion de servicios empresariales.
Relacion entre los estandares SOA [ http://arquitecturaorientadaaservicios.blogspot.com/ ]
Implementación de SOA sobre arquitecturas J2EE
J2EE incluye diferentes especificaciones orientadas a soportar la aplicación de arquitecturas SOA, entre ellas tenemos:
JAX-WS(Java Api for XML Web Services): esta implementación en sus utlimas especificaciones permite manejar protocolos como SOAP (simple object access protocol) y XML, permitiendo el desarrollo de webservices, los cuales serán publicados por un servidor de aplicaciones.
JBI(Java Business Integration): esta es una especificación con iniciativa de la industria para crear una versión estandarizada e integral para aplicaciones de negocios. JBI direcciona las necesidades de integración orientadas a servicios (SOA) creando un meta contenedor de servicios integrados. Esta es una arquitectura basada en plugins orientados por mensajes; puede recibir plugins de terceros y pueden operar normalmente. En JBI no se define el como se conectan los componentes, pero si define los frameworks, interfaces de contenedores, comportamientos y servicios comunes.
La principal meta de JBI es proveer una arquitectura y un framework base para la creación dinámica y distribución de aplicaciones débilmente acopladas y de componentes orientados a servicios. Del JBI es que nace la arquitectura para el desarrollo de los ESB o Enterprise Service Bus.

Enterprise Service Bus (ESB)
Es la combinacion de diferentes arquitecturas que proporcionan servicios fundamentales para otras arquitecturas mas complejas a traves de un sistema de mensajes y que responde a eventos. ESB se centra en la integracion de los sistemas, especificamente hablando de protocolos y formas de acceso (http, ftp, sockets... etc).

Componentes de un ESB:
  • Invocación: Se encarga de proporcionar apoyo a los protocolos de transporte de manera sincrónica y asincrónica.
  • Routing: Responsable para el envío de la información para un lugar u otro, lo hace de un modo estático o dinámico. Podemos usar el enrutamiento basado en reglas con Drools por ejemplo.
  • Mediación (Trasformación): Se encarga de proporcionar la transformación de protocolos, por ejemplo entrar en una http y salir en un SFTP.
  • Mensaje: Se encarga de proporcionar el tratamiento, procesamiento y el refuerzo de mensajes. Por ejemplo, si lee un xml el ESB debe ser capaz de añadir o eliminar información de ese XML antes de llegar al destino.
  • Orquestación / Coreografía: Se refieren a procesos complejos y BPMN / BPEL si no usamos BPEL no precisaremos de estas dos, muchas personas piensan que están obligados a usar estos dos en un ESB, y en muchos casos no existe tal necesidad.
Frameworks de Buses de Servicios (ESB)
Como Framework entendemos una estructura conceptual y tecnologica con soporte definido; y para buses de servicios tenemos los siguientes frameworks de trabajo, los cuales ayudan a implementar el modelo SOA sobre java:

Apache ServiceMix:

ServiceMix combina SOA y EDA(Arquitectura orientada a eventos) en un solo paquete; esta basado en la especificacion JSR208(JBI)
Apache Synapse

Synapse es un bus de servicios de apache diseñado para ser ligero y agil. Esta basado en un potente motor que actualiza asincronicamente los servicios y provee muy buen soporte a xml, web services y REST(Representational State Transfer).
Existen otras iniciativas como:
* OpenESB
* Spring Integration: basado en Spring Framework
* Celtix
* Mule

Encabezado fijo

Actualizacion.... evitense todo esto con:
http://www.tablefixedheader.com/


Se me presento un problema en el trabajo, tenia una tabla con muchos registros, pero no queria usar paginacion, ademas de esto sobre los 20 registros ya no me acordaba que significaba cada columna porque el encabezado se perdia; asi que me di en la tarea de buscar como mantener el encabezado fijo de una tabla html y el contenido movil, algo asi como esto: http://www.cssplay.co.uk/menu/tablescroll.html el truco esta en jugar con los tbody, thead, div y css


La receta es:


1. Crea el encabezado en una tabla, tienes que usar la recomendacion html stric, es decir algo como:



<table class="tabla_encabezado" border="1">
<caption>Titulo de mi tabla</caption>
<thead>
<tr>
<th class="th1"> Columna 1</th>
<th class="th2"> Columna 2 </th>
<th class="th3"> Columna 3</th>
</tr>
</thead>
</table>

Es necesario que cada columna apunte a un class diferente, después en el archivo .css de la pagina, se definirá el ancho de cada columna por medio de clases.

2. Debajo de la tabla creada anteriormente, crea otra tabla, pero esta ves solamente tendrá tbody, y un solo campo con el colspan igual al numero de columnas de la tabla anterior, algo como:

<table>
<tbody>
<tr>
<td colspan="10">
<div class="div_interna">
<table class="tabla_interna">
<tr >
<td class="td1"> Dato 1</td>
<td class="td2"> Dato 2</td>
<td class="td3"> Dato 3</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>



Aquí en realidad hicimos una tabla (tabla_interna) dentro de una celda de otra tabla, y esa tabla interna rodeada por un div (div_interna), que es el que nos permitirá movernos por esa tabla sin mover la pagina; para eso hay una propiedad en css.

3. Por ultimo, creamos el CSS, la mayor parte del truco esta en este archivo, aquí siempre se hará referencia a las clases que especificamos en las tablas anteriores.

.tabla_encabezado{
border-collapse: collapse;
border: 1px solid #666666;
font: normal 11px verdana, arial, helvetica, sans-serif;
text-align: left;
word-wrap: break-word;
}
.div_interna{
height:350px; 
overflow:auto; // Aquí esta el truco de poder mover la tabla sin mover el encabezado
margin:0 auto;
}
.tabla_interna{
border-collapse: collapse;
border: 1px solid #666666;
font: normal 11px verdana, arial, helvetica, sans-serif;
text-align: left;
word-wrap: break-word;
}

.th1 {width:80px;word-wrap: break-word; }
.th2 {width:80px;word-wrap: break-word; }
.th3 {width:80px;word-wrap: break-word; }

.td1 {width:80px;word-wrap: break-word; }
.td2 {width:80px;word-wrap: break-word; }
.td3 {width:80px;word-wrap: break-word; }


Recuerda que tanto el ancho del encabezado como el ancho de los datos deben ser iguales, pueden cambiar cuando colocas padding o bordes a las tablas




ncurses... de vuelta al inicio


ncurses

Es una librería escrita en C++ que tienes sus raíces en la antigua librería conio.h de C++, la cual se usaba para crear interfaces a los programas en C y C++. Lo admito, no sabia que existía, y con el auge de las ventanas y el html ni se me pasaba por la mente usarla en algo... pero la curiosidad me llamo la atención, porque para mi ese tipo de software de consola es de los mas estables y compatibles.. para un ejemplo esta Midnight Commander [MC] que es un manejador de archivos en modo consola.


Sobre ncurses encontre este tutorial para empezar muy bueno, el cual recomiendo para los que deseen realizar software sencillo, liviano y que no sea devorador de recursos, fue echo por Carles Pina y se encuentre en:

http://bulma.net/body.phtml?nIdNoticia=2004

Otro tutorial interesante y mas completo se encuentra en http://gluc.unicauca.edu.co/wiki/index.php/Programaci%F3n_con_Ncurses y fue hecho por Wilson Libardo Pantoja Y.