Automágica: durante 2017 estoy trabajando bastante en Automágica, mi software para editar libros: Más información - Posts relacionados

Alfabeto Calculadora

Todo empezó con este mail en la lista del Gleducar.

La entrada: una lista de palabras representables en una calculadora normal simplemente girando el display.

Esto parece algo sin mucha utilidad, pero esta técnica es utilizada en muchos dispositivos con capacidades gráficas reducidas para mostrar mensajes de error u otra informaición adicional a la salida numérica.

En este archivo están las palabras a procesar enviadas a la lista de correos (en la selección original de palabras no se incluyeron aquellas con la letra 'z', pero también podrían haber sido elejidas para representar en Alfabeto Calculadora): palabras.txt

El programa

Almuerzo de por medio escribí este código y lo mandé a la lista del Gleducar como respuesta al reto: alfabeto_calc.py (update: tiene la corrección que me sugirió Alecu)

La forma de representación que elejí es esta: tomar todas las letras y conviértalas a mayúsculas excepto a la 'h' ('h' puede representarse con un '4' de calculadora invertido, pero 'H' no se puede representar con ningún número). Podemos representar la 'l' en minúsculas o en mayúscula ('L'), al usar la mayúscula y representarla con el '7', nos guardamos el '1' para la 'I'. Una vez que se tiene la palabra en formato upper_except_h cambiar cada letra por el número correspondiente e invertir el orden de los números.

Links para leer un poco más

Resultado

Esta es la salida que se obtiene al correr el programa en una terminal con el archivo palabras.txt en el mismo directorio:

be = BE = 38

bebe = BEBE = 3838

bebible = BEBIBLE = 3781838

beisbol = BEISBOL = 7085138

belio = BELIO = 01738

bello = BELLO = 07738

beso = BESO = 0538

bielgo = BIELGO = 097318

bilioso = BILIOSO = 0501718

bilis = BILIS = 51718

biologo = BIOLOGO = 0907018

bis = BIS = 518

bisbiseo = BISBISEO = 03518518

bisel = BISEL = 73518

biso = BISO = 0518

bobilis = BOBILIS = 5171808

bobillo = BOBILLO = 0771808

bobo = BOBO = 0808

bohio = BOhIO = 01408

boi = BOI = 108

bolillo = BOLILLO = 0771708

bollo = BOLLO = 07708

bolo = BOLO = 0708

bolsillo = BOLSILLO = 07715708

bolso = BOLSO = 05708

e = E = 3

eh = Eh = 43

el = EL = 73

ele = ELE = 373

elegible = ELEGIBLE = 37819373

eliseo = ELISEO = 035173

elisio = ELISIO = 015173

elle = ELLE = 3773

ello = ELLO = 0773

elogio = ELOGIO = 019073

elogioso = ELOGIOSO = 05019073

eolio = EOLIO = 01703

es = ES = 53

ese = ESE = 353

eso = ESO = 053

gel = GEL = 739

geologo = GEOLOGO = 0907039

giboso = GIBOSO = 050819

gil = GIL = 719

gili = GILI = 1719

gis = GIS = 519

globo = GLOBO = 08079

globoso = GLOBOSO = 0508079

gobio = GOBIO = 01809

gol = GOL = 709

goloso = GOLOSO = 050709

he = hE = 34

helio = hELIO = 01734

heliosis = hELIOSIS = 51501734

hibleo = hIBLEO = 037814

hiel = hIEL = 7314

hielo = hIELO = 07314

higo = hIGO = 0914

hilo = hILO = 0714

hiogloso = hIOGLOSO = 05079014

hobo = hOBO = 0804

ibis = IBIS = 5181

ilegible = ILEGIBLE = 37819371

ileo = ILEO = 0371

ileso = ILESO = 05371

le = LE = 37

legible = LEGIBLE = 3781937

lego = LEGO = 0937

leible = LEIBLE = 378137

lelili = LELILI = 171737

lelo = LELO = 0737

leo = LEO = 037

les = LES = 537

lesbio = LESBIO = 018537

leso = LESO = 0537

libelo = LIBELO = 073817

libio = LIBIO = 01817

liego = LIEGO = 09317

ligio = LIGIO = 01917

lilili = LILILI = 171717

lio = LIO = 017

lioso = LIOSO = 05017

lis = LIS = 517

lisis = LISIS = 51517

liso = LISO = 0517

lo = LO = 07

lobo = LOBO = 0807

loboso = LOBOSO = 050807

logis = LOGIS = 51907

o = O = 0

obelo = OBELO = 07380

obeso = OBESO = 05380

oboe = OBOE = 3080

obolo = OBOLO = 07080

obseso = OBSESO = 053580

oh = Oh = 40

oible = OIBLE = 37810

oislo = OISLO = 07510

ole = OLE = 370

oleo = OLEO = 0370

oleoso = OLEOSO = 050370

os = OS = 50

oseo = OSEO = 0350

oso = OSO = 050

se = SE = 35

sebe = SEBE = 3835

sebillo = SEBILLO = 0771835

sebo = SEBO = 0835

seboso = SEBOSO = 050835

seis = SEIS = 5135

seise = SEISE = 35135

sello = SELLO = 07735

seo = SEO = 035

ses = SES = 535

seseo = SESEO = 03535

sesgo = SESGO = 09535

seso = SESO = 0535

si = SI = 15

sibil = SIBIL = 71815

sieso = SIESO = 05315

sigilo = SIGILO = 071915

sigiloso = SIGILOSO = 05071915

siglo = SIGLO = 07915

silbo = SILBO = 08715

silboso = SILBOSO = 0508715

silesio = SILESIO = 0153715

silo = SILO = 0715

siseo = SISEO = 03515

so = SO = 05

sobeo = SOBEO = 03805

sobo = SOBO = 0805

sois = SOIS = 5105

sol = SOL = 705

soleo = SOLEO = 03705

solio = SOLIO = 01705

solo = SOLO = 0705

sos = SOS = 505

sosiego = SOSIEGO = 0931505

soso = SOSO = 0505


Programación Temporal de Eventos con Python

Este artículo estuvo en mi lista de borradores (draft posts) por mucho tiempo ya. Evidente mente no cumplí con la consigna release early del desarrollo tipo bazar. Enough!

Este artículo va a hablar un poco de simulación de sistemas discretos, va a presentar un módulo que escribí como prueba de que se podía hacer y me va a servir para contarles algunas cosas uq e aprendí en el camino.

Sigo Aprendiendo Python y esta es una clase más.

Programación temporal de eventos

En el primer cuatrimestre de este año cursé una materia llamada Simulación. Estudiamos principalmente como simular sistemas discretos (como un grupo de pasajeros subiendo a un avión. Suben de a uno, en un momento hay 7 pasajeros a bordo y en otro momento hay 8, nunca hay 7.5) en contraposición a los sistemas continuos (como el tanque de nafta del avión dónde su nivel baja instante a instante cuando el avión está volando).

Básicamente existen dos tipos de técnicas que se pueden utilizar para simular sistemas discretos, las de orientación al intervalo y las de orientación al evento. En las del primer tipo, cada cierto tiempo t se verifica de alguna forma si ha ocurrido un evento y se realiza el procesamiento asociado a este. Esto lleva a impresiciones y en ocasiones a un gasto innecesesario de cpu. En las técnicas de orientación al evento estos problemas no existen.

Una de las técnicas más primitivas de orientación al intervalo (no se si se usa en la actualidad) es la de Programación Temporal de Eventos. Básicamente se tiene un reloj que cuenta el tiempo de simulación y una lista de eventos ordenada en el tiempo. Uno debe escribir una función o procedimiento por cada uno de los eventos principales del sistema (por ejemplo la llegada de una pieza a una máquina) y una función principal que contenga el main loop de la simulación. Esta irá tomando eventos de la lista, avanzará el tiempo de simulación según corresponda y los ejecutará. Siempre se toma el primero y se lo ejecuta, si no hay más elementos en la lista termina la siumulación.

Los eventos son agregados a la lista con una primitiva llamada por ejemplo PPE (programar próximo evento), dónde además de indicar cual será el próximo evento, se debe indicar dentro de cuanto tiempo a partir del actual se debe ejecutar.

Mientras cursaba, estudiaba y rendía pensaba que sería muy fácil implementar en Python un módulo que provea las primitivas necesarias para realizar una simulción por programación temporal de eventos. Poner y sacar funciones de una lista seguro sería sencillo en un lenguaje muy dinámico y donde todo (incluidas las funciones) son objetos. La semana siguiente a rendir estuve escribiendo un poco de código Python. El resultado es un módulo llamado pte que cubre las funcionalidades mínimas que yo pretendía.

Resultado

No pretendía realizar un imponente desarrollo ni pienso que alguien use esto alguna vez en serío. Es más bien una prueba de concepto (Proof of concept). Lo había avandonado y ni siquiera funcionaba sin tirar errores. Objetivo: que funcione.

Este es el módulo: pte.py (versión orginal)

Una versión con el consejo de Daniel: pte-d.py (gracias Daniel!)

Y este un ejemplo en el que lo uso: pte_ej2.py

Ejemplo de ejecución:


juanjo@sarge:~/python$ ./pte_ej2.py



500 piezas fueron aceptadas en 1247.55 unidades de tiempo.



Máximo tamaño de la cola para procesamiento 5.

Qué aprendí

Módulos

Más de lo que pueda decir sobre módulos: http://docs.python.org/tut/node8.html

reload(modulo)
Reload a previously imported module. The argument must be a module object, so it must have been successfully imported before. This is useful if you have edited the module source file using an external editor and want to try out the new version without leaving the Python interpreter. The return value is the module object (the same as the module argument).
Entonces lo que hay que hacer cuando se está trabajando en la consola de Python[1] es, primer importar el módulo que se quiere probar:

>>> import modulo

Hacer algunas pruebas:

>>> modulo.var1

1

>>> modulo.cuad(3)

9

Si luego editamos el texto de modulo y queremos probar la función que agregarmos:

>>> modulo = reload(modulo)

Funciones como objetos

En Python todo es un objeto, incluso las funciones. Sabiendo esto y teniendo en mente lo que quería hacer (en la definición de una función, explicitar que esta se llame en el futuro, es decir almacenarla en una lista de eventos) hice una pequeña prueba en el intérprete:

>>> l = []

>>> def f():

    l.append(f)





>>> l

[]

>>> f()

>>> l

[<function f at 0x418bce9c>]

>>> l[0]

<function f at 0x418bce9c>

>>> l

[<function f at 0x418bce9c>]

>>> l[0]()

>>> l

[<function f at 0x418bce9c>, <function f at 0x418bce9c>]

Esto es posible justamente gracias a que en Python las funciones son objetos. En ciencias de la computación esto se conoce como Funciones de Primera Clase, es decir que las funciones sean Objetos de Primera Clase, es decir que puedan ser creadas durante la ejecución de un programa, almacenadas en estructuras de datos, recuperadas más tarde para usarlas, pasadas como argumentos y retornadas en otras funciones. Más al respecto en wikipedia.

Ordenar según un criterio propio

Una lista puede ser ordenada según un criterio propio pasándole al método sort de una lista ese criterio en forma de función:

def _comparar_tiempos(a,b):

    """ Función auxiliar usada para ordenar los pares eventos,tiempos

    en la lista de eventos.

    """

    t1 = a[1]

    t2 = b[1]

    if (t1 > t2): return 1

    elif (t1 < t2): return -1

    else: return 0

y luego..

eventos.sort(_comparar_tiempos)

Espero les haya resultado interesante! [1] También conocida como REPL, algo muy piola cuando uno esta desarrollando.


GNU/Linux en Oro Verde

En Software Libre antes de reinventra la rueda uno puede ver si alguien ya resolvió el mismo problema, estos son links a los relatos del siempre bien ponderado César Emilio Portela y el archienemigo de persianas, jarrones y otroas cosas delicadas Bruno Vicente Gnoato:

    <li><a href="http://www.ceportela.com.ar/2006/09/03/jornada-gnulinux-del-lug-oro-verde/">Jornada GNU/Linux del Lug Oro Verde</a></li>
    
  • Viaje a Oro Verde, Part 2
  • Bonus track: http://www.lugoroverde.com.ar/nuevositio/node/430


    Fito Páez: “Yo, cuando tenía 15 años, compraba un disco y grababa 10”

    Interesante declaración, no? Estoy seguro de que a Fito no le molesta que en el cajón del escritorio donde estoy trabajando tenga dos CDs suyos que me copió un amigo o que en mi reproductor de mp3 tenga otro album suyo.

    Andrés Calamaro piensa algo parecido:

    "Si los conciertos están llenos, la piratería no me importa".

    Por cierto.. escucharon Calamaro querido!? Está muy bueno! Mi hermana trajo una copia al departamente hace un par de días y no dejamos de escucharlo. El apretado bolsillo de estudiante universitario no nos hubiera dejado comprarlo, además: ¿por qué alguien compraría un CD si puede obtenerlo gratis? ¿para ayudar a su artista favorito? Te tengo noticias: los artistas no reciben casi nada por la ventan de sus discos.

    El artículo que me hizo pensar estas cosas se titula: Mi cultura pirata (de La Nación de Chile). Si bien no me gustó mucho el título (robar barcos en alta mar poco tiene que ver con compartir música con amigos[1]) el contenido lo compensa.

    Esta es la sección del artículo de donde recojí las citas:

    “LA PIRATERÍA ES GENIAL” La megaestrella Robbie Williams, que ha vendido más de 41 millones de discos en el mundo, se atrevió a decir en una feria de música en Cannes: “La piratería es genial. Y nadie puede hacer nada para pararlo. Ya sé que mi compañía, mi jefe y mis contables me van a odiar por decir esto”. Algo parecido piensa el artista argentino Andrés Calamaro, y añade: “Si los conciertos están llenos, la piratería no me importa”. Y Fito Páez: “Yo, cuando tenía 15 años, compraba un disco y grababa 10”. O Manu Chao, quien junto a la precandidata a la Presidencia de Francia, Sègoléne Royal, y otras 70 personalidades, lanzaron el año pasado un manifiesto en contra de la persecución criminal de los que piratean música en Internet. Pero la poderosa industria del disco puede llegar a ser feroz. Cuando Alaska, la cantante símbolo de la “movida madrileña”, declaró que “como artista y autora soy la menos perjudicada por la piratería, porque soy la que menos gana por disco vendido”, retiraron todos sus CD de las tiendas porque no quiso retractarse. Ella, magnífica, con su desafiante melena roja, les contestó: “Estupendo, ahora mis discos serán aún más codiciados en los top manta” (como se llama a los “éxitos” de cuneta en ese país).

    El artículo no sólo habla de música, hay más cosas interesantes para leer:

    Pero la reina del top pirata es J.K. Rowling, autora de “Harry Potter”, que es la mujer más rica de Inglaterra, por encima de la Reina Isabel, a pesar de los desalmados que copian sus libros y sus millones de lectores ilegales.

    Así que no te lo pierdás: Mi cultura pirata

    Y vos.. ¿Qué pensás de la copia ilegal?

    [1] Si alguna vez te preguntaste por que se usa la palabra piratería, seguí este link: http://www.gnu.org/philosophy/words-to-avoid.es.html#Piracy (es solo un párrafo).


    Generación de imágenes con GD desde PHP

    Este es un ejemplo minimalista (pero de alguna utilidad) en el que un script php devuelve una imagen.

    Antes que nada

    Para que funcione hay que tener instalado el paquete php4-gd, descomentar la línea extension=gd.so en el archivo /etc/php4/apache2/php.ini y reiniciar el servidor web (apache).

    Barra de progreso

    Este script recibe como parámetro un pocentaje (10, 20, 50 o 90, qué tan completa está una tarea) y genera la barra de progreso correspondiente.

    Ver archivo: progreso.php

    Si accedemos a este script desde un navegador y le damos un valor al parámetro porcentaje obtendremos imágenes como estas:

    (suponiendo que el archivo está en /home/juanjo/public_html/)

    http://localhost/~juanjo/progreso.php?porcentaje=10

    10

    http://localhost/~juanjo/progreso.php?porcentaje=20

    20

    http://localhost/~juanjo/progreso.php?porcentaje=60

    60

    http://localhost/~juanjo/progreso.php?porcentaje=90

    90

    Más interesante que acceder directamente a este script es utilizarlo como fuente para una etiqueta img en html. Podemos tener un template donde haya algo como esto:

    <img src="progreso.php?porcentaje={P}"/>

    y a P se le da un valor calculado dinámicamente cada vez que se solicita la página.

    Recursos

    Un ejemplo más completo en: http://www.zend.com/zend/tut/dynamic.php (fué el hola-mundo con el que empecé a probar GD)

    GD en php.net: http://www.php.net/gd


    Fin de semana en Córdoba (mi selección de fotos)

    Esta es mi selección de fotos del viaje a Córdoba (con comentarios y todo!), que las disfruten!

    Pablito revisando el mapa en una parada para cargar gas.

    Pablito mirando el mapa

    En la misma estación, recién venidos del baño nos totamos esta foto con Mariano.. yo estaba re dormido!

    Con Mariano

    Una leidita de repaso al material de la charla.

    Repasando la charla

    l final.. no había por que ponerse nerviso! Me gustó la experiencia.

    Exponiendo

    El decálogo del expositor dice: No mostrará código en vivo. No funcionará. Por suerte la regla no se cumplió!

    Mostrando código en vivo

    El sueño todavía dejaba marcas en los cabellos de algunos de los miembros de la comunidad.. marcas que perdurarían todo el día :D

    Despeinado

    Señor.. nos saca una foto? El equipo completo de personas que viajamos a Córdoba: Bruno (Gorrito negro), César (Buso Negro), Juanjo (Campera gris), Pablito (Rubio), Mariano (Abajo).

    En la peatonal

    Un saludo luego de cruzar la avenida para los que se quedaron del otro lado.

    Saludo

    Pablo desde el cole que lo llevaba a Carlos Paz sacó la última foto el viaje.

    Tomada por Pablo desde el cole

    Un relato del viajé aquí: http://www.ceportela.com.ar/pythonday-cordobes/


    Creando plug-ins para GIMP con Python (charla)

    Este es el material de la charla que dí el sábado pasado (19 de agosto) en el 1º Python Day del Grulic:

      <li><a href="https://viejoblog.juanjoconti.com.ar/files/python/fu/charla-cordoba/index.html">Presentación (navegable y link al formato original)</a></li>
      
      <li>Código fuente</li>
      

      También tengo un texto que escribí para ordenar mis ideas, pero está muy desprolijo como para publicarlo. SI alguien lo quiere (es buena ayuda para seguir la presentación) pídamelo por mail y se lo mando.



      2 nuevos plug-ins en mi WP!

      Hoy agregé dos plug-ins en mi instación de WordPress (el sistema que uso como blog).

      Estadísticas de visitantes

      Hace un tiempo tenía instalado un sistema de estadísticas llamado.. bueno no recuerdo como se llamaba, pero no importa por que era bastante malo. Hoy leyendo en el blog de César M. Sandrigo descubrí otro y tal vez mi búsqueda (casi abandonada) de una buena forma de conocer sobre mis visitantes haya llegado por fin a Ítaca. El plug-in se llama PopStats.

      Votar los artículos

      Desde hoy, abajo de cada artículo, hay 5 estrellitas con las que los visitantes pueden rankear los posts publicados. La verdad, está muy lindo: Post Star Rating.

      Cuando dejé mi primer voto me pareció gracioso leer "1 votos" :) Luego pensé que no debería ser difícil de corregir, acá está la receta:

      Hay que hacer un pequeño cambio en dos métodos de la clase PSR (psr.class.php). Tanto en _drawStars($votes, $points) como en _drawVotingStars($votes, $points) cambiar ('votos') por ($votes == 1 ? 'voto' : 'votos').

      En la misma clase también se puede cambir el texto que se muestra.

      Otro detallecito que encontré fué que el texto que acompaña a las estrellitas, por ejemplo "2 votos" se veía cortado abajo, revisando el código fuente de la clase anterior encontré el método css() que le da el estilo; en una parte decía:

                 <code><pre> .PSR_stars {
      
                    height: 15px;
      
                    overflow: hidden;
      
                    padding: 0;
      
                    margin: 0;
      
                  }</pre></code>
      

      PSR_starts es la clase del div que contiene a las estrellitas y el texto. Simplemente comenté el límite impuesto a la altura:

                 <code><pre> .PSR_stars {
      
                    /*height: 15px;*/
      
                    overflow: hidden;
      
                    padding: 0;
      
                    margin: 0;
      
                  }</pre></code>
      

      Seguro que a más de uno le sirve!

      Saludos!


      OLPC en Argentina (audio con las últimas novedades)

      Acabo de mandar este mail a la lista de Gleducar:

      Franco Iacomella wrote:

      Hola gente,

      esta disponible el audio grabado en la sala de conferencia

      directamente desde los micrófonos. Pueden descargarlo desde Educ.ar:

      http://media.educ.ar/podcast/conferencias/OLPC/educar-charlaOLPC.mp3

      Me pidió Franco que lo pase a ogg y lo ponga en internet. Unos minutos

      para bajarlo, algunos menos para convertirlo[1] y toda la tarde para

      subirlo!!

      En formato ogg: http://firebirds.com.ar/~juanjo/educar-charlaOLPC.ogg

      Pasar un archivo de un formato lossy a otro formato lossy (como lo son

      mp3 y ogg, ya que comprimen a costa de perder caldiad información)

      no es recomendado: http://www.vorbis.com/faq/#transcode

      Quines prefieran usar un formato libre a pesar de perder un poco de

      calidad (yo no lo noté en este caso en particular) pueden hacerlo

      bajando el archivo desde la dirección que pasé.

      Además la versión ogg es más liviana:

      juanjo@sarge:~/Desktop$ ls -lh educar-charlaOLPC.*

      -rw-r--r-- 1 juanjo juanjo 148M 2006-07-23 15:03 educar-charlaOLPC.mp3

      -rw-r--r-- 1 juanjo juanjo 74M 2006-07-23 16:07 educar-charlaOLPC.ogg

      Saludos!

      Juanjo

      [1] Usé mp32ogg