Michel Vuijlsteke's weblog

Tales of Drudgery & Boredom.

Categorie: Programmeren (pagina 1 van 4)

Ik zou niet welkom zijn op het werk met zo’n manier van werken

Lang geleden programmeerde ik voor mijn loon. Enfin ja, ik zeg “programmeren”, ik bedoel eigenlijk: ik defelde maar een beetje aan, en ik stampte en duwde aan code tot er iets uitkwam.

Gaandeweg heb ik wel geleerd hoe het eigenlijk zou moeten, maar tegen dat ik dat aan het leren was, was mijn werk niet meer het programmeren zelf maar eerder andere mensen doen programmeren.

En toen ging ik helemaal een andere richting uit, en was “programmeren” iets dat ik hier en daar eens deed tussendoor, maar nooit voor het werk. Soms eens een scriptje ja, maar echt ontwikkelen: neen. Er zijn mensen die daarvoor gestudeerd hebben, en die dat duizend keer beter dan mij kunnen.

Ik ben al content dat ik begrijp waar het over gaat als er over unit testing en decorators en scalars gaat, dat dat geen testers van airconditioning en binnenhuisarchitecten en muurklimmers zijn. En ik ben al content als ik code kan lezen en mij kan verplaatsen in de nodige manier van denken.

developers

Maar zeer soms kan ik geen neen zeggen tegen een project, en dan komt het er toch nog eens van dat ik iets méér dan een klein scriptje links of rechts doe.

Gelijk deze week: Django. The web framework for perfectionists with deadlines, weetwel. Bijzonder leutig, dat had ik al gezegd, en met een beetje Google en Stack Overflow is alles op te lossen, als er niet van al te dichtbij naar de properteid van de code moet gekeken worden.

Om nog niet te spreken van de properteid van de werkmethode. En ’t is niet dat ik niet weet hoe het zou moeten hé.

De theorie: lokaal ontwikkelen, werken met een lokale git reposity, lokaal testen in development, om de zoveel tijd eens een stuk pushen naar github, en als een groot stuk af is, dan pas deployen naar de productieserver.

Helaas.

De praktijk: files editeren op mijn computer (van thuis of van het werk, afhankelijk of ik aan mijn bureau in de living zit of niet), en zo ongeveer alles committen en pushen naar github, en dan op de server pullen om daar te testen.

Ja, op de live versie. Met de live data. En voor ge mij doodschiet dat ik op live data werk: ge moet er niet mee inzitten, want de data leeft in een sqlite-bestand, dat ik gewoon mee naar de repository stuur.

Ja, nu moogt ge mij doodschieten. (Alhoewel: ik heb wel degelijk een betalende github-account, dat ik die data van de rest van de wereld kan weghouden.)

En nee, ’t is niet proper, op die manier werken. En mijn commitgeschiedenis is dan ook navenant:

  • remove unnecessary donotwant
  • verdwijn!
  • ga weg!
  • donotwant nu helemaal weg, oef
  • job pools added
  • nieuwe db tralala
  • jobpool aangepast, hopelijk
  • sorl weg gvd vuilaard waarom bleef dat staan?
  • jobs per poule ipv per eigen voorkeur
  • taalkennis Nederlands apart toegevoegd
  • max length not needed, pf, serieus gast
  • db hoezee
  • opmerkingen vergeten kak
  • kennis e.d. in database gestoken
  • allerlei taalrelated stuff toegevoegd aan admin en fiche
  • eens kijken of dit iets doet want het werkte niet
  • dit zou toch moeten werken, denk ik
  • poging drie talen en eigen/assessment split
  • poging zoveel talenstuff waarom zie ik het niet aaargh
  • ’t is officieel: ik ben een idioot
  • we hebben geen switch! fuck it! we’ll do it without labels!
  • time to call it a night, peisk

Of nonsens zoals dit:

Capture

Jaja, het glamoureuze leven van een has-been programmeur die nog net genoeg weet om een beetje zijn plan te trekken.

Sneek

Ziet, een snake-spelletje.

PICO-8_1

Spelletjes maken is wijs. Hier te downloaden:

snake.p8

En wat hebben we geleerd? Dat alles in een array dat in één clocktick gedaan kan worden, ook blijkbaar allemaal samen gedaan wordt. Ahem, denk ik toch. In alle geval: ik wou op een bepaald moment mijn computer uit het venster smijten. 🙂

En hier online te spelen — pijltjes om te bewegen, “z” is fire. (Er wordt niet geschoten maar ’t is om voorbij het logo te geraken.)

It’s full of stars!

Zeer weinig kleuren, 128 op 128 pixels, en getallen die maar tot drie cijfers na de komma juist zijn (en dan nog).

Ziet!

PICO-8_0

Een resem x, y en z-coördinaten, met voor elke ster een random z-snelheid die er elke frame aan toegevoegd wordt; hoe dichter bij de caera hoe lichter getekend. En dan voor de leutigheid de camera een beetje doen over en weer bewegen ook, en dan de sterren in 3D roteren en neerslaan in 2D.

Een starfield is meestal het tweede dat ik ergens in maak. 🙂

Zie, dit is trouwens hoe zo’n pico-8-programma gedistribueerd kan worden:

stars.p8

Jawel, gewoon een png. De code zelf zit in een header ergens, vermoed ik.

 

Het stonk in mijn template

In een tabel met contactmogelijkheden stond er gewoon contacttype (tekst) en contactdata (ook tekst).

Eerst was alleen GSM of telefoon mogelijk, en e-mail zat ergens anders. Daar ga ik dus toch geen aparte tabel voor maken zeker, om het lijstje (‘GSM’, ‘telefoon’) in bij te houden?

Oh, maar dan zat e-mail plots ook bij de lijst van GSM en telefoon. En dan bleek dat er ook nog Twitter bij moest. En LinkedIn natuurlijk. En soms ook eens een persoonlijke website. En aaarg voor ik het wist, zag de code in de template er zo uit, en was het einde niet in zicht:

<ul>{% for contact in contacten %}
  <li>
    {% if contact.contacttype = "gsm" %}
      GSM {{ contact.contactdata }}
    {% elif contact.contacttype = "email" %}
      <a href="mailto:{{ contact.contactdata }}">{{ contact.contactdata }}</a>
    {% elif contact.contacttype = "linkedin" %}
      <a href="{{ contact.contactdata }}">LinkedIn</a>
    {% elif contact.contacttype = "twitter" %}
      <a href="http://twitter.com/{{ contact.contactdata }}">@{{ contact.contactdata }}</a>
    {% elif contact.contacttype = "website" %}
      <a href="{{ contact.contactdata }}">{{ contact.contactdata }}</a>
    {% elif contact.contacttype = "telefoon" %}
      Tel. {{ contact.contactdata }}
    {% else %}
      {{ contact.contacttype }}: {{ contact.contactdata }}
    {% endif %}
    {% if contact.opmerking %}
      ({{ contact.opmerking }})
    {% endif %}
  </li>
{% endfor %}
</ul>

Euh ja, qua stinken kan dat tellen.

Dus maar rap properkes een tabel met contactmiddelen gemaakt, en bij elk contactmiddel in de tabel een template gezet, genre tel. % voor telefoon en <a href="http://twitter.com/%">@%</a> voor Twitter. En een formatteringsding gemaakt om de contactdata in de template te smijeren, en nu ziet de code er zo uit:

{% for c in contacten %}
  <li>
    {{ c.contactmiddel.template|formatcontact:c.contactdata|safe }}
    {% if c.opmerking %}
      ({{ c.opmerking }})
    {% endif %}
  </li>
{% endfor %}

Een mens moet zijn plezier uit kleine dingen halen, soms.

Overdrijven met SQL

Mensen hebben een adres. Of nee, mensen hebben eventueel een adres. Of nee, mensen hebben eventueel meer dan één adres. Of nee, mensen hebben eventueel meer dan één adres, waarvan er 0, 1 of meer nog geldig zijn en/of waren, eventueel van een bepaalde datum tot een bepaalde datum.

Deze situaties zijn (onder meer) mogelijk:

  • Persoon A
    1. Adres 1 (tot 1998)
    2. Adres 2 (1998-2000)
    3. Adres 3 (sinds 2000)
  • Persoon B
    1. Adres 1 (tot 2010)
    2. Adres 2 (2010-2012) <– dus niet meer geldig!
  • Persoon C
    1. Adres 1 <– aangeduid als ‘ongeldig’, bijvoorbeeld omdat een brief onbesteld terugkwam
  • Persoon D
    1. Adres 1 (tot 1998)
    2. Adres 2 (sinds 1998) <– aangeduid als ‘ongeldig’

Het is ook mogelijk dat een persoon gezegd heeft dat hij niet meer in de adressenlijst wil staan, mensen kunnen meer dan één geldig adres hebben (thuis en werk, bijvoorbeeld, of buitenlands adres en Belgisch p/a voor correspondentie).

Gegeven dit, wil ik een lijst van mensen waar adresproblemen mee zijn:

  • alle mensen die geen adres hebben
  • alle mensen met enkel ongeldige adressen
  • voor de mensen met enkel ongeldige adressen: het meest recente ongeldige adres, met de ‘geldigheidsdata’ erbij

Dat lijkt op het eerste zicht allemaal zo simpel als iets, maar uiteindelijk toch niet echt: ik wou een bestaande template hergebruiken en dus was ik beperkt tot een bepaald aantal velden (en moesten die ‘geldigheidsdata’ in het adresveld geplakt worden, maar dat lukt niet als ze soms null zijn. En oh ja, het is niet evident om mensen zonder adressen en mensen met alleen ongeldige samen te krijgen, en dan nog eens voor die laatste enkel het meest recente ongeldige adress erbij.

Maar impossible pas français, en SQL is een gewillige hoer als het op dergelijke dingen doen aankomt, en uiteindelijk was het min of meer snel in orde. Maar zoals ze zeggen: it really puts the ‘dirty’ in ‘quick & dirty’.

Dat is de miserie soms: het bouwt en bouwt en voor ge het weet, is een query een monstrositeit zoals dit:

SELECT p.id, p.voornaam, p.achternaam, 
       r.bla, r.spel, c.geriefdata blop,  
   if(length(a.adres)>0, 
      concat(coalesce(a.adres,''), 
         '\n[', coalesce(a.van,''),
         ' - ',coalesce(a.tot,''),
         ']'), 
      null) adres
FROM persoon p 
   inner join dink r on p.dink_id=r.id
   left outer join gerief c on p.id=c.persoon_id
   left outer join 
      (select a1.adres, a1.persoon_id, 
         a1.geldig, a1.van, a1.tot
       from adres a1
         inner join (
            select persoon_id, 
               max(van) as recentste
            from adres
            where geldig=0
            group by persoon_id
         ) a2 on a1.persoon_id=a2.persoon_id and 
               a1.van = recentste
      ) a on p.id=a.persoon_id
WHERE
   p.splut=0 and
   p.pulk=1  and
   (a.geldig=0 or a.geldig is null) and 
   (c.gerieftype='blop' or c.id is null) and
   p.id not in (
      select persoon_id
      from adres
      group by persoon_id
      having sum(geldig)>0
   )
GROUP BY p.id
ORDER BY  r.bla, r.spel, p.achternaam

Erm ja. Niet dat het zó enorm groot is, maar ik zou dat eigenlijk eens moeten van nul af aan herbekijken, ja. 🙂

“Zware menselijke fout”, Bourgeois? Neen, niet echt

Schrijft de Gazet Van Antwerpen

Een voorzitter van een bureau in Zoersel heeft volgens Vlaams minister Geert Bourgeois een “zware menselijke fout” gemaakt, door zijn computer in standby-modus te laten staan. Een deel van de registratie van de uitgebrachte stemmen moet daardoor manueel opnieuw gebeuren. 

Wat een compleet laffe en laagbijdegrondse uitspraak, om de schuld van dat ding in Zoersel bij de voorzitter van het stembureau te leggen. 

Ik heb op de televisie die stemcomputers zien piepen en rode lichten doen afgaan als mensen hun kaartje er te vroeg uit trokken, of omgekeerd in staken. 

De fout en de schuld en ligt uiteraard 100% bij de maker van de software van de stemcomputer: een systeem dat als een zot begint lawaai te maken en blijkbaar BAHUUT BAHUUT doet bij het minste, en dat dan niets doet als het hele systeem na een bepaald uur nog altijd in testmodus staat, dat is een slecht gemaakt systeem. 

In De Standaard, die Radio 1 citeert, is het ook van dat:

Volgens minister van Bestuurszaken Geert Bourgeois zou het grootste deel van de fouten het gevolg zijn van het niet correct gebruiken van de machines. Dat zou 80 tot 90 procent van de problemen verklaren. Slechts minder dan 20 procent heeft echt met de computers te maken, zei hij op Radio 1.

Pfeh. 

Zelfs als de fout bij de gebruiker ligt, is het nog altijd de schuld van de maker. Zeveraars. 

Variabelen en scoping en dink

Grmbl, grmbl. 

Ik maak een custom taxonomy aan in WordPress, ik geef die de propere naam “author”, en alles lijkt in orde te zijn: ik kan aan posts meer dan één author geven (in plaats van standaard één, die dan nog eens een WordPress-user moet zijn), daar zijn archieven van, en tag clouds en watnog, en dat linkt allemaal proper naar elkaar zonder al te veel moeite.

De auteurs, om ze alfabetische te kunnen sorteren, sla ik op als “achternaam – voornaam”, en als ze dan getoond moeten worden, zet ik voornaam voor achternaam. En neen, ik kan er geen rol bij zetten (schrijver, illustrator, vertaler, …), maar bon, ’t is geen boekendatabase die ik aan het maken ben. 

En alles werkt goed tot er een auteur met één naam toegevoegd wordt, bijvoorbeeld “Moebius” als ik er niet “Giraud – Jean” van zou maken: daar geeft WordPress een lege archiefpagina voor. 

Aargh! 

Debug, debug, debug. Blijkt dat de query om de lijst van posts van een auteur met voor- en achternaam er zo uitziet:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (246) ) AND (wp_posts.post_author != 0) AND wp_posts.post_type IN ('post', 'page', 'attachment') AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 1 AND wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 20

en een query voor een auteur met één naam zo:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (138) ) AND (wp_posts.post_author = 0) AND wp_posts.post_type IN ('post', 'page', 'attachment') AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 1 AND wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 20

Het verschil al gezien? Ha, inderdaad de ene doet 

(wp_posts.post_author != 0)

de andere doet 

(wp_posts.post_author = 0)

Toink? Als de taxonomieterm twee of meer woorden bevat, zoek dan posts waarvan de WordPress-auteur niet nul is, en anders: zoek posts waarvan de WordPress-auteur wél nul is (en die user bestaat niet). 

Wat in de WordPress-code gewroet, maar niet enorm vreselijk veel zin om daar in te gaan prutsen — en dan maar mijn taxonomie hernoemd van “author” naar “myauthor”: 

update wp_term_taxonomy taxonomy='myauthor' where taxonomy='author';

en dan in functions.php 

register_taxonomy('author', 'post', array( 'hierarchical' => false, …

vervangen door 

register_taxonomy('myauthor', 'post', array( 'hierarchical' => false, …

en taxonomy-author.php hernomen naar taxonomy-myauthor.php: hey presto, alles werkt zoals het zou moeten gewerkt hebben. 

Ik heb niet enorm veel goesting om te gaan kijken wat het precies was, maar ik kan niet anders dan vermoeden dat er érgens een variabele de naam van de taxonomie krijgt ($author in dit geval) en dat die een andere variabele $author overschrijft die ergens gebruikt moet worden om godweetwat in op te slaan, en dat dat op de één of andere manier verkeerd loopt onder zeer specifieke voorwaarden. 

Een interessante bug, denk ik, want treedt herhaalbaar op, zou niet mogen optreden, en is wellicht gemakkelijk te verbeteren. 

Als ik dan nog eens tijd en goesting heb, maak ik een tiketje aan. 

Demo

Meeemorieesss.

Moleman 2 – Demoscene – The Art of the Algorithms (2012) from Moleman on Vimeo.

Life, in APL

Mijn hersenen bloeden een beetje:

[via]

Goeie bloederige help, in 4k

Vorig jaar maakte hij deze (“basically a mix of spheretracing, orbit traps, fake ambient occlusion and a little bit post postprocessing timed with some nice 4klang synth”):

Dit jaar maakte hij deze:

Zegt de mens:

It’s a mix of shere-tracing, fake ambient occlusion and a lot of post-processing. And it took me nearly two months to complete it. The shader basically encapsulates a sphere-tracing based raymarcher for a single fractal formula with camera handling. An extra post-processing shader adds effects like god-rays, tv-lines and noise to make the result look more interesting and less ‘sterile’. The different intro parts are all parameter and camera position variations of the same fractal.

Voor de duidelijkheid: die “4k”, dat wil zeggen dat het (gecompileerde, uiteraard) programma dat dit maakt maximum 4096 bytes lang mag zijn. Uitgeschreven zijn dat 64 lijntjes van 64 karakters.

Meer hier ([via].

QB

Sinds er Windows 8 op de computer staat, werkte Warcraft III niet meer, zei Louis. En ik moest kijken wat er aan de hand was. 

Blijkt: hij startte Warcraft op met een verkeerde shortcut. Die naar Reign of Chaos in plaats van die naar Frozen Throne (want ik had de upgrade er ook op gezet — ja, helemaal legaal, van de originele CD’s, zelfs), en dat liep verkeerd. 

Enfin, shortcut in de startbalk gezet, Louis content. 

Op weg naar die oplossing kwam ik voorbij allerlei dingen die nog op de computer stonden, en waar ik al half van vergeten was dat ze erop stonden. Een oude Age of Empires III, bijvoorbeeld. Waar Louis nu al een volledige avond op gespeeld heeft. 

En een directory met de naam QB, die ik al sinds jaar en dag op al mijn PC’s zet: QuickBasic 4.5. Van 24 jaar geleden, en nog altijd even fantastisch, vind ik. 

Louis vroeg wat dat was, en ik heb het hem in de rapte getoond:

cls
input "Wat is jouw naam? ", f$
for t=1 to 100
   print "Hallo", f$, t
next t

Uitgelegd:

  • cls is “maak het scherm leeg”
  • input wil zeggen “stel een vraag en zet het resultaat in wat er na de komma staat” (in dit geval f$ — die $ staat er om te zeggen dat het tekst mag zijn, als er gewoon f stond, zou het alleen getallen aanvaarden) 
  • for…next wil zeggen “geef t de waarde 1, doe dan iets, maak t eentje groter, en blijf dat doen tot t 100 is”
  • print wil zeggen: zet iets op het scherm, in dit geval “Hallo”, en dan wat er in f$ gezet werd, en dan de waarde die t nu heeft (dus eerst 1, dan 2, dan 3, enzoverder)

Louis: oh! maar als ik zeg dat mijn naam Louis is, dan gaat hij honderd keer “Hallo Louis” zeggen!

Programma gerund, en jawel hoor: ik denk dat ik lichtjes in zijn ogen heb gehoord. 

En ik denk dat ik dat eens ga beginnen aankweken, programmeerskills. 

Renaissanceinternetmens

Daarnet zat ik met een probleem: een context aangemaakt in de Context-module (één van die fijne modules die in theorie fantastisch zijn maar in de praktijk op, euh, onverwachte momenten niet doen wat ze moeten doen), en in soep.

Context verwacht een machine name voor zijn items, fair enough (al zou ik een echte naam gemakkelijker vinden, dat die nog gewijzigd kan worden). Ik had een context aangemaakt met de fijne naam “Kalender/nieuws ABC”, en dat werkte van de eerste keer perfect hoe ik het wou: als ik op pagina ABC sta, toon dan de blokken “laatste nieuws ABC” en “binnenkort ABC” in twee kolommen naast mekaar onderaan de pagina.

Maar! Dan wou ik een “Kalender/nieuws DEF” maken, en die eerste clonen lukte niet. Die eerste wijzigen, lukte ook niet. Die eerste verwijderen, lukte ook niet. Ahem. Ah ja, die slash werd geïnterpreteerd als een parameterscheidend ding, verdomme. De mannen van Context hadden geen validering voorzien, en ik was niet de enige die er last mee had.

Okay, bon, geen probleem. Naar de server getoogd, mysql in gang gesleurd, show tables om te kijken of er ergens iets context-achtig in staat, hey kijk: een tabel dpl_context! Describe dpl_context toont dat er een name-veld in zit als primary key, select name from dpl_context geeft mij effectief alle namen, update dpl_context set name=’ABC home’ where name like ‘Kalender/nieuws ABC’ doet wat het moet doen, een refresh in Drupal later: hopla, probleem opgelost!

Dat moet, denk ik, zo ongeveer de twintigste keer zijn, de laatste paar dagen, dat ik op mijn twee knieën content ben dat ik de laatste twintig jaar gedaan heb wat ik gedaan heb, en dat ik misschien nergens een echte expert in ben, maar toch bij redelijk wat dingen mee kan spreken.

En dat ik van niet al te veel andere mensen moet afhangen als ik iets wil maken.

Dat zijn de mooiste momenten, in hobby of in werk: als ge het gevoel krijgt dat de afgelopen pakweg twintig jaar effectief ergens voor gediend hebben. 🙂

DHSC

Ha. ‘t Is eens wat anders dan Kretschmer of Jung: Your programmer personality type is DHSC.

You’re a Doer.
You are very quick at getting tasks done. You believe the outcome is the most important part of a task and the faster you can reach that outcome the better. After all, time is money.

Ik programmeer bij momenten redelijk snel, ja.

You like coding at a High level.
The world is made up of objects and components, you should create your programs in the same way.

Ik zit inderdaad niet echt graag in de loopgraven. Beetje top-down mens, ik. Mijn laatste ervaring in de loopgraven was, euh, Z80 assembler. Om u een idee te geven. 😀

You work best in a Solo situation.
The best way to program is by yourself. There’s no communication problems, you know every part of the code allowing you to write the best programs possible.

Um. Kweetniet. Ik heb er nooit problemen mee gehad om met meer dan één mens tegelijk te pogrammeren aan iets.

You are a Conservative programmer.
The less code you write, the less chance there is of it containing a bug. You write short and to the point code that gets the job done efficiently.

Mwof. Ik vlieg er wel meestal meteen in, en dan komt er soms veel te veel code. Maar dan refactor ik regelmatig wel eens, en durf ik wel helemaal opnieuw te beginnen. De blutsen met de builen, veronderstel ik?

Code search

Humor, zie ook Kottke:

Heh.

Schlurpts

…dat is het geluid van mijn hart dat bloedt.

Ik ben aan een WordPress-template aan het programmeerderen.

Niet “aan het programmeren”. Want “programmeren”, dat impliceert serieus werken. WordPress moedigt serieus werken niet aan.

Scheiding tussen inhoud en presentatie is er nauwelijks, abstractie wordt er nauwelijks gemaakt, en vies werken wordt praktisch aangemoedigd.

Het is dan ook altijd weer schipperen tussen binnen de lijntjes van de WordPress-functies te werken en een plugin schrijven en gewoon brutekracht hap smijt MySQL-queries en PHP te doen… vies, vies, vies. Ick ick ick.

En het stomme van de zaak: uiteindelijk zijn dat allemaal zo geen ingewikkelde zaken, en uiteindelijk heb ik soms de indruk dat het bijna gemakkelijker zou zijn om het allemaal zelf te programmeren.

Tot ik kijk wat er allemaal zou moeten gedaan worden, en dat het toch wel weer het wiel uitvinden zou worden… urgh ack crap.

Toch maar eens kijken naar een betere oplossing dan WordPress? Drupal toch nog?

Pfff.

Oudere berichten

© 2017 Michel Vuijlsteke's weblog

Thema gemaakt door Anders NorenBoven ↑