miércoles, 26 de mayo de 2010

Escogiendo números al azar o RTFA

Hoy un mensaje breve y al grano, para ilustrar la importancia de perder un rato investigando el API de Java, que es muy rico y uno de las mejores cosas que tiene el lenguaje (vale, no es perfecto y tiene algunas cagadas *ehem* Date *ehem* pero te da muchas cosas hechas).

El problema planteado es el típico que sale habitualmente en foros de "escoger X números entre Y posibles de forma aleatoria y sin repeticiones". Una especie de Lotería Primitiva, vamos. Las soluciones habituales suelen tender a usar Random para generar números de forma aleatoria y comprobar si el número ya lo tenemos o no, solución que por probabilidad no podemos asegurar cuanto tiempo se tirará ejecutándose, o meter todos los números en una lista, escogerlos aleatoriamente e irlos borrando etc.

La segunda opción no es mala y al menos es "determinista*", pero si perdemos 5 minutos en el API de las colecciones, podemos llegar a esto (como extra devolvemos los números ordenados):

/**
   * Devuelve numberCount números de entre 1 y
   *  maxNumber escogidos de forma aleatoria y
   * ordenados.
   * 
   * @param maxNumber
   * @param numberCount
   * @return La lista ordenada con los números seleccionados aleatoriamente.
   */
  private static List selectRandomNumbers(int maxNumber, int numberCount)
  {
    List numberList = new LinkedList();
    for (int i = 1; i <= maxNumber; i++)
    {
      numberList.add(i); //**
    }
    Collections.shuffle(numberList);
    numberList =
      numberList.subList(0, numberCount);
    Collections.sort(numberList);
    return numberList;
  }
Y eso es todo. Dos métodos de Collections y uno de List hacen todo el trabajo y no tenemos que preocuparnos de nada. Los ingenieros del JDK se preocuparán de optimizar ese código y nosotros podemos dedicarnos al “core” de nuestro negocio. La moraleja es... no hagas tú el trabajo si alguien ya lo ha hecho por ti. O como decía Mulder cuando programaba en Java... "La verdad, está en el API" ;P

*: Determinista en cuanto sabemos el flujo de ejecución que va a seguir sin depender del azar.
**: Sí, estoy metiendo primitivas en una lista, cosa que solo funciona gracias al mágico autoboxing de las últimas versiones de Java y que no me gusta, pero para este caso el compilador escribiría el mismo código, así que...

Happy coding! EJ

viernes, 7 de mayo de 2010

Los criterios que NO deberías utilizar para escoger una solución

Hola,
Hoy toca hablar de un tema interesante aunque menos técnico que los anteriores: Criterios a la hora de escoger una solución. O mejor dicho, criterios que no hay que seguir para escoger una solución.
Me explico:
En Internet y en Java en particular suele haber montones de herramientas, librerías y frameworks que se solapan en funciones y que se venden como "la solución a tu problema". Muchos desarrolladores tienen alergia a escoger cuando hay mucho donde elegir, siempre es más fácil cuando otra persona carga con la responsabilidad, y tienden a dejarse llevar por razonamientos simples que no suelen tener mucha base. Aunque es complicado decir cuales son las buenas razones para escoger una opción sobre otras, es relativamente fácil descartar algunas opciones populares, aunque no por ello menos erroneas.

Así que sin más dilación, pasaremos una serie de argumentos en los cuales NO te tendrías que basar para escoger una solución sobre otra:
  • Por que es nuevo: Éste es uno de los argumentos favoritos de los “entusiastas por las novedades”, para los cuales todo lo nuevo es muchísimo mejor que lo anterior. La demostración de la estupidez de semejante argumento es muy sencilla: Cualquier cosa, repito: cualquier cosa, cuando sale es nueva. Así que ser novedad es algo que todo el mundo tiene y que cura el tiempo independientemente de lo adecuada que sea o no una solución.
  • Por que lo usa "todo el mundo": Éste, en cambio, es el argumento favorito de la gente sin criterio que prefiere ir en medio de la manada, sin importarle si la manada se dirige a un pozo o no. Los males compartidos parecen menos males, ¿no? Pues no. Si lo usa todo el mundo, efectivamente hay mayores probabilidades de que te sirva, si eres como todo el mundo, pero no es una garantía y como dice el chiste: “¡Come mierda! ¡Millones de moscas no pueden estar equivocadas!” :). Ten en cuenta que hubo un tiempo donde “todo el mundo” hacia JSPs con EJB1.1 y CMP... auch.


  • Por que lo usa Google/EBay/Amazon...: Éste es un argumento parecido al anterior pero por el lado opuesto, apto para mentes que se sienten mejor si escogen lo mismo que “los grandes”. Desafortunadamente para nosotros, la mayoría no somos Google/Ebay etc. ni tenemos sus necesidades, recursos ni prioridades, así que usar una arquitectura pensada para recibir millones de visitas por segundo puede ser muy “cool”, pero seguramente sea una perdida de tiempo y un ejemplo claro de sobre-ingeniería. No hay nada de malo en no ser una de esas grandes compañías, millones de compañías no lo son, así que es mejor usar la cabeza y adaptarnos a NUESTRA situación.


  • Por que es caro:... y como es caro es bueno. Sí, sí, ríete pero yo he estado presente en reuniones donde ese ha sido el único criterio de selección. Por otro lado, sólo hace falta estar como oyente, atónito pero oyente, en una reunión donde se fija el precio de un producto para darse cuenta de lo que éste significa: Era una herramienta que se vendió por cifras con 6 ceros y en € y el precio fue fijado después de un estudio sobre “el precio que los potenciales clientes estarían dispuestos a pagar”. Ni más ni menos.


  • Por que es diferente a lo anterior: Un argumento muy común, utilizado para “diferenciarse de la competencia” pero que, al fin y al cabo, por si mismo no dice nada sobre lo adecuado o no de una solución. Cabe preguntarse si el resto de soluciones que lo hacen de la otra forma son todas parte de una confabulación judeo-masónica, son tontos... ¿o quizá es por que si lo hacen así es por que es más adecuado? En fin, que la evolución es necesaria pero diferente no es necesariamente mejor.


  • Por que su publicidad dice que...: Ésta es un clásico y siempre me sorprende que gente por otro lado totalmente racional e inteligente sea tan “tonta” de creerse lo que dice la auto-publicidad. ¿Que esperan? ¿Que ellos mismos digan que su solución no es adecuada para todo el mundo o que es un asco? No debería ser necesario mencionarla... pero es que todavía la gente sigue cayendo en ella.


De momento esa es la lista de las razones más flagrantemente inválidas que se me ocurren, seguro que hay más pero estas son unos buenos ejemplos. Y repito, no es que esas razones no signifiquen nada, es simplemente que sin otras razones para sustentar la elección, no significan mucho.

Así que no os dejéis llevar y haced vuestras propias elecciones basadas en razonamientos un poco lógicos. Al fin y al cabo se supone que intentamos que ésto sea una ciencia, así que un poco de método científico no viene mal de vez en cuando.

¡Hasta la próxima!

EJ
Happy Coding!