Category Archives: Temas técnicos

Todo lo que tiene que ver con mi área: computación, gadgets, programación. Recomendada para los que están en el mundo de las computadoras

Fcitx en Ubuntu 16.04 después de actualizar

Debido a que escribí en Twitter al respecto, y que en general no tengo que editar mucho cuando escribo cosas técnicas, decidí dejar esto por acá para la posteridad (y a ver si a alguien más le sirve).

Hace unos días, actualicé la máquina que uso en el trabajo. Tenía Ubuntu 14.04 y todo funcionaba bien, pero el día apenas comenzaba y yo estoy súper atorado en el proyecto en el que estoy, por lo que decidí darme un “descanso” y actualizar a 16.04.

Todo estuvo bien, salvo unos archivos de apt. Pero cuando llegué a la configuración del método para escribir (donde agrego lo necesario para escribir en japonés), tuve un problema: ibus no reaccionaba. Pensé que era buena oportunidad de cambiar a fcitx, ya que en casa lo instalé y no medio problemas. No fue el caso en la máquina del trabajo: fcitx funcionaba en la terminal y en algunas otras aplicaciones, pero en Chrome, Firefox o similares, nada. Tampoco en Gedit… y fue eso último que me llevó a pensar que quizás había un problema con esa configuración.

En mi .xsession, tenía configuradas estas 2 variables:


export GTK_IM_MODULE=xim
export QT_IM_MODULE=xim

(que si no hay razón para seguir usando XIM es harina de otro costal). Cambié a:


export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx

Pero nada…Pasé un buen rato buscando algo de información, pero no daba con algo en concreto. Obviamente había buscando en la información oficial, pero no lo hice de nuevo después de pensar que GTK podría ser el problema.

Me encontré entonces en el FAQ de fcitx:

  • If you are using Ubuntu and upgrade to 12.04 recently, or something werid happens to your system (Due to packager careless, or buggy package manager which can not do upgrade in correct order, for example, pacman), you might notice that gtk.immodules related files doesn’t generate correctly during upgrade. Try uninstall fcitx-frontend-gtk2fcitx-frontend-gtk3 or coressponding package on your system and re-install them to trigger the file generate. Then recheck the input method menu to see whether it have “Fcitx” in the menu or not.

¡Ajá! Yo había actualizado a 16.04, pero los síntomas eran muy similares. Así que hice lo indicado:


$ sudo apt purge fcitx-frontend-gtk2 fcitx-frontend-gtk3

$ sudo apt install fcitx-frontend-gtk2 fcitx-frontend-gtk3

$ fcitx -r &

Ejecuté Gedit y, ¡bien! Ya podía escribir en japonés de nuevo. Pero seguía la prueba final: Google Chrome (o Vivaldi, que también lo uso)

成功!

Pasé día y medio teniendo que escribir en Emacs y copiando y pegando a Chrome cuando tenía que enviar algún correo en japonés. ¡Pero no más! 😀

Título de canción de Spotify en Xmobar

Aunque sé que Xmobar tiene Mpris1 y Mpris2, resulta que no lo instalé con soporte para ninguno, por lo que si quería poner el título de la canción que está siendo reproducida en Spotify, tenía que hacerlo a mano.

Tenía un buen rato de no hacer un script de estos. Quizá haya mejores alternativas, pero para algo que me tomó unos 20 minutos, creo que cumple su objetivo:

#!/bin/bash

spotify_pid=`pgrep spotify | head -1`

if [[ ! -z $spotify_pid ]]; then
   found=false
   while [ "$found" = false ] && IFS= read -r line; do
      pid=`echo $line | awk '{ print $3 }'`
      if [ "$pid" = "$spotify_pid" ]; then
         title=`echo $line | awk '{$1=$2=$3=$4=""; print $0 }' | tr -s ' '`
         echo "Spotify: ${title} | "
         found=true
      fi
   done < <(wmctrl -lp)
fi

El resultado:

Reflejar el área maestra en XMonad

Tengo 2 monitores en el trabajo. Mi silla está justo en medio de los 2, por lo que las áreas que más uso para trabajar son la mitad derecha del monitor izquierdo y la mitad izquierda del derecho.  Ahora bien: si han usado XMonad, sabrán que por lo general las áreas maestras de los layout están del lado izquierdo, lo que no me conviene para el monitor de ese lado, pero realmente nunca me había puesto a buscarle solución.

Hoy tuve un buen de ventanas abiertas y estuve revisando datos en todas, pero trabajando en ellos en el área maestra. De repente sentí la necesidad de tener la del monitor izquierdo en la parte derecha y me di a la tarea de investigar qué podía hacer.

Continue reading Reflejar el área maestra en XMonad

Detectando si hay monitor conectado en el puerto HDMI con Haskell

Generalmente hay 2 lugares en donde uso la laptop:

  • En mi escritorio, donde la conecto a un par de monitores, uno de ellos por HDMI).
  • En cualquier otro lugar.

Como uso XMonad, la posición de algunas barras personalizadas varía dependiendo de si estoy usando el monitor de la laptop o el de HDMI. El cambio siempre lo he he hecho manualmente comentando o habilitando un par de líneas en el xmonad.hs, pero quería automatizar el proceso de ser posible. Tenía rato que no usaba Haskell en forma, así que…

Básicamente, lo que necesito es hacer esto en Haskell:

xrandr | grep HDMI1 | cut -d " " -f2

Me eché un clavado en la documentación, y encontré la librería System.Process, concretamente la función createProcess, la cual está definida de la siguiente forma:

createProcess :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)

Donde CreateProcess está definido como se menciona acá:

http://hackage.haskell.org/package/process-1.2.0.0/docs/System-Process.html#t:CreateProcess

Lo que necesito entonces es crear un proceso por cada comando que quiero ejecutar, pero pasar los resultados de uno al siguiente (pipe).  Por tanto, necesito  declarar CreateProcess de la siguiente manera:

Continue reading Detectando si hay monitor conectado en el puerto HDMI con Haskell

Logrotate error en MySQL

Tenía ya tiempo recibiendo a diario esta notificación en los logs:

/etc/cron.daily/logrotate:
error: error running shared postrotate script for /var/log/mysql.log /var/log/mysql/mysql.log /var/log/mysql/mysql-slow.log
run-parts: /etc/cron.daily/logrotate exited with return code 1

Busqué en internet y todos los sitios mencionaban que la causa era que el password de la cuenta debian-sys-maint no era el que estaba indicado en el archivo /etc/mysql/debian.cnf (en Ubuntu):

[client]
host     = localhost
user     = debian-sys-maint
password = xxxxxxxxxxxxxxxx
socket   = /var/run/mysqld/mysqld.sock
[mysql_upgrade]
user     = debian-sys-maint
password = xxxxxxxxxxxxxxxx
socket   = /var/run/mysqld/mysqld.sock
basedir  = /usr

Cambié el password en la base de datos, pero nada. Todo seguía igual. Y al revisar el hash antes y después de cambiar el password era exactamente el mismo, lo que quería decir que el password estaba bien.

Usando ping en mysqladmin

mysqladmin --defaults-file=/etc/mysql/debian.cnf ping

me di cuenta de que no se podía se conectar por problemas del socket. Entonces entendí qué estaba pasando: el directorio en donde el socket de MySQL se crea está especificado en my.cnf, y lo tengo definido como /tmp/mysqld.sock . Le puse ese valor al archivo arriba mencionado, volví a correr el proceso y todo funcionó a la perfección.

Lo anterior pasó porque primero instalé MySQL “a pie”, y recuerdo que cambié varias configuraciones; después, tuve que instalar MySQL usando apt y usé el mismo archivo de configuración. Eso fue lo que causó el problema.

¿Por qué instalé con apt si ya tenía todo configurado bien a mano? Porque lo que instalé por mi cuenta fue para hacer correr un sistema que tenía configuraciones y versiones del año del caldo, y para poder reproducir el comportamiento original tenía que tener exactamente la misma configuración. Afortunadamente eso ya quedó en el pasado y no lo necesito más.

Sobreviviendo en Windows

Llevo semana y media en el nuevo trabajo, y lo que más me “duele” es que tengo que usar Windows 7 voluntariamente a fuerzas…

Dejando atrás el hecho de que muchos de los sistemas internos funcionan solamente con la fantabulosa combinación Windows + IE (del 7 para arriba) *pausa para que se les quiten las náuseas*… el hecho de tener que hacer reportes en Excel ya se me hace de lo más normal (sí, me siento sucio).

Hecho el respectivo rant…

He estado buscando la forma de dejar Windows lo más parecido posible a XMonad. Realmente los tiling window manager me hacen la vida más fácil, y al mismo tiempo me hacen más productivo porque no se pierde tiempo acomodando ventanas o buscándolas con el mouse. Total que después de navegar un rato, lo más cercano a XMonad a lo que he podido llegar es:

  1. mDesktop. Para crear los escritorios virtuales. Usa Alt como la tecla especial y se pueden crear hasta 10 escritorios.
  2. WinSplit Revolution. Para acomodar las ventanas en ciertas regiones de la pantalla. No es para nada tan funcional como XMonad, pero peor es nada. Tampoco se puede configurar mucho que digamos.
  3. Launchy. El launcher, para reemplazar a dmenu. De los 3 programas aquí mencionados es con el que más satisfecho estoy.

Sé que lo anterior no es remotamente nada similar a dwm o XMonad, pero algo es algo. Sigo todavía buscando opciones, sobre todo en lo que al acomodo de ventanas se refiere. Si alguien tiene sugerencias, son todas bien recibidas.

Para cliente de Twitter, he estado jugando con MetroTwit, y la verdad es que es muy recomendable. Linux carece de buenos programas en este rubro (yo uso Hotot). Sin embargo, hoy me recomendaron Janetter y también me gustó la interface. Es cuestión de decidirme por alguno. Pero aun así, estoy buscando uno que deje “tuitear” desde el system tray o un popup ahí cercano, porque eso de tener que abrir la ventana para mandar un tweet es una acción que prefiero evitar en el trabajo, y no es porque me regañen por estar en Twitter (no lo hacen. No está prohibido).

En lo que a navegadores se refiere, además del fatídico IE9 *pausa para que les quiten las náuseas*… ya instalé Firefox, Chrome y Opera, siendo este último el que estoy usando como “navegador personal”, mientras que los otros los tengo para pruebas. Tenía rato que no usaba Opera “seriamente”, y me dio gusto encontrar un navegador maduro con varias opciones interesantes. Si sólo Midori tuviera soporte para más tecnologías (entre ellas Flash), no dudaría en instalarlo (y sólo por el nombre, jeje).

Entre otras cosas que instalé:

  • WinScp
  • Virtual Clone Drive (para no extrañar el mount de ISO de Linux).
  • Notepad++
  • Haskell Platform
  • Leksah
  • Imgburn

Se aceptan tips de buenos programas para… dejen agarro aire… windows… que hagan más amena la experiencia.

Obteniendo todas las posibles “palabras” de 7 letras (o menos)

Últimamente, el juego al que más le dedico tiempo (además de Tekken) es a Angry Words (apalabrados en español). Con eso que me gusta Scrabble desde hace mucho, me relaja mientras voy en el tren y al mismo tiempo me ayuda a practicar mi vocabulario.

De la misma manera, le he estado dedicando tiempo a aprender Haskell, ya que veo que algunas cosas de PLN podrían ser implementadas más fácilmente con programación funcional.

Buscaba un problema que me ayudara a practicar Haskell, a dar mis primeros pinitos en el lenguaje. Y mientras disfrutaba el mencionado juego y veía que es más de “ponle lo que sea a ver si pega” en vez de “piensa en alguna palabra interesante”, se me ocurrió crear un programa que, dada una serie de letras, mostrara todas la combinaciones posibles entre ellas. Lo veía fácil y factible, por lo que me decidí a poner manos a la obra.

¿Qué tan difícil puede ser?… me pregunté. Y aunque no es algo tan complicado, sí me tomó más tiempo del que pensaba debido a que había que hacer el cambio a programación funcional y no a imperativa.

Primero, a definir el algoritmo:

Tomemos una palabra de 3 letras (por conveniencia, más adelante verán por qué), digamos “ola”. ¿Qué es lo que quiero obtener? La lista de posibles permutaciones con esas 3 letras, es decir: ola, oal, loa, lao, aol, alo. Aquí me di cuenta de un patrón: tomo una letra de la palabra, la pongo al principio, y simplemente tomo las otras 2 letras restantes y les cambio el orden. Para comenzar, tomo la “o” como la letra principal, entonces me quedo con “la”, y las únicas combinaciones posibles son “la” y “al”; después, agrego la letra principal “o” y la pongo al principio de cada palabra, obteniendo “ola”,”oal”. Continúo con la siguiente letra, la “l”, la tomo como principal, quedándome “oa”, de la cual obtengo “oa” y “ao”; le pongo la “l” al principio de cada una y obtengo “loa”,”lao”. Por último tomo la “a” como letra principal, lo que me deja con “ol” como el resto, obteniendo “ol” y “lo”; le pongo la “a” al principio de cada una y resultan “aol”, “alo”. Juntando todos los resultados parciales, obtengo la lista de palabras que estoy buscando.

Con la definición anterior, recursivamente se pueden analizar palabras de cualquier longitud. ¿Buenas noticias para los que juegan apalabrados? En teoría, si es que tienen la paciencia de ver todos los resultados. ¿Cuántos son? Saquemos cuentas:

Una palabra de 3 letras resultó en una lista de 6 palabras. ¿Cuántas resultarán de una de 4? Como lo que buscamos son permutaciones, la fórmula es sencilla:

n!

Revisemos: 3! = 3x2x1 = 6. ¡Bien! Si cuadra el resultado

Entonces, con 4 letras tendremos: 4! = 4x3x2x1 = 24 Todavía no son muchas…

Con 5 : 5! = 5x4x3x2x1 = 120 ya da flojera ver tantas permutaciones…

¿Y con 7? Pues 7! = 7x6x5x4x3x2x1 = 5040 Está bien que no haya límite de tiempo en cada jugada de apalabrados, pero qué flojera (o ganas de ganar) de aquél(la) que se ponga a leerla cada vez.

¡Ajá! Dirán ustedes: ¿qué pasa si hay letras repetidas? Obviamente habrá palabras repetidas también, lo cual reduce nuestra lista. ¿A cuánto? Oh benditas matemáticas:

n!/(a!b!c!…)

En donde a es el número de veces que se repite una letra, b es el número de veces que se repite otra, c es el número de veces que se repite otra… y así sucesivamente.

Supongamos que tenemos las letras “atajada” (si las tienen, ¡no la piensen y jueguen esa palabra!). La letra “a” se repite 4 veces, entonces, tendremos:

7!/4! = 7x6x5 = 210

Quizá pude haber pensado el algoritmo con una palabra de 4 letras desde el principio, y aunque sí revisé a mano después, me era más fácil iniciar con una de 3 (sólo 6 posibles permutaciones).

Luego, a hacer el programa. El resultado, a sabiendas de que puede haber una mucho mejor implementación, es una belleza de 18 líneas de código (y porque puse doble enter en algunos lugares):

Continue reading Obteniendo todas las posibles “palabras” de 7 letras (o menos)

XMonad: Cambiar el nombre del layout que se muestra

Hace tiempo escribí sobre XMonad y un xmonad.hs básico en donde mostraba cómo mostrar íconos en vez del título del layout. Esta vez esalgo similar, pero como ahora sí estoy estudiando Haskell en forma, ando buscando cómo hacer lo que quiero con guards:

En uno de los escritorios estoy usando LayoutCombinators para combinar 2 layouts (concretamente simpledTabbed y DragPane Horizontal). Al mostrarse el nombre del layout aparece lo siguiente:

“combining Tabbed Simplest with DragPane Horizontal 0.1 0.099999999”

Debido a su longitud, me quita espacio del título de la ventana activa, por lo que pensé hacer un shorten, pero después recordé que en la laptop hago pattern matching para mostrar un ícono en vez del nombre del layout, por lo que pensé hacer algo parecido: si el nombre del layout comienza con “combining”, muestro un nombre que yo defina, y en cualquier otro caso muestro el nombre original.

El layout quedó así:

myXmobarPP h = xmobarPP
             { ppOutput = hPutStrLn h
             , ppCurrent = xmobarColor "green" "" 
             , ppHidden = xmobarColor "#5f7962" ""
             , ppVisible = xmobarColor "#f4a460" ""
             , ppUrgent = xmobarColor "#cc0000" "" . wrap "*" "*"
             , ppSep = " | "
             , ppWsSep = "  "
             , ppLayout = xmobarColor "#5CBAF5" "" .
                          (\lName -> showLayoutName lName)
             , ppTitle = xmobarColor "white" "" . shorten 150
             }

showLayoutName :: String -> String  
showLayoutName a | Just rest <- stripPrefix "combining" a = "Tabbed + DragPane H" 
showLayoutName a = a

Donde lo que quiero hacer está en ppLayout: una expresión lambda para revisar si el título comienza con “combining” o no. Esa revisión la hago en la función showLayoutName con la función stripPrefix, que recibe una lista y regresa otra lista que contiene los elementos después del prefijo indicado si es que existe, o Nothing en caso contrario. Si el título del Layout comienza con “combining”, regreso “Tabbed + DragPane H”, y si no, simplemente regreso lo que me llegó.

Intenté hacerlo con guards, pero nomás no me compiló el código, y como estoy en el trabajo, no me dio más tiempo de probar, por eso lo implementé como aquí se muestra.

Si quisiera hacerlo en Scala, el código quedaría así:

val xmobarColor = (bgColor: String) => (fgColor: String) => (output: String) => {
  // Hacer algo con los parámetros y regresar un String
  ...
}

val showLayoutName = (layout: String) => {
  layout.startsWith("combining") match {
    case true => "Tabbed + DragPane H"
    case _ => layout
}

// Asignando todo a ppLayout

val ppLayout = ((xmobarColor("#5CBAF5")("")) compose showLayoutName)

// Siendo layoutName el nombre del layout actual

ppLayout(layout)

Aunque sigo siendo novato en Scala (y para esos fines, en programación funcional), me late más la forma concisa de Haskell. Hacer function composition en scala es agregar demasiadas palabras (aunque si usara scalaz todo cambiaría), mientras que en Haskell el currying, la aplicación parcial y la composición se hacen sin mayor complicación.

Sigo estudiando y practicando.

De “hackeos” y otras cosas

Muchos de ustedes se dieron cuenta que a principios de esta semana el blog fue bloqueado por Google debido a que se detectó malware en él. Aunque no fue la primera vez que me ponen anuncios o redirecciones a sitios que venden viagra o pornografía, sí fue la primera vez que sufrí el bloqueo de la gran G.

La situación parece haber vuelto a la normalidad, pero me lo tomo con pincitas, porque ya antes habíamos (incluyo al panda, quien me ha hecho grandes favores en este blog y hosting en general) hecho limpieza y en teoría todo estaba bien, y zas… nos cayó por donde menos esperábamos.

Razones puede haber muchas, pero las principales parece que ya han sido solucionadas: borrar los lugares que no uso o no actualizo tan seguido, así como sus bases de datos. En concreto:

  • Desaparece el blog de tecnología. No porque quiera, sino porque no tengo tiempo de estarle dando mantenimiento. Todos los posts de allá ya habían sido migrados aquí desde hace varios meses.
  • Desaparece el sitio de las fotos. Quizá muchos no lo conocieron porque nunca hubo una liga directa en el blog. Era Gallery 3, pero la última vez que le di mantenimiento fue en la versión 3.02 RC. También se va por falta de tiempo.
  • Borré varios sitios y bases de datos que alguna vez ofrecí a gente o instituciones que lo necesitaban pero que a fin de cuentas nunca usaron. Ni modo, uno les da la oportunidad, pero a final de cuentas depende de ellos .

Sinceramente, para mí no hay nada mejor que tener el control total de lo que uno usa. Por eso la instalación de WordPress de este blog se hizo desde ceros y la mantengo a mano en vez de usar la versión que se ofrece en el hosting. Sin embargo, la falta de tiempo es una situación que me afecta mucho en estos momentos, por lo que, para mi desgracia, no puedo mantener tantos sitios al mismo tiempo. Las fotos es lo que quizá más me duele, pero no hay de otra por el momento. Las subiré ya sea a Picassa o a Flickr (aunque me inclino más por el primero) en una oportunidad que tenga.

Por lo demás, parece que todo está en orden. Quisiera darle una manota de gato al blog (me prometieron un skin personalizado para el blog hace como 2 años), pero sinceramente con todo lo que traigo entre manos (una gran parte es el esclavajo) todo tendrá que esperar.

Ahí les encargo si ven algo raro en el blog, o si les vuelven a salir mensajes o anuncios de productos milagrosos o redirecciones a sitios extraños.

Errores

Como ya se habrán dado cuenta, he andado muy desconectado del blog, y para el caso también de internet. Han sido semanas pesadas en el trabajo, pero la anterior se caracterizó por una carga de trabajo moderada con una de presión bastante más grande.

Para no hacer el cuento largo, me pidieron hacer una prueba de estrés en un servidor. Pensé que la prueba en sí sería fácil (con algo como ab), pero leyendo y siguiendo el consejo del buen panda, opté por usar siege, herramienta que también es mencionada en el libro de Tomcat de O’Reilly. Leí, según yo me preparé bien, revisé varias veces las condiciones de la prueba, y en el día y la hora indicada la realicé (en realidad fueron varias).

Pensé que todo había salido bien, así que procedí a hacer el respectivo reporte… y fue donde realmente comenzó todo. Dejemos al lado que el formato del reporte no fue el que esperaban: los resultados no cuadraban. Y entre que yo soy un noob para esto de las pruebas y entre que no confiaban en que hubiera realizado la prueba correctamente, fueron 3 días para olvidar, pues terminé saliendo en promedio después de las 12 de la noche.

Entrando en detalles más técnicos, siege pide un archivo con una lista de URL a probar. El problema, y mi error, fue haber puesto URL de más, por haber entendido que se probarían N tipos de páginas y no N páginas exactamente. Pero por lo demás, las características de la prueba no estaban mal, y la forma de ejecutar la prueba tampoco. ¿Entonces?

Lo que me alegaban era que en la prueba se emulaban N número de usuarios que accederían al servidor al mismo tiempo, pero los resultados reportaban que no era así, y el número de veces que se visitaban los URL era realmente muy poco para el tiempo que duró la prueba. El panda me auxilió muchísimo con la interpretación de los resultados, y efectivamente, salió a relucir que una de las razones era por haber puesto URL de más. Error 100% mío, y en una situación laboral como la que estoy viviendo ahora, era de esperarse que me fueran a reclamar, con justa razón. Sin embargo, aun con reconocer mi error, los resultados marcaban claramente que el servidor no aguantaba mucho, pero me seguían insistiendo que la forma de hacer la prueba había estado mal, independientemente del número de páginas que había seleccionado para probar.

Después de la tormenta, se corrió una prueba emergente para comprobar que realmente había hecho la prueba original correctamente. Los resultados no mentían: se probaron menos páginas (un número cercano a las que originalmente se tenía planeado), pero se mostraba también la tendencia del servidor a no aguantar al número de usuarios indicados al mismo tiempo.

¿Qué aprendí de todo esto?

  1. Que el mundo del benchmark es mucho, pero mucho más complicado de lo que yo creía.
  2. Que aunque sé que soy humano y que obviamente me puedo equivocar, un error bajo esta situación puede costarme muy caro.
  3. Que estoy bajo mucha más presión que la que originalmente  pensaba.
  4. Que no quiero estar por siempre en una situación laboral como la actual.

Ahondando un poco en el punto 4, no tiene mucho que ver lo pesado del trabajo, o ni siquiera que no paguen las horas extra; tiene mucho más peso para mí el tiempo que le puedo dedicar a los demás, y por supuesto, a mí mismo.

Añoraba el fin de semana. Lástima que ya terminó. Tengo en puerta decisiones muy grandes, y relativamente poco tiempo para hacerlas. Como hace algunos años, necesito que los días tengan al menos 48 horas para poder hacer todo lo que debo. Mientras tanto, aquí andamos, tratando de no sucumbir ante la situación.

Agradezco muchísimo al panda por su invaluable ayuda y su tiempo en estos días, así como las palabras de aliento de varios de los mexicanos en Japón (ellos saben quienes son).