Ir al contenido principal

Ralsina.Me — El sitio web de Roberto Alsina

Old Guy @ The Terminal Ep 3: Puede Fallar!

Episo­dio 3!

Igual que casi nadie pub­li­ca los es­tu­dios con re­sul­ta­dos neg­a­tivos, nadie hace videos en Youtube ac­er­ca de co­mo no le sale hac­er al­go. Bueno, yo sí.

Este episo­dio es so­bre una de las cosas que más me in­tere­san en el de­sar­rol­lo de soft­ware, es­pe­cial­mente para al­guien que es­tá apren­di­en­do (o sea to­do el mundo) y más aún para un prin­cipi­ante: el fra­ca­so.

Véan­me fra­casar du­rante un­os 20 min­u­tos, mien­tras tra­to in­fruc­tu­osa­mente de hac­er una cosa que tenía ganas de hac­er!

¡Y no pasa nada! Es im­posi­ble ten­er sin­drome de im­pos­tor si uno no hace co­mo que sabe.

Programación, matemática, y el problema de los tomates venenosos.

Malditos Tomates

Mucha gen­te, cuan­do no sabe pro­gra­mar, tiene pre­juicios. Al­gunos de los más co­munes son:

  • "Para pro­gra­mar hay que ser un bo­cho."
  • "Para pro­gra­mar hay que saber matemáti­ca."

Am­bos pre­juicios son per­ju­di­ciales para ese posi­ble fu­turo pro­gra­mador por var­ios mo­tivos. El primero y más ob­vio es que no son cier­tos. Pero no es que no son cier­tos en la man­era en que "el to­mate es una ver­du­ra" no es cier­to, son fal­sos de la mis­ma man­era que "el to­mate es ve­nenoso" es fal­so.

Eso es lo que lo hace com­pli­ca­do. Porque el to­mate ... el to­mate es ve­nenoso.

En el siglo 18, uno de los so­brenom­bres del to­mate era "man­zana ve­nenosa"1 porque la gente ri­ca solía com­er to­mates y morir en­ve­ne­na­da. Porque comía en platos de pel­tre, que con­tiene plo­mo y el ju­go del to­mate di­s­olvía el plo­mo, y com­er plo­mo es mal­o, gente.

Por otro la­do el to­mate es ve­nenoso en sí mis­mo. Es una solanácea, un género de plan­tas que pro­ducen alcaloides. La to­mat­era pro­duce solan­i­na, un tóx­i­co que provo­ca di­ar­rea, vómi­to y do­lor ab­dom­i­nal.

O sea, de­cir "el to­mate es ve­nenoso" es téc­ni­ca­mente cier­to que es la pe­or man­era de es­tar equiv­o­ca­do. Lo mis­mo pasa con de­cir "para pro­gra­mar hay que saber matemáti­ca".

Es téc­ni­ca­mente cier­to. Pero no es im­por­tante. Igual que es téc­ni­ca­mente cier­to que el to­mate es ve­nenoso, pero no es im­por­tan­te, y por eso comem­os to­mate igual.

Me voy a con­cen­trar en el se­gun­do pre­juicio, ac­er­ca de pro­gra­mar y matemáti­cas, porque el primero no re­siste el mas mín­i­mo con­tac­to con pro­gra­madores (yo in­cluí­do).

¿Por qué es téc­ni­ca­mente cier­to?

1. Te enseñan cosas que son "matemática" cuando aprendés a programar

Por ejem­plo, te van a hablar de cosas co­mo números bi­na­rios, hex­adec­i­males y has­ta oc­tales. Y sí, eso es "matemáti­ca" y es nece­sario para ... ¿para qué, ex­ac­ta­mente?

Para casi na­da. Es­tas son las cosas que más fre­cuente­mente en­cuen­tres pro­gra­man­do para las cuales eso es útil:

  1. bi­na­rios: para cal­cu­lar sub­re­des IP
  2. oc­tales: para cal­cu­lar per­misos en sis­temas UNIX-­like
  3. hex­adec­i­mal: in­ter­pre­tar archivos o datos bi­na­rios a mano sin es­cribir los bytes en dec­i­mal

Men­ti­ra. El uso más fre­cuente del hexa­dec­i­mal es bus­car pal­abras que se pueden es­cribir co­mo números hex­a. Aguante DEAD­BEEF!

Si este año ten­go que us­ar números bi­na­rios más al­lá de saber "un byte cuen­ta has­ta 255" va a ser la se­gun­da vez en la dé­ca­da.

Real­mente es una de esas cosas que uno apren­de, las guar­da en un rincón de la cabeza y de­spués las saca a pasear una vez ca­da tan­to cuan­do se en­cuen­tra con un prob­le­ma es­pecí­fi­co, igual que la ex­pli­cación de la regla del off­side o co­mo se or­ga­ni­za un tor­neo por sis­tema suizo.

2. Algunas áreas del desarrollo de software tienen realmente una base matemática

Si querés hac­er ma­chine learn­ing tenés que saber hac­er re­gre­sión lin­eal. tenés que ten­er idea de cál­cu­lo. Te va a venir bi­en saber mon­tones de cosas más.

De la mis­ma man­era si vas a hac­er un sis­tema de liq­uidación de suel­dos te va a ser útil saber so­bre leg­is­lación lab­o­ral.

Si sos un médi­co y querés saber si la as­pi­ri­na hace bi­en vas a ten­er que saber dis­eño ex­per­i­men­tal y es­tadís­ti­ca.

Si sos un man­ag­er de base­ball y querés saber si te con­viene com­prar un bateador con un OPS de .575 pagán­dole 23 mil­lones de dólares vas a nece­si­tar prob­a­bil­i­dad y es­tadís­ti­ca y con­tabil­i­dad.

Si querés pro­gra­mar un al­go­rit­mo de cryp­to tenés que parar y no pro­gra­mar­lo porque no es bue­na idea.

Que para una tarea en par­tic­u­lar nece­sites saber al­go no hace que sea un pre­req­ui­si­to para el área en gen­er­al. Nadie sabe hac­er to­do. Nadie sabe pro­gra­mar to­dos los tipos de cosas. Eso es sim­ple­mente la condi­ción hu­mana.

Yo no sé hac­er to­do. Y no, no sé hac­er ma­chine learn­ing. Y tam­poco te puedo hac­er un pro­gra­ma de trad­ing. Y si va­mos al ca­so tam­poco puedo hac­er una sim­ple me­dia teji­da porque no sé tejer.

Para saber hac­er cosas hay que es­tu­di­ar, no hay mu­cho se­cre­to. En­ton­ces, para pro­gra­mar hay que es­tu­di­ar co­mo se pro­gra­ma, y para pro­gra­mar al­gu­nas cosas en par­tic­u­lar hay que es­tu­di­ar otras cosas tam­bién.

3. La programación en sí es matemática

Este mo­ti­vo es más es­otéri­co, pero si, es cier­to. La matemáti­ca y los matemáti­cos te van a de­cir ale­gre­mente que el con­cep­to mis­mo de al­go­rit­mo es matemáti­ca.

En cuyo ca­so, ob­vi­a­mente, ape­nas aprendés a hac­er un if ya aprendiste matemáti­ca y es im­posi­ble ex­pre­sar un pro­gra­ma sin matemáti­ca y pasamos de "téc­ni­ca­mente cier­to" a "ob­vio e in­útil". Si to­do es matemáti­ca en­tonces el "hay que saber matemáti­ca" es una triv­i­al­i­dad. Será que sí, pero ¿cuán­ta? y ¿cuál?

4. La matemática es útil para hacerte mejor programador

Si aprendés com­ple­ji­dad al­go­rít­mi­ca pro­gramás mejor.

Si aprendés su­fi­ciente "num­ber sense" para saber cuan­do vale la pe­na hac­er al­go pro­gramás mejor.

Si aprendés su­fi­ciente prob­a­bil­i­dad co­mo para saber si al­go es un ries­go que vale la pe­na at­acar pro­gramás mejor.

Y varias cosas sim­i­lares.

Éste es tal vez el sen­ti­do en el que es­toy más dis­puesto a de­cir que "para pro­gra­mar hay que saber matemáti­ca" pero tiene el prob­le­ma de que no es lo que el re­cep­tor en­tiende cuan­do se lo decís.

Si el ob­je­ti­vo de co­mu­ni­carse es que se trans­mi­ta un men­saje (hey, teoría de la in­for­ma­ción! Más matemáti­ca!) es im­por­tante no só­lo ser cor­rec­to en lo que se dice, es im­por­tante que lo que uno dice sea en­ten­di­do de man­era cor­rec­ta por el re­cep­tor.

Así que ...

Mi declaración sobre la programación y la matemática a ver si me explico, mire

La matemáti­ca es una cosa su­per am­pli­a, y en la vi­da nos cruzamos to­do el tiem­po con el­la.

El saber la trayec­to­ria que va a hac­er la pelota cuan­do pateás con com­ba es matemáti­ca. Pero cuan­do pateás lo hacés sin cal­cu­lar­la porque sabés esa parte de la matemáti­ca. No hace fal­ta que la ex­p­re­ses "matemáti­ca­mente". no te ponés a cal­cu­lar el efec­to Mag­nus de acuer­do a la ve­loci­dad de rotación de la número cin­co y la in­flu­en­cia de los gajos en la aero­d­i­nami­a.

Pro­gra­mar, en la súper gran may­oría de los ca­sos, se parece mu­cho más a eso que a lo que te viene a la cabeza cuan­do te di­cen matemáti­ca.

Vas a ten­er que apren­der al­gu­nas her­ramien­tas. Y te las vas a olvi­dar. ¿Y sabés qué? No hay prob­le­ma. Las aprendés de vuelta.

Y vas a hac­er cosas co­mo mi­rar un ca­cho de códi­go y de­cir ... "a­já, com­ple­ji­dad log­a­rít­mi­ca". Y mien­tras te acuerdes que for­ma tiene el dibu­jo com­para­do con una parábo­la, has­ta ahí llegó lo que te im­por­ta en ese mo­men­to.

Y a ve­ces vas a ten­er que me­terte has­ta las cachas en matemáti­ca, y vas a ten­er que ver co­mo hac­er una trans­for­ma­da afín, o co­mo hac­er un curve fit­ting, o un mon­tón de otras cosas. ¡Yo una vez tuve que hac­er análi­sis de re­gre­sión para ver co­mo or­ga­ni­zar una tabla HTM­L! ¿Y?

La matemáti­ca es­tá por to­dos la­dos. Para pro­gra­mar vas a us­ar matemáti­ca. Tam­bién podés us­ar matemáti­ca para vender chan­cle­tas.

No es que sea fal­so que "para pro­gra­mar hay que saber matemáti­ca" es que no es in­tere­sante.


  1. De aho­ra en más se van a imag­i­­nar a Blan­­canieves mor­fán­­dose un to­­mate. Sor­ry. 

Old Guy @ The Terminal Ep 2: Python Sucks!

Episo­dio 2! Oh yeah!

Es­ta es una char­la relám­pa­go que dí en la Py­Con Ar­genti­na de 2018, es cor­ti­ta y sen­cil­la, ojalá les guste!

Old Guy @ The Terminal: Episodio 1!

Este es el primer (y por aho­ra úni­co, ob­vi­a­mente) episo­dio de un nue­vo canal de video lla­ma­do "Old Guy @ The Ter­mi­nal" en el que mue­stro al­gu­nas cosi­tas de Lin­ux, pro­gra­mación, co­mo se rela­cio­nan cosas ac­tuales con cosas vie­jas y ver­e­mos qué más a me­di­da que se me ocur­ran temas.

Nun­ca había he­cho al­go pare­ci­do, así que no sean muy duros con­mi­go ;-)

En este episo­dio ve­mos qué es una ter­mi­nal, co­mo se hace un pro­gra­ma para ter­mi­nal y una ter­mi­nal para el pro­gra­ma, porque por qué no.

En al­gún mo­men­to va a haber una ver­sión en in­glés (tal vez).

El código: en GitHub

Adventures In Electronics: PC Volume Knob

I have some rather un­usu­al holes in my ed­u­ca­tion. I nev­er, for ex­am­ple, learned much about elec­tron­ic­s. It has al­ways been a mis­tery, a thing oth­er peo­ple knew about.

And then one day I ran in­to this gad­get:

What is it? A vol­ume knob for your PC. It plugs via USB and you can use it to turn vol­ume up or down. I sup­pose if you press it it mutes au­dio or some­thing.

It costs 50 dol­lars. 50 fuck­ing dol­lars. For a di­al.

Sure, it's pret­ty but how hard can it be?

So, I start­ed look­ing at how to do it. Here's what I learned first:

  • The thingie that spins and gives feed­back is called a "ro­tary en­coder"
  • I would need some­thing like a mi­cro­con­troller to ... well, con­trol it.
  • It would prob­a­bly in­volve sol­der­ing.
  • There are a bunch of tu­to­ri­als / in­structa­bles on how to do it.
  • The com­po­nents are damn cheap!

The last item is im­por­tan­t. When I was a kid in the 70s, elec­tron­ics was a thing for wealthy kid­s. I was not wealthy. So, the pos­si­bil­i­ty of do­ing this sort of thing? With cheap stuff? Sign me up!

So, I did what ev­ery­one does to learn stuff in 2019: I jumped in­to youtube and asked to be taught elec­tron­ic­s. And a day lat­er ... well, I know enough to break things and to im­ple­ment this!

The goal is:

  • USB vol­ume knob.
  • Press­ing it lights a LED
  • A but­ton click mutes the speak­ers
  • A longer click en­ables the mi­cro­phone while the di­al is pressed (push-­to-talk)

So, here is the BOM:

  • The cheap­est Ar­duino-­like thing with a USB in­ter­face: Digis­park
  • A ro­tary en­coder. I used a KY-040 be­cause it's cheap and work­s.
  • A gener­ic LED (red)
  • Some bread­board ca­bles.
  • A bread­board
  • A US­B-A male/fe­male ca­ble
  • A 1k re­sis­tor

A sec­ond stage (once I have an­oth­er Digis­park) will in­volve mak­ing it nice, but for now let's make it work.

Here is the wiring, which is prob­a­bly a pile of crap but works for me (sor­ry, don't want to learn how to do it prop­er­ly).

Wiring be­tween the Digis­park and the KY-040:

  • P0 -> CLK
  • P1 -> SW
  • P2 -> DT
  • 5V -> +
  • GND -> GND

I also connected KY-040's SW -> 1K resistor -> LED -> 5V so the LED turns on when the button is pressed, but that's optional.

IM­POR­TANT NOTE In or­der for P1 to work prop­er­ly, I need­ed to scratch off a con­nec­tion to dis­able the on­board LED so, if that's a prob­lem, you may be able to use P5 in­stead but P5 is dis­abled in the cheap Digis­park clones. We can't use P3 and P4 be­cause they are need­ed for US­B. So, your choice.

So, here is all the wiring. If the im­age dif­fers from my de­scrip­tion, trust the im­age be­cause it's work­ing ;-)

Once you have ev­ery­thing wired, we need to work on the soft­ware side of things.

I used a cou­ple of li­braries:

I had to configure a global shortcut to enable/disable the michrophone. I used the F10 key and the command pulseaudio-ctl mute-input but you figure out what you want to do.

I wrote a Sketch that does the fol­low­ing:

  • When the en­coder ro­tates clock­wise: send Vol­ume Up key.
  • When the en­coder ro­tates coun­ter-­clock­wise: send Vol­ume Down key.
  • When the en­coder is clicked less than half a sec­ond: send mute key.
  • When the en­coder is pressed for more than half a sec­ond: send mute-in­put tog­gle short­cut.
  • When the en­coder is re­leased af­ter be­ing clicked more than half a sec­ond: send mute-in­put tog­gle short­cut.

This way, if you want to mute, just click. If you want to talk, make sure you mute in­put when the ses­sion start­s, then click­-and-hold and while it's pressed the mi­cro­phone is en­abled. Nice, is­n't it?

Does it work? Oh yeah! (No, the mu­sic is not com­ing from the PC, just look at the screen to see what changes) and sor­ry this video is so crap­py.

And here's the code (which is my 1st ar­duino sketch, but I have been pro­gram­ming for a long time ;-)

#include "TrinketHidCombo.h"
#include <SimpleRotary.h>  // https://github.com/mprograms/SimpleRotary

// Pin A, Pin B, Button Pin
// Setting the button to 5 because this code handles it manually.
SimpleRotary rotary(0, 2, 5);

void setup() {
  TrinketHidCombo.begin();
  pinMode(1, INPUT);
}


void loop() {
  static unsigned long time_pressed = 0;
  static byte ptt_flag = 0;
  byte i = rotary.rotate();
  if (i == 1) {
    TrinketHidCombo.pressMultimediaKey(MMKEY_VOL_UP);
  }
  else if (i == 2) {
    TrinketHidCombo.pressMultimediaKey(MMKEY_VOL_DOWN);
  }

  int button = digitalRead(1);
  if (button == LOW) {  // Yes, clicking the button makes it LOW
    if (time_pressed == 0) {  // It's a new click
      time_pressed = millis();
    }
    else {  // Button has been pressed a while
      if ((millis() - time_pressed) > 500 && ptt_flag == 0) {
        // Pressed half a second, switch to push-to-talk
        // I configured my machine to toggle the input muting when F10 is clicked
        TrinketHidCombo.pressKey(0, KEYCODE_F10);
        TrinketHidCombo.pressKey(0, 0);
        ptt_flag = 1;
      }
    }
  }
  else {  // Button not pressed
    if (time_pressed) {// Has been pressed
      time_pressed = 0;
      if (ptt_flag == 0) {  // Was a short click
        // Toggle mute
        TrinketHidCombo.pressMultimediaKey(MMKEY_MUTE);          
      }
      else {  // Was a long click
        // Toggle push-to-talk
        TrinketHidCombo.pressKey(0, KEYCODE_F10);
        TrinketHidCombo.pressKey(0, 0);
        ptt_flag = 0;
      }
    }
  }
  TrinketHidCombo.poll();
}

Contents © 2000-2024 Roberto Alsina