Mostrando entradas con la etiqueta progamacion. Mostrar todas las entradas
Mostrando entradas con la etiqueta progamacion. Mostrar todas las entradas

17 de septiembre de 2011

Genericos y Colecciones Parte 1. Sobreescribiendo equals y hashCode

Genéricos y colecciones

Los genéricos fueron una de las características principales en el lanzamiento de Java 5. Con la salida de los genéricos cambio la forma en como podemos manejar colecciones en Java. Una de las características que tienen las colecciones es el poder ordenar y buscar entre los elementos que forman parte del contenido. Podemos establecer el criterio de búsqueda u ordenamiento para nuestras colecciones, pero para esto debemos sobrescribir los métodos equals y hashCode. En esta primera publicación tocaré el tema de sobrescribir los métodos equals y hashCode, las características de cada uno de estos métodos y algunos ejemplos.

Puntos a tocar en esta publicación:

  • Sobrescribiendo el método equals
  • Reglas que sigue el método equals
  • Ojo, mucho ojo.
  • Sobrescribiendo el método hashCode
  • ¿Que implica el hashcode?
  • Reglas que sigue el método hashCode
  • Ojo, mucho ojo.


Sobrescribiendo el método equals

Indagando en la javadoc acerca del método equals(Object o), podemos encontrar lo siguiente:

Método: equals(Object o)
Valor de retorno : boolean
Descripción: Indica si un objeto es igual a este.

Este método lo utilizamos para saber si un objeto es igual que otro. Este método utiliza el operador == para comparar a dos objetos y decidir si son iguales, por ejemplo podemos tener la siguiente clase:


public class Demo {

private int boleta;

public Demo(int boleta){
this.boleta = boleta;
}

public int getBoleta(){
return this.boleta;
}

public static void main(String[] args) {
Demo demoA = new Demo(20);
Demo demoB = new Demo(20);

System.out.println(demoA.equals(demoB));
}
}

La ejecución del anterior método main da como resultado en consola false. Esto es porque el método equals sin sobrescribir ocupa el operador == para comparar a dos objetos. Pero supongamos que queremos diferenciar a los objetos mediante su atributo boleta, ya que es el identificador de un Alumno para una aplicación escolar. Para esto debemos sobrescribir el método equals, diciéndole qué propiedad del objeto debe ser comparada para determinar si un objeto es igual a otro. El método sobrescrito se vería de esta forma:

@Override
public boolean equals(Object o){
if(( o instanceof Demo) && (((Demo)o).getBoleta() == this.boleta))
{
return true;
}else{
return false;
}
}

la tercera linea es la que tienen la magia. En ella hacemos un par de validaciones, la primera tiene que ver con estar seguros de que el objeto o es una instancia de la clase Demo, y la segunda es verificar si la propiedad boleta de el objeto o es igual a la propiedad boleta del objeto que invoco el método equals. Si los valores de boleta son los mismos, el método equals que sobrescribimos regresara true. Con esto nosotros tomamos la decisión sobre que criterio se debe tomar para comparar a nuestros objetos.

public static void main(String[] args) {
Demo demoA = new Demo(20);
Demo demoB = new Demo(20);

System.out.println(demoA.equals(demoB));
}

Por lo anterior, esta ejecución del método main, nos dará como resultado un true en la salida por consola.

Hay tipos de colecciones como los Sets que no nos permiten agregar objetos duplicados a la colección. La forma en como los Sets van a decidir si un objeto esta duplicado o no, la especificamos nosotros cuando sobrescribimos el método equals. Lo mismo cuando en una colección de tipo Hash* queremos buscar un elemento en especifico, la colección sabe que objeto regresar, dado el criterio que nosotros definimos al sobrescribir el método equals y hashCode. En esto radica la importancia de sobrescribir estos métodos, siempre y cuando este dentro de nuestras intenciones contar con este tipo de prestaciones.

Reglas que sigue el método equals

  • Reflexivo: Para cualquier referencia al valor x, x.equals(x) debe regresar true.
  • Simetrico: Para cualquier referencia a los valores x y z, x.equals(z) debe regresar true si y solo si z.equals(x) es true.
  • Transitivo. Para cualquier referencia a los valores w, x y z, si w.equals(x) regresa true y x.equals(z) regresa true, entonces w.equals(z) debe regresar true.
  • Consistente: Para cualquier referencia a los valores x y z, múltiples invocaciones a x.equals(z) consistentemente regresaran true o false, si es que los valores utilizados para la comparación de los objetos no ha sido modificada.
  • Para cualquier referencia no nula al valor x, x.equals(null), debe regresar false.

Ojo, mucho ojo

  • Asegúrate de sobrescribir el método equals. Las siguientes son implementaciones del método equals que son validas para el compilador, pero no validas para sobrescribir el método:
    • boolean equals(Objeto o). Esta implementación no sobreescribe el método equals de la clase Object, ya que el método debe ser declarado como public.
    • public boolean equals(Demo o). Esta implementación no sobreescribe el método equals de la clase Object, ya que el parámetro que necesita el método equals debe ser explícitamente un objeto de la clase Object, y no uno que extienda de éste. Esta implementación, al igual que la anterior es una sobrecarga del método equals, mas no sobreescribe este método.

La descripción correcta del método equals, es decir, la forma en como debe sobrescribirse es la siguiente:

public boolean equals(Objeto o);



Sobrescribiendo el método hashCode

¿Qué implica el hashcode?

Algunas colecciones usan el valor hashcode para ordenar y localizar a los objetos que están contenidos dentro de ellas. El hashcode es un numero entero, sin signo, que sirve en colecciones de tipo Hash* para un mejor funcionamiento en cuanto a performance. Este método debe ser sobrescrito en todas las clases que sobrescriban el método equals, si no se quiere tener un comportamiento extraño al utilizar las colecciones de tipo Hash* y otras clases. Si dos objetos son iguales según el método equals sobrescrito, estos deberian regresar el mismo hashcode. Véase el siguiente ejemplo:


public class Demo {

private int boleta;

public Demo(int boleta){
this.boleta = boleta;
}

public int getBoleta(){
return this.boleta;
}

@Override
public boolean equals(Object o){
if((o instanceof Demo) && (((Demo)o).getBoleta()== this.boleta))
{
return true;
}else{
return false;
}
}

public static void main(String[] args) {
Demo demoA = new Demo(20);
Demo demoB = new Demo(20);

System.out.println(demoA.equals(demoB));
System.out.println(demoA.hashCode());
System.out.println(demoB.hashCode());
}
}

Esto nos da como resultado:

true
1414159026
1569228633

regresa true porque estos objetos son iguales, debido a que se sobrescribió el método equals. Si son considerados iguales por equals, esto se reflejará al utilizarse en las colecciones de tipo Hash*. Lo que podemos ver en la salida de este código es que a pesar de que ambos objetos son iguales, el hashcode no es igual. Esto es porque no hemos sobrescrito el método hashCode.

El uso principal del hashcode, es como lo mencionamos arriba, cuando se manejan colecciones de tipo Hash*. La forma en como operan las colecciones de este tipo es a grandes rasgos la siguiente: Las colecciones de tipo Hash* almacenan los objetos en lugares llamados baldes, de acuerdo al numero obtenido por el método hashCode. Si el método hashCode regresa un 150, el objeto será guardado en el balde numero 150. Puede llegar a pasar que haya mas de un objeto de diferente tipo en el mismo balde. Esto no ocasiona ningún problema al momento de recuperar el objeto del balde, ya que al buscarlo este tipo de colecciones necesita como parámetro un objeto con el mismo valor hashcode, el cual utilizara para buscar el numero de balde que contiene a el objeto en cuestión. Si hay mas de un objeto, el siguiente criterio para determinar cual es el objeto buscado, es la utilización del método equals. Así es como este tipo de colecciones para buscar un objeto, ya sea para regresarlo y para ordenarlo. Lo cual falla si no sobrescribimos el método hashCode.

Sobrescribiendo el método hashCode

A continuación veremos como podremos sobrescribirlo:


@Override
public int hashCode() {
int hash = 7;
hash = 97 * hash + this.boleta;
return hash;
}

La salida que obtenemos una vez que se rescribe este método en el ejemplo de arriba es :

true
699
699

lo que nos dice que estos métodos son iguales según equals, y que además tienen el mismo numero hashcode.

Este método hashCode regresara consistentemente el mismo valor, siempre y cuando el campo boleta no cambie. Cada desarrollador puede implementar de diferente manera igualmente validas, correctas y eficientes este método. Lo que debemos de tener en mente al sobrescribir este método es que si para sobrescribir el método utilizamos variables de instancia (en nuestro ejemplo boleta), también debemos utilizar variables de instancia para generar un hashcode correcto. En el caso de las constantes que se utilizan en el ejemplo de arriba, se recomienda utilizar números primos, para una mejor distribución del hashcode generado.


Reglas que sigue el método hashCode

  • Si el método hashCode es invocado en múltiples ocasiones durante la ejecución de una aplicación, debe regresar consistentemente el mismo valor entero, esto si la información utilizada para calcular el hashcode no ha cambiado entre invocación e invocación del método hashCode.
  • Si dos objetos son iguales según el método equals, entonces la llamada al método hashCode debe regresar el mismo hashcode.
  • No es requerido que si dos métodos no son iguales según el método equals, tengan diferentes valores hashcode.

Ojo, mucho ojo

  • Si dos métodos son iguales según el método equals, el método hashCode debe regresar el mismo entero para ambos métodos. Sin embargo, si el métodos equals dice que dos métodos no son iguales, el método hashCode puede o no regresar el mismo entero.
  • Retornar un valor fijo en un método hashCode es una mala idea, ya que tendremos múltiples objetos con el mismo valor hashcode, lo cual no ayuda en nada a la hora de trabajar con colecciones de tipo Hash*.
  • Si utilizamos variables de clase de tipo transient para generar un hashcode, serializamos el objeto en cuestión y queremos recuperar el hashcode de ese método, nos encontraremos con que el hashcode será diferente al hashcode con que se serializó el objeto. Ya que este tipo de variables no se serializa. Por eso es una mala idea utilizar variables transient para generar el hashcode.

3 de abril de 2011

Crear una libreria para una aplicacion Java ME

En mi ignorancia en aplicaciones mobiles ( y en java ), pensaba que el procedimiento para crear y agregar una libreria propia a un proyecto nuevo, era el mismo para la version de Java SE y ME. Pero estaba equivocado. 

Generalmente, cuando se quiere crear una libreria, solo se toma un proyecto, se construye (build), esto nos genera un archivo con extension ".jar" que es el que contiene las clases listas para ser agregardas a otro proyecto a manera de libreria. Entonces lo que hariamos en nuestro proyecto de Java SE seria agregar la libreria. Si estamos en Netbeans, bastaria con dar clic derecho en la carpeta de librerias de nuestro proyecto y seleccionar "add library". Y con esto podriamos hacer uso de nuestra libreria. 

Quise hacer este procedimiento para una aplicacion mobile que actualmente desarrollo (PipaApp). El compilador me decia que todo estaba correcto,  pero al momento de correr la aplicacion en el emulador obtenia este error:


java.lang.NoClassDefFoundError: com/blogspot/pplouis/saludo/Saludo
        at hello.PipaApp.getFormPrincipal(+2)
        at hello.PipaApp.startMIDlet(PipaApp.java:50)
        at hello.PipaApp.startApp(PipaApp.java:183)
        at javax.microedition.midlet.MIDletProxy.startApp(MIDletProxy.java:43)
        at com.sun.midp.midlet.Scheduler.schedule(Scheduler.java:374)
        at com.sun.midp.main.Main.runLocalClass(Main.java:466)
        at com.sun.midp.main.Main.main(Main.java:120)



Y es que no se puede agregar un archivo .jar creado con Java SE a un proyecto Java ME ( sin antes hacer unos cambios en un archivo de configuracion ), aunque se trate de solo una clase, que no haga ningun import y que solo imprima un hola mundo.  Un archivo .jar asi deberia de funcionar en ambar versiones de Java, pero no lo hace porque en el archivo META-INF, que se encuentra dentro del .jar, dice lo siguente:


Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.1
Created-By: 1.6.0_14-b08 (Sun Microsystems Inc.)
X-COMMENT: Main-Class will be added automatically by build


mientras que un archivo .jar creado para una app mobile de Java Me, tiene lo siguiente:


Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.1
Created-By: 1.6.0_14-b08 (Sun Microsystems Inc.)
MIDlet-Vendor: Vendor
MIDlet-Name: SaludoLibreriaMobile
MIDlet-Version: 1.0
MicroEdition-Configuration: CLDC-1.1
MicroEdition-Profile: MIDP-2.1


y se observa que hay especificaciones acerca de la configuracion y el perfil de la libreria.

 Para crear una libreria para Java Me es necesario que sea especificamente para un proyecto Java Me. Para esto haremos lo siguiente:

Primero creamos nuevo proyecto de tipo Java Me, dentro de las categorias que nos muestra ponemos que sea un "Mobile Class Library"


Despues se escoje la configuracion que y perfil que le queremos dar a nuestra libreria. Esto es importante, ya que esta libreria tendra mejor compatibilidad con las aplicaciones que tengan la misma configuración.


Ya creado el proyecto, solo necesitamos escribir nuestro codigo:




darle en netbeans "clean" o "clean and build".




 Esto nos genera el archivo distribuible, que para este caso sera un .jar, el cual es nuestra libreria, y que se encuentra en la carpeta dist de nuestro proyecto. 


La carpeta lib viene vacia, y el archivo Demos.jad, es basicamente un archivo de informacion, que generalmente se ocupa cuando se va a descar la aplicaciocion de algun sitio y sirve para dar informacion acerca de la version, tamaño del archivo, configuracion , etc.

Y ya por ultimo solo basta agregarla a nuestro proyecto Java Me. Para eso damos clic derecho en la carpeta de "Resources", despues en "add jar/zip" y agregarmos el archivo .jar generado previamente.  


24 de marzo de 2011

error: The virtual machine does not support this operation: schema change not implemented

Los errores de Netbeans. cuando estas en modo debugger para una app: puedes hacer cambios en el codigo y verlos reflejados en la aplicacion sin que tengas de desplegarla otra vez. Esto agiliza el proceso de debuggear.

Hay ciertos cambios que no los puede actualizar, como por ejemplo el añadir o elminar un field o variable de clase, cuyo error cuando queramos "Apply Code Changes" es:

The virtual machine does not support this operation: schema change not implemented
D:\SACMx\SACMx6.0.0\nbproject\build-impl.xml:914: The following error occurred while executing this line:
D:\SACMx\SACMx6.0.0\nbproject\build-impl.xml:401: The virtual machine does not support this operation: schema change not implemented
BUILD FAILED (total time: 0 seconds)

Esto es porque la implementacion de la maquina virtual no lo permite. Si navegamos hasta build-impl.xml en la linea 914 y build-impl.xml en la linea 401, nos daremos cuenta de que es un error al querer recargar una clase

Ademas de esta condicion no se podra "Apply Code Changes" cuando el codigo tenga errores de compilacion (obviamente).

15 de marzo de 2011

Error: "home/manie/netbeans-6.5/mobility8/WTK2.5.2/bin/emulator: 26: java: not found"

Ahora que junto a mis buenos amigos Benja, Shaike y Monroy, estoy levantando aplicaciones mobiles en java, para despues hacer lo necesario (que talves sea solo recompilar) para ejecutarlas en terminales con androy, me vino a salir un erro al momento de querer probar mi aplicacion con el emulador de netbeans. La parte interesante del strack trace que obtuve en la exception arrojada es la siguiente:

/home/louis/netbeans-6.5/mobility8/WTK2.5.2/bin/emulator: 26: java: not found


y es que pasan 2 cosas, o que en la ruta especificada no este el ejecutable "emulator", y en este caso habra que descargarselo, o bien por separado, o descargar de nuevo el sdk de la micro edition de java.  Y la segunda es que si se encuentre el emulador pero no tiene configurada la variable "javapathtowtk". En este ultimo caso, lo que se tiene que hacer es abrir el archivo "emulator", y modificar el script configurando javapathtowtk asi:

javapathtowtk="/usr/java/jdk1.6.0_13/bin/" 

no esta por demas decir que hay que cambiar la ruta por la que corresponda a tu carpeta de instalacion del jdk. Con esto el problema queda solucionado.

Como se puede ver a simple vista, esta correccion solo aplica para sistemas operativos linux, ya que es posible editar el script de el archivo "emulator". En Guindous no he tenido este problema con el emulador, pero creo que aplicaria otra solucion, ya que no se puede modificar el archivo "emulator" ya que nos aparece en forma binaria. Ahi la solucion que podria aplicar es la de ejecutar desde consola el emulador pasandole como parametro la ruta del jdk. Esa seria mi solucion, espero algun dia poder comprobarla ( no mejor que todo funcione bien ). 



8 de junio de 2010

¿Es la nube lo de hoy? ¿Sera lo de mañana?

05 junio 2010 sabado 05:06

Un recuerdo de hace unos dias, fue el de la exposicion de 3 min que hizo cada una de las personas de mi grupo en la U-pizza para la clase de Psicosociologia Industrial. Tenian que ser 3 min delante del grupo, y el tema era el que quisieras. Obviamente yo hable de cosas interesantisimas, ya saben, politica, finanzas, transacciones de millones de dolares, la crisis financiera en Grecia, el sistema educativo de Alemania del siglo XVIII, etc. El mismo dia de mi participacion, hablo Oscar sobre el cloud computing. Oscar, quien es todo un geek (aunque ese dia mas bien parecia vendedor de servicios de nube de una empresa como Sun, impresionante ehh!), decia que es lo que va a prevalecer en el futuro inmediato. En pocas palabras, la nube era la onda. Que todo iba a estar en la nube. Con lo cual difiero un poco.

Para empezar en concepto de nube nos dice que las empresas ya no van a tener que lidiar con hardware, software dentro de su organizacion, reducira el personal de IT, menos mantenimiento a su equipo de computo, y de mas puntos, ya que todas las necesidades computacionales seran contratadas como un servicio a terceros. Es decir, si necesitas almacenamiento, procesamiento de datos, software, vas con un proveedor de nube, implementa la solucion, y tu ni te enteras como se hace, que se implementa, que hardware, que software, que metodologias, que servidores, pero tendras la solucion a tus necesidades.

Me parece que mucha gente esta y estara renuente a darle su informacion critica a un 3ro, ya que no se sabe como y donde almacenara esa informacion, por las manos de quien pasara, cuales son las politicas de seguridad que tienen para esa informacion, etc. Como te aseguras de que la "nube" sabe como manejar la seguridad e integridad de la informacion que es critica para tu organizacion??? Siento todavia a la gente renuente a tener su informacion fuera de su empresa, y en parte tienen razon. Para intentar atenuar esta, si quieren excusa, hay nubes privadas, nubes hibridas y soluciones que te venden el hardware y software necesario pera que implementes la nube en tu propia empresa, pero, se pierde un poco el concepto e idea de lo que es la nube, por lo que comento en el 2do parrafo.

Creo que pasa lo que paso hace algunos años cuando se decia que los servicios web eran el futuro. Eso es lo que las empresas de tecnologia nos vendian, y ya se vio que no fue asi. Y hoy lo que se intenta vender es la nube como la solucion por excelencia. Pero, como toda tecnologia, tiene su nicho, hay cosas para las que va perfecto, otras para las que va mas o menos, y otras para las que no es la opcion, como todo en la vida.

4 de junio de 2010

Editores de Texto

Esto lo escribi hace como mes y medio, se habia quedado alvidado en mi escritorio. Pero vale bastante la pena como para que lo deje alli. Asi es que corre y se va:

Taria bueno escribir algo acerca de los editores de texto, al menos de los que uso mas frecuentemente. Mmmm, eeh, pues elegir un editor de texto esta en funcion del uso que le vas a dar a ese editor, del tipo de documentos, archivos que vas a generar y el uso que les vayas a dar. No utilizas el mismo editor cuando vas a redactar un informe de una practica escolar, o cuando escribes una novela, codigo para un programa en Java, un blog, etc.
Los que utilizo son:
*Vim - Gvim ---> Vi Improved y Graphic Vi Improved, respectivamente.
Este don editor es un editor de texto plano (como el note pad de Guindous). Viene en su version consola (Vim), y para los menos geeks, en su version grafica (GVim). Lo utilizo cuando escribo codigo de programacion, ya que de pinta el codigo de diferentes colores, deacuerdo a si son constantes, variables, keys words, etc. La curva de aprendizaje para poder usarlo de una manera intermedia, es corta. Una vez aprendido como usarlo, se llega a ser mas productivo, respecto a cuando se utiliza otro editor de text plano.
Ademas tiene el plus de ser software libre, asi evitamos ser solapadores de empresas monopolistas. Originalmente solo venia en Sistemas Operativos Unix, despues tambien en Linux, y ahora tambien en Guindous.
Hay que decir que no marca errores de sintaxis ni de compilacion.
*Programmer's Notepad.
Como su nombre lo dice, es un editor de texto orientado a programadores.Soporta infinidad de lenguajes de programacion y pone de colores distintos variables, constantes, keywords, etc. No marca errores de sintaxis, ni de compilacion, solo es un editor de texto plano.
El plus que da este editor de texto, es su capacidad de ayudarte a identar el codigo para una mayor legibilidad de codigo. Es grafico y mola (no tamto como Vim). Esta para Guindous y Mac (creo). Lo uso en Linux usando un programa que sirve para correr aplicaciones de Guindous que se llama Wine (no, no es un emulador, de hecho las siglas de Wine quieren decir: Wine Is Not Emulator) y jala perfecto.
*TextRoom
Sirve perfecto para textos que son muy largos, siento que es bueno para bloggers, escritores de libros o articulos. Editor nada espectacular, pero muy util. Lo puedes poner en full screen, cambiar el color de la letra y del fondo, insertar fecha y hora, y tiene un sonido que simula el sonido de cuando se teclea en una maquina de escribir mecanica (para los melancolicos). Lo hay para diferentes plataformas.
Lo unico malo que en Linux tiene el bug de que no pone la hora exacta, sino que con cierto retraso. Pero en general mola. Recomiendo el full screen, para no distraerse con otras ventanas y barras de menus, iconos, etc.
*Writer de Open Office
Este es para tareas que necesitan mas formato. Es las version libre de Word de Guindous. Puedes dar formato con un clic, insertar imagenes, graficos, objetos, etc. Guarda en el fomato Open Document Text, cuya extencion es .odt. Este claro no es compatible con los cerrados de Office, y no podras abrirlos ahi (aunque si viceversa). Da la opcion de guardar tambien en .doc, .pdf, entre otros. Asi que por portabilidad no me quejo.
Pues creo que son los que mas utilizo, pues me son utilies y son buenos cada uno para diferente aplicacion y requerimientos especificos.

17 de agosto de 2009

Buenas Prácticas Para Empezar Como Programador

La programación puede llegar a ser una de las actividades mas satisfactorias o mas frustrantes realizadas por un informático. Esto debido a la complejidad adherida a dicha actividad y a malas practicas o hábitos que se tienen al iniciar el estudio y la practica de la programación.

Al igual que cuando empezamos con el aprendizaje de cualquier otra cosa, para iniciar a programar necesitamos seguir algunas buenas practicas, la mayoría de las cuales se mantienen durante toda la vida de un desarrollador(a).

Aquí listo algunos tips y buenas practicas que me han funcionado en la programación:


- Identificar y analizar el problema al cual se le quiere dar solución programándolo. Es una buena practica sentarse a pensar el problema en cuestión y en su posible solución, antes de intentarcodificarlo. Esto para evitar la frustacion y perdida de tiempo de cuando apenas leermos o escuchamos el problema, y nos queremos sentar frente a la pc a programar. Además de que evitamos "parchar" el código por deficiencias en este, ya que haría todo mas engorroso para uno, le quitaría limpieza y claridad al programa, y ya no seria código de calidad.

- Realizar diagramas y/o pseudocódigo. Esto va ligado a punto de arriba, ya que al momento de analizar el problema y proponer una posible solución a este, es recomendable plasmarlo en papel y/o digitalmente, en forma de algún tipo de diagrama o pseudocódigo. Esta practica, en el caso de los diagramas, nos ayudara a visualizar de una manera gráfica la solución del problema, detectar fallas o mejoras que se puedan realizar. Y en el caso de pseudocódigo, comose acerca mas a lo que va a ser el código en la pc, es mas fácil la migración del contenido del pseudocódigo a la pc en forma de algún lenguaje de programación.



- Darse un tiempo de descanso cuando tenemos problemas difíciles. A veces por lo complicado del problema a resolver, la falta de experiencia cuando se inicia a programar, el cansancio, el mal humor, etc. nos atoramos en una parte especifica de la solución del problema. Eso es muy frustrante, ya que crees que por donde se vea, el problema no se puede resolver. En estos casos lo mejor es dejar despejar la mente, tomarse un break, realizar algo de actividad física (para oxigenar el cerebro), darse una vuelta, tomarse una cerveza con los cuates, etc. Y tiempo después (tomate 1 día si el tiempo te lo permite) regresa a la resolver el problema, ahora con la mente despejada. Veraz que le encontraras solución a problemas que creías imposibles.



- Utilizar la lógica positiva, no la lógica negada (<--- como aquí, je). Utilizar "Si Mario tiene hambre, entonces come" -> (come(Mario,si)), es lo mismo que "Si Mario no no tiene hambre, entonces come" -> (come(Mario,si)), solo que la segunda nos puede llevar a confusiones y errores de lógica cuando se opere con esa sentencia y otras sentencias que tienen lógica positiva. Además de que siempre es mas intuitivo y natural tratar con sentencias positivas. Son mas intuitivas para afirmar y para negar.

- Leer a mas de un autor de programación. Suele pasar que cuando iniciamos el estudio de la programación nos cerremos al primer autor de libro o portal de internerd que nos topemos y no miremos a otras fuentes. Esto tal ves porque sentimos que es una autoridad en el tema, porque estamos teniendo una buena experiencia de aprendizaje con tal autor u otras razones no tan validas. El hecho es que si nos limitamos a aprender de solo una persona, tenderemos mucho a imitar el estilo de programación de quien seguimos de mas. Por el contrario, si echamos un ojo a la forma de trabajar de otras personas, tendremos mucha mas información y nos crearemos con mucha mas facilidad un criterio y estilo de programación propio.



- No dejes que el IDE te domine, eres tu quien debe dominar al IDE. Cuando se inicia a programar, lo mas cómodo y didáctico es utilizar un entorno de desarrollo. Ya que un IDE te evita la "molestia" de compilar "a mano", te muestra errores de sintaxis y de lógica enseguida que los comentes, muestra si hace falta alguna librería y bueno, en general hace una abstracción de todo lo que rodea el desarrollo y te lo pone facilito. Esto esta bien cuando se inicia a programar, o cuando ya profesionalmente lo que deseas es desarrollar de una manera mas rápida. Pero hay que tener cuidado de no volvernos dependientes de los IDEs y sobre todo de un IDE es especifico. ¿Que pasaría si toda la vida como programadores hemos utilizado Netbeans, y llegamos a un lugar donde se tenga que trabajar con Eclipse o con otro entorno de desarrollo? o peor, lleguemos a un lugar en donde no se trabaje con IDEs (algo difícil, pero puede pasar). Además de que prescindir de los entornos de desarrollo nos ayuda a comprender mejor el proceso que hay para elaborar y correr un programa en la computadora. Procura no ser dependiente de los IDEs.



- Identar y comentar el código. Casi se me pasa este, pero no puede faltar, es básico. Hacer una buena identación de código, resulta muy útil para ver, por ejemplo, entre ciclos anidados, donde empieza una secuencia de instrucciones y donde termina, en que nivel afecta tal o cual instrucción, identificar cuantos métodos o funciones tiene nuestra clase o estructura, todo esto y mas con solo una ojeada. Además de que un código identado resulta mas agradable a la vista, e influye en la facilidad y estado de animo para leer un código, sobre todo cuando vamos a compartir el código o se revisa ese mismo código meses después. Suena muy mamón, pero así es, je. En cuanto a los comentarios, procura poner solo los necesarios, no atiborrar el con ellos. Unos buenos comentarios ayudaran a otra persona a entender tu código, o a ti mismo cuando lo editas tiempo después a la fecha de creación. A medida de que hagas un código auto documentado, necesitaras menos comentarios.



- Ayudar a alguien con menos experiencia. El hecho de ayudar a quienes llevan menos tiempo en la programación que tu, además de que ayudas a alguien que lo necesita y es bueno para el aprendizaje (porque en la vida todos aprendemos de todos), te ayudara a reforzar los conocimientos que compartas sobre programación. Además de que siempre es enriquecedor conocer cual es la forma de ver los problemas de otras personas.

Pues ahí están algunas buenas practicas para entrarle a la programación de una forma mas eficiente, mas placentera y menos frustrante. Me han funcionado y espero te funcionen a ti también. Se quedaron algunas en el tintero (tintero, si aja), pero estas son las mas importantes creo yo. 8^)