Thursday, July 12, 2012

ASUS Zenbook UX31E and Kubuntu 12.04: some tips

After a couple of months with this ultrabook as my main computer at work, I wanted to share a few tips. First of all, I am using Kubuntu 12.04, so I followed the instructions in Community Ubuntu regarding this computer. These are very useful and I advice anyone to follow them, except for one thing that I will comment on later.

There are lots of reviews of this computer out there, so I will be very shallow here:
  • It is fast and responsive. The SSD hard disk plus the intel iCore 5 and the 4GB of RAM make this a fast computer (though obviously not for hard gamers, graphic designers, movie makers etc.).
  • It is light, thin and beautiful. People are usually impressed by its looks.
  • The screen is good, but improvable: fantastic resolution, good brightness/contrast, decent colors, not very good viewing angles and glossy (I prefer matte screens). Again more than enough for many users, but not for all.
  • The clickpad is not as bad as I expected after reading some reviews. For Ubuntu users there is more information in the link I have included before. I do not use it in a daily basis (I prefer a wireless mouse), but for an occasional use I find it more than acceptable.
  • The keyboard is bad. It has flat and separated keys with a few minor issues (the key action is short, the feeling is not very good) and a big one: some key presses are not detected. In some keys, if you press them on a side the key press is not detected, so you make a typo. After a couple of weeks using it, I decided that it was enough and I bought a wireless keyboard. For occasional use it is not that bad, but it is not good for writing long texts in a daily basis.
  • I do not use it unplugged for long periods, so I cannot tell much about the battery life (the tray icon in Kubuntu gives between 6 and 7 hours, but I do not know if that is true).
Now a few tips that I have learned over these weeks of using this laptop with Kubuntu 12.04 (there are many other useful tips in the instructions in Community Ubuntu):
  • The USB Ethernet adapter must be plugged in the left USB port (USB 2.0), not in the rigth one (USB 3.0). It works in both of them, but in the USB 3.0 port the network is far slower.
  • If you are having random system freezes (you can move the mouse cursor but nothing else is responding; some times you can change to a virtual terminal (i.e. Ctrl-Alt-F1) and do something, and others you just have to make a hard reset) check your kernel logs for "GPU hungs". In a terminal, write: "cat /var/log/kern.log | grep GPU". In KDE you can also use the graphical tool KSystemLog. If you see something like "[drm:i915_hangcheck_elapsed] *ERROR* Hangcheck timer elapsed... GPU hung ... [11959.817883] [drm:kick_ring] *ERROR* Kicking stuck semaphore on render ring" when you suffered the freezes, then I suggest you to make sure that in your kernel parameters you have "i915.semaphores=0" (the instructions in Community Ubuntu suggest to give this parameter a 1; follow those instructions but put a 0 instead (*)). I suppose this can be helpful too for other computers with Sandy Bridge and an Intel HD 3000 graphics card running an Ubuntu-based Linux distro and having this problem. This has completely fixed this problem for me.
  • I run the synaptiks application on the system start, and I have configured it to have the clickpad automatically disabled when I am typing on the keyboard or when an external mouse is connected. This is a very important usability improvement if you are using the laptop keyboard.
  • I have detected screen tearing in videos (this is the worst problem I always have with Linux; in my home laptop I have not been able to solve it after trying everything). I haven't worked too much on this issue, I do not use this computer for watching movies but, for now, I strongly recommend VLC over the default Dragon Player in Kubuntu. With the out-of-the-box configuration, the VLC version included in the Ubuntu repositories shows no tearing at all in movies where Dragon Player shows a lot of it. This may work for you or not, as tearing depends on many things, but for now it is an acceptable and simple workaround for me.
If I can think of something else, I will update this post, unless it is something long enough that deserves a new one.



(*) And do not forget to run "sudo update-grub" after changing /etc/default/grub, some people are known for having committed this mistake before... ;-)

Sunday, June 24, 2012

Research at Google

Alfred Spector, Peter Norvig and Slav Petrov have published a paper on the different approaches to research followed at Google. I just want to highlight a few things that I have found interesting:
  • "...the computer systems we construct have become so large that analytic techniques cannot properly describe their properties, because the systems now dynamically adjust to the difficult-to-predict needs of a diverse user community, and because the systems can learn from vast datasets and large numbers of interactive sessions that provide continuous feedback."
  • "The way research results are disseminated is also evolving and the  peer-reviewed paper is under threat as the dominant dissemination method. Open source releases, standards specifications, data releases, and novel commercial systems that set new standards upon which others then build are increasingly important."
  • "...has led Google to a 'Hybrid Research Model.' In this model, we blur the line between research and engineering activities and encourage teams to pursue the right balance of each, knowing that this balance varies greatly."
  • "Example Research Patterns: 1. An advanced project in a product-focused team that, by virtue of its creativity and newness, changes the state of the art and thereby produces new research results. The first and most prevalent pattern exemplifies how blurry the line between research and development work can be."
I would recommend, to anyone interested in computer science research aimed at solving *real* problems, to read the whole paper at least a couple of times.

Monday, May 14, 2012

Implementación funcional del tres en raya en Scala

Aquí va una implementación del tres en raya, o tic-tac-toe, en Scala. Mi nueva contribución a Rosetta Code. El juego es interactivo humano-computador. Comienza el humano. El computador no es muy listo: hace movimientos legales pero puramente aleatorios. La implementación es funcional. El listado completo lo tenéis en Rosetta Code. Voy a comentar aquí algunos de sus elementos más interesantes.
  • val BaseBoard = ('1' to '9').toList Esto define una variable inmutable que contiene una Lista de caracteres entre el 1 y el 9, que serán nuestro tablero base. Representaremos un tablero como una Lista de caracteres.
123
456
789
    • '1' to '9' define un rango de caracteres del '1' al '9'. 1 to 9 definiría un rango de enteros entre el 1 y el 9. 1 until 9 definiría un rango de enteros entre el 1 y el 8
  • val WinnerLines = List((0,1,2), (3,4,5),...,(2,4,6)) En WinnerLines guardamos una Lista de Tuplas, donde cada Tupla contiene uno de los movimientos ganadores (líneas completas). 0,1,2 corresponde a  la primera línea horizontal (ojo, son los índices de las posiciones que corresponden a la primera línea horizontal), mientras que por ejemplo 2,4,6 se corresponde a una de las dos diagonales.
  • class Board(aBoard : List[Char] = BaseBoard) La clase Board representará nuestro tablero y nos permitirá instanciar objetos funcionales (que no guardan estado mutable). Esta clase tiene un constructor que recibe como parámetro una Lista de caracteres. Si no se le pasa parámetro, esa Lista de caracteres será por defecto BaseBoard. El parámetro del constructor (aBoard) automáticamente pasa a ser accesible por las funciones de la clase, aunque no lo es desde fuera.
  • def availableMoves = aBoard.filter(c => c != Human && c != Computer) 
    • Definimos una función de la clase Board que no tiene parámetros, y pero eso no es necesario poner paréntesis después del nombre (aunque podríamos hacerlo; def availableMoves() = ...).
    • Esta función devuelve una Lista de caracteres. Scala es un lenguaje tipado estáticamente, pero el compilador puede deducir muchas veces los tipos de variables y funciones y en estas ocasiones no es necesario decírselos explícitamente. Aunque el compilador lo deduzca, si queremos podemos hacerlo explícito (puede ser una buena documentación): def availableMoves : List[Char] = ...
    • El cuerpo de la función es una llamada a la función filter sobre el objeto aBoard (que es una List[Char]). Sobre una Lista, filter toma como parámetro una función que devuelve un booleano, y lo aplica a cada elemento de la Lista; luego devuelve una nueva Lista en la que sólo se copian aquellos elementos de la original para las que el filtro es cierto. 
    • c => c!= Human && c!= Computer es una función anónima. Toma como parámetro un carácter que llamamos c y devuelve cierto si es distinto de Human y es distinto de Computer (Human y Computer son dos constantes que están definidas como 'X' y 'O'). En este caso Scala puede deducir que c es un Char porque se usa para filtrar una Lista de caracteres. También podríamos ponerlo explícito: (c : Char) => ... Si el parámetro sólo se usara una vez en el cuerpo de la función anónima, ni siquiera habría que darle un nombre. Por ejemplo si sólo queremos quedarnos los elementos distintos de Human: aBoard.filter(_ != Human) es todo lo que necesitaríamos poner.
    • Un ejemplo: si aBoard es List('1','2','X','O'), availableMoves nos devolverá List('1','2')
  • def availableMovesIdxs = for ((c,i) <- aBoard.zipWithIndex if c != Human && c != Computer) yield i Esta función usa una list comprehension. El for ... yield nos permite crear una lista a partir de otra, u otras, con bastante flexibilidad. 
    • En nuestro ejemplo, lo primero es coger aBoard (List[Char]) y llamar a zipWithIndex, que nos devuelve una Lista de pares ([Char], [Int]) en la que se asocia a cada elemento de una Lista su posición en la misma: por ejemplo, List('a','b').zipWithIndex nos devolvería List(('a',0), ('b',1)). 
    • Luego, para aquellos pares que cumplan la condición de que el carácter (c) no es ni Human ni Computer, nos quedaremos con el índice (i). Por ejemplo, si aBoard es List('1','2','X','O'), availableMovesIdxs nos devolverá List(0,1).
  • def computerPlays = new Board(aBoard.updated(availableMovesIdxs(randomGen.nextInt(availableMovesIdxs.length)), Computer)) Esta función devuelve un nuevo objeto Board, después de que el computador haga un movimiento aleatorio. 
    • Primero, hay que hacer notar que este estilo es característico de los objetos funcionales: en lugar de modificar el estado del objeto Board actual, instanciamos uno nuevo con los cambios que queramos. De esta forma podemos trabajar sin tener estado mutable (por ejemplo, sin tener variables en el sentido imperativo de la palabra variable).
    • Usamos la función updated sobre la Lista de caracteres aBoard para crear una copia de esta Lista donde el elemento en la posición que le pasamos como primer parámetro se cambia por el segundo parámetro (Computer en este caso). El primer parámetro availableMovesIdxs(randomGen.nextInt(availableMovesIdxs.length)) selecciona aleatoriamente un elemento de entre availableMovesIdxs. Notad que availableMovesIdxs es una función que no tiene parámetros y aquí parece que le estamos pasando uno. No es verdad, availableMovesIdxs devuelve una Lista, así que el "parámetro" en realidad es el acceso al elemento i-ésimo de esa Lista. Notad que en este caso no podríamos escribir availableMovesIdxs()(0) porque el compilador protestaría porque intentamos acceder a un elemento de una Lista sin especificar cual.
  •   def isWinner(winner : Char) =
        WinnerMoves.exists{case (i,j,k) => aBoard(i) == winner && aBoard(j) == winner && aBoard(k) == winner}
    Esta función determina si el carácter pasado como parámetro (que debería ser 'O' o 'X' aunque no lo estamos comprobando) hace una línea completa en aBoard. Para ello usamos la Lista de Tuplas WinnerMoves donde teníamos guardados los índices de todas las líneas completas posibles en el tablero, y usamos la función exists, que toma como parámetro una función que devuelve un booleano y la aplica a cada elemento de la Lista. Si para algún elemento la función parámetro devuelve cierto, exists termina y devuelve cierto.
    • La función que le pasamos como parámetro tiene una sintaxis un tanto especial. Lo primero es que va entre llaves, en lugar de paréntesis. Y segundo, empieza con la palabra reservada case. Es otro ejemplo de lo que se puede hacer con emparejamiento de patrones en Scala: definir funciones parciales (que sólo devuelven un valor para ciertas entradas). En nuestro caso, sabemos con certeza que todos los elementos de la lista WinnerMoves son 3-tuplas y que todas tienen tres caracteres, así que podemos emparejar con confianza con un patrón que sólo acepte 3-tuplas y comparar sus tres elementos con el parámetro recibido. Si alguna de las 3-tuplas de WinnerMoves tiene todo 'X' o todo 'O' en nuestro tablero, tenemos un ganador.
    • Si queremos mayor seguridad, podemos asegurarnos de que lo que recibe la función es 'O' o 'X'. Para eso añadiríamos require(winner == 'X' || winner == 'O') como primera línea de la función. Esto nos permite añadir fácilmente precondiciones a nuestras funciones: si no se cumple la precondición, la función termina con una excepción de tipo IllegalArgumentException, y si se cumple, se ejecuta normalmente.
  •   def print {
        aBoard.grouped(3).foreach(row => println(row(0) + " " + row(1) + " " + row(2)))
      }
    Aquí tenemos un procedimiento. Notad que no lleva = después del nombre, directamente va el cuerpo entre llaves. En realidad un procedimiento en Scala es una función que devuelve algo de tipo Unit (o sea, que devuelve algo sin interés; Unit es similar al void de Java). En este caso print no devuelve ningún valor de interés, lo que hace es escribir por pantalla el tablero. Primero agrupa la Lista aBoard en grupos de tres, y luego para cada grupo de tres lo escribe en una línea en pantalla.
  • object TicTacToe extends Application {   En Scala podemos crear objetos singleton, que sólo se instancian una vez, con la palabra reservada object. Si creamos uno que extiende el trait (los traits para otro día) Application, el objeto será directamente ejecutable (el trait Application define automáticamente un método main que instancia el objeto singleton que acabamos de crear y ejecuta el código que lleve).
  • def readValidMove() : Char = { Una última cosa que quiero mencionar, y esta función me sirve como ejemplo (no copio aquí el código completo, ya está en Rosetta Code). Tenemos que leer la entrada del usuario de teclado hasta que nos proporcione un movimiento válido. Si creamos un bucle (algo tipo while(!validMove)...) vamos a necesitar leer la entrada del usuario en una variable mutable posiblemente varias veces. Las variables mutable en Scala se declaran con la palabra reservada var (val es para las inmutables). Sin embargo las variables mutables no son funcionales, así que en lugar de un bucle he implementado esto como una función recursiva, y así puedo usar val en lugar de var. En este caso creo que sería perfectamente razonable usar var y un bucle para esta parte del código, y Scala nos da la opción de hacerlo así, pero he preferido mantener un estilo funcional en todo el ejemplo. Lo mismo he hecho con la función play.
    • Por si no queda claro, esto es perfectamente legal en Scala: var a = 5; a = 6;  y hace lo que un programador acostumbrado a un lenguaje imperativo esperaría. Esto sin embargo es ilegal: val a = 5; a = 6; y nos devulve un error.
Para terminar, y por si acaso alguien lo nota, voy a señalar que la entrada/salida en este programa no es "puramente" funcional. Lo que busco es explorar y mostrar las posibilidades que Scala ofrece de combinar programación funcional y orientada a objetos sobre la plataforma Java. Scala también permite programar en un estilo totalmente imperativo, o mezclando el estilo imperativo y el funcional. El que busque programación funcional "pura" debería aprender Haskell.

Saturday, May 12, 2012

Detección de palíndromos en Scala

Mi primera, y pequeña, contribución a Rosetta Code: la versión recursiva de la detección de palíndromos en Scala:

def isPalindrome(s : String) : Boolean = s match {
  case s if s.length > 1 => (s.head == s.last) && isPalindrome(s.slice(1, s.length-1))
  case _ => true
}

Y aquí un pequeño ejemplo de uso:

scala>isPalindrome("holaloh")
res4: Boolean = true

Breve explicación de su funcionamiento:
  • def isPalindrome(s : String) : Boolean Definimos una función, llamada isPalindrome, que toma como entrada una cadena y devuelve un booleano. 
  • s match { ...} Usaremos emparejamiento de patrones (pattern matching). No es la única forma, ni mucho menos, de escribir esta función, pero yo diría que es la más idiomática en Scala (aparte de la versión no recursiva que aparece en Rosetta Code, que es sin duda la opción más sencilla).
  • case s if s.length > 1 Si la cadena s tiene longitud > 1
  • => (s.head == s.last) && isPalindrome(s.slice(1, s.length-1)) La función devuelve cierto si el primer carácter de la cadena es igual al último, y si el resto de la cadena (lo que está entre el primer carácter y el último sin incluirlos) es también un palíndromo
  • case _ => true En otro caso la función devuelve cierto (esto se emparejará con cadenas de longitud <= 1, y todas esas las consideramos palíndromos, incluyendo la cadena vacía).
Si nos pasan null como parámetro, la función terminará con una excepción de tipo NullPointerException, porque intentará averiguar si un null tiene longitud > 1. Para protegernos, podríamos añadir otro case al match (tendría que ser el primero): case null => false

Las cadenas en Scala son Strings de Java, pero tienen métodos añadidos para soportar todas las operaciones de las secuencias de Scala (Seq) (por eso podemos usar head, last o slice).

El emparejamiento de patrones da muchísimo más juego, esto apenas da una pequeña idea de la sintaxis que tiene y lo que se puede hacer en Scala.

Tuesday, May 08, 2012

The object-relational mapping problem: my two cents

This is a big problem, nicely summarized by Martin Fowler in http://martinfowler.com/bliki/OrmHate.html.

In my view, the main issue is that we have different abstraction levels in memory and in the database. If you work with classes like Person and Flight and Passenger in memory, and you work with varchars and ints in the database, you are calling for trouble. If your business logic is simple, and your objects look more like data than like objects, these differences may be a minor issue, but an issue after all: you can write things like select * from PASSENGERS, FLIGHTS where PASSENGERS.DESTINY = FLIGHTS.DESTINY and PASSENGERS.AGE > 18, which is OK, but also things like select * from PASSENGERS, FLIGHTS where PASSENGERS.DESTINY = FLIGHTS.DESTINY and PASSENGERS.AGE > FLIGHTS.NUMBER which does not make sense, but it works because both are ints, and may return some data.

In a higher abstraction level, you could possibly want to write things like select * from PASSENGERS, BAGGAGE_PIECES where PASSENGERS.ID = BAGGAGE_PIECES.PASSID and PASSENGERS.AGE > BAGGAGE_PIECES.WEIGHT and be warned that you are trying to compare an Age and a Weight, and that it is not allowed. To achieve this, you need support for Abstract Data Types (ADTs) in your relational database, and current commercial and open source database managers provide this support. The relational model allows this, although some vendors prefer to call it object-relational. If you are thinking that storing ADTs would violate the first normal form in relational databases, you are missing the A in ADT.

Working at the highest possible abstraction level, and the one which is closest to your problem domain, is usually a good idea, specially if there are a number of developers involved and if you plan to create a maintainable application. Your relational database is a part of your application and, as long as you have the choice, you should aim at the highest possible abstraction level there too.

Thursday, November 17, 2011

Problemas por el desconocimiento de las leyes de la probabilidad

"Asumiendo que el 1% de mujeres de 40 que se hacen mamografías rutinarias tiene cáncer de mama, que el 80% de las mujeres con cáncer de mama obtienen mamografías positivas (o sea, que se les detecta algo que resulta ser un cáncer real) y que el 9,6% de las mujeres sin cáncer de mama también obtienen mamografías positivas (que son falsos positivos, en realidad no tienen cáncer). Si a una mujer de 40 le sale una mamografía positiva en un test rutinario, qué probabilidad hay de que realmente tenga cáncer de mama?"

Esto es un problema de estadística de bachillerato que se puede resolver aplicando la fórmula de Bayes. Varios experimentos confirman que sólo alrededor del 15% de los médicos (hablamos de médicos alemanes, australianos...) saben calcular la respuesta correcta en este tipo de problemas (y los que fallan típicamente fallan por mucho). No es broma, ni es un bulo (hasta donde he podido comprobar; es posible que los que publicaron los experimentos hayan cometido fraude científico, pero hasta ese nivel de escrutinio lógicamente no puedo llegar :-). Podéis localizar la respuesta a este problema, las referencias a los experimentos que he mencionado y más información relacionada con este tipo de fallos en la experimentación científica en http://norvig.com/experiment-design.html (en inglés).

Obviamente hace falta más educación en probabilidad y estadística en particular y en matemáticas y ciencias en general. La estadística es un campo amplio y complejo, pero ¡lo de arriba es de bachillerato!

Tuesday, August 02, 2011

What do SOAP, Flex and GWT have in common?

I suppose that you can find many things if you think about it for a while. However, today I am focused on what I think it is their main problem: they all try to attract developers by, supposedly, making their lives easier, but in the end they just manage to have developers without control of their developments, and this is bad for their users.

SOAP, and its related standards, seem to be more focused on making it easier for a developer to deploy a web service without knowing details of how this web service works, than in helping developers to create well-designed distributed applications. And then it comes REST, and JSON, and SOAP becomes a zombie.

Flex intends to provide developers with a more controlled environment than the web browsers, better development tools and documentation to develop web clients and, of course, lots of GUI bells and whistles; however, they do so by providing yet another virtual machine, never designed to be virtual machine in the first place, with another set of headaches (versions, bugs in different platforms, performance and security issues...). And then it comes Apple, and decides that Flash is not for their products, because Apple, with their many defects, is always thinking in their users' experience. And Flex developers are doomed because it seems that even Adobe has accepted that HTML 5 is the way to go, and should start learning another platform ASAP, if they ask me.

And then is GWT and the supposedly good idea to take a Java developer and allow her to develop web applications in Java by hiding the browser and the JavaScript behind Java objects. And this works, as good as it can work something that is so complex: the browser is a different world, and JavaScript is more flexible than Java, not the other way round. The result: a bunch of Java developers who still need to learn JavaScript, and to learn about the browser as a platform, if they want to create web applications that look and behave as web applications without the constraints imposed by GWT.

Users come first. If something is hard for developers and good for users, then that is the way to go. If something is easy for developers at the expense of the users that is a FAIL (sometimes this is not easy to foresee, other times it is). If something is easy for developers and good for the users, then that is an EPIC WIN (not many of these I am afraid). It seems to me that there are not many shortcuts in software development.