Damián Avila: How to pin Conda

One interesting advance feature in Conda is the capacity to pin packages from your environments so they can not be updated at all. If you are interested in that specific version of some package and not the next one because it breaks your work completely or for some other reason, you are probably pinning that package. If you are adding the specific version in every command you run instead of pinning the package, you are doing it wrong and you should keep reading ;-)

But, is it possible to pin Conda itself so it does not get updated every time you try to install/update something else?

Read more… (2 min remaining to read)

Marcos Dione: tracing-python-execution

Today I stumbled upon PyCon 2016's youtube channel and started watching some of the talks. The first one I really finished watching was Ned Batchelder's "Machete debugging", a very interesting talk about 4 strange bugs and the 4 strange techniques they used to find where those bugs were produced. It's a wonderful talk, full of ideas that, if you're a mere mortal developer like me, will probably blow your mind.

One of the techniques they use for one of the bugs is to actually write a trace function. A trace function in cpython context is a function that is called in several different points of execution of Python code. For more information see sys.settrace()'s documentation.

In my case I used tracing for something that I always liked about bash: that you can ask it to print every line that's being executed (even in functions and subprocesses!). I wanted something similar for ayrton, so I sat down to figure out how this would work.

The key to all this is the function I mention up there. The API seems simple enough at first sight, but it's a little more complicated. You give this function what is called the global trace function. This function will be called with three parameters: a frame, an event and a event-dependent arg. The event I'm interested in is line, which is called for each new line of code that is executed. The complication comes because what this global trace function should return is a local trace function. This function will be called with the same parameters as the global trace function. I would really like an explanation why this is so.

The job for this function, in ayrton's case, is simple: inspect the frame, extract the filename and line number and print that. At first this seems to mean that I should read the files by myself, but luckily there's another interesting standard module: linecache to the rescue. The only 'real complication' of ayrton's use is that it would not work if the script to run was passed with the -c|--script option, but (un)luckily the execution engine already has to read the hold the script in lines, so using that as the cache instead of linecache was easy.

Finally, if you're interested in the actual code, go take a look. Just take in account that ayrton has 3 levels of tracing: à la bash (script lines prepended by +), with line numbers, and tracing any Python line execution, including any modules you might use and their dependencies. And don't forget that it also has 3 levels of debug logging into files. See ayrton --help!

ayrton python

Juanjo Conti: Clase de Guillermo Martínez en Santa Fe (audio)

Juanjo Conti: Taller de Python para NO programadores

La segunda meetup de Python en Santa Fe fue un taller de programación para no programadores. Es decir, un taller para personas no sabían ni siquiera qué es programar.


Estuvo muy bueno.

Use unas slides de Facundo Batista modificadas https://github.com/jjconti/charla-intro-python/blob/master/introprogram.odp

y fuimos armando un pequeño juego con lo que ibamos aprendiendo.

Al final, todos se coparon tirando features y las ibamos implementado en vivo:


Marcos Dione: creating-your-own-importer-in-python

ayrton has always been able to use any Python module, package or extension as long as it is in a directory in sys.path, but trying to solve a bigger bug, I realized that there was no way to use ayrton modules or packages. Having only laterally heard about the new importlib module and the new mechanism, I sat down and read more about it.

The best source (or at least the easiest to find) is possibly what Python's reference says about the import system, but I have to be honest: it was not an easy read. Next week I'll sit down and see if I can improve it a little. So, for those out there who, like me, might be having some troubles understanding the mechanism, here's how I understand the system works (ignoring deprecated APIs and corner cases or even relative imports; I haven't used or tried those yet):

def import_single(full_path, parent=None, module=None):
    # try this cache first
    if full_path in sys.modules:
        return sys.modules[full_path]

    # if not, try all the finders
    for finder in sys.meta_path:
        if parent is not None:
            spec = finder.find_spec(full_path, parent.__path__, target)
            spec = finder.find_spec(full_path, None, target)

        # if the finder 'finds' ('knows how to handle') the full_path
        # it will return a loader
        if spec is not None:
            loader = spec.loader

            if module is None and hasattr(loader, 'create_module'):
                module = loader.create_module(spec)

            if module is None:
                module = ModuleType(spec.name)  # let's assume this creates an empty module object
                module.__spec__ = spec

            # add it to the cache before loading so it can referenced from it
            sys.modules[spec.name] = module
                # if the module was passed as parameter,
                # this repopulates the module's namespace
                # by executing the module's (possibly new) code
                # clean up
                del sys.modules[spec.name]

            return module

    raise ImportError

def import (full_path, target=None):
    parent= None

    # this code iterates over ['foo', 'foo.bar', 'foo.bar.baz']
    elems = full_path.split('.')
    for partial_path in [ '.'.join (elems[:i]) for i in range (len (elems)+1) ][1:]
        parent = import_single(partial_path, parent, target)

    # the module is loaded in parent
    return parent

A more complete version of the if spec is not None branch can be found in the Loading section of the reference. Notice that the algorithm uses all the finders in sys.meta_path. So which are the default finders?

In [9]: sys.meta_path

Of those finders, the latter one is the one that traverses sys.path, and also has a hook mechanism. I didn't use those, so for the moment I didn't untangle how they work.

Finally, this is how I implemented importing ayrton modules and packages:

from importlib.abc import MetaPathFinder, Loader
from importlib.machinery import ModuleSpec
import sys
import os
import os.path

from ayrton.file_test import _a, _d
from ayrton import Ayrton
import ayrton.utils

class AyrtonLoader (Loader):

    def exec_module (klass, module):
        # «the loader should execute the module’s code
        # in the module’s global name space (module.__dict__).»
        load_path= module.__spec__.origin
        loader= Ayrton (g=module.__dict__)
        loader.run_file (load_path)

        # set the __path__
        # TODO: read PEP 420
        init_file_name= '__init__.ay'
        if load_path.endswith (init_file_name):
            # also remove the '/'
            module.__path__= [ load_path[:-len (init_file_name)-1] ]

loader= AyrtonLoader ()

class AyrtonFinder (MetaPathFinder):

    def find_spec (klass, full_name, paths=None, target=None):
        # TODO: read PEP 420 :)
        last_mile= full_name.split ('.')[-1]

        if paths is not None:
            python_path= paths  # search only in the paths provided by the machinery
            python_path= sys.path

        for path in python_path:
            full_path= os.path.join (path, last_mile)
            init_full_path= os.path.join (full_path, '__init__.ay')
            module_full_path= full_path+'.ay'

            if _d (full_path) and _a (init_full_path):
                return ModuleSpec (full_name, loader, origin=init_full_path)

                if _a (module_full_path):
                    return ModuleSpec (full_name, loader, origin=module_full_path)

        return None

finder= AyrtonFinder ()

# I must insert it at the beginning so it goes before FileFinder
sys.meta_path.insert (0, finder)

Notice all the references to PEP 420. I'm pretty sure I must be breaking something, but for the moment this works.

ayrton python

Mariano Guerra: Papers of the Week VII

Because nothing lasts forever and after a week half traveling and a busy one I managed to read 4 papers this week.

The first one was interesting but comes from an area I will describe as "let's bend relational databases to fit Event Stream Processing", which is not bad per se but has things like joins and being able to remember past events that make its scalability (at least in terms of memory) quite hard, also it never discuses distribution, which is ok for the field but not what I'm looking for.

The interesting part about this one is the part where it introduces Visibly Pushdown Languages something that looks really interesting but I couldn't find an introduction for mere mortals, the descriptions are really dense an mathematical, which is ok but hard to learn for outsiders like me.

Another interesting point is the fact that it uses the XML Schema to optimize the generated VPA (Visibly Pushdown Automata) and that the implementation not only applies to XML but to any nested semistructured data.

The review of the next one will seem conflicting with my previous reviews, but this one had too much enfasis on the low level implementation details, not novel things and optimizations, just a lot of details, like the guys found the implementation really cool and wanted to share it with the world. Not a bad thing per se, but in this batch I was looking for abstractions, optimizations and distribution characteristics of stream processing, better if focused on distributed systems, and this one talked mainly about the DSL they build that compiles to C. It also sorts the streams, does multiple passes over the data, does lookahead in the stream and does a kind of "micro batches" which isn't what I was looking for.

The last one, I found the approach interesting, they seemed to try to push the purity of the approach (everything is a regular expression) which may have end up with a nice model (a thing I like) but by reading the code it doesn't seem to be really clear, at least for a OO/functional background, and I think less for non programmers. Maybe the syntax doesn't help and some other syntax would make things clearer, I don't know.

Other than that the approach is interesting and it made me think on some ways to define a stream processing language using mainly pattern matching.

Papers this week: 4

Papers so far: 33

Papers in queue: 76

Juanjo Conti: Paredón

Durante la escuela primaria, jugaba mucho al fútbol. Jugaba en los recreos de la escuela, en el club y en una canchita cerca de casa. A esa canchita iba en bici, una bici roja con calcomanías plateadas. La dejaba tirada y corría hasta donde el resto estaba pateando. Éramos siempre seis o siete. La mayoría, de la misma escuela; algunos un año más chicos, otros un año más grandes, y, de vez en cuando, algún que otro desconocido. Por lo general, pensábamos que los desconocidos no iban a la escuela, a ninguna, y eso les daba un aura de renegados, un halo de misterio que provocaba admiración y respeto. Si la pateaban lejos la pelota, no se la hacíamos buscar.

La canchita quedaba al lado de la casa del Sapo; era de tierra y tenía arcos que su abuelo había hecho con ramas secas atadas con alambre. Nunca conoció la gramilla. Jugábamos tanto que no le dábamos tiempo de crecer al pasto. Era un manto marrón violáceo con textura de talco. Parecía que jugábamos en una cancha de chocolate "El Quilla".

El Sapo era nuestro mejor delantero. Era zurdo y tenía una pegada que hacía temblar el alambrado que estaba atrás de los arcos. Muchas veces, si pegaba en el palo, hacía que el travesaño se cayera. Teníamos que suspender el partido y arreglar el arco. El resto éramos de regular para abajo. Ninguno iba a llegar a primera nunca. Sin embargo, el Sapo… sí podría haber llegado.

Una característica que tenía nuestro grupo era que carecía de arquero. A nadie le gustaba tener que atajar. Seguramente por eso, uno de los juegos más comunes entre nosotros era el "veinticinco". Alguien al azar empezaba en el arco. Cada vez que atajaba un tiro, podía usar la pelota para intentar golpear a uno de los otros jugadores. Si lo conseguía sin que la pelota pique, el jugador golpeado se convertía en el nuevo arquero. La secuencia seguía hasta llegar a los veinticinco puntos en el marcador global, que se acumulaban a medida que hacíamos goles. Diferentes tipos de goles valían diferente cantidad de puntos. Por ejemplo, un gol normal con el pie valía uno, pero un gol de cabeza, cinco. Cuando se llegaba a los veinticinco puntos, quien estaba en el arco tenía que cumplir una prenda. La clásica era el capotón: la víctima se agachaba, tratando de cubrirse, mientras todos los demás le pegábamos en la espalda.

Una de esas tantas tardes, el Sapo estaba en el arco y el puntaje acumulado era de veinticuatro. En total, éramos seis chicos jugando. Los que no estábamos en el arco, nos acercábamos tocando la pelota y cuando estábamos lo suficientemente cerca, pateábamos con la esperanza de hacer un gol. Inmediatamente después, retrocedíamos a toda velocidad para intentar evitar la embestida del arquero, que nos tiraba con potencia la pelota.

En un determinado momento, Fitipaldi, uno que era nuevo en la escuela, pasó a tener la pelota. No se animó a patear y me dio un pase muy cerca del área. El Sapo se me vino arriba y pateé como pude. El Sapo atrapó la pelota en el aire y antes de que pudiera reaccionar, me la lanzó con suavidad sobre el cuerpo. Estaba tan cerca que no pude esquivarla y en el intento, me caí. Ante las carcajadas de todos, tomé mi lugar en el arco con la pelota en la mano. La suma seguía en veinticuatro.

Todos estaban a más de quince metros de distancia. Imposible alcanzarlos. De todas formas, lo intenté. Con fuerza, lancé la pelota con la mano derecha, apuntando vagamente al montón. Se abrieron. Algunos para la derecha, otros para la izquierda, y la pelota pasó picando entre ellos.

En menos de un minuto, luego de otro pase de Fitipaldi, el Sapo pateó al arco de media distancia y me hizo el gol que sumó veinticinco.

---¡Veinticinco, capotón! ---gritó uno mientras yo iba tomando la posición adecuada para recibir el castigo.

---No, mejor no. Tengo otra prenda ---dijo el Sapo y a continuación, explicó el "paredón"---. El que tiene que cumplir la prenda se para de espalda a nosotros, mirando la pared. Ponemos la pelota a seis pasos largos y uno patea "a fundir" para pegarle en la espalda.

---¡Sí! ---vitorearon todos con entusiasmo.

Yo no dije nada; estaba pensando en mis posibilidades. A diferencia del capotón en el que tenía la golpiza asegurada, en esta nueva modalidad tenía la posibilidad de salir ileso. Por supuesto, si me embocaban, el golpe sería más duro.

---¿Y quién patea? ---preguntó uno.

---El que metió el último gol ---respondió el Sapo.

Me ubiqué sin chistar y me persigné varias veces repitiendo en silencio una jaculatoria. "Que le erre", "que le erre", "que le erre".

El sonido pareció uno, pero en realidad fue un repique rápido de tambor: el botín del Sapo en contacto con la pelota de cuero y una fracción de segundo después, el cuero de la pelota contra mi espalda.

---¡Uhhhhhhh! --- gritó el coro de espectadores que, en una onomatopeya, expresó lo que yo no pude. Casi no podía respirar. Encorvado y con un brazo levantado pedía clemencia.

Como no quería que me vean llorar, agarré la bicicleta y pedaleando rápido me volví a mi casa. Estaba transpirado y sucio de tierra. Apenas llegué, sin saludar a nadie, me metí en el baño. Me saqué la remera y mirando para atrás, me vi la espalda en el espejo. Tenía un círculo rojo perfectamente delimitado. Mi espalda parecía la bandera de Japón. Ya no me dolía el golpe, pero ahora sentía un ardor en la piel. Me bañé y no hablé con nadie sobre el asunto.

Al otro día, con el dolor y la vergüenza casi olvidados, volví a la canchita. Además de los de siempre, había un chico nuevo.

El Crema, le decían. Yo lo había visto alguna vez en la escuela.

Que hubiera uno nuevo era bueno. Todos nos complotábamos para hacerlo perder. Si no estaba en el arco, hacíamos que se acerque a él mediante falsas promesas de gol y lo traicionábamos a último momento. Cuando ya estaba en el arco, pateábamos de lejos sin importar que tardásemos en sumar. Así pasó esa tarde con el Crema. Cuando entró en el arco, no salió más.




Yo quería hacer el último gol. Y quería que le hagamos "paredón". Quería vengarme. No me importaba que el Crema no haya estado el día anterior. Solo quería darle un puntinazo con fuerza a la pelota e incrustársela en la espalda.


Otra vez el Sapo, desde muy lejos, metió un zapatazo y cerró el juego.

---¿Qué eligen? ---dijo con la pelota bajo el brazo--- ¿capotón o paredón?

---¡Paredón! ---grité solo. Se ve que a los demás les daba lo mismo.

El Crema, que conocía la prenda, se paró resignado mirando la pared.

El Sapo depositó la pelota en el suelo y, como si estuviera por ejecutar un penal, se paró dos metros atrás. Miró al Crema, miró la pelota. Volvió a mirar al Crema y luego volvió a mirar la pelota. Tomó carrera y cuando su pie impactó en el esférico, con una sonrisa endiablada me felicité por no estar ahí, de espaldas, esperando el impacto.

La pelota no le dio en la espalda. Le pegó en la cabeza. El Crema se quedó tirado en el piso. Quieto.

Este cuento fue escrito para el concurso #historiasdefutbol de Zenda.