Python WTF: Entendiendo cómo funciona is

He estado echando un ojo a un post de Reddit, donde algunos comportamientos del lenguaje parecen que no son los adecuados (bug), pero que se deben en su mayoría a pequeños fallos de comprensión de la sintaxis tan propia de python.

El que os traigo aquí es el siguiente:

>>> a = 256
>>> b = 256
>>> a is b
True
>>> a = 257
>>> b = 257
>>> a is b
False

Aparentemente vemos que hay una inconsistencia en el funcionamiento. Lo esperado es que si comparas si 256 is 256 es que te de que sí. Hasta aquí bien. El problema lo tenemos con el siguiente número: 257, donde no funciona igual.

Esto se debe a dos causas. La primera de las dos es la implementación interna de CPython, la distribución python por excelencia. Aquí, todos los enteros desde -5 hasta 256 (ambos incluidos), tienen una única instancia, por ser los enteros que más se utilizan. Sin embargo, los enteros que son mayores de 257 o menores que -5 tienen otra dirección en memoria a medida que se crean.

La segunda causa es cómo funciona realmente is. Lo que hace es comparar referencias a bajo nivel en memoria, por lo que, como hemos visto antes, los números contenidos en el intervalo [-5, 256] tendrán la misma dirección en memoria y darán True en la comparación.

Como dato curioso, si intentamos lo mismo en pypy, una implementación de Python optimizada para cálculos numéricos, nos funcionará para todos los enteros.

Para concluir, lo mejor que podemos utilizar para comparar en python es el operador ==, que éste sí que tiene el comportamiento esperado en todos los casos. Si queremos ir más en modo hardcore utilizando las referencias a memoria con cuidado, entonces utilizaremos is.

Fuente | Reddit

2 0

GTK y Python: Cambiar el estilo de una GTKLabel

Lleva siendo así prácticamente desde que implementé la GtkHeaderBar en Pimagizer, pero como habéis podido ver, recientemente uso el tema Arc, que implica tener un fondo oscuro en las barras de menús y herramientas. Y el problema surge ahí, en que los botones que tan bonitos se veían con el tema por defecto de GTK, pero cambia con un tema oscuro:

A la derecha botones con imagen en un tema GTK claro, a la derecha lo mismo pero con un tema oscuro
Claramente la diferencia está ahí…

La solución más eficaz pasa por convertir ese botón en uno normal y corriente, sin imágenes de ningún tipo, simplemente utilizando texto, y en concreto GTKLabel. Si estáis utilizando Glade o algún sistema gráfico parecido, podéis saltar a la siguiente sección.

Crear los elementos básicos

Daremos por hecho que ya tienes una ventanita corriendo con GTK, ya que el objetivo del artículo no es enseñar a utilizar los elementos de GTK, sino utilizar uno muy concreto. Aquí repasamos cómo se crea la etiqueta dentro del botón.

buttonPx = Gtk.ToggleButton()
labelPx = Gtk.Label("Px")  # Aquí va nuestro texto
buttonPx.add(labelPx)
buttonPx.show()
labelPx.show()

Un código bastante sencillito. Creamos un GtkToggleButton (hereda de GTKButton) y un objeto GTKLabel con el texto Px. Le decimos al botón que utilice la etiqueta que acabamos de crear y mostramos ambos objetos. Veamos cómo quedaría:

Los botones de la HeaderBar con etiquetas de texto pequeñas
No se parece demasiado al resultado que queremos conseguir…

Como podemos ver en la imagen, se consigue el objetivo de no usar una imagen para mostrar en los botones, pero son muy distintos de lo que teníamos antes: dos botones con el texto bien visible.

Decidiendo el estilo de la GTKLabel

Afortunadamente GTK ofrece bastantes herramientas para poder personalizar los aspectos que necesitemos, como este concretamente. Lo que estamos buscando exactamente es esto: Text Attribute Markup, que inicialmente fue desarrollada por Pango. Formalmente lo conocemos como Pango Text Attribute Markup Language. No os preocupéis demasiado: es muy parecido a HTML, así que aprender la sintaxis no será complejo.

Básicamente, la sintaxis se basa en XML al igual que HTML. Tenemos el soporte de etiquetas algo más reducido, pero las clásicas <b>, <i> o <u> las tenemos. Añade alguna más como <big>, <small>, <sup> y <sub>, permitiendo hacer cosas más complejas sin meterse con CSS. Lo interesante con las opciones viene con la etiqueta <span>, que permite una serie de opciones muy interesante, como distintas tipografías, colores o tamaños. De la que nos ocupa ahora son los tamaños, ya que los colores vendrán predefinidos por el tema GTK del usuario.

Para decidir el tamaño de nuestra etiqueta podemos utilizar medidas absolutas (píxeles, puntos, etc…) o relativas. Lo recomendable es utilizar medidas relativas, porque se adaptarán a la resolución que esté usando el usuario. Las medidas absolutas las veremos muy bien en nuestro ordenador, pero cambiará drásticamente cuando cambiemos a otro con una resolución más distinta.

Para la etiqueta <span> disponemos del atributo size=”” o font_size=””. En la documentación tenéis informacion sobre otros muchos atributos, y modos de uso, pero nos centaremos en los tamaños relativos. Disponemos de una escala de 7 tamaños, ordenadas de menor a mayor: ‘xx-small‘, ‘x-small‘, ‘small‘, ‘medium‘, ‘large‘, ‘x-large‘, ‘xx-large‘. La que aplicaremos en nuestra aplicación será la más grande, pues obtendremos el resultado similar al que conseguíamos con las imágenes.

<span size="xx-large"><b>Px</b></span>

También le ponemos la etiqueta <b> para darle más grosor a la fuente. Ahora sólo nos queda incorporarlo al código

Utilizar marcado Pango en GTKLabel

Al código de nuestra primera sección le debemos de dar unos breves retoques para poder poner lo que necesitamos. Y es que si rellenamos la etiqueta tal cual lo tenemos en el cuadro de texto anterior el usuario verá las etiquetas, que es algo que no deseamos. GTKLabel tiene un atributo que indica si se está utilizando marcado o no.

buttonPx = Gtk.ToggleButton()
labelPx = Gtk.Label("<span size="xx-large"><b>Px</b></span>")
buttonPx.add(labelPx)
buttonPx.show()
labelPx.set_use_markup(True)  # Muy Importante!!
labelPx.show()

Como vemos, la penúltima línea es la que nos dejará hacer la magia. Le estamos diciendo que aplique el marcado a esa etiqueta. Y ya, al ejecutar de nuevo nuestra aplicación tendremos el resultado que buscábamos:

Las GTKLabel de la aplicación ahora se ven adecuadamente
¡Ahora sí!

Siempre podéis consultar el resultado en directo en la versión 0.4.5 de Pimagizer.

Un saludo!

Véase: Documentación GTK | Pimagizer

0 0

Recuperar el acceso al sistema cuando pierdes la contraseña de usuario

Lo mío con la Raspberry es una especie de relación amor-odio. La abandoné en su caja hace algún mes, y esta misma semana la quise retomar, de nuevo, como un proyecto multicosa (perdón por la patada al diccionario). Algo así como mediacenter Kodi, servidor de ficheros y alguna que otra cosa. Eso sí, con la lentitud propia de la primera raspberry (la de 256MB de RAM).

El caso, que para ahorrar algo de tiempo decidí que era más sencillo retomar la copia de la tarjeta de memoria que ya traía instalada la distribución OSMC. Todo bien hasta que no podía iniciar sesión con SSH. Ni una sola de las contraseñas que recuerdo hacía que diera válido el usuario (no, ni siquiera con la que viene por defecto: osmc). Me había olvidado la contraseña.

Por suerte, simplemente sacando la tarjeta SD y metiéndola en un ordenador cualquiera es posible acceder al sistema de archivos. Y es aquí donde radica la principal condición para poder aplicar este método: tienes que poder acceder, tanto como lectura y escritura, al sistema de ficheros, incluidos los que corresponden al usuario root. Dicho de otro modo, debes de ser capaz de acceder físicamente al disco desde otra máquina.

Atención: Este método es aplicable a cualquier sistema Linux al cual  tengas acceso root al disco duro, sea la tarjeta sd de una raspberry pi o el disco duro o SSD de un ordenador cualquiera. Eso sí, no puede estar cifrado. Continuar leyendo “Recuperar el acceso al sistema cuando pierdes la contraseña de usuario”

2 0

BookletImposer: Crear libros y folletos para imprimir desde PDF

El verano no sólo ha traído falta de lluvias, sino que también ha habido buena sequía de artículos por aquí. Pero vamos, que el ordenador no ha faltado en la mano y los documentos PDF son de los ficheros más utilizados cuando se navega por la red.

Dicho esto, los PDF no sólo están muy bien pensados para leer por la pantalla del ordenador, sino para imprimirlos y poder leerlos en papel. Pero imprimirlos en A4 a veces no es del todo respetuoso con el medio ambiente: el papel es un recurso muy preciado que hay que cuidar.

Una opción para ahorrar papel puede ser imprimirlo a doble cara, que muchas impresoras lo soportan hoy en día. Pero probablemente sea una idea mucho mejor convertirlo en un folleto DIN A5 que se grapa en el lomo y queda como un pequeño libro. Continuar leyendo “BookletImposer: Crear libros y folletos para imprimir desde PDF”

1 0

Pimagizer, por fin, para Arch Linux

Tuvo hace algunos meses una escasa presencia en el AUR, el repositorio de Usuarios de Arch, pero debido a cambios que hicieron y a que no tuve tiempo en su momento, lo dejé pasar un poco. Ahora ha renacido y está disponible la aplicación Pimagizer lista para instalar en Arch y derivados con un sólo comando:

sudo yaourt -S pimagizer

Lo he podido probar sólo en mi ordenador. Si encontráis errores, no dudéis en reportarlos.

Y ya aprovecho y si no la conocéis, pues la doy un poco de bombo

Captura de Pimagizer en AntergosPimagizer nació para hacer la vida fácil a todos. Nació para muchas personas, que como yo trabaja con la web y necesita subir imágenes cambiando el tamaño de las fotos para no sobrecargar con muchos datos el tráfico. Porque muchas veces si se ve bien, no es necesario subir una imagen de 5Mb cuando los usuarios pueden ver mermado su rendimiento.

Nació prácticamente con Gnome 3 y ha ido evolucionando con él. Soy consciente de que necesita muchas mejoras, pero el código está en launchpad, y no es nada complicado colaborar. Os animo, aunque sea, a traducirla 😉

Saludos!

 

3 1

Actualización del código para extraer las fuentes de Google Fonts

No, no tiene mucho que ver con que Google haya mudado el repositorio de las fuentes a Github, pero me recordó que el script para extraer los .ttf lo tenía bastante olvidado. Así que lo he mejorado un poquillo y lo he convertido a Python 3. No debería daros muchos problemas para ejecutarlo.

webfonts2Lo primero que os pedirá es que le metáis una ruta del repositorio, es decir, primero necesitáis descargaros el repositorio de Github

git clone https://github.com/google/fonts.git

y después ejecutar el script*. Esta nueva versión permite extraerlo directamente a la carpeta .fonts/, para así tener todas las fuentes disponibles nada más arrancar un programa.

Para descargar el script: Lo tenéis como Gist o como archivo

* Si os diera fallo al ejecutar, es posible que no tenga permisos de ejecución. Para dárselos: o bien botón derecho->propiedades->permisos->permisos de ejecución o bien:

$ chmod +x extractttf3.py
./extractttf3.py

para darle permisos de ejecución y ejecutarlo directamente

Espero que lo disfrutéis 😉

1 0

Python logger: Deja de ensuciar la salida por consola

Algo muy común (y que yo hago a menudo) es poner muchos prints a la hora de hacer debug, para saber donde las cosas van bien y dónde se empiezan a desviar del resultado esperado. Luego, quitarlos, no es mucho trabajo, pero si las cosas vuelven a ir mal, pues toca meterlos de nuevo.

He descubierto no hace mucho la librería logging, que viene por defecto incluida (forma parte del batteries included!) en python. Tiene varios niveles de salida, según la importancia de lo que estemos notificando. Podríamos utilizarlo con opciones para que el programa muestre una salida de información extra (verbose) determinada, tal y como se comenta por StackOverflow.

De forma muy general, aunque podéis ampliarlo mucho más en la documentación oficial, para activar la salida debug, simplemente hay que llamar al método con ese nombre de la librería logger:


import logging

logging.warning("Mensaje de depuración")

Y veremos como salida:

WARNING:root:Mensaje de depuración

Si lo intentas con logging.info() o con logging.debug() no mostrará salida, ya que por defecto sólo muestra las salidas con mayor o igual importancia que warning. Para cambiarlo, hay que poner al principio una breve configuración:

logging.basicConfig(level=logging.DEBUG)

Saludos, y a disfrutar!

1 0

[Tip]Resolver una ecuación en Sage

Sage, para quienes no lo conozcan es un sistema de cálculo avanzado y muy complejo, similar a Mathematica, Matlab o Maple. Si por ejemplo queremos resolver una ecuación del tipo , solo hay que hacer lo siguiente:

x^2 - 2 = 0

solve( x^2 - 2 == 0, x)

En esta función observamos dos argumentos: la propia función y x. Este último argumento indica a sage que es una variable.

Si tenemos un sistema de ecuaciones como éste, debemos meter las dos ecuaciones en un array, definir las variables a usar, y meter los datos en la función “solve”:

3x+2y=47
9y-6x=4x

var('x,y')
solve ([3*x + 2*y == 47, 9*y - 6*x == 4*x], x,y)

Un buen lugar para probar esto puede ser Sage Cell

1 0