Ir al contenido principal

Ralsina.Me — El sitio web de Roberto Alsina

Publicaciones sobre programming (publicaciones antiguas, página 88)

This is why you don't run random stuff.

Yes­ter­day I was try­ing to fig­ure ou­ut some ob­scure in­put things in Co­braPy such as "de­tect­ing the En­ter key" and ran in­to a love­ly pack­age in PyP­I: Pym­put

What does it do? It lets you in­ject and read in­put events.

And by in­put events I mean mouse and­key­board.

And it does so in your whole ses­sion.

And you would­n't no­tice if it was do­ing that.

And it does this in 20 lines of friend­ly python code. Here, have a key­board snif­fer:

from pynput import keyboard

def on_press(key):
        print('alphanumeric key {0} pressed'.format(
    except AttributeError:
        print('special key {0} pressed'.format(

def on_release(key):
    print('{0} released'.format(
    if key == keyboard.Key.esc:
        # Stop listener
        return False

# Collect events until released
with keyboard.Listener(
        on_release=on_release) as listener:

This is one of the rea­sons why Way­land (or Mir, I re­mem­ber Mir!) needs to hap­pen. It's triv­ial for any desk­top app to mon­i­tor ev­ery­thing you do. Of course nowa­days you al­so will see soft­ware ad­ver­tis­ing this, as a "fea­ture" where it's used to "mon­i­tor em­ploy­ee pro­duc­tiv­i­ty".

Be­cause re­mem­ber, of­ten things are on­ly il­le­gal when in­di­vid­u­als do them, if you are a com­pa­ny and are charg­ing for it, then Bob's your un­cle.

Side Projects have Projects as Side Effects

I went and did a thing. But why, why?

When I start­ed play­ing with the idea of do­ing a sort-of-retro-80s-pro­gram­ming-en­vi­ron­ment called Co­braPy I sus­pect­ed one of the prob­lems would be find­ing a graph­ics li­brary that did what I want­ed and had good per­for­mance.

I have used PyGame a lit­tle in the past but nev­er liked it too much, so I tried Py­glet and it was work­ing great ... un­til I tried to add some­thing as sim­ple as a wid­get to en­ter tex­t. It does­n't re­al­ly do wid­get­s, for that you ap­par­ent­ly use glooey

But glooey is ... I don't like it. And then I ran into a bug where you can either clean the contents of an EditableLabel and set it to focused without it crashing deep in its bowels. I worked around it by using fake mouse events to focus. And then noticed you can't type a double quote in one of those widgets. So, I got pissed.

It lit­er­al­ly took me less time to find a nice C game li­brary, read a tu­to­ri­al on CF­FI, do min­i­mal ed­its to its head­er file, learn how to use in­voke and write my first pro­gram us­ing it than I wast­ed chas­ing that glooey bug.

And now, the ques­tion­s:

  • Does it work well? How could I know, I on­ly wrote the bind­ing, I have not used it yet!
  • Will I main­tain it? I don't think it re­quires much main­tain­ing.
  • Will I re­lease it? Maybe. It's here, mixed up with oth­er stuff

... aaaaand some­one else had al­ready done it. http­s://pyp­­jec­t/raylib/ But that's raylib 2.6, cur­rent is 3.0 :-)

CobraPy: baby steps

Some con­text: I am do­ing a sort of mod­ern retro-pro­gram­ming en­vi­ron­men­t-thingie.

So ... I caved. I caved and start­ed typ­ing.

It's still just ex­plorato­ry, fool­ing around, but I want­ed to see whether the vague ideas I had about how this could, maybe work were right, and hey, they are!

Text Mode

I want­ed a text mod­e. Some­thing with N rows and M col­umns where you could just say "put this text there". Done. In the most ba­sic pos­si­ble way that work­s.

Implemented a print_at function that takes row, column and text, and does what it says in the label.

Immediate Graphics Mode

In these old com­put­ers you could just draw in the graph­ics mem­o­ry. In 2020 ... not so much. So, I im­ple­ment­ed a sort of off­screen buf­fer. You draw there, and it gets blit­ted a lot to screen. Ends up work­ing like a flick­er-free dou­ble-buffered screen! Nice!

Implemented ellipse which ... draws an ellipse. I know, surprising.

Interpreter / Prompt

It would not be 80s-­like if you could not do those things in­ter­ac­tive­ly. So, yes, you can.

Now that was in­ter­est­ing. you see, nowa­days you are sup­posed to have an event loop. The com­put­er is there, idling and when some­thing hap­pen­s, then it does some­thing. So, you clicked? It re­act­s. 10 mil­lisec­onds passed? It does its thing.

In the 80s it was not like that. Your pro­gram start­ed and it owned the ma­chine. It went through your code, run­ning it as fast as it could with its lit­tle two-mega­herz-­heart un­til it ran out of code and then it was done.

So, how to make it act like that?

  • Start the event loop.
  • Start a sec­ond thread with a promp­t.
  • Have the us­er in­ter­act with the promp­t.
  • When the user presses Enter ... send the command to the event loop via a queue.
  • When the event ar­rives, do the thing.

And yes, it work­s! It's prob­a­bly hor­ri­ble for per­for­mance, but it does work just fine, and it's much, much eas­i­er to make a work­ing pro­gram fast than it is to make a fast pro­gram work.

So, what's nex­t?

The Future

I may try to in­te­grate the prompt and the win­dow where the text and such is dis­played (right now it's in a ter­mi­nal) ... maybe sprites.

Af­ter that:

  • Make the API nice and use­ful (a few weeks of work)
  • Make the thing run well (a few days of work)
  • Do the jan­i­to­ri­al work to make it us­able by some­one else (a cou­ple days of work)
  • Sup­port it, doc­u­ment it, etc (8 to 30 years of work)

The Nerdy Details

  • To do the graph­ics I am us­ing py­glet
  • To do off­screen draw­ing I am us­ing Pil­low
  • Tool­ing in­cludes the usu­al sus­pect­s: Python 3.8, po­et­ry, pylin­t, flake8
  • Code (all 50 lines or so!) in GitHub

Yes, this means this "80s" thing is ac­tu­al­ly mul­ti­thread­ed hard­ware-ac­cel­er­at­ed OpenGL graph­ic­s. I know, I know.

Possible New Project

I'm Old

I have not start­ed a re­al se­ri­ous open source project in a while. Ok, that's a lie. I have start­ed a num­ber of things and aban­doned them, but the last soft­ware project I start­ed that had last­ing pow­er was Niko­la and that was in 2012!

I turned 7**2 a couple weeks ago, so I am officially old (it's the law!) and us olds get bored because we don't get all the tiktok and whatever you youn'uns do.

So, I am get­ting itchy, and have been think­ing of start­ing some­thing. Af­ter see­ing a num­ber of retro­com­put­ing videos, it turns out the ZX-81 of my child­hood is vin­tage enough that they are ac­tu­al­ly old­er than ENI­AC was when I got it.

And it got me think­ing ... was there any­thing in that kind of com­put­ers that is worth sav­ing for some­thing oth­er than nos­tal­gia's sake? Sure, play­ing Mon­ty on The Run is as fun as al­ways and peo­ple still re­lease soft­ware for C64 and sim­i­lar an­cient com­put­er­s.

How­ev­er ... well, that sort of reeks of masochis­m, be­cause de­vel­op­ing for those sys­tem was ab­surd­ly painful. You can get the same lev­el of pain cod­ing for pi­co8 and peo­ple can play your games much eas­i­er.

There's al­so the retro-hard­ware thing but ... hon­est­ly, I like mod­ern hard­ware much bet­ter! For ex­am­ple, a Col­or Maximite looks much more fun that a C64 to de­vel­op in.

But stil­l.

There is this feel­ing that cur­rent com­put­ers are miss­ing some­thing.

Why not ex­plore it a lit­tle? I have a the­o­ry.

The Theory

Mod­ern com­put­ers are made to run things, old com­put­ers were not.

Get­ting some­one else's soft­ware in­to your com­put­er in 1984 was ab­surd­ly dif­fi­cult.

  1. Get a com­put­er (try do­ing that while liv­ing in Ar­genti­na in 1984)
  2. Now what? There's no In­ter­net
  3. Read the man­u­al and start cod­ing (yes, the man­u­al for the com­put­er ex­plained how)
  4. Fail
  5. Find some­one else who had a com­put­er and had ac­tu­al soft­ware for it
  6. Get copies. That of­ten in­volved copy­ing au­dio tapes. That would take be­tween 10 and 20 min­utes.
  7. Try out the copy on your com­put­er. Load­ing it in­to the com­put­er would al­so take be­tween 10 and 20 min­utes.

And af­ter that you had ... a port of Man­ic Min­er to C64 with crap­py sound.

So, some of us, we stuck a lit­tle to the oth­er side of those re­mark­able ma­chines. That they boot­ed in­to a de­vel­op­ment en­vi­ron­men­t. That you could make them do shit.

And that's what cur­rent com­put­ers don't do. They don't do shit. They don't in­vite you to start do­ing your own shit. Which is per­fect­ly and ag­gres­sive­ly fine, I don't mind. But I do.

The Plan in My Head

What would the evo­lu­tion of an 80s com­put­er look like nowa­days?

  • It should in­vite you to code and do shit
  • It should run on cheap, com­mod­i­ty hard­ware that is cheap and easy to find and buy
  • It should not do much out of the box. It's a box to do shit not to run shit.

There­fore, how about ...

A disk im­age that you can pop in­to a rasp­ber­ry Pi and...

  • Boots to a lim­it­ed en­vi­ron­ment
  • Where you can do shit
  • With fixed APIs and a pro­vid­ed soft­ware suite so that:
    • You can do some graph­ic­s, eas­i­­ly
    • You can do some sound, eas­i­­ly
    • You can ed­it a pro­­gram, eas­i­­ly
    • You can share it some­how, eas­i­­ly

Why the Pi?

  • It's fixed, known, cheap, sup­port­ed hard­ware.
  • You have IO pins to do ex­tra shit
  • It's cheap
  • Al­so, in­ex­pen­sive

What APIs?

  • Di­rec­t-ad­dress text mode (fake)
  • One or two graph­ics modes. 720p and 1080p?
  • Graph­ic prim­i­tives
  • Sprites! (hey, it's not the 80s with­out sprites)
  • Ba­sic mod play­ing
  • Some beep­ing thingie

What language?

Python. Sor­ry. I am play­ing with it, it's not go­ing to be BA­SIC.

Any weird thing?

Oh yes.

  • No im­port. You get the APIs you get.
  • Pro­grams are one file. You can use pack­ages in your big­boy box over there that has chrome in it.
  • No in­ter­net (no web brows­ing at least) just use your phone.
  • In­clud­ed sprite en­di­tor
  • In­clud­ed Mu­sic track­er

Are you really going to write this?

Well, I'm go­ing to give it a try and see if it's fun to do. If it's not I won't.

Are you looking for collaborators?

Nope. I want to do this so­lo at least for the first few month­s. My cod­ing at ear­ly project stages is way too er­rat­ic and would make ev­ery­one hate me.

What's it called.

It's nos­tal­gic. It's 80s. It has snakes in it. It should be Co­bra Kai.

But be­cause copy­right ex­ist­s, it's Co­bra Py. Or maybe Co­bra Pie, be­cause there's al­so oth­er python things called Co­bra.

h/t to Gui­do de Ca­so for fig­ur­ing out the name.

Programar no es un objetivo..

Hi­ce unas pre­gun­tas y res­pues­tas el otro día, y una de las pre­gun­tas fue "Co­mo salir del eterno ha­go pro­yec­to / co­dea­ca­de­my a co­sas más in­te­re­san­tes?" ... no es­toy 100% se­gu­ro de lo que sig­ni­fi­ca, pe­ro lo voy a to­mar co­mo una opor­tu­ni­dad pa­ra ran­tear so­bre al­go que me im­por­ta y que es­tá (me pa­re­ce) va­ga­men­te co­nec­ta­do.

Tal vez te sien­tas co­mo que es­tás atra­pa­do en un ci­clo de apren­der al­go, usar­lo en un pro­yec­to de ju­gue­te y des­pués ... ¿qué? ¿a­pren­dés otra co­sa? ¿Y ha­cés otro pro­yec­ti­to? ¿Y se­guís así?

¿Y sen­tís que eso ca­re­ce de sig­ni­fi­ca­do y no te da sen­sación de lo­gro, no te mo­ti­va y en ge­ne­ral que es­tás con­de­na­do a ser un new­bie pa­ra siem­pre?

Bue­no, si es así ... cu­chá, cu­chá ...

Tus proo­yec­tos de ju­gue­te se sien­ten in­sig­ni­fi­can­tes por­que no son rea­le­s.

¿E­sa sen­sació­n? Es tu pro­gra­ma­dor in­te­rior di­cién­do­te que te de­jes de pa­vear y em­pie­ces de una vez por to­das a pro­gra­mar en se­rio. Y te voy a dar un plan pa­ra que lo ha­ga­s.

PASO 1: Buscá algo que querés que tu compu haga pero que tu compu no hace.

¿Que­rés que tus vi­deos de you­tu­be apa­rez­can en tu blog?

¿Que­rés sa­ber cuán­tos Ro­ber­tos na­cie­ron en 1934 en Ar­gen­ti­na?

Bue­no, ami­go ima­gi­na­rio, des­pués de en­con­trar al­go así, po­dés pa­sar al pa­so 2.

Su­pon­ga­mos por aho­ra que de­ci­dis­te im­ple­men­tar "u­na co­sa" que es­pan­te los pa­ja­ri­tos que te des­pier­tan ca­da ma­ña­na en es­ta eter­na pe­s­adi­lla en la que to­dos vi­vi­mos de aho­ra en más pa­ra siem­pre.

PASO 2: Decidí algunos detalles básicos de tu meta

Es­to se lla­ma un pro­yec­to. Im­ple­men­tar al­go­rit­mos de or­de­na­mien­to no es un pro­yec­to, es un ejer­ci­cio. Im­ple­men­tar la ver­sión 200 de un chat usan­do web­so­cke­ts pa­ra tu "por­tfo­lio" no es un pro­yec­to, es so­la­men­te un apén­di­ce abu­rri­do de tu cu­rrí­cu­lu­m.

Un pro­yec­to es una me­ta. Un pro­yec­to es "¡­Quie­ro que mi com­pu ha­ga ES­TO y en el sagra­do nom­bre de Mar­cos Mun­d­s­to­ck, voy a ha­cer el es­fuer­zo pa­ra obli­gar­la!"

En­ton­ce­s, quie­ro al­go que cuan­do de­tec­ta pá­ja­ros can­tan­do ha­ga rui­do pa­ra es­pan­tar­lo­s.

  1. Es­cu­cha bus­can­doo rui­do­s.
  2. De­ci­de si son rui­dos pa­ja­res­co­s.
  3. Res­pon­de con un rui­do des­agra­da­ble pa­ra em­plu­ma­do­s.

PASO 3: Convencéte de que es una cosa que una compu puede hacer.

Por­que bue­no, las com­pus pue­den ha­cer mu­chas co­sas, pe­ro no pue­den ha­cer to­do. En­ton­ce­s, hay que ha­cer un rá­pi­do "rea­li­ty che­ck". Rá­pi­do, por­que no que­re­mos per­der más de me­dia ho­ra en es­to y por­que no es lo im­por­tan­te.

  • ¿Las com­pus pue­den es­cu­char so­ni­do­s? ✔
  • ¿Las com­pus pue­den ha­cer rui­do? ✔
  • ¿Los so­ni­dos es­pan­tan pá­ja­ro? ✔
  • ¿Pue­de una com­pu de­ci­dir si un rui­do es un pá­ja­ro o no? ... ¿ca­paz que sí? Las he vis­to ha­cer co­sas más ra­ra­s.

PASO 4: Encontrar un mecanismo semi-coherente para implementarlo.

Pue­de ser muy va­go. Ti­po "sí, pue­do usar es­ta API de Google y es­te tra­po re­ji­lla vie­jo­". Una va­ga idea.

  • Im­ple­men­tar al­go que es­cu­che rui­do­s.
  • Al­go en el me­dio que de­ci­da si un rui­do es de un pá­ja­ro
  • Que la de­tec­ción de rui­do "dis­pa­re" otro có­di­go
  • Có­di­go que ha­ga rui­do

PASO 5: Describir la versión más estúpida que puedas imaginar

¿Que­re­mos ha­cer un de­tec­tor de pá­ja­ro­s? Em­pe­ce­mos con un de­tec­tor de rui­do­s.

O más bien, bus­que­mos al­go que pue­da reac­cio­nar cuan­do tu mi­cró­fono de­tec­ta rui­do­s. O aun­que sea una bi­blio­te­ca que te de ac­ce­so a tu mi­cró­fono.

  • Bus­car una bi­blio­te­ca pa­ra leer so­ni­do del mi­cró­fono
  • De­tec­tar rui­do
  • Bus­car bi­blio­te­ca pa­ra ha­cer rui­do
  • Ha­cer rui­do
  • Co­nec­tar las dos mi­ta­des

PASO 6: Poné el culo en la silla e implementá la versión estúpida

Ha­cé­lo RÁ­PI­DO. Si pla­neás de­ma­sia­do no vas a ha­cer más que pla­near mu­cho. Que­rés ser un pro­gra­ma­do­r, no un PM. Me pre­gun­to co­mo se­ría la ver­sión PM de es­te ran­t.

PASO 7: Mostrále la versión estúpida a alguien que respetes y escuchá.

Si, es­ta par­te de mie­di­to, pe­ro pro­gra­mar es, en gran par­te, acer­ca de per­so­na­s. Mos­trar­le co­sas a per­so­na­s, es­cu­char a per­so­na­s, en­ten­der que es lo que esas per­so­nas real­men­te es­tán tra­tan­do de de­ci­r, y co­sas así.

Así que: mos­trá­se­lo a al­guien. Es­cu­chá. To­má de­ci­sio­nes acer­ca de si hi­cis­te lo co­rrec­to en los pa­sos 3 y 4. Tal vez ajus­tá un po­co tu ob­je­ti­vo.

PASO 8: repetir pasos 5 a 7 con una versión ligeramente menos idiota

Re­pe­tir has­ta que lle­gues a al­go que no te­nés idea de co­mo ha­ce­r. En es­te ca­so pro­ba­ble­men­te sea "de­ci­dir si eso es un pá­ja­ro­".

PASO 9: buscá ayuda

Pre­gun­t;a. De nue­vo: pro­gra­mar es ma­yor­men­te acer­ca de gen­te. En es­te ca­so, vas a prac­ti­car "pe­dir ayu­da". No que­rés que te di­gan có­mo se ha­ce (o ca­paz que sí?) pe­ro es­te es un pa­so crí­ti­co.

Po­dés ter­mi­nar en va­rios es­ce­na­rio­s.

  1. Lo re­sol­vis­te.
  2. De­ci­dis­te que es im­po­si­ble.
  3. Es po­si­ble pe­ro no te­nés idea có­mo.

¡Si lo re­sol­vis­te, no hay pro­ble­ma! Vol­vé al pa­so 5 y se­guí has­ta que es­tés con­for­me con el pro­yec­to y apren­dis­te al­go nue­vo. ¡Fe­li­ci­ta­cio­nes!

Los otros dos es­ce­na­rios te lle­van a ...

PASO 10: trabáte

Si de­ci­dis­te que es im­po­si­ble, en­ton­ces apren­dis­te so­bre un pro­ble­ma que es, en es­te mo­men­to al me­no­s, im­po­si­ble. Da­do que sos nue­vo en es­ta cla­se de co­sas, es im­pro­ba­ble que vos lo arre­gle­s, pe­ro ... si real­men­te te in­te­re­sa es­te pro­yec­to, tal vez te in­di­que un nue­vo ti­po de csas que te in­te­re­se apren­de­r.

¿No po­de­mos de­ci­dir si un rui­do es un pá­ja­ro? ¿Por qué? ¿Hay gen­te in­ves­ti­gan­do eso? ¿Co­n, po­né­le, Ma­chi­ne Lear­nin­g? Sue­na in­te­re­san­te ... nor­mal­men­te los ejem­plos son con imá­ge­nes. ¿Hay tra­ba­jos in­te­re­san­tes pa­ra apli­car­lo a au­dio? ¿Hay bi­blio­te­cas ya he­cha­s? ¿Hay da­ta se­ts? ¿Hay tu­to­ria­le­s? Y aho­ra te­nés al­go nue­vo pa­ra es­tu­dia­r. Di­vertí­te.

El ter­cer es­ce­na­rio es el com­pli­ca­do. Di­ga­mos que se pue­de ha­cer con ML y que hay da­ta­se­ts de so­ni­dos ur­ba­nos y de can­tos de pá­ja­ro y que sa­bés que se pue­de ha­ce­r, y en­ten­dés un po­qui­to del te­ma, pe­ro vos no sa­bés ha­cer­lo.

Bue­no, fe­li­ci­ta­cio­nes, has lle­ga­do al lí­mi­te ac­tual de tu in­com­pe­ten­cia, to­do lo que te­nés que ha­cer es achi­car­la un po­co. Y así es la vi­da de un pro­gra­ma­do­r.

¿Entonces, como te ayuda todo este laburo?

Es­tás apren­dien­do co­sas dis­tin­tas que cuan­do ha­cías ejer­ci­cio­s.

  • Apren­dés a de­ci­dir qué ha­ce­r.
  • Apren­dés a pe­dir ayu­da.
  • Apren­dés a pre­sen­tar tu tra­ba­jo an­te otro­s.
  • Apren­dés a pro­ce­sar fee­dba­ck.
  • Apren­dés a in­ves­ti­gar tu es­pa­cio de pro­ble­ma­s.
  • Apren­dés a par­tir un pro­yec­to en ta­reas
  • Apren­dés a to­mar de­ci­sio­nes.

Y sí, po­dés apren­der una o dos co­sas de pro­gra­ma­ció­n.

Y tal vez (pe­ro es im­pro­ba­ble) es­pan­tes esos pá­ja­ros de mier­da.

PD: http­s://­gi­thu­b.­co­m/ka­rol­pi­czak/­BA­DC-2017

Contents © 2000-2024 Roberto Alsina