Facundo Batista: Pasaron los PyDays de Mayo

Dos PyDays teníamos planeados para este mes, el de La Plata y el del NEA.

Fui a ambos, salieron los dos muy bien.

El de La Plata fue el primero que se hacía en dicha ciudad. Organizado por Sofia y un par de secuaces, se realizó en la Facultad De Informática de la UNLP y contó con tres tracks en paralelo, un hall con varios stands, charlas de todo tipo (incluyendo lightning talks) y hasta un cierre con banda de rock.

Incluso tuvimos una charla debate sobre diversidad donde charlamos sobre el problema que tenemos en las comunidades de informática en donde los hombres estamos sobrerrepresentados y varios temitas más. Salió muy bien, y llegamos a la conclusión de que debemos hacer más de estos debates (aunque con un moderador que sepa moderar :p ).

En la charla debate sobre diversidad

El del NEA se hizo en Corrientes, en el Club de Emprendedores. Lo organizaron Sergio y Marian, y también salió bárbaro. Vino mucha más gente de lo que esperábamos, saturamos completamente las instalaciones... pusimos sillas en la parte de atrás de la sala, afuera, y hasta en el patio, y al final de todo eso había gente parada!

El próximo se va a tener que hacer en un lugar más grande! :D

Mucha gente

Acá hay algunas fotos que sacó Marian.

En el segundo semestre vamos por más: ya estamos esperando el PyDay de Luján, fecha a confirmar :). Mientras, para que no decaiga, iremos armando algunos meetups... este miércoles vamos invitados a este.

Roberto Alsina: GitHub and GitLab for newbies

I wrote a git tutorial for those who don't know git where I tried to explain how to use Git for version control on your local machine.

Of course those of you who know about these things already know that half the fun of git is not using it locally, but using a server that can centralize the develpment and allow collaboration.

Well, good news! I just wrote the chapter where I cover that part!

Read and let me know what you think:

Git Hosting

Facundo Batista: PyCamp 2018

Pasó una nueva edición del mejor evento del año, el PyCamp!

Como siempre, lleno de Python, pero también de mil cosas más.

A nivel Python, estuve laburando en fades un poco, pero más que nada difundiéndolo y haciendo que todos, todos, todos, estén al tanto de las bondades del sistemita... un poco denso, estuve, sí :p. También llevé como proyecto a linkode pero acá el que estuvo laburando (en la migración del mismo a Python 3) fue Matías, un capo.

También estuve en largas charlas sobre cual va a ser el futuro de la lista de correo de PyAr (estuvimos analizando opciones), y el diseño del sitio web de gestión para la Asociación Civil Python Argentina. Y después yendo y viniendo por ahí, ayudando a gente en cosas puntuales que necesitaban, charlando, aprendiendo, disfrutando.

La típica grupal

Fuera de lo que es Python o programación en sí, podemos separar las actividades en dos grupos: juegos de mesa y resto.

El primer juego de mesa al que jugué, valga la cacofonía, fue el Belfort, al cual ya jugué varias veces y me encanta. Gané por lejos. Otro repetido fue el Galaxy Trucker, pero en este si juegan Sofia o Fisa no tenés chance. Otro en el que fui vapuleado fue (nuevo para mí) el Age of War. Y también jugué al Timeline (de inventos), gané el primero, el segundo quedé como cuarto.

Actividades sociales por fuera de los juegos de mesa también hubieron un montón. Aprendí a hacer malabares rebotando pelotitas contra el piso (sólo, con dos y tres pelotitas, y grupal, de a 3, 4 o 5 personas, haciendo combinaciones superlocas, armando y desarmando coreografías, fue muy divertido). Aprendí arquería con arcos de verdad (gracias Joaco por las clases). Jugué al basquet (y me raspé una rodilla y rompí una zapatilla). Armé un campeonato de ping-pong, pero perdí en la segunda ronda, 18-21 en el tercer partido, contra el que finalmente ganó el torneo. Hicimos música a cuatro manos en un piano. Montonazazazo de actividades.

Nos agarraste trabajandoHaciendo música

Obviamente, como en todo PyCamp, también hicimos una reunión de PyAr. Charlamos sobre los próximos eventos, algunos anuncios operativos de esos días, y algunos detalles más, pero lo principal fue el balance del PyCamp: qué estuvo bueno, qué estuvo fantástico, en qué cosas debemos mejorar. Nos llevamos un par de ideas para el PyCamp del año que viene, tanto en la preparatoria de las semanas anteriores, como mejoras a hacerle al bot del PyCamp.

Como nota de color, una tarde fuimos a buscar a unos chicos que llegaban a la terminal de Baradero, y al volver nos quedamos en el barro. Estuve 25 minutos tratando de sacar el auto de donde se había empantanado (en dos lugares distintos, imposibles), y al final salí victorioso. Pero me tembló hasta el culo por un par de horas....

Los que fueron magos en algún punto del eventoAlecu y el ventilagón, que fue uno de los proyectos

También, pero más importante, quiero destacar que brillamos en nuestras métricas de diversidad (gracias PSF por las becas para esto): fuimos un 25% de mujeres, y 50% de gente que era su primer PyCamp. Un éxito.

Pero no todo es brillar, especialmente cuando se corta la luz en todo el barrio! Fueron un par de horas, cuando anochecía, pero no nos amedrentamos y seguimos pycampeando casi como si nada hubiera pasado...

Se nos cortó la luzHicimos basquet, malabares, pingpong, espadas... y arquería

Para cerrar, les dejo las fotos mías (más algunas que saqué del grupo de Telegram), las de Yami (fotógrafa oficial), y les prometo el video presentación de todo lo que hicimos (cuando José Luis lo procese, digamos todos "gracias José Luis").

Roberto Alsina: Playing With Picolisp (Part 1)

I want to learn new languages. But new as in "new to me", not new as in "created last week". So I decided to play with the grandaddy of all cool languages, LISP. Created in 1958, it's even older than I, which is good because it's experienced.

One "problem" with LISP is that there are a million LISPs. You can use Scheme or Common Lisp, or Emacs' Lisp, or a bazillion others. I wanted something simple so it was supposed to be Scheme... but a few days ago I ran into something called Picolisp and it sounded so cool.

Leer más… (quedan 7 minutos de lectura)

Damián Avila: Some thoughts about the 2017 ACM Software System Award for Project Jupyter

I am very happy to inform you that Project Jupyter has been awarded the 2017 ACM Software System Award!

As part of the Jupyter Steering Council, I am one of the official recipients of the award, but I wanted to highlight that I am just one member of a large group of people (contributors and users) working together to push the Project Jupyter forward and beyond its limits.

Project Jupyter is an essential part of my life. It gave me the opportunity to work with amazing people, to learn a lot of new things, to help other people. Some years ago, I left academia for several reasons, but one of the most important ones was to find an opportunity to make a substantial impact on people’s lives. I wanted to be involved in something that could empower people to do amazing things. And I certainly believe that Project Jupyter filled that space and allowed me to achieve that goal more than I could imagine.

Read more… (2 min remaining to read)

Roberto Alsina: Playing with Nim

A few days ago I saw a mention in twitter about a language called Nim

And... why not. I am a bit stale in my programming language variety. I used to be fluent in a dozen, now I do 80% python 10% go, some JS and almost nothing else. Because I learn by doing, I decided to do something. Because I did not want a problem I did not know how to solve to get in the way of the language, I decided to reimplement the example for the python book I am writing: a text layout engine that outputs SVG, based on harfbuzz, freetype2 and other things.

This is a good learning project for me, because a lot of my coding is glueing things together, I hardly ever do things from scratch.

So, I decided to start in somewhat random order.

Preparation

I read the Nim Tutorial quickly. I ended referring to it and to Nim by example a lot. While trying out a new language one is bound to forget syntax. It happens.

Wrote a few "hello world" 5 line programs to see that the ecosystem was installed correctly. Impression: builds are fast-ish. THey can get actually fast if you start using tcc instead of gcc.

SVG Output

I looked for libraries that were the equivalent of svgwrite, which I am using on the python side. Sadly, such a thing doesn't seem to exist for nim. So, I wrote my own. It's very rudimentary, and surely the nim code is garbage for experienced nim coders, but I ended using the xmltree module of nim's standard library and everything!

import xmltree
import strtabs
import strformat

type
        Drawing* = tuple[fname: string, document: XmlNode]

proc NewDrawing*(fname: string, height:string="100", width:string="100"): Drawing =
        result = (
            fname: fname,
            document: <>svg()
        )
        var attrs = newStringTable()
        attrs["baseProfile"] = "full"
        attrs["version"] = "1.1"
        attrs["xmlns"] = "http://www.w3.org/2000/svg"
        attrs["xmlns:ev"] = "http://www.w3.org/2001/xml-events"
        attrs["xmlns:xlink"] = "http://www.w3.org/1999/xlink"
        attrs["height"] = height
        attrs["width"] = width
        result.document.attrs = attrs

proc Add*(d: Drawing, node: XmlNode): void =
        d.document.add(node)

proc Rect*(x: string, y: string, width: string, height: string, fill: string="blue"): XmlNode =
        result = <>rect(
            x=x,
            y=y,
            width=width,
            height=height,
            fill=fill
        )

proc Text*(text: string, x: string, y: string, font_size: string, font_family: string="Arial"): XmlNode =
        result = <>text(newText(text))
        var attrs = newStringTable()
        attrs["x"] = x
        attrs["y"] = y
        attrs["font-size"] = font_size
        attrs["font-family"] = font_family
        result.attrs = attrs

proc Save*(d:Drawing): void =
   writeFile(d.fname,xmlHeader & $(d.document))

when isMainModule:
        var d = NewDrawing("foo.svg", width=fmt"{width}cm", height=fmt"{height}cm")
        d.Add(Rect("10cm","10cm","15cm","15cm","white"))
        d.Add(Text("HOLA","12cm","12cm","2cm"))
        d.Save()

While writing this I ran into a few issues abd saw a few nice things:

To build a svg tag, you can use <>svg(attr=value) which is delightful syntax. But what happens if the attr is "xmlns:ev"? That is not a valid identifier, so it doesn't work. So I worked around it by creating a StringTable filling it and setting all attributes at once.

A good thing is the when keyword. usingit as when isMainModule means that code is built and executed when svgwrite.nim is built standalone, and not when used as a module.

Another good thing is the syntax sugar for what in python we would call "object's methods".

Because Add takes a Drawing as first argument, you can just call d.Add() if d is a Drawing. Is simple, it's clear and it's useful and I like it.

One bad thing is that sometimes importing a module will cause weird errors that are hard to guess. For example, this simplified version fails to build:

import xmltree

type
        Drawing* = tuple[fname: string, document: XmlNode]

proc NewDrawing*(fname: string, height:string="100", width:string="100"): Drawing =
        result = (
            fname: fname,
            document: <>svg(width=width, height=height)
        )

when isMainModule:
        var d = NewDrawing("foo.svg")
$ nim c  svg1.nim
Hint: used config file '/etc/nim.cfg' [Conf]
Hint: system [Processing]
Hint: svg1 [Processing]
Hint: xmltree [Processing]
Hint: macros [Processing]
Hint: strtabs [Processing]
Hint: hashes [Processing]
Hint: strutils [Processing]
Hint: parseutils [Processing]
Hint: math [Processing]
Hint: algorithm [Processing]
Hint: os [Processing]
Hint: times [Processing]
Hint: posix [Processing]
Hint: ospaths [Processing]
svg1.nim(9, 19) template/generic instantiation from here
lib/nim/core/macros.nim(556, 26) Error: undeclared identifier: 'newStringTable'

WAT? I am not using newStringTable anywhere! The solution is to add import strtabs which defines it, but there is really no way to guess which imports will trigger this sort of issue. If it's possible that importing a random module will trigger some weird failure with something that is not part of the stdlib and I need to figure it out... it can hurt.

In any case: it worked! My first working, useful nim code!

Doing a script with options / parameters

In my python version I was using docopt and this was smooth: there is a nim version of docopt and using it was as easy as:

  1. nimble install docopt
  2. import docopt in the script

The usage is remarkably similar to python:

import docopt
when isMainModule:
        let doc = """Usage:
        boxes <input> <output> [--page-size=<WxH>] [--separation=<sep>]
        boxes --version"""

        let arguments = docopt(doc, version="Boxes 0.13")
        var (w,h) = (30f, 50f)
        if arguments["--page-size"]:
            let sizes = ($arguments["--page-size"]).split("x")
            w = parse_float(sizes[0])
            h = parse_float(sizes[1])

        var separation = 0.05
        if arguments["--separation"]:
            separation = parse_float($arguments["--separation"])
        var input = $arguments["<input>"]
        var output = $arguments["<output>"]

Not much to say, other that the code for parsing --page-size is slightly less graceful than I would like because I can't figure out how to split the string and convert to float at once.

So, at that point I sort of have the skeleton of the program done. The missing pieces are calling harfbuzz and freetype2 to figure out text sizes and so on.

Interfacing with C libs

One of the main selling points of Nim is that it interfaces with C and C++ in a striaghtforward manner. So, since nobody had wrapped harfbuzz until now, I could try to do it myself!

First I tried to get c2nim working, since it's the recommended way to do it. Sadly, the version of nim that ships in Arch is not able to build c2nim via nimble, and I ended having to manually build nim-git and c2nim-git ... which took quite a while to get right.

And then c2nim just failed.

So then I tried to do it manually. It started well!

  • To link libraries you just use pragmas: {.link: "/usr/lib/libharfbuzz.so".}

  • To declare types which are equivalent to void * just use distinct pointer

  • To declare a function just do some gymanstics:

    proc create*(): Buffer {.header: "harfbuzz/hb.h", importc: "hb_buffer_$1" .}

  • Creates a nim function called create (the * means it's "exported")

  • It is a wrapper around hb_buffer_create (see the syntax there? That is nice!)

  • Says it's declared in C in "harfbuzz/hb.h"

  • It returns a Buffer which is declared thus:

type
    Buffer* = distinct pointer

Here is all I could do trying to wrap what I needed:

{.link: "/usr/lib/libharfbuzz.so".}
{.pragma: ftimport, cdecl, importc, dynlib: "/usr/lib/libfreetype.so.6".}

type
        Buffer* = distinct pointer
        Face* = distinct pointer
        Font* = distinct pointer

        FT_Library*   = distinct pointer
        FT_Face*   = distinct pointer
        FT_Error* = cint

proc create*(): Buffer {.header: "harfbuzz/hb.h", importc: "hb_buffer_$1" .}
proc add_utf8*(buffer: Buffer, text: cstring, textLength:int, item_offset:int, itemLength:int) {.importc: "hb_buffer_$1", nodecl.}
proc guess_segment_properties*( buffer: Buffer): void {.header: "harfbuzz/hb.h", importc: "hb_buffer_$1" .}
proc create_referenced(face: FT_Face): Font {.header: "harfbuzz/hb.h", importc: "hb_ft_font_$1" .}
proc shape(font: Font, buf: Buffer, features: pointer, num_features: int): void {.header: "harfbuzz/hb.h", importc: "hb_$1" .}

proc FT_Init_FreeType*(library: var FT_Library): FT_Error {.ft_import.}
proc FT_Done_FreeType*(library: FT_Library): FT_Error {.ft_import.}
proc FT_New_Face*(library: FT_Library, path: cstring, face_index: clong, face: var FT_Face): FT_Error {.ft_import.}
proc FT_Set_Char_Size(face: FT_Face, width: float, height: float, h_res: int, v_res: int): FT_Error {.ft_import.}

var buf: Buffer = create()
buf.add_utf8("Hello", -1, 0, -1)
buf.guess_segment_properties()

var library: FT_Library
assert(0 == FT_Init_FreeType(library))
var face: FT_Face
assert(0 == FT_New_Face(library,"/usr/share/fonts/ttf-linux-libertine/LinLibertine_R.otf", 0, face))
assert(0 == face.FT_Set_Char_Size(1, 1, 64, 64))
var font = face.create_referenced()
font.shape(buf, nil, 0)

Sadly, this segfaults and I have no idea how to debug it. It's probably close to right? Maybe some nim coder can figure it out and help me?

In any case, conclusion time!

Conclusions

  • I like the language
  • I like the syntax
  • nimble, the package manager is cool
  • Is there an equivalent of virtualenvs? Is it necessary?
  • The C wrapping is, indeed, easy. When it works.
  • The availability of 3rd party code is of course not as large as with other languages
  • The compiling / building is cool
  • There are some strange bugs, which is to be expected
  • Tooling is ok. VSCode has a working extension for it. I miss an opinionated formatter.
  • It produces fast code.
  • It builds fast.

I will keep it in mind if I need to write fast code with limited dependencies on external libraries.

Facundo Batista: Relanzamiento del Blog

Entramos en la tercer etapa de mi blog.

La primera habían sido esos textos que había escrito mientras estaba en Italia haciendo el Máster en el segundo semestre del 2002, y que colgaba de un sitio armado muy a mano.

La segunda, desde el 2004 hasta ahora, con forma propiamente de "blog", soportado por un software hecho en PHP que primero se llamó "pLog", pero que luego se renombró a "LifeType", que luego de irse quedando cada vez más y más, se murió algo así como hace 5 años.

Llegó el momento de cambiarlo por algo moderno, vivo, y mantenible. Y en lo posible, lindo.

El ciclo de la vida es renovarse

No tenía demasiados requerimientos para el nuevo sistema, pero tenía que ser en Python, liviano, y que me dejara tener toda la estructura (especialmente los textos) en algún repositorio, y con un markup decente. Elegí Nikola, un generador de sitios estáticos que cumple con todos esos requisitos, y encima fue creado por un amigo.

El tema de mantener los textos de forma estándar era un tema: en LifeType se editaban los posts directamente desde la web, y como el editor fue cambiando durante sus años de vida, los formatos de los textos (el markup HTML que tenían alrededor) eran todos diferentes. Eso, sumado a que ya que migraba quería asegurarme de no dejar basura escondida, hizo que me dedicara los últimos dos años (poquito a poquito, sin que me tome demasiado tiempo, y por eso es que tardó mucho) a ir convirtiendo a mano los más de 700 posts al nuevo formato.

Como ya tenía demasiado trabajo con la migración de estos textos, y empecé a estar presionado con la migración a un nuevo sistema (porque tanto LifeType como el server donde tenía todo montado no tenían parches de seguridad hace rato) decidí tercerizar la construcción del nuevo sitio en Nikola. Así que todo esto que ven acá fue realmente construido en su mayoría por Marian Vignau del lado estructural del blog (todo lo que tiene que ver con Nikola, mostrar las propaganditas, meter el widget de twitter, etc, etc, etc) y por Cecilia Schiebel en lo que respecta a diseño y estética.

Uno de los puntos débiles de los sitios estáticos es el sistema de comentarios. Para esto traté de ir a "lo más usado", a una especie de "default en la industria" que es Disqus. Algunas desventajas tenía, como que es medio pesado, y dicen por ahí que hace mucho tracking de la gente que lo usa. Pero no tenía ganas de invertir demasiado tiempo en eso (todavía no estoy seguro de que valga la pena mantener un sistema de comentarios! ¿pensás distinto? demostralo haciendo un comentario :p ), así que intenté ir por ahí. Es más, Marian lo integró al sitio y todo, pero después me di cuenta que los nombres de los autores originales, cuando no eran 100% ASCII, estaban rotos. Y charlando con gente de Disqus me reconocieron que es un bug, y andá a saber cuando lo van a arreglar.

Así que fui por otro lado. Isso. Tiene la "desventaja" de que hay que hostearlo uno mismo, pero es simple, y me saco de encima tener que suscribirme a un servicio de terceros, que trackeen mis lectores, etc. No tenía una forma de importar comentarios que no sea de Disqus o Wordpress, pero como está hecho en Python, lo hice yo mismo (y lo propuse para que lo integren al sistema).

En fin. Bienvenidos al futuro (?).

Nos prometieron autos voladores y todo lo que tenemos son generadores de sitios estáticos

La estructura del sitio en sí tampoco cambió tanto. Seguimos teniendo el texto en el centro, con la barra de la derecha, aunque dejé ahí sólo lo que corresponde a contenido y moví otras cosas (licencia, rss, archivos, etc.) al footer. La búsqueda la provee Duck Duck Go (aunque le cambié recién el dominio de beta a final y está un poco confundido, vamos a darle unos días). Y en general debería verse bien más allá del tamaño de pantalla.

Obvio, me falta corregir un montón de cosas, algunas visibles y otras no, pero ya quería hacer la migración y anunciar esto (los últimos ~5 posts los tuve que hacer en los dos sistemas, encima que tengo poco tiempo, laburar duplicado no escala).

Cualquier detalle que encuentren o lo que sospechen que está roto, chiflen.

Roberto Alsina: Código Charla PyDay "Como Hacer una API REST en Python, spec first"

El 4/4/2018 di una charla en un PyDay sobre como implementar una API REST a partir de una especificación hecha en Swagger/OpenAPI usando Connexion

/images/pyday-api-rest.jpg

Foto tomada por Yamila Cuestas

Si bien no pude grabar la charla (alguien en la audiencia si lo hizo, pero no me dio el video! Pasame el video, persona de la audiencia!) y no hay slides, acá está el código que mostré, que es relativamente sencillo y fácil de seguir.

Código de la charla

Cualquier cosa pregunten.

PD: Sí, podría hacer la charla en un video nuevo. Sí, me da mucha pereza.

Roberto Alsina: My Git tutorial for people who don't know Git

As part of a book project aimed at almost-beginning programmers I have written what may as well pass as the first part of a Git tutorial. It's totally standalone, so it may be interesting outside the context of the book.

It's aimed at people who, of course, don't know Git and could use it as a local version control system. In the next chapter (being written) I cover things like remotes and push/pull.

So, if you want to read it: Git tutorial for people who don't know git (part I)

PS: If the diagrams are all black and white, reload the page. Yes, it's a JS issue. Yes, I know how to fix it.

Roberto Alsina: I have written half a book

LIke mentioned before I am trying to write a book and ... well, I may be actually making progress? At least the generated PDF is about 170 pages long, which means I have written a bunch in this past month.

I have finished the second of four planned parts, which means I have done about half of it. Since I expect the next two parts to be shorter, it's actually more than that.

The target audience are people who have finished the python tutorial but are not exactly programmers yet. They have the syntax more or less in their heads, but how do you turn that into an actual piece of code?

  • Part 1 is about "prototyping", the process of dumping an idea into rough code.
  • Part 2 is about polishing that rough code into ... not so rough code. Includes a gentle introduction to testing, for example.
  • Part 3 (to be written) is about things that are not code:
    • Git / Gitlab
    • Issues
    • Packaging
    • Setting up a website
    • CI
    • Lots more
  • Part 4 is still to be thought but basically it will cover implementing a large feature from the ground up.

I much appreciate comments about it.

PD: Si, va a haber una traducciń al castellano. O mas bien al argentino. Una vez que lo termine.