Property decorator

Python heeft een leuk concept, namelijk dat van een property. Dit concept is enkel beschikbaar bij klassen die overerven van object.

Stel dat we een klasse hebben die alle interactie met een auto maken. We noemen de Klasse Car. Als je met de auto rijdt, druk je op het gaspedaal en een snelheid (speed) te verkrijgen. Dus dit zetten we in de klasse.

Het resultaat van car.speed is dus 6. Wat als we nu een maximumwaarde willen invoeren, want op onze wegen mag je toch niet sneller dan 120 rijden. Dan moeten we getters of setters gebruiken:

Deze update voegt deze beperking perfect in. Maar er is een probleem. Nu moeten de gebruikers van deze code al hun code updaten, en dat is niet altijd de bedoeling. Om de compatibiliteit te vrijwaren, kunnen we het property concept gebruiken.

In Python is de property functie een ingebouwde functie die dat een property object voor ons aanmaakt.

Nu kunnen we gelukkig terug car.speed gebruiken. Als we een waarde toekennen aan car.speed, dan wordt de setter set_speed uitgevoerd en als we er van lezen de get_speed. Zo moet dat.

Maar omdat python ook van leesbare code houdt, is er een decorator gemaakt die @property heet. Dit verbergt onze property functie voor ons en maakt van de functie een property object met dezelfde naam.

Maar we hadden hiervoor ook een setter. Ook dat bestaat, want de speed functie is nu een property en die heeft een setter.

Nu hebben we met deze code exact dezelfde functionaliteit als we willen zonder dat de oorspronkelijke interface gewijzigd is. En bovendien makkelijker te lezen als met de property functie.

List comprehensions

Ik ontdekte dat er mensen zijn die niet weten wat sommige syntax is van de python code die ik geschreven heb in mijn test framework. Een van de zaken die nog niet algemeen geweten is, zijn list comprehensions.

Als ik even zoek naar de python website zelf, dan zie ik daar wat zij beschouwen als list comprehension. Het is een bondige manier om lijsten aan te maken. Met een list comprehension moet je als programmeur dus niet altijd een for loop maken in een functie om een lijst aan te maken.

Een list comprehensions is een bondige manier om lijsten aan te maken.

Een voorbeeld zegt meer dan duizend woorden. Stel dat we een lijst willen hebben met getallen die met een vaste waarde worden verhoogd. We kunnen dit maken door de volgende functie:

Als we deze functie oproepen, krijgen we als resultaat een lijst:

Dit zelfde kunnen we vervangen door deze code:

Simpel, niet? Eens je de basis syntax van een list comprehension door hebt, is dit helemaal niet moeilijk meer.

Model Based Testing

De laatste maanden hoor ik veel over model based testing. Het idee vind ik alvast zeer goed. Maak een model en genereer al je testen met een druk op een knop. Modellen kunnen figuren zijn, en dat is dus makkelijker om te interpreteren, want een mens is toch visueel aangelegd, niet ?

Helaas zijn er nog geen goede tools die dat zoiets op een makkelijke manier kunnen doen. Er zijn al wel zogenaamde runners, die dat zoals een soort robot framework, door je figuur stappen en dan proberen alle pijlen uit te voeren.

Ook het aanmaken van de modellen, of graphs is niet zo simpel. Er zijn nog niet echt goede tools om deze graphs op een eenvoudige manier te maken. dotEditor is er eentje, maar de tools ondersteunen dan meestal het graphiz formaat nog niet.

In de open source wereld bestaat het alvast nog niet, en om aan de tools nu veel geld te geven doen we ook niet, het is echt nog veel te vroeg.

start_stop_graphAls we nu even naar die graphs zelf kijken. Niet simpel om een model te maken dat voldoet aan alles. De vraag is, moet dat, maar laten we eens iets proberen.

Stel, we hebben een knop in onze user interface met het woordje START op. Als we erop drukken, dan wijzigt de tekst op de knop naar STOP. Als we dan erop klikken is er terug START te zien, en zo verder.

Hoe modelleren we dit? De figuur hier toont hoe het zou kunnen. Maar wat gebeurd er nu als we met 2 user interfaces zitten die allebei naar dezelfde backend kijken? Moet dan de START van de andere browser ook mee wijzigen? Of niet? Wat als we te samen duwen op de knop?

Dus het is niet simpel om dat allemaal te modelleren. Toch is het concept een goed idee, om zeker te blijven naar te kijken.

Communicatie en Cultuur in Technologie

Woensdag 11 mei 2016, het is weer zover. Het voorjaarsevent van Testnet met als thema “Verbreed je basis, nieuwe vaardigheden voor Testers” is begonnen. Na het woordje van de voorzitter, was het tijd voor de eerste Keynote. De keynote kwam deze keer van Kristoffer Nortström. Communicatie en Cultuur was het thema.

Software Development is a social Activity
J. Weinberg

Het grootste probleem dat we als technische mensen hebben, is volgens Kristoffer niet het technologische. Dat kunnen we immers wel oplossen, hoe moeilijk het ook is. Neen, volgens hem is de interactie met andere mensen een van de moeilijkste zaken. Moeten we wel communiceren met anderen, is dan een vraag. Natuurlijk, want Software Ontwikkeling is eigenlijk een sociale activiteit. Waarom is dat? Omdat software ontwikkeling problemen van mensen moet oplossen. Als er geen probleem was, zou er ook niets te maken zijn. En omdat er problemen bij mensen zijn, moet er ook mee gecommuniceerd worden. Vragen zoals “Wat gaan we maken” of “Zijn we het juiste aan het maken” zijn dan ook enkele van de meest gestelde vragen bij het ontwikkelproces.

Maar als we even naar de prioriteiten gaan kijken bij de meeste projecten, zien we dat de zaken die te maken hebben met menselijke interactie meestal de laagste prioriteiten krijgen. Dat komt volgens Kristoffer omdat dat het moeilijkste is van software projecten, of van projecten in het algemeen. Menselijk gedrag is namelijk moeilijk te doorgronden.

In vele bedrijven hebben we nog andere problemen. Dat is kennisoverdracht. Als je naar de pure kennis kijkt, dat kan je opschrijven, maar de niet verbale kennis (tacit knowledge in het Engels), dat is een ander paar mouwen. Hoe moet je die overdragen? Hoe draag je over dat een collega op een maandagochtend niet aanspreekbaar is? Zulke zaken, dat zijn ook zaken die in elk project voorkomen en er ook toe doen, want die dragen bij aan de sfeer van een bedrijf, of van een project. Agile kan volgens Kristoffer dit oplossen omdat je er elke dag met elkaar moet communiceren, via de stand-ups. Maar persoonlijk denk ik dat dat toch niet zo simpel is als hij het stelt. Dit omdat je enkel over de vooruitgang praat. Wat deed je? Wat ga je doen? Welke struikelblokken ervaar je? Dat zijn de vragen tijdens een stand-up.

Dat de sfeer goed moet zitten in een bedrijf of project is een feit. De kwaliteit wordt dan beter. Meer zelfs, als de kwaliteit die mensen afleveren niet zo hoog is, dan gaat je eigenwaarde naar beneden. Daarom is het niet technische  veel belangrijker dan het technische.

Wijzigen van de cultuur in een organisatie is een van de moeilijkste zaken die er zijn.

Wat ook nog fnuikend is voor de sfeer in organisaties is het “Ons versus Wij” verhaal. Dit komt meestal voor als we met verschillende teams zitten. En daar moet je voor oppassen. De mens is nu eenmaal geprogrammeerd dat ze in groepen willen leven. En mensen die niet tot de groep behoren zijn dan concurrenten en behoren dan tot het slechte kamp. Dit is evolutionair zo gekomen en dat krijgen we er niet uit. Maar zulk gedrag is wel nefast voor de sfeer in een organisatie. Daarom is communicatie ook tussen teams noodzakelijk. Als je dat in een organisatie voorhebt, moet je proberen de cultuur te wijzigen. Maar dat is niet eenvoudig, het is eigenlijk bijna onmogelijk omdat dit afhangt van de mensen, managers, het product, ja eigenlijk van alles waar je mee te maken hebt.

Tot slot vermelde Kristoffer nog het principe van de “Open Kimono“. Daarmee bedoelde hij dat je open moet zijn met de communicatie, zeker als manager. Vertel de mensen wat ze niet zo goed doen, maar vertel hun ook wat ze goed doen. En dan het allerbelangrijkste. Behandel ze niet als kinderen, want dan gaan ze zich als kinderen gedragen.

Als je even over deze keynote nadenkt, dan merk je dat eigenlijk je met meer vragen zit na dan voor de keynote. Maar dat is de bedoeling denk ik. De oplossing voor al deze mogelijke problemen bestaat immers niet, want dat hangt af van situatie tot situatie.

Lijst met alle gemergde branches

remove_checkboxOnze repositories hebben vele branches, wat niet slecht is, goed zelfs, vind ik. Omdat elke branch het resultaat is van een nieuwe feature of bugfix zijn er nogal veel te vinden in onze repository. Als zulk een branch klaar is om gemerged te worden, dan moet iemand deze zaken reviewen. Dit reviewen gebeurd op gitlab. En als het allemaal klaar is, dan is 1 druk op de knop genoeg om alles automatisch te mergen naar onze master branch.

Na het mergen zou de oorspronkelijke branch gewist moeten worden, anders blijf je met vele branches zitten. Gitlab heeft hiervoor een check box. De default waarde is echter dat deze niet geselecteerd is, dus vergeten sommige team leden dit aan te vinken, met als gevolg dat deze branch niet weg is.

Om de branch te wissen kan je de volgende commando’s uitvoeren :

Als dit echter niet onmiddellijk na de merge gedaan wordt, dan is dat vergeten werk. Vandaar dat er vele branches overblijven, en na maanden werk is het niet echt zichtbaar meer welke branches nu gemerged zijn, en welke niet. Gelukkig heeft git hier ook een oplossing voor in de vorm van een commando:

Het bovenstaande commando toont welke remote branches er reeds gemerged zijn in de master branch. Het omgekeerde lukt ook, tonen welke branches er nog niet gemerged zijn in de master:

Runtime Descriptors

In python kan je een klasse hebben met variablen. Dat is een van de basiszaken in een programmeertaal trouwens. Achter deze variablen kan je echter logica steken in python. Daarom is de property decorator uitgevonden.

Met deze properties, kan je dus in plaats van gewoon 1 waarde te geven, een actie doen of nakijken of de waardes voldoet aan de vereisten. Dit volstond voor mij niet, omdat ik de code voor deze properties graag in een andere klasse stak. Gelukkig hebben de ontwikkelaars van python daar al aan gedacht. De Descriptor heeft het ding. De syntax is:

Dit is dus de syntax van een property. Als we nu de property willen aanspreken, dan wordt de logica in de MyProperty classe opgeroepen. Dat is simpel, maar ik wou meer.

Ik wou dat deze properties dynamisch werden aangemaakt. Waarom? Omdat ik een beschrijvende file had gekregen waarin de API staat beschreven om onze backend aan te sturen. Als hieruit zelf code kon worden gegenereerd, moest ik niet al die functies uitschrijven en die gewoon gebruiken met een python achtige syntax. Daarom wou ik tijdens het runnen van mijn testen, die file inlezen en zo code genereren, die ik dan nadien zou kunnen oproepen.

Na lang zoeken, vond ik de manier om deze properties dynamisch te krijgen. Python heeft een functie setattr. Deze zit standaard in de taal en is de oplossing voor mijn probleem:

Op deze manier bevat de Container klasse properties die dynamisch aangemaakt kunnen worden en kan de backend op een manier aangesproken worden zonder er nog bij na te hoeven denken.

Mocht ooit een descriptor of property worden gedelete, dan is delattr ook te bekijken waard.

Wijzigen van de auteur

De eerste keer dat je git gebruikt, zou je jezelf moeten identificeren door je gebruikersnaam en je mail adres op te geven. Dit omdat deze gegevens in elke commit verwerkt wordt.

Dat kan gedaan worden op systeem niveau door:

Soms wil je een ander mail adres hebben voor een ander project, dus in een andere repository. Dat kan door in die repository de global optie weg te laten:

Ik gebruik dit vaak, omdat mijn open source werk met een ander mail adres gedaan wordt, dan mijn echte dagdagelijkse job.

Maar meestal vergeet ik de eerste keren wel eens om mijn mailadres goed te zetten, zeker als ik de repository nog eens clone. Gelukkig kan dit allemaal ook ongedaan gemaakt worden, afhankelijk van de situatie.

Stel dat enkel de mail van de laatste commit gewijzigd moet worden. Dat is de makkelijkste manier, dan moet je enkel het volgende typen:

Nu kan je de commit message saven en alles is in orde.

Stel nu dat er enkele commits gewijzigd moeten worden. Dan is er een iets complexere methode. Interactieve rebase is onze oplossing deze keer:

Na dit commando komt een editor naar boven en nu kan je de commits wijzigen die je wil wijzigen. Kies dan ook voor de edit optie van de commits die je wil wijzigen, dat is de optie e. Het process start daarna en stopt bij een commit message. Dan moet je het volgende ingeven:

Save het en ga verder met de rebase:

Nu is de auteur gewijzigd. Een beetje meer werk, maar alles is dus mogelijk.

Disable fast forwarding in git

In git is er een optie om fast forwarding niet meer te doen tijdens een merge:

In ons team is de afspraak om nooit fast forwarding te gebruiken, dus is het handig dat deze optie nooit meegegeven hoeft te worden. Dit kan door een configuratie parameter:

Nadat je dit commando hebt gegeven, zijn alle merges voortaan zonder fast forwarding.