lunes, 9 de diciembre de 2013

Como crear presentaciones con el lenguaje Go!


En este post les quería mostrar como armar presentaciones de este estilo: Go: a simple programming environment con el mismo lenguaje GO ;)




Lo primero que debemos realizar es obtener la herramienta que nos permitirá mostrar nuestras presentaciones ;) eso lo podemos hacer con el comando:
go get code.google.com/p/go.talks/present

(recuerden que debemos tener instalado Go correctamente y configurada nuestra variable de entorno $GOPATH, como lo explico acá: Comenzando con el lenguaje Go)
Una vez que obtenemos la herramienta, deberemos crear nuestro archivo .slide como se espesifica en la siguiente URL: 
http://godoc.org/code.google.com/p/go.talks/pkg/present

Este es el formato que debería tener el archivo, la primera linea que no este en blanco y que no sea un comentario va a ser el titulo de la misma

························· Comienzo de la presentación ··························
Como armar una presentacion con Go

Gabriel Pozo
Programador
http://aprendiendodeandroidymas.com/
@jackgris2
http://golang.org

* Este es un nuevo slide

Y esto es texto en el nuevo slide

* Si no colocamos texto en el slide

* Correr codigo

Con esto vamos a poder correr codigo Go en el mismo slide

.play go1.1/intdiv.go /func f/,/}/

* Mostrar codigo

Vamos a poder mostrar porciones de codigo para que se vean diferente al texto, y como podemos ver, podemos decir que muestre solo una u otra funcion de nuestro codigo ;)

.code go1.1/return-old.go /func slurp/,/^}/

.code go1.1/return-old.go /func min/,/^}/

* Cargar imagenes en la presentacion

Podemos crear enlaces [[go1.1/blockprofile.svg][Texto que se ve]].
Como tambien mostrar las imagenes que tengamos guardadas

.image go1.1/blockprofile.png

* Donde coloco los archivos que queremos mostrar?

Simplemente con crear una carpeta que contenga lo que queremos mostrar y lo coloquemos en el mismo directorio donde esta nuestro archivo .slide

Por los enlaces, en este caso pueden ver que tome y modifique la presentacion del año 2013 que escribio Andrew Gerrand llamada What's new in Go 1.1 y que se encuentra en el codigo fuente

····························· fin de la presentación ····································


Las lineas en blanco después del titulo y el texto están correctas, pero no son obligatorias, y las lineas que comiencen con # van a ser comentarios.



Una vez que lo terminemos, lo podremos correr de la siguiente forma:
present archivo.slide (si agregamos la carpeta bin a nuestro path, sino el comando podría ser este $GOPATH/bin/present archivo.slide)
Y para verlo simplemente nos deberemos dirigir a un navegador y colocar la siguiente URL:  http://localhost:3999/



Datos extras:

Si ven dentro de la carpeta que se crea en $GOPATH/src/code.google.com/p/go.talks, encontraran carpetas con el nombre de años, por ejemplo 2013, dentro de cada una de ellas, verán los slides que han creado desarrolladores del lenguaje con esta misma herramienta. Esto es muy bueno porque simplemente con el comando present van a poder ver cada una de ellas de manera local, pero ademas podrán ver el código de cada una. Así podrán guiarse para que puedan armar sus propias presentaciones de la misma forma que lo han hecho ellos ;) (y como lo hice yo en este post :D)

El segundo dato, es que dentro de esa carpeta, si nos dirigimos a la carpeta present/templates, podemos modificar cosas predeterminadas como por ejemplo el saludos del final donde dice "thank you" lo podremos cambiar según nuestro idioma por el saludo que deseemos colocar :D

Eso  es todo por ahora ;) espero que les sea de utilidad, creo que es una buena forma de armar nuestras presentaciones con el propio lenguaje Go :D Además de que esta muy bueno de que podamos correr el propio código en las mismas ;) Nos vemos en la próxima, espero que les haya gustado ;)

Saludos, Gabriel

viernes, 6 de diciembre de 2013

Como comenzar con Beego: web framework para Go!



Hola a todos, en este post les quería presentar este interesante web framework para el lenguaje Go! De los que probé hasta ahora para ese lenguaje, creo que es uno de los más sencillo de utilizar y que mejor armado se encuentra.


Este framework es sencillo, ligero y totalmente libre (más abajo se encuentra el enlace hacia el código fuente) soporta RestFul, diseño MVC, sesiones, etc.  Lo que me gusta de este es, que esta diseñado para trabajar con Go, al estilo del lenguaje y no como varios otros frameworks, que son imitaciones de otros lenguajes. Lo que termina haciendo es que se mezclen estilos quedando un código bastante rebuscado y horrible :D (hay varias imitaciones de frameworks web de Ruby y Python dando vueltas por ahí)

Algo bueno para mi gusto sobre su arquitectura, es el diseño modular, lo que nos permite elegir que queremos o no, utilizar, en la siguiente imagen se ven los 8 mayores módulos que posee.

 Arquitectura del framework


Posible estructura que podríamos utilizar para nuestro proyecto: (no es obligación hacerlo de esta manera, solo es una opción)
 
├── conf
│   └── app.conf   
├── controllers
│   ├── admin
│   └── default.go
├── main.go
├── models
│   └── models.go
├── static
│   ├── css
│   ├── ico
│   ├── img
│   └── js
└── views
    ├── admin
    └── index.tpl

Otra ventaja es que para comenzar ya tenes la opción de que te arme un proyecto básico, de esta manera lo vas a tener andando en muy poco tiempo, y podrás ver como funciona ;)

Para esto solo necesitamos tener instalado una versión de Go 1.1 como mínimo (cualquier cosa acá explico como hacerlo Comenzando con el lenguaje Go)

Entonces para obtener Beego simplemente debemos utilizar un comando:

go get github.com/astaxie/beego
 
Y para que el manejo del proyecto sea más sencillo, instalamos la herramienta bee:

go get github.com/beego/bee

Para crear nuestra primer aplicación solo son unos simples pasos: (recuerden que siempre es recomendable cuando trabajen con Go tener configurado correctamente su GOPATH ;) )

$ cd $GOPATH/src
$ bee new hello
$ cd hello
$ bee run
 
Lo que hacen estos comandos es, movernos a la carpta src de nuestro GOPATH, crear con 
bee un nuevo proyecto llamado hello, movernos dentro del mismo, y correr el servidor para
pruebas que re-compila automáticamente al modificar un archivo y corre nuestra app en
 http://localhost:8080/.
   
Si nos dirigimos en nuestro navegador después de seguir esos pasos a esa dirección, vamos a poder ver el ejemplo que trae por defecto Beego ;)


Actualización 07/12/2013: (GAE: Google App Engine)





Repositorio de Beego modificado para GAE:
https://github.com/astaxie/beegae

Ejemplo:
http://beegogae.appspot.com
Código fuente:
https://github.com/astaxie/beegogae

Si quieren hacer funcionar el ejemplo de manera local, simplemente se descargan el ejemplo:
git clone https://github.com/astaxie/beegogae
Obtienen la versión modificada BeeGAE:
go get https://github.com/astaxie/beegae

Y ahora es cuestión de hacerlo funcionar con el servidor que GAE nos ofrece en el SDK: dev_appserver.py beegogae
Ya con eso vamos a poder ver el ejemplo de Beego sobre GAE de manera local en el puerto por defecto 8080, para eso nos dirigimos al navegador a la siguiente dirección:
http://localhost:8080

Sitio Oficial:

Código fuente: Beego

Post sobre el tema:

Espero que les haya gustado el post, en este caso solo vimos la herramienta, más adelante vamos a hacer cosas más complejas. Otra cosa interesante y que creo que va a ayudar mucho a atraer más gente a utilizarla, es que ya tienen soporte total para Google App Engine ;) Nos vemos en la próxima.


Saludos a todos, Gabriel

martes, 3 de diciembre de 2013

The Original Hacker segunda edición !!!


En este nuevo post, vuelvo a agradecer a Eugenia por compartir su conocimiento con todos nosotros, presentando la segunda edición de The Original Hackers :D



 
La verdad que la lectura es totalmente recomendable, sin ningún tipo de desperdicio, en la misma trata los siguientes temas:

Desarrollar Software Aplicando la Ingeniería Inversa: Donde muestra una excelente práctica para el desarrollo de software, que debo admitir que muchas veces me cuesta bastante implementarla :D Creo que lo más complicado es al principio, hasta que la cabeza nos hace un click, y comenzamos a ver las cosas de manera diferente. Creo que el artículo es muy útil, aunque no planeemos usarla, esta explicado de manera tan clara, que aunque no deseemos utilizar la técnica de desarrollo, vamos a saber exactamente de qué se trata  y de esta forma poder elegir teniendo un verdadero conocimiento de cómo funciona.

Manipular Archivos de Configuración Mediante ConfigParser: Este artículo me gusto mucho, yo lo e utilizado pero verdaderamente no había encontrado una explicación tan clara ya sea en español o en inglés :P Creo que para el que nunca lo utilizó es un excelente punto de partida, y para el que ya lo hizo, es una muy buena referencia ;)






Agregado de archivos cron y ejecución periódica de procesos en los paquetes .deb: Esta serie de artículos siempre me resultaron extremadamente buenos desde que comenzó con la revista Hackers & Developers Magazine, aunque hace un tiempo largo que no estoy utilizando una distro derivada de Debian, creo que son una excelente herramienta para conocer cómo trabajar con archivos .deb y así poder empaquetar nuestro software para una de las plataformas más populares en el mundo Linux. En este caso en particular nos enseña algo muy interesante y útil, como es automatizar tareas periódicas que nuestro software necesite que realice el sistema operativo donde es instalado. Con un ejemplo muy didáctico.

En cuanto a los dos últimos artículos, yo no sé absolutamente nada sobre PHP, pero de todas formas los leí y son muy recomendables:

¿cómo se hicieron los ABM de la Web “The Original Hacker Library”?: Este en este artículo muestra cómo pensar y trabajar para armar los ABM de una web, en esta ocación utilizando PHP y el framework que ella misma armó. De todas maneras creo que la utilidad real, es ver como se pensó y trabajó en un caso real como es la propia web de la revista, lo que le da un valor agregado muy grande.

Capas de Seguridad Inteligentes en PHP – Saneamiento del array superglobal $_POST: Ese artículo habla sobre cosas muy particulares del funcionamiento de PHP, pero lo que me gustó es que es un caso de estudio real que la autora investigó, creo que es un buen ejemplo de cómo proceder para realizar una investigación seria. Además de que trata un tema interesante como es el filtrar los datos que nos envían de manera automática, con lo cual podemos aumentar en gran medida la seguridad y de forma no tan complicada, como también ayudarnos a que nuestra web mantenga un funcionamiento correcto.

Y este es un breve resumen que la autora nos brinda sobre la misma:


[Ingeniería Inversa] Desarrollar Software Aplicando la Ingeniería Inversa: el arte de la ciencia:
Básicamente en este artículo se explica "cómo pensar lateralmente" para lograr aplicar Ingeniería Inversa en el desarrollo de sistemas. No es un artículo para cualquiera pero para quiénes estén pensando en dar un gran salto en sus carreras, les puede significar el primer paso.

[Python Scripting] Manipular Archivos de Configuración Mediante ConfigParser:
ConfigParser es un módulo de Python que sirve para manipular archivos de configuración basados en secciones como los típicos .conf y .ini de fail2ban o PHP. Este artículo más que "artículo" terminó siendo un manual de ConfigParser y me atrevo a decir que es lo más completo que se pueda encontrar no solo en la Web sino también, comparado con libros de editorial.

[Ingeniería de Software] Agregado de archivos cron y ejecución periódica de procesos en los paquetes .deb: Si hay que le hacía falta a la serie de artículos sobre paquetes Debian, era algo que explicara exactamente, como manejan Debian los cron.daily,los cron.d y compañía. Este artículo no solo explica este manejo a nivel Debian como Sistema Operativo, sino que además, expone la forma en la cuál se pueden implementar scripts periódicos en los paquetes .deb.

[Europio Engine Lab] ¿cómo se hicieron los ABM de la Web “The Original Hacker Library”?: Un laboratorio basado en la biblioteca de la revista. Incluye TODOS los códigos de ejemplo!

[Seguridad Informática] Capas de Seguridad Inteligentes en PHP –
Saneamiento del array superglobal $_POST:
El pequeño artículo "casi" estrella de esta edición: los resultados de una investigación sobre como fusionar una "mala" característica de PHP con Inteligencia Artificial y obtener una capa de seguridad automatizada, capaz de identificar el tipo de datos que el programador espera, filtrarlos, limpiarlos y sanearlos y todo esto, sin que el programador deba escribir ni un byte de código. Un artículo imperdible!


Casi terminando este post, quiero comentar que realmente les recomiendo la lectura de la revista, y que si no son programadores PHP no se salteen los artículos donde utiliza ese lenguaje, porque sin importar cual sea el lenguaje que les guste utilizar, en esos artículos nos deja conceptos muy interesantes y nos abren la mente para pensar como verdaderos programadores.

Antes de terminar quería citar otra parte del mail que nos envió Eugenia, donde dice:

De verdad que me hace mucha ilusión poder seguir compartiendo el conocimiento de manera libre y siento que entre todos estamos demostrando que el egoísmo y la avaricia de lo privativo, no es el único medio al cual recurrir cuando se quiera información confiable.


Esto lo quería compartir, porque yo creo firmemente en lo mismo, y que la única forma de avanzar con esto, es aportando cada uno con lo que pueda. Yo intento hacerlo compartiendo algunas cosas en el blog, y otras con los grupo donde participo como Cultura Libre Rosario, el GDG Rosario y la lista de correo desarrolladores-android.

Espero que les allá gustado el post, y por supuesto la revista :D

Sitios:
http://culturalibrerosario.org

http://rosario.gtugs.org

Lista de correo:
http://desarrolladores-android.com

Esta es la web de The Original Hackers: http://originalhacker.org

Y pueden descargarla directamente desde aquí: Enlace


Saludos a todos, Gabriel

lunes, 2 de diciembre de 2013

Charla con el GDG Rosario en Njambre el día 26/11

Hola a todos, este post es solo para mostrar algunas de las imágenes y compartir los temas de los que hablamos en la última presentación del grupo GDG Rosario, donde se trataron las tecnologías AppEngine y AngularJS.

La charla de AngularJS la dio mi compañero Alejandro Felcaro, y yo hable sobre AppEngine.

Algunas fotos, Alejandro hablando sobre AngularJS





Algunos de los regalos para las personas que asistieron






Hablando sobre AppEngine


Estos son los enlaces a las presentaciones:
Presentación AppEngine
Presentación AngularJS

Sitios Oficiales sobre las herramientas:
https://developers.google.com/appengine/
http://angularjs.org/

Esperamos verlos en la próxima presentación del grupo, a los que asistieron espero que les haya gustado, y a los que no, seguro nos vemos en la próxima.
La URL del ejemplo de AppEngine es http://gdg-rosario-409.appspot.com , el código fuente esta basado en https://github.com/coto/gae-boilerplate
Como se comento en la charla, la idea principal de esto es poder reunir a la gente de Rosario que le interesan las nuevas tecnologías de Google, para que podamos aprender unos de otros, conseguir contactos, y básicamente ayudarnos entre todos a poder crecer juntos. 

También los invitamos a ver nuestra web http://rosario.gtugs.org/, seguirnos en el Perfil de G+ y unirse a la lista de correo

 Saludos a todos, Gabriel

viernes, 29 de noviembre de 2013

Como utilizar Robolectric y JUnit en AndroidStudio


El otro día en el trabajo, vi la necesidad de comenzar un proyecto Android, y tenía que ver cómo incorporar la librería Robolectric y JUnit para realizar los test del proyecto. Y como utilizo de IDE el Android Studio, vi que todavía no hay muchos tutoriales sobre este tema en español, así que me pareció bueno dejarlo plasmado en un post.  




Para poder utilizar esto, vamos a recibir la ayuda de Jake Wharton (responsable también de la librería ActionBarSherlock ) y a utilizar su plugin para Gradle, eso lo pueden encontrar acá :D
https://github.com/JakeWharton/gradle-android-test-plugin





Lo queden hacer entonces, será crear un proyecto Android con el Android Studio y modificar el archivo build.gradle para que les quede de una forma similar a esta:


buildscript {
    repositories {
        mavenCentral()
        maven {
            url 'https://oss.sonatype.org/content/repositories/snapshots/'
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.6.+'
        classpath 'com.squareup.gradle:gradle-android-test-plugin:0.9.1-SNAPSHOT'

    }
}
apply plugin: 'android'
apply plugin: 'android-test'

repositories {
    mavenCentral()
    maven {
            url 'https://oss.sonatype.org/content/repositories/snapshots/'
    }
}

android {
    compileSdkVersion 18
    buildToolsVersion "18.0.1"

    defaultConfig {
            minSdkVersion 15
            targetSdkVersion 19
    }

    buildTypes {

        release {
                runProguard true
                    proguardFile getDefaultProguardFile('proguard-android-optimize.txt')
            }
    }

    productFlavors {
            defaultFlavor {
                    proguardFile 'proguard-rules.txt'
            }
    }

    sourceSets {
            instrumentTest.setRoot('src/test')
    }
}

dependencies {

    testCompile 'junit:junit:4.10'
    testCompile 'org.robolectric:robolectric:2.1.+'
    testCompile 'com.squareup:fest-android:1.0.+'

    instrumentTestCompile 'junit:junit:4.10'
    instrumentTestCompile 'org.robolectric:robolectric:2.1.+'
    instrumentTestCompile 'com.squareup:fest-android:1.0.+'

}


Básicamente es agregar lo siguiente dentro de la sección buildscript:

maven {
            url 'https://oss.sonatype.org/content/repositories/snapshots/'

 
Y allí mismo en las dependencias:
classpath 'com.squareup.gradle:gradle-android-test-plugin:0.9.1-SNAPSHOT'

Después de eso agregamos el plugin con: apply plugin: 'android-test'

En la configuración de android, al final agregamos:

sourceSets {
            instrumentTest.setRoot('src/test')


 
Esto es para que Android Studio no busqué los test en la carpeta por defecto src/instrumentTest, y si lo haga en src/test

Y por último tenemos que agregar en nuestras dependencias las librerías que vamos a utilizar:

testCompile 'junit:junit:4.10'
testCompile 'org.robolectric:robolectric:2.1.+'
testCompile 'com.squareup:fest-android:1.0.+'

instrumentTestCompile 'junit:junit:4.10'
instrumentTestCompile 'org.robolectric:robolectric:2.1.+'
instrumentTestCompile 'com.squareup:fest-android:1.0.+'



Ya con eso, solo nos queda crear en la raíz de nuestro proyecto, dentro de la carpeta src, una llamada test, dentro de ella una java, para que quede de esta forma:




Casi por último sincronizamos el proyecto con gradle lo que nos va a descargar las librerías. Una vez que tengamos esto, para poder utilizar el framework Robolectric debemos agregar en cualquier parte de esa carpeta (test/java) una clase como esta:


import org.junit.runners.model.InitializationError;
import org.robolectric.AndroidManifest;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.res.Fs;

public class RobolectricGradleTestRunner extends RobolectricTestRunner {
    public RobolectricGradleTestRunner(Class<?> testClass) throws InitializationError {
        super(testClass);
    }

    @Override protected AndroidManifest getAppManifest(Config config) {
        String manifestProperty = System.getProperty("android.manifest");
        if (config.manifest().equals(Config.DEFAULT) && manifestProperty != null) {
            String resProperty = System.getProperty("android.resources");
            String assetsProperty = System.getProperty("android.assets");
            return new AndroidManifest(Fs.fileFromPath(manifestProperty), Fs.fileFromPath(resProperty),
                    Fs.fileFromPath(assetsProperty));
        }
        return super.getAppManifest(config);
    }
}


Ya con eso habremos terminado, ya podemos escribir nuestros test (siempre dentro del árbol de directorio bajo test/java ), este es un pequeño ejemplo de ello.

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.assertTrue;

@RunWith(RobolectricGradleTestRunner.class)
public class pruebaTest {

    @Test
    public void probandoTest(){
        assertTrue(true);
    }
}


Para correr los test solo necesitamos abrir la terminal dentro de la carpeta de nuestro proyecto y ejecutamos ./gradlew test (puede que la primera vez necesites darle permisos de ejecución al archivo con chmod +x gradlew) Si los test corren correctamente nos dira que BUILD SUCCESSFUL ;) en caso contrario (pueden probarlo colocando false en el anterior test) les mostrará el siguiente mensaje:
There were failing tests. See the report at:
Y una dirección de archivo, si lo colocan en un navegador web, podrán ver el informe de error y log de porque sucedió el mismo;)

Para trabajar y poder correr algunos test más interesante podrían hacer cosas como estas:


// Crear una activity
@Before
public void setup() {
    activity = Robolectric.buildActivity(MainActivity.class).get();
}

// comprobamos que no sean null las referencias que vamos a usar
@Test
public void noDebeSerNull() {
  assertThat(activity).isNotNull();

  TextView textView = (TextView) activity.findViewById(R.id.textView);
  assertThat(textView).isNotNull();

  Button button = (Button) activity.findViewById(R.id.button);
  assertThat(button).isNotNull();

  EditText editText = (EditText) activity.findViewById(R.id.editText);
  assertThat(editText).isNotNull();
}

// para luego poder comprobar cosas como esta
@Test
public void AccionAlPresionarBoton() {
  TextView textView = (TextView) activity.findViewById(R.id.textView);
  Button button = (Button) activity.findViewById(R.id.button);
  EditText editText = (EditText) activity.findViewById(R.id.editText);

  editText.setText("Hola");

  button.performClick();

  assertThat(textView).containsText("Hola, como estas?");
}


Espero que les sirva, creo que es una interesante forma de poder trabajar con el Android Studio, nos vemos en la próxima ;) 


P.D: Acá les dejo un ejemplo completo de un archivo de configuración gradle:
Gist: Archivo de configuración

Saludos a todos, Gabriel

jueves, 28 de noviembre de 2013

Script para el sorteo de remeras del ultimo GDG Rosario

Hola a todos, este post en realidad es una pavada que quería compartir :D
Para la última reunión del GDG Rosario, repartimos algunas remeras, y previo a eso no teníamos una forma de repartirlas de manera igualitaria, pensamos en un sorteo, pero no teníamos mucho tiempo ni números ni nada. Solo la lista de personas que se habían anotado en el formulario de inscripción. Por eso decidí armar un pequeño script en Python, así que lo comparto por si a alguno le sirve ;)




#!/usr/bin/env python
# -*- coding: utf-8 -*-
import random
import sys

listaDeNombres = ['Daniel King', 'Santiago Mazzucchelli', 'Mauro Zadunaisky', 'Victor Pezzetti','Cristian Tsakim','Bruno Piaggio','Sergio Gómez', 'Pablo Sanfilippo', 'Antonio Roman Lauriano', 'Esteban de la Peña', 'I. Nadir    Palacios', 'Sebastián Baskovich','Marisol Opreni', 'juan ignacio paccapelo', 'yoel pruss', 'Juan Manuel    Rodriguez Guerrero','Roger Alcivar', 'Matias Antola', 'German Andino', 'Erica Mendez', 'Miguel Angel Vides', 'Sebastián Vansteenkiste', 'Magali Kain', 'Aldo Ortiz', 'Fernando Uranga']


random.shuffle(listaDeNombres)

raw_input("Comenzamos el sorteo en el GDGRosario\n")


while True:
    if not listaDeNombres:
           print "\nSe finalizó la lista para el sorteo"
           sys.exit()


    print 'Ganador ' + listaDeNombres.pop()
   
    if listaDeNombres:
           raw_input("\nContinuamos el sorteo... \n")


Era solamente para eso, en este caso la lista de nombres la agregamos en el mismo fuente, porque eran pocas personas, para la próxima seguro lo mejoro un poco, y me molesto de tomarlo del mismo archivo de inscripción :D Espero que les sirva ;)

Saludos a todos, Gabriel

jueves, 21 de noviembre de 2013

Como puedo usar el logcat para ayudarme al debug de mi aplicación?

Hola a todos, como están en este pequeño post, voy a tratar un tema que le trae problemas normalmente al que recién comienza a desarrollar con Android. El mismo es como utilizar los logs para poder realizar un debug y hasta para poder preguntar en foros y lista de correo. Ya que la mejor forma de que te ayuden a resolver tu problema es que les muestres una salida del logcat correcta y con bastante información de lo que le sucede a la aplicación en el momento del error o del funcionamiento inapropiado de la misma (ya que no siempre son errores :D )



Para poder hacer esto vamos a utilizar el logcat y la clase Log que nos provee el mismo SDK de Android, no digo que esta forma sea la mejor, pero creo que es una medianamente correcta y que les ayudara bastante si no saben utilizarlo, voy a poner un ejemplo de código:

Supongamos que tenemos una función llamada inputStreamToString donde realizamos un catch, y en muchos casos veo que para eso realizan algo similar a esto:

 catch (IOException e) {
        // e.printStackTrace();
        Toast.makeText(getApplicationContext(),
          "Error..." + e.toString(), Toast.LENGTH_LONG).show();
       }

En vez de eso, lo correcto podría ser utilizar el logcat así:

catch (IOException e) {
    Log.e(TAG, "Error inputStreamToString " + e);  
}

Deben notar que utilizó Log.e, eso es porque se trata de un error, para debug podría ser Log.d, u otro tipo de salida, esto es útil para que el logcat te coloree de forma diferentes la salida, y sea más fácil poder seguirlo ;)

Dónde TAG debe ser un string, si ven el código fuente de Android normalmente este contiene la string del nombre de la clase, por ejemplo:

private static final String TAG = "Activity";


Para más referencias, la documentación oficial:

Esa forma de usarlo es buena para ver el logcat y saber de donde vienen los errores o filtrar por clases a los logs ;)

Ahora lo que deberían hacer, es usar logs en su código fuente :D por ejemplo: Log.d(TAG, "Datos que caen al listview " + datos); otro ejemplo Log.d(TAG, "Datos que tomo del webservice " + datos);

En resumen, el logcat no es solamente para ver errores, sino para saber qué datos toma del medio que sea, pasa tu aplicación de un lado a otro, o para ver cualquier información que creas que te resulte necesaria para entender qué le sucede a tu aplicación y así poder corregir tu código.

Este post a sido corto, más que nada es un tip para que les resulte más sencillo encontrar y así poder corregir los errores en sus aplicaciones, además de poder consultarles a otras personas y que están puedan ayudarlos. Espero que les allá sido de utilidad.

Saludos, Gabriel


martes, 5 de noviembre de 2013

The Original Hacker primera edición !!!

Hola a todos como están? Nuevamente escribiendo un post, pero este será un poco diferente a lo que estoy acostumbrado, generalmente escribo el contenido de los mismos. Pero en este caso les deseo presentar una revista que me pareció muy interesante para ayudar a difundir, la misma se llama "The Original Hacker", fue creada por Eugenia Bahit, y trae una serie de contenido muy interesante, paso a resumir un poco de que consta esta primera edición.

Python: habla sobre una utilidad muy interesante que trae el core de Python, para poder crear y manejar de forma muy sencilla los argumentos que podemos utilizar en nuestros programas ya sean Python o script de bash.

Patrones de diseño: en este caso habla sobre el patrón Adapter, donde muestra ejemplo reales de como y porque utilizarlo, mostrándolo con código Python y PHP.

Manejo de paquetes en distribución Linux: En este caso nos muestra como manejar nuestro propios script de instalación para paquetes Debian (comentario: muy bueno!!! :D )

Formularios Web y tablas HTML: nos muestra como crearlos de manera sencilla utilizando el framework Europio (es un framework creado por la misma autora, libre, y aunque no tengo conocimientos de PHP, parece funcionar muy bien)

Y por ultimo, uno de los temas que más me gustan, que es la seguridad informática, en este caso, trata la emulación de tokens temporales como mecanismo de verificación de usuarios. Realmente creo que el contenido no tiene desperdicio.



Este es un resumen, del motivo de la publicación de la misma, por parte de la autora Eugenia Bahit:


==============================
============

The Original Hacker es una nueva revista digital, de distribución
libre y gratuita, enfocada al Software Libre, al Hacking y a la
Programación. El nombre surge en homenaje a la definición original del
término "Hacker" dada por Richard Stallman en los años '70.-

La idea era lanzarla en paralelo a Hackers & Developers Magazine,
colocando todos los esfuerzos en que The Original Hacker se
convirtiese en un complemento para H&D (ya que sería mucho más pequeña
que ésta) y que, entre ambas revistas, se dieran difusión mutua.
Lamentablemente, la idea ni siquiera llegó a plantearse, que a menos
de 36 hs de anunciar mi salida de H&D, se desintegró el equipo por
completo.-

A fin de no dejar morir el esfuerzo de todos los que habíamos
trabajado en Hackers & Developers Magazine durante un año y al no
existiendo nadie dispuesto a continuar sosteniendo el proyecto, decidí
transformar a The Original Hacker en la continuación de Hackers &
Developers.

Esta nueva etapa -una especie de "segunda temporada"- de
publicaciones, plantea artículos orientados exclusivamente a
profesionales de nivel medio en adelante, lo que sumado a una temática
fija, la hace bastante diferente a Hackers & Developers. Los temas
propuestos en The Original Hacker son:
- Ingeniería Inversa (con enfoque en la Ingeniería Inversa de Código
aplicada al desarrollo de Software y análisis de vulnerabilidades)
- Ingeniería tradicional de Software
- Seguridad Informática
- Shell Scripting orientado a SysAdmins, auditores de seguridad y afines
- y laboratorio con Europio Engine

Si bien tanto la temática como el público objetivo de The Original
Hacker se modifica sutilmente con respecto al de Hackers & Developers
Magazine, se continúa conservando el espíritu de libertad en
referencia a la elección de tecnologías tratadas en la revista y de
ética profesional y responsabilidad social, con respecto al tipo de
información que será publicada.

El lanzamiento oficial será el próximo 5 de noviembre de 2013 y la
revista será publicada periódicamente, el primer martes de cada mes en www.originalhacker.org

Entre otras cosas, la Web contará con una hemeroteca donde se podrán
descargar todos los ejemplares de la revista y de la primera temporada
de Hackers & Developers Magazine.

================================

Sitio Oficial: http://originalhacker.org/

Descargar


Espero que les haya gustado el post y sobre todo, la revista por supuesto, para resumir y como comente anteriormente, la misma trae temas muy útiles e interesantes para el que no los conocía. Creo que puede ser una buena forma, para aquellos que tienen ya conocimientos en programación, el aprender nuevas técnicas de desarrollos y nuevas herramientas, como sus utilidades. Para finalizar y sin tener menor importancia, lo bueno del contenido de la misma es su licencia libre, como el de las herramientas que nos brinda.

Saludos a todos, Gabriel

martes, 27 de agosto de 2013

Como customizamos nuestras vistas con el BaseAdapter?

Hola a todos, en este post vamos a ver el tema de como generar nuestras propias vistas, implementando la clase BaseAdapter, por ejemplo para poder modificar la forma en la que se ve un ListView?





Bueno vamos a arrancar con algunas buenas prácticas para el uso de estos Adapters ;) la forma estándar por ejemplo para mostrar un ListView es usando un ListAdapter, ahora el tema esta en que tenemos varias formas de armar estos ListAdapter.


ArrayAdapter


Bueno normalmente cuando comenzamos a trabajar con ListView, y vemos los primeros tutoriales, generalmente nos dicen que la forma más sencilla de implementar este es usando un ArrayAdapter, lo que más adelante nos puede traer algún que otro dolor de cabeza :P Esto es, porque es tan sencillo que tiene muchas limitaciones, entonces para hacer pruebas todo funciona lindo :D pero cuando lo vamos a implementar en una app real, seguramente terminaremos insultando un poco :P


Entre estas limitaciones tenemos:
  • Solo podemos mostrar texto
  • Nos obliga a usar una lista de items de tipo CharSequence, o items que tengan implementados el método toString()
  • Nos obliga a utilizar un layout que solo contenga TextView
  • Nos bloquea cualquier actualización de la UI desde procesos que estén corriendo en background, esto es para asegurarse de ser Thread Safe pero obviamente nos quita mucha funcionalidad :P


Entonces? Este es el primer consejo, usar BaseAdapter :D


Así que generamos la clase que va a controlar la vista del ListView que extienda de BaseAdapter, ahora solo debemos implementar un par de métodos para que esto funcione, y un constructor. En este ejemplo, la clase Noticia es solo una clase POJO ;)


public class NoticiasAdapter extends BaseAdapter {


   private List<Noticia> noticias;
   private Context context;


   public NoticiasAdapter(Context context, List<Noticia> noticias){
       this.noticias = noticias;
       this.context = context;
   }


   @Override
   public int getCount() {
       return noticias.size();
   }


   @Override
   public Object getItem(int position) {
       return noticias.get(position);
   }


   @Override
   public long getItemId(int position) {
       return noticias.get(position).getIdNoticia();
   }


   @Override
   public View getView(int position, View convertView, ViewGroup parent) {


       // Este método, es el que debemos, implementar para nuestra vista ;)
      
       return null;
   }
}


Thread Safe


Como dije antes, el ArrayAdapter para asegurarse de ser Thread Safe directamente nos bloquea, eso esta bien pero existen otras maneras que seguramente nos resultaran más utiles, para asegurarnos que nuestro adapter sea utilizado por un unico hilo, el principal que maneja la UI.


Por ejemplo, podemos forzar de manera sencilla a que falle de manera rápida:


public void updateNoticias(List<Noticia> noticias) {
   ThreadPreconditions.checkOnMainThread();
   this.noticias = noticias;
   notifyDataSetChanged();
}


Y este es el resto del ejemplo de implementación:


public class ThreadPreconditions {
   public static void checkOnMainThread() {
       if (BuildConfig.DEBUG) {
           if (Thread.currentThread() != Looper.getMainLooper().getThread()) {
               throw new IllegalStateException("Este metodo deberia ser llamado por el hilo principal");
           }
       }
   }
}


Ahora lo más importante a implementar, el método getView() este podría ser un ejemplo:


@Override
public View getView(int position, View convertView, ViewGroup parent) {


   View rootView = LayoutInflater.from(context)
     .inflate(R.layout.noticias, parent, false);


   ImageView fotoView = (ImageView) rootView.findViewById(R.id.foto);
   TextView noticiaView = (TextView) rootView.findViewById(R.id.noticia);


   Noticia noticia = getItem(position);
   fotoView.setText(noticia.getFoto());
   noticiaView.setImageResource(noticia.getNoticia());


   return rootView;
}


También podríamos tener en cuenta que ListView recicla las vistas que no se muestran más, y nos las da de vuelta a través del objeto convertVIew, esto es un ejemplo de cómo podemos aprovecharlo:


@Override
public View getView(int position, View convertView, ViewGroup parent) {


   if (convertView == null) {
       convertView = LayoutInflater.from(context)
         .inflate(R.layout.noticias, parent, false);
   }


   ImageView fotoView = (ImageView) rootView.findViewById(R.id.foto);
   TextView noticiaView = (TextView) rootView.findViewById(R.id.noticia);


   Noticia noticia = getItem(position);
   fotoView.setText(noticia.getFoto());
   noticiaView.setImageResource(noticia.getNoticia());


   return rootView;
}


Un problemita con findViewById


Podemos tener un problema con este método, cada vez que el método getView es llamado, nos devuelve nuestro objetos por medio de findViewById, este es un ejemplo muy simplificado de cómo funciona:


public View findViewById(int id) {
   if (this.id == id) {
       return this;
   }
   for(View child : children) {
       View view = child.findViewById(id);
       if (view != null) {
           return view;
       }
   }
   return null;
}


Como se puede ver, este método navega a través de toda la jerarquía de la vista, hasta encontrar la vista que le pedimos y esto lo realiza cada vez que lo llamamos. Que esto sea un problema o no, va a depender mucho de nuestra aplicación y dispositivo en el que lo hagamos correr. Puede que no necesitemos la optimización, en caso contrario podemos utilizar el traceview y medir cuánto tiempo gastamos con el.


El patrón ViewHolder


Este patrón nos ayudará a limitar la cantidad de llamadas al método findViewById. La idea sería llamarlo una vez, y entonces guardar la vista hija a la que hace referencia en la instancia de ViewHolder que será asociada con el objeto convertView gracias al método View.setTag()


private static class ViewHolder {
   public final ImageView fotoView;
   public final TextView noticiaView;


   public ViewHolder(ImageView fotoView, TextView noticiaView) {
       this.fotoView = fotoView;
       this.noticiaView = noticiaView;
   }
}


@Override
public View getView(int position, View convertView, ViewGroup parent) {


   ImageView fotoView;
   TextView noticiaView;
   if (convertView == null) {
       convertView = LayoutInflater.from(context)
         .inflate(R.layout.noticias, parent, false);
       fotoView = (ImageView) convertView.findViewById(R.id.foto);
       noticiaView = (TextView) convertView.findViewById(R.id.noticia);
       convertView.setTag(new ViewHolder(fotoView, noticiaView));
   } else {
       ViewHolder viewHolder = (ViewHolder) convertView.getTag();
       fotoView = viewHolder.fotoView;
       noticiaView = viewHolder.noticiaView;
   }


   Foto foto = getItem(position);
   noticiaView.setText(foto.getNoticia());
   fotoView.setImageResource(foto.getFoto());


   return convertView;
}


Tag con el ID?


Una alternativa al patrón anterior, que podemos comenzar a usar desde la versión de la API 15 (Android 4) No es recomendable utilizarlo con versiones anteriores.


Ahora el ejemplo:


@Override
public View getView(int position, View convertView, ViewGroup parent) {


   ImageView fotoView;
   TextView noticiaView;
   if (convertView == null) {
       convertView = LayoutInflater.from(context)
         .inflate(R.layout.noticias, parent, false);
       fotoView = (ImageView) convertView.findViewById(R.id.foto);
       noticiaView = (TextView) convertView.findViewById(R.id.noticia);
       convertView.setTag(R.id.foto, fotoView);
       convertView.setTag(R.id.noticia, noticiaView);
   } else {
       fotoView = (ImageView) convertView.getTag(R.id.foto);
       noticiaView = (TextView) convertView.getTag(R.id.noticia);
   }


   Foto foto = getItem(position);
   noticiaView.setText(foto.getNoticia());
   fotoView.setImageResource(foto.getFoto());


   return convertView;
}



ViewGroup personalizado


Con esta tercera opción, obtendremos un mejor desacoplamiento ;)


@Override
public View getView(int position, View convertView, ViewGroup parent) {
   FotoNoticiaView fotoNoticiaView;
   if (convertView == null) {
       fotoNoticiaView = (FotoNoticiaView) LayoutInflater.from(context)
         .inflate(R.layout.foto_noticia, parent, false);
   } else {
       fotoNoticiaView = (FotoNoticiaView) convertView;
   }


   FotoNoticia fotoNoticia = getItem(position);


   fotoNoticiaView.update(fotoNoticia);


   return convertView;
}



Benoît Lubek en la red social G+, enlace que dejaré más abajo, sugirió otro enfoque que puede ser bastante interesante, por las dudas se los dejo acá :D


public class ViewHolder {
   // He añadido un tipo de retorno genéricos para reducir el ruido que genera el casting   
  // en el código del cliente
   @SuppressWarnings("unchecked")
   public static <T extends View> T get(View view, int id) {
       SparseArray<View> viewHolder = (SparseArray<View>) view.getTag();
       if (viewHolder == null) {
           viewHolder = new SparseArray<View>();
           view.setTag(viewHolder);
       }
       View childView = viewHolder.get(id);
       if (childView == null) {
           childView = view.findViewById(id);
           viewHolder.put(id, childView);
       }
       return (T) childView;
   }
}


Y esta sería la implementación del método getView:


@Override
public View getView(int position, View convertView, ViewGroup parent) {


   if (convertView == null) {
       convertView = LayoutInflater.from(context)
         .inflate(R.layout.foto_notocia, parent, false);
   }


   ImageView fotoView = ViewHolder.get(convertView, R.id.foto);
   TextView noticiaView = ViewHolder.get(convertView, R.id.noticia);


   FotoNoticia fotoNoticia = getItem(position);
   noticiaView.setText(fotoNoticia.getNoticia());
   fotoView.setImageResource(fotoNoticia.getFoto());


   return convertView;
}



Sitio Oficial:


Sitio no-oficial:



Esto fue todo por ahora, espero que les guste y sea de utilidad, realmente puede ser un poco complicado al principio, y nos den ganas de usar ArrayAdapter :D pero una vez que se acostumbran, se van a dar cuenta que es lo mejor y que es bastante sencillo implementarlo.

Saludos a todos, Gabriel