coge la información y corre

Defensa a ultranza del Software Libre

25 de Noviembre del 2009 Escrito por Alex Barros

En una discusión con el equipo de desarrollo del índice de dificultad IBP Index, en el que les sugiero que liberen su código por ser un proyecto sin ánimo de lucro, y con interés por propagarse (dos razones de peso para liberar código), me contestaron algo así como

entendemos la idea, pero no queremos que surjan 100.000 versiones distintas y así perder el ser un referente como índice de dificultad

(La cita no es literal)

El planteamiento de entrada me parece absurdo. No veo ningún interés en clonar el código y alterar los parámetros para ofrecer el mismo producto. No es interesante ni para el que lo ofrece, ni mucho menos para los usuarios, que preferirán “el que usa la mayoría”

Por eso me he dedicado a redactarles una respuesta que me ha llevado tanto de escribir que quiero compartirlo en éste mi blog:

Disculpad el tono de los anteriores mails. Resulta muy frustrante trabajar con tan poca documentación, más aún cuando mi tiempo para dedicar es escaso, al ser una contribución altruista.

Sigo sin estar de acuerdo con vuestro planteamiento, estoy seguro de que es fruto de un prejuicio, muy común en programadores y equipos que nunca han liberado código. Y me explico: una vez se da el paso de liberar un código, como es el caso del cálculo del índice IBP, planteamientos típicos son:

  • “me van a robar el código”
  • “no van a respetar la licencia que le ponga”
  • “van a surgir 100.000 versiones diferentes que acapararán mi target o mi público potencial, desbancándome”
  • “perderé la ilusión ante esta situación de caos”

Sin embargo, la realidad es siempre muy distinta. Los hechos del software libre son:

  • Consigues que otros programadores aporten ideas, en ocasiones brillantes, para que el software mejore más rápido y trabaje de forma más eficiente. Se llegan a conseguir dinámicas de trabajo muy potentes en algunos proyectos libres
  • La licencia es respetada en el 99% de los casos. Por norma, el 1% que no respeta tu licencia no consigue la más mínima repercusión y es muy fácil olvidarse de estos caso por lamentables y anecdóticos.
  • Nunca salen 100.000 versiones de un proyecto libre. De hecho, casi nunca hay dos proyectos que hagan lo mismo. Lo que sí es común es un fenómeno llamado “bifurcación” (o fork en inglés) que consiste en crear un proyecto nuevo basándose en otro, pero con objetivos distintos. Ésto, lejos de perjudicar a los usuarios (por ejemplo con muchos índices diferentes para calcular dificultad en rutas de montaña) lo que hace es beneficiarles, ya que son alternativas al proyecto padre, pero adaptadas a otro objetivo (por ejemplo adaptar IBP para calcular la dificultad de un trazado en la luna destinado a robots motorizados). Tened en cuenta que si licenciáis el código bajo GNU/GPL todo fork está OBLIGADO a liberar también su código, una licencia libre es un documento legal y su incumplimiento un hecho demandable ante la ley.
  • Lejos de perder la ilusión, suele resultar una inyección de motivación. Recibes sugerencias y trackback de compañeros programadores que te ayudan a mejorar el software y a plantearte nuevas ideas y nuevas formas de enfrentar los problemas. La comunidad de programadores es siempre muy activa y respetuosa.

Por último, ofrezco algunos ejemplos de éxito rotundo del software de código abierto: enciclopedia Wikipedia, servidores Apache, lenguaje PHP, sistema operativo Ubuntu, navegador Firefox, sistema de gestión de blogs Wordpress y podría continuar con miles de proyectos que han alcanzado un éxito más que evidente gracias a ser código abierto. Caso similar son las aplicaciones de software privativo que fundamentan sus sistemas con Software Libre (véase YouTube, Flickr, Wikiloc, Google, etc…)

Espero que os lo volváis a plantear, una vez más o las que hagan falta (me podéis plantear cualquier duda del tema), y que superéis los miedos; porque más allá del código lo que realmente tiene valor son las ideas, y nadie os va a hacer sombra si tenéis una comunidad apoyándoos (que la tenéis) y si vosotros, junto con otros programadores que crean en el proyecto, mantenéis IBP como un software actualizado, versátil y de calidad.

También quería comentaros que finalmente he creado una clase en PHP para Gpsia que administra las llamadas a IBP. Es software libre por lo que no sólo podéis publicarlo en vuestra web, sinó que en cierta forma es un compromiso el distribuirlo. Os lo adjunto.

Un saludo, y gracias por vuestra atención.

Por cierto, el código es éste:

ibp.class.php

  1. <?php
  2. // Class for getting the IBPIndex given a local filename, further information on http://www.ibpindex.com
  3. // By Alex Barros for Gpsia software. License: GNU/GPL v3
  4. // Requirements: PHP + Curl
  5.  
  6.  
  7. define(‘IBP_TMP’, ‘/tmp’); //temporary folder with 777 chmod permission
  8.  
  9. class IBP {
  10.     var $filename; //Source filename
  11.     var $ibp; //Resoult: NN XX (N=number X =alphabetic)
  12.    
  13.     function IBP($filename = false){ //Constructor
  14.         if(!empty($filename)) $this->getIBP($filename);
  15.     }
  16.     function getIBP($filename) {
  17.         if(strlen(basename($filename)) > 55) { //filenames are limited
  18.             $filename = $this->shortenName($filename); //Makes a copy with shorter filename in the temporary folder
  19.             $isTmp = true;
  20.         }
  21.        
  22.         $this->filename = $filename;
  23.        
  24.         if(file_exists($filename)) {
  25.             //Post fields
  26.             $post_data = array();
  27.             $post_data[‘fichero’] = "@$filename";
  28.  
  29.             $post_data[‘MOD’] = ‘BTT’;
  30.             $post_data[‘UDO’] = ‘Gpsia’;
  31.            
  32.             //Curl connection
  33.  
  34.             $ch = curl_init();
  35.             curl_setopt($ch, CURLOPT_URL, "http://www.ibpindex.com/esp/ibpresponse.asp" );
  36.             curl_setopt($ch, CURLOPT_POST, 1 );
  37.             curl_setopt($ch, CURLOPT_HEADER, 0);
  38.             curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); //Needed because redirection is used on the app
  39.  
  40.             curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
  41.             curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  42.             $postResult = curl_exec($ch); //return result
  43.            
  44.             if (curl_errno($ch)) {
  45.                 die(curl_error($ch)); //this stops the execution under a Curl failure
  46.             }
  47.            
  48.             curl_close($ch); //close connection
  49.            
  50.             $this->ibp = $postResult;
  51.            
  52.             if($isTmp) @unlink($filename); //remove temporary file
  53.            
  54.             return $postResult;
  55.         }
  56.     }
  57.     function shortenName($filename) {
  58.         $newName = IBP_TMP.‘/IBP-’.substr(basename($filename),-20); //new shorter temporary filename
  59.         if(file_put_contents($newName, file_get_contents($filename)))
  60.             return $newName;
  61.         return false;
  62.     }
  63. }
  64.  
  65. // usage: $ibp = new IBP(’path/to/file.gpx’); echo $ibp->ibp; //Returns something like 696 AB
  66.  
  67. ?>

Categorias: Sin categoría | 4 comentarios »

Múltiples join y solución al encadenar LEFT JOINS

5 de Noviembre del 2009 Escrito por Alex Barros

Desde que publiqué el artículo de Inner Join para unir tablas y más especialmente el de Explicación visual de los SQL Join – Unir tablas con SQL me han consultado en muchos comentarios cómo hacer múltiples JOIN en una sóla consulta.

Hasta hoy no lo había necesitado, y nunca supe contestar. Hasta hoy.

Encadenar Joins es tan simple como ponerlos uno a continuación de otro.
ejemplo:

  1. SELECT A.*, B.*, C.id FROM tabla_a A
  2. INNER JOIN tabla_b B ON A.id = B.foo
  3. LEFT JOIN tabla_c C ON A.id = C.bar

Y así sucesivamente. Puedes tener tantos joins como necesites, y si es necesario jugar con los paréntesis para cambiar la preferencia (por defecto MySQL lee de izquierda a derecha).

Pero una vez esto aclarado, me he encontrado con un problema. Lo que yo quería hacer es una serie de LEFT JOINs para consultar en una serie de tablas la cantidad (COUNT()) de registros de otras tablas que estaban asociados a la clave primaria de una tabla principal.

En mi caso concreto, tengo una serie de Rutas de bicicleta en una tabla, y en otras tablas satélite tengo almacenados los comentarios asociados a la ruta, las votaciones, los archivos adjuntos, etc… de modo que haciendo un COUNT en estas tablas para cada una de las claves primarias de la principal (Rutas) me saldría la cantidad asociada.

Así que hice algo como esto:

  1. SELECT R.*, COUNT(C.id) comments, COUNT(S.id) saved, COUNT(V.id) votes, COUNT(P.id) photos, U.name owner, U.mail, U.about, U.image avatar, U.authority
  2.  
  3. FROM geo_routes R
  4. LEFT JOIN geo_comments_routes C ON R.id = C.cid
  5. LEFT JOIN geo_saved S ON R.id = S.route
  6. LEFT JOIN geo_votes V ON R.id = V.route
  7. LEFT JOIN geo_photos P ON R.id = P.route
  8. LEFT JOIN geo_users U ON U.id = R.property
  9.  
  10. GROUP BY R.id

Pero esta consulta no daba valores correctos, sinó que en estos campos COUNT aparecía generalmente el mismo número replicado.

La solución es usar la cláusula DISTINCT en los COUNT, ya que en cada uno de los LEFT JOIN se están asociando muchos campos a cada registro de la tabla principal, y si no especificas el que te interesa cuántos DISTINTOS hay (y no sólo cuántos hay) te hincha la cifra o simplemente te la altera.

De modo que mi consulta ha quedado así:

  1. SELECT R.*, COUNT(DISTINCT C.id) comments, COUNT(DISTINCT S.id) saved, COUNT(DISTINCT V.id) votes, COUNT(DISTINCT P.id) photos, U.name owner, U.mail, U.about, U.image avatar, U.authority
  2.  
  3. FROM geo_routes R
  4. LEFT JOIN geo_comments_routes C ON R.id = C.cid
  5. LEFT JOIN geo_saved S ON R.id = S.route
  6. LEFT JOIN geo_votes V ON R.id = V.route
  7. LEFT JOIN geo_photos P ON R.id = P.route
  8. LEFT JOIN geo_users U ON U.id = R.property
  9.  
  10. GROUP BY R.id

Después he asociado a esta consulta una Vista, para poder tratarla como si fuera una tabla con esos campos ya incluidos.

Espero que estos consejos os puedan servir de mucho! A mi me ha costado mucho dar con las respuestas.

Categorias: Boozox | 8 comentarios »

del.icio.us meneame.net RSS

Buscar:

Gpsia Descubre y comparte rutas por todo el mundo, tomadas con GPS. Ver más Imaset Edita tus imágenes de Wordpress con este sencillo plugin. Ver más

¡Mi música es tuya!

Digo yo que...

Mis fotos de Flickr

Entradas Recientes

Meta:

Respeta el copyleft

,