Mostra totes les entrades de Gabriel Massip Fons

Defunció Scott Adams

Ahir es va conèixer la defunció de Scott Adams, creador del personatge Dilbert i les tires còmiques farcides de sarcasme sobre el món de l’empresa, les relacions treballadors-caps i la inutilitat d’algunes feines, sobretot en el camp de les tecnologies de la informació.

Fa uns anys en llegia una tira diària, que era accessible per mitjà de RSS. Aquesta font va deixar de funcionar, no en vaig buscar cap més i li vaig perdre la pista.

Avui n’he buscat unes quantes tires, en deixo mitja dotzena.

RIP, Scott Adams.

HTTP/3

HTTP/3 activat per aquest blog.

Costa moltíssim avançar estàndards en la tecnologia de fons d’internet. IPv6 no s’implanta, encara hi ha moltíssim HTTP/1.1, i només el frau i la privacitat ha forçat l’extensió de la navegació encriptada (https).

12/01/26: He hagut de tocar el fitxer de configuració nginx per fer servir $host on hi havia $http_host.

Em queda algun error a les eines d’administració de wordpress, també relacionat amb HTTP_HOST; confio que el resoldré retocant una mica més la configuració de nginx.

14/01/2026: Resumeixo els passos:

Cal permetre el tràfic amb protocol UDP pel port en què hi ha el web (normalment 443).

Nginx ha d’estar compilat amb l’opció –with-http_v3_module.

Al bloc server de nginx.conf cal afegir:

    listen 443 quic reuseport;
    listen [::]:443 quic reuseport;
    http3 on;
    ssl_protocols TLSv1.3;
    ssl_prefer_server_ciphers on;

    add_header alt-svc 'h3=":443"; ma=86400';

    reuseport només es pot fer servir a un dels servidors.

    No tinc clar que ssl_prefer_server_ciphers sigui estrictament necessari.

    add_header alt-svc publicita la disponibilitat de HTTP/3 per aquest servidor.

    I wordpress necessita $HTTP_HOST informat, l’he passat a l’entorn fastcgi de php-fpm a partir de $HOST:

    fastcgi_param HTTP_HOST $host;

    Reduir el narcotràfic?

    En el supòsit que la captura i trasllat de Nicolás Maduro al Estats Units i el presumpte control de Venezuela per part del govern nord-americà redueixi la quantitat de droga que entra als Estats Units (o que circula pel món), això acabarà amb la plaga de les addiccions?

    Hi ha tràfic de droga perquè hi ha drogoaddictes, és a dir, persones que no poden estar-se de consumir regularment drogues. Si hi ha menys droga s’encarirà, la qual cosa abocarà determinats consumidors a una marginalitat encara més greu, delinqüència o crisis fatals de salut pels que no puguin obtenir-ne.

    Per reduir el narcotràfic cal reduir la demanda de droga: amb més educació, amb més serveis d’atenció a salut mental, amb més oportunitats per persones vulnerables, amb programes de desintoxicació a l’abast de tothom, amb la construcció d’una societat diferent.

    De tot això, n’ha dit res, Donald Trump? O ho arreglarà el mercat, és a dir, la major misèria, marginalitat i precarietat dels drogoaddictes sense recursos els portarà a defuncions prematures i, mira, ja tindrem menys drogroaddicció?

    Python: eliminació espais superflus

    Python no té una funció específica per eliminar espais superflus (és a dir, eliminar tots els espais del principi i del final d’un text, i entre paraules deixar-hi només un espai).

    Hi ha una manera molt pythònica de fer-ho:

    " ".join(text_amb_espais.split())

    I això és ràpid? Doncs comparem 3 alternatives amb timeit:

    • Aquesta de join i split
    • Un bucle pas a pas: mirar caràcter a caràcter si hauríem de posar-lo al resultat final, depenent de si aquest o l’anterior són espais.
    • Amb tantes substitucions com calgui de dos espais seguits a un.

    El codi per mesurar-ho és:

    from timeit import timeit
    
    def eliminar_espais_split_join (text: str) -> str:
        return " ".join(text.split())
    
    def eliminar_espais_posicio_a_posicio (text: str) -> str:
        anterior_es_espai = True
        sense_espais_redundants = ""
        for x in text:
            if x == " ":
                if not anterior_es_espai:
                    sense_espais_redundants += x
                    anterior_es_espai = True
            else:
                sense_espais_redundants += x
                anterior_es_espai = False
    
        if len(sense_espais_redundants) > 0:
            if sense_espais_redundants [-1] == " ":
                sense_espais_redundants = sense_espais_redundants[:-1]
        return sense_espais_redundants
    
    def eliminar_espais_replace (text: str) -> str:
        r2 = text
        while (r1:= r2.replace("  ", " ")) != r2:
                r2 = r1
        if len(r2) > 0:
            if r2[0] == " ":
                r2 = r2[1:]
        if len(r2) > 0:
            if r2[-1] == " ":
                r2 = r2[:-1]
        return r2
    
    TEXT_PROVA = "      Vivamus       quis        lacus     quis  sapien    elementum     finibus   et    sollicitudin nisi.   "
    
    assert (eliminar_espais_posicio_a_posicio (TEXT_PROVA) == eliminar_espais_split_join(TEXT_PROVA))
    assert (eliminar_espais_replace (TEXT_PROVA) == eliminar_espais_split_join(TEXT_PROVA))
    
    EXECUCIONS = 100_000
    
    temps = (timeit (lambda: eliminar_espais_split_join (TEXT_PROVA), number=EXECUCIONS),
             timeit (lambda: eliminar_espais_posicio_a_posicio (TEXT_PROVA), number=EXECUCIONS),
             timeit (lambda: eliminar_espais_replace(TEXT_PROVA), number=EXECUCIONS))
    
    temps_minim = min(temps)
    
    print (f"eliminar_espais_split_join: {temps [0] / temps_minim:.2f} vegades el mínim")
    print (f"eliminar_espais_posicio_a_posicio: {temps [1] / temps_minim:.2f} vegades el mínim")
    print (f"eliminar_espais_replace: {temps [2] / temps_minim:.2f} vegades el mínim")

    I el resultat:

    eliminar_espais_split_join: 1.00 vegades el mínim
    eliminar_espais_replace: 2.25 vegades el mínim
    eliminar_espais_posicio_a_posicio: 8.83 vegades el mínim

    He provat algunes variants, sense que influeixin significativament en els resultats:

    • Sense fer servir l’operador walrus (notació := al while) a eliminar_espais_replace.
    • Amb substitucions de 2 i 3 espais concatenades a eliminar_espais_replace.
    • Amb un índex per accedir als diferents caràcters a posicio_a_posicio.

    O sigui, he deixat l’split_join al codi, la manera més genuïna del Python és alhora la més ràpida.

    Dades EXIF en imatges WhatsApp

    Una fotografia que m’ha arribat per WhatsApp i que m’he passat a l’ordinador no té cap dada EXIF, ni la data / hora.

    D’entrada m’ha xocat, després he vist que no està mal pensat, per privacitat. Desconec qui ho esborra: el sistema operatiu en posar-la al xat, l’aplicació WhatsApp o el meu telèfon en rebre-la o desar-la. Tampoc no sé amb quin telèfon va ser feta.

    Sqlite

    He passat la base de dades de fotografies a Sqlite. Fins ara havia fet servir Sqlite molt poc.

    El canvi ha estst fàcil perquè tinc l’aplicació amb Sqlalchemy. He pogut canviar noms de columnes tocant només el fitxer de configuració (definició d’entitats Sqlalchemy). Traspàs de dades amb select de MySQL i insert a Sqlite.

    L’aplicació funciona de meravella, i podria deixar-la així, però segueixo amb MySQL. Sqlite no em fa el pes per dos detalls, irrellevants en una aplicació com aquesta:

    • Camps de tipus text sense longitud màxima. M’agrada que el motor de base de dades comprovi aquestes restriccions, atès que en ser violades poden ser símptoma d’errors de programació.
    • Mancança de camps de tipus data, de nou “massa” responsabilitat per desenvolupador. Val a dir que amb Sqlalchemy les possibilitats que es degradi són baixes.

    I potser ho passo a Firebird.

    Actualització 1/10/25: Descarto Firebird, la creació de la base de dades amb Sqlalchemy no funciona.