Otro de mis pequeños proyectos

Etiqueta: Programación

El patito de goma como método de debug

Uno de los métodos más baratos y conocido para hacer debugging «en parejas» es el método denominado «el patito de goma». Creo que esta es la primera vez que se habla sobre él.

Es realmente sencillo y he tenido he podido comprobar (conmigo y con otros) como la eficacia de este método es elevadí­sima. Hay que seguir unos sencillos pasos:

  1. Conseguir un patito de goma, preferiblemente variedad baño (aunque se aceptan versiones tipo pirata, Sherlock Holmes o incluso ¡diablo!)
  2. Colocar el patito cerca nuestra, en el escritorio por ejemplo e informarle que vais a ver un poco de código, a ver si está de acuerdo.
  3. Explicar al pato qué es lo que se supone que hace el código y tras esto, entrar en detalle explicándolo lí­nea a lí­nea.
  4. En algún momento le dirás al patito lo que se supone que es lo siguiente a hacer y te darás cuenta que eso no es lo que realmente está haciendo tu código. El pato se mantendrá sentado serenamente, contento de saber que te ha ayudado en tu tarea.

Existen variantes al patito de goma, como otro tipo de peluches y objetos, pero su efectividad no está tan demostrada como con el patito de goma.

Configurar el fichero hosts de Android Emulator

Es posible que te encuentres en la situación (doy un par de ejemplos más abajo) en los que necesites que tu Android Emulator haga caso a tu /etc/hosts en vez de al DNS. Para este caso, lo que tienes que hacer es seguir estos dos sencillos pasos:

  1. Crear un fichero hosts en tu ordenador (o usar el que ya tienes en /etc/hosts)
  2. Remontar el emulador y copiar el fichero anterior

La necesidad de remontar viene porque si no, el dispositivo está como sólo lectura y por lo tanto es imposible escribir nada en él.

Supongamos que tenemos partimos de nuestro /etc/hosts, irí­amos al directorio donde tenemos las tools del SDK y teclearí­amos:

adb remount
adb push /etc/hosts /system/etc/

También es posible coger el fichero hosts que tiene el emulador (por ejemplo, copiandolo a nuestro directorio /tmp):

adb push /system/etc/hosts /tmp

¿Y en qué casos nos puede hacer falta? Bueno, yo en concreto lo he necesitado cuando estaba desarrollando una aplicación que se alimentaba de un webservice. Realizaba el desarrollo del webservice en paralelo y por lo tanto no estaba (todaví­a) en la máquina de producción. De esta forma, gracias al fichero hosts obligaba al emulador a buscar en mi entorno de desarrollo en vez de ir al de producción, haciendo que la aplicación tuviese un comportamiento transparente, en código, sobre dónde atacar.

Return no numérico en funciones bash

Por defecto en bash sólo se pueden retornar enteros. ¿Qué hay que hacer entonces para que retorne un valor no entero?

El truco está en hacer un echo del valor y asegurarnos en la llamada de la función que se asigna a una variable. Es decir, nuestra función serí­a:

function retorna_texto {
 echo -n "este es el valor a retornar"
}

Y la llamada:

VALOR=$( retorna_texto )

Ahora en ${VALOR} tendremos el texto tal y como querí­amos

XHP: una extensión para escribir PHP de forma distinta

Una de las noticias de esta semana en el mundo PHP es sin duda toda la información acerca de HipHop for PHP por parte del equipo de desarrollo de Facebook. Una de las extensiones que ha salido a la luz por parte del equipo de front-end es la que han llamado XHP y, como ellos mismos rezan, «a new way to write PHP» (una nueva forma de escribir PHP).

La explicación de cómo funciona es muy sencilla. Intentan evitar que al desarrollar la parte de frontal, cuando nos «pegamos» con el XHTML, tengamos que unir código XHTML y PHP. En el ejemplo que muestran se ve más claramente.

De un código como:


 Hello, .

 
What is your name?

Nos da como opción generar este otro:

Hello, {$_POST['name']};
} else {
 echo
 
What is your name?
; }

No voy a negar que, de primeras, XHP parece más sencillo de seguir y de generar. Eliminar los tags de apertura y cierra de PHP aligera el código en gran medida. Además, eliminamos problemas con el XSS así­ como detectar problemas por malformación de XHTML en tiempo de parsing.

A mi personalmente me sigue gustando bastante más usar un motor de plantillas. Un motor real como XTemplates (sí­, he dicho XTemplates, no smarty o similares). Separar el código PHP del HTML me parece bastante importante y necesito verlo con más claridad.

No obstante, hay que seguir el tema de cerca. Si es algo que la gente de Facebook ha visto que es necesario ya que aumenta el rendimiento, es evidente que en este tipo de entornos será uno de los puntos de referencia. Sin embargo, XHP como técnica para el resto de las webs donde no se reciban tantas peticiones como Facebook (si no recuerdo mal, sirven más doscientas mil millones de páginas al mes, sí­, sí­, 200.000.000.000), es posible que un objetivo que cumpla a primera vista es juntar el PHP con el HTML, algo que, repito, me parece bastante "sucio" si no hay una justificación clara. Pos supuesto, un motor de plantillas tiene sus desventajas, no vamos a negarlo 🙂

Lo dicho, XHP de momento me parece algo que puede provocar que el código sea más rápido pero a costa de hacerlo más guarro. Habrá que seguirle la pista para ver por dónde avanza, no lo descarto de primeras porque el objetivo de aumentar el rendimiento es muy importante, pero analizando el coste (ni monetario ni de recursos en este caso, jeje).

Enlaces:

Update: Muy muy muy interesante lo que comenta Rasmus en su web. Importante verlo.

Una forma sencilla de hacer bien las cosas

Para romper este «silencio» de casi un mes debido a la Navarparty y al trabajo, volvamos a la carga con un pequeño post.

Quiero tratar el tema de «cómo hacer bien las cosas programando» con un sencillo ejemplo que pasó el otro dí­a por mis manos. Y para ello contaremos con dos actores, un array y un if. Supongamos que tenemos los siguientes datos:

$a = array
 array('from' => 0, 'to' => 100),
 array('from' => 101, 'to' => 250),
 array('from' => 250, 'to' => 1000),
 array('from' => 1001, 'to' => 2000)
);

Nuestro sencillo código va a retornar el í­ndice del array $a en el que se encuentra un número $b. Ahora bien, tenemos dos formas de hacerlo:

Opción a:

function getRange($b) {
 foreach($a AS $index => $actual) {
 if($actual['from'] <= $b && $actual['to'] >= $b) {
 return $index;
 }
 }
}

Opción b:

function getRange($b) {
 foreach($a AS $index => $actual) {
 if($actual['to'] >= $b && $actual['from'] <= $b) {
 return $index;
 }
 }
}

El único cambio es el if que, como se puede ver, cambia el orden de las condiciones.

Entonces, hacemos la pregunta, ¿cuál de las dos opciones es más eficiente? Es posible que no lo veas claro, pero si lo miras un poco veras como en la mayorí­a de los casos es la opción b. Únicamente son igual de eficientes cuando $b se encuentra entre los valores de la primera posición.

¿Y por qué es más eficiente la opción b? La respuesta es porque dentro del if, al tener un Y lógico (los dos ampersands &&) si la primera condición es falsa, la otra condición ni siquiera se evalúa. Es decir, nos ahorramos que el microprocesador tenga que hacer esa comprobación lógica. Y este caso se da si pensamos que $b = 150. Para la opción a el if tiene que ejecutar ambas condiciones (0 <= 150 && 100 >= 150) para descubrir que es false y pasar a la siguiente iteración, mientras que con la opción b bastarí­a con la primera comprobación (100 >= 150) para saber que es false y pasar a la siguiente iteración.

Si se hace este if una única vez estamos hablando de una parte muy pequeña de un segundo, pero si esta tarea es muy repetitiva o el array tiene muchas posiciones, el efecto es claramente favorable e incluso se puede notar directamente.

Este sencillo ejemplo demuestra como pensar un poco las cosas y cambios muy pequeños en tu código pueden hacer que tengas un código mucho más optimizado y que te de mayor rendimiento.

Y por si quieres rizar el rizo, la opción a puede ser más eficiente que la b, pero sólo en el caso de que se recorra el array de forma descendente o este ordenado de forma inversa.

5 expresiones regulares que todo programador web deberí­a conocer

Extraigo de I’m Mike un artí­culo bastante interesante 5 expresiones regulares (también llamadas regexp) que deberí­as conocer si eres programador web.

Bien es sabido por los que me conocen que considero las expresiones regulares como uno de los mejores método que se han inventado para los programadores (y en general, para cualquier persona que quiera comprobar si una cadena de caracteres cumple ciertas caracterí­sticas y posibilidades). Como definió @acidonitrix en su momento: en todas las empresas hay algún loco que le encantan las expresiones regulares; pues bien, ¡ese es mi caso! (Ya me lo haré mirar algún dí­a, pero de momento no molesta)

Pues bien, las 5 expresiones que Mike comenta son las siguientes

Comprobar un nombre de usuario

Esta es la más sencilla de todas. Comprueba si el nombre de usuario está compuesto únicamente por letras, mayúsculas o minúsculas, números de 0 a 9 o el guión bajo (underscore) y cuya longitud total sea entre 3 y 16 caracteres.

/^[a-zA-Z0-9_]{3,16}$/

Buscar una etiqueta HTML/XHTML

Partiendo del ejemplo de querer buscar la etiqueta tag aquí­ coincido con Mike en que la mejor forma (de las varias y farragosas que existen) es usar lo que se denomina un «cuantificador vago» (lazy quantifier) para obtener todo el contenido de la etiqueta.

/]*>(.*?)<\/tag>/

Existen otras soluciones, pero ninguna tan directa como esta. Podrí­amos buscar el contenido por [^>]*, pero eso nos obligarí­a a post-procesar el resultado ya que es posible que dentro de esa etiqueta tengamos otra.

Buscar una etiqueta HTML/XHTML con cierto atributo y valor en su interior

Esta expresión es algo más compleja y usa las referencias (matching backreference) que son los \\1 y \\2 para buscar el tag y la comilla o las dobles comillas que cierran el valor del atributo. Este truco también se podí­a haber usado antes, pero yo creo que queda más claro así­.

Para este ejemplo, supongamos que se quiere buscar la etiqueta tag, el atributo attribute y el valor value:

/]*attribute\s*=\s*(["'])value\\2[^>]*>(.*?)<\/\\1>/

Cuando incluyáis esta regexp en PHP, tened cuidado en escapar una de las dos, según el carácter que uséis para crear la cadena de texto. Por ejemplo:

preg_match('/]*attribute\s*=\s*(["\'])value\\2[^>]*>(.*?)<\/\\1>/', $text, $matches)

Tengo que reconocer que esta expresión como esta no la he usado apenas. Las veces que he tenido que buscar algún atributo, solí­a ser más de uno o más complejo que una simple asignación y, partiendo del ejemplo anterior, el de buscar una etiqueta HTML/XHTML, procesaba el resultado.

Comprobar una dirección de correo electrónico

Esto ya son palabras mayores. La solución que se plantea, dada por Cal Henderson, cumple con la RFC 822 que define cómo son las direcciones de correo electrónico. Poco más se puede añadir, no hay nada más completo:

function is_valid_email_address($email){
 $qtext = '[^\\\x22\\x5c\-\ÿ]';
 $dtext = '[^\\\x5b-\\x5d\-\ÿ]';
 $atom = '[^\-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c'.
 '\\x3e\\x40\\x5b-\\x5d\\x7f-\ÿ]+';
 $quoted_pair = '\\x5c[\-\\x7f]';
 $domain_literal = "\\x5b($dtext|$quoted_pair)*\\x5d";
 $quoted_string = "\\x22($qtext|$quoted_pair)*\\x22";
 $domain_ref = $atom;
 $sub_domain = "($domain_ref|$domain_literal)";
 $word = "($atom|$quoted_string)";
 $domain = "$sub_domain(\\x2e$sub_domain)*";
 $local_part = "$word(\\x2e$word)*";
 $addr_spec = "$local_part\\x40$domain";

 return preg_match("!^$addr_spec$!", $email) ? 1 : 0;
}

Comprabando una URL

En mi sincera opinión, crear una regla genérica para comprobar una URL es un berenjenal horrible. Hace falta realizar alguna particularización. Seguidamente os pongo el código de I’m Mike.

{
 \\b
 # Match the leading part (proto://hostname, or just hostname)
 (
 # http://, or https:// leading part
 (https?)://[-\\w]+(\\.\\w[-\\w]*)+
 |
 # or, try to find a hostname with more specific sub-expression
 (?i: [a-z0-9] (?:[-a-z0-9]*[a-z0-9])? \\. )+ # sub domains
 # Now ending .com, etc. For these, require lowercase
 (?-i: com\\b
 | edu\\b
 | biz\\b
 | gov\\b
 | in(?:t|fo)\\b # .int or .info
 | mil\\b
 | net\\b
 | org\\b
 | [a-z][a-z]\\.[a-z][a-z]\\b # two-letter country code
 )
 )

 # Allow an optional port number
 ( : \\d+ )?

 # The rest of the URL is optional, and begins with /
 (
 /
 # The rest are heuristics for what seems to work well
 [^.!,?;"\\'<>()\[\]\{\}\s\x7F-\ÿ]*
 (
 [.!,?]+ [^.!,?;"\\'<>()\\[\\]\{\\}\s\\x7F-\ÿ]+
 )*
 )?
}ix

Como se puede comprobar es realmente una tarea complicada y, aunque esta regexp funciona bastante bien para la amplia mayorí­a de casos, hay TLD que se deja como por ejemplo .name, .travel, etc.

Y de momento dejo el post aquí­, ya que tengo en marcha otro sobre expresiones regulares que llegará en breve.

Update: ya tengo mi propio post sobre expresiones regulares

Euskal Encounter 17

Ya es bien conocido que del pasado 23 al 26 de julio se celebró la Euskal Encounter 17 en el BEC! de Bilbao. Otro año más, y ya son unos cuantos, tuve la suerte de poder asistir rodeado de buenos colegas. Por un problema u otro no pudieron estar todos los habituales, pero aprovechamos todo lo que se pudo.

Hay poco que decir de la Euskal Encounter a estas alturas. Todo perfecto. Me recuerda a la Navarparty (risa malévola). La red funcionó bien en todo momento, al igual que la conexión a internet, menos un par de cortes puntuales y totalmente perdonables que se solucionaron en cuestión de segundos. Muchas competiciones de todo tipo, de las llamadas oficiales, extraoficiales y un sin fin de pequeñas competiciones que animaban mucho el ambiente. Incluido un ImproveEverywhere basado en una grabación MP3 como ya hemos podido ver unos cuantos por ahí­.

Además, este año decidimos ir Garath y yo, junto con la gente de DiarioLinux a jugar a un laser tag! Nos lo pasamos en grande y descargamos un poco de adrenalina. Jugamos dos batallas, en la primera estuvimos 15 personas y 10 en la segunda. En Pamplona hace ya unos años estaba el famoso Qzar que ya desapareció, aunque donde estuvimos tení­a que ser de la misma casa. Me esperaba que la partida fuese más cara, pero por 6 euros podí­as jugar 20 minutos, no estuvo nada mal. Si me dicen de ir el año que viene, repetiré.

Y bueno, este año por fin, tras varios de sequí­a, hemos conseguido algunos premios con los que nos volvimos contentos para casa. En particular, un tercer puesto en el Hack-it de mano principalmente de Ontza, dueño y señor de la prueba en nuestro grupo al que ayudamos en lo que buenamente pudimos cada uno. La prueba estuvo muy reñida en todo momento y hay que reconocer la gran labor de Ontza que, participando de forma individual, consigió este magní­fico tercer puesto (y 150 euros que no vienen nada mal).

Y no puedo dejar pasar (que no quepo de gozo en mi), también logramos un segundo puesto en la prueba de FOSS Coding que me llevé yo personalmente. Se trataba de una prueba de programación rápida (24 horas) al que me presenté de forma individual (se podí­a también en grupos de 2, 3 ó 4 personas) y tras darle algunas vueltas decidí­ presentarme y probar suerte ya que no esperaba demasiado ya que apenas estuve programando 6 ó 7 horas. Pero tuve la suerte de no presentar código incompleto, error que cometieron otros grupos y así­ llevarme una magní­fica GP2x Wiz, tarjeta de 4GB y accesorios varios. Estoy esperando a ver si publican los código y así­ ver qué otros códigos se presentaron, incluyendo el primer premio que tuvieron que repartir entre los dos componentes del grupo.

Y he aquí­ a los ganadores del FOSS Coding de la Euskal Encounter 17

Y he aquí­ a los ganadores del FOSS Coding de la Euskal Encounter 17

Y volvimos contentos. Algunos todaví­a más, jeje. Con la entrada amortizada, unos muy buenos ratos pasados en compañí­a de buenos colegas, esperaremos a la llegada de la Navarparty.

Lectura de datos binarios en perl

Hace un par de dí­as me encontré en la situación de leer datos de un fichero en formato binario. Este tipo de ficheros, al contrario que uno de texto, la separación no viene dada mediante saltos de lí­nea (prácticamente todos los lenguajes de programación tiene funciones para leer lí­nea a lí­nea), sino que o bien se tiene una cabecera donde se indica el tamaño y formato de la información o, como es mi caso, tení­a que leer en bloques de 32 caracteres (16 palabras de dos caracteres, es decir, 16 palabras de 16 bits).

Para hacer esto con Perl, es tan sencillo como iniciar el método binario en el fichero mediante binmode.

El programa es similar a este (en $filein tenemos el nombre del fichero):
open INF, $filein
or die "\nNo se puede abrir $filein para leer: $!\n";
# Activamos el modo binario para el fichero
binmode INF
# Leemos 32 bytes y los metemos en $buffer
while (read INF, $buffer, 32) {
# Aquí­ trabajamos con los datos, en mi caso, 32 bytes
}
close INF
or die "No se ha podido cerrar $fiein: $!\n";

Realmente sencillo (y rápido).