Ny blogg om programmering

03 april 2010

Jag har en längre tid funderat på att börja flytta ut mina programmeringsrelaterade inlägg till en ny blogg.

Jag tog tag i saken när jag idag fick lust att skriva ett inlägg om programmering. En förändring jag gör är att jag där kommer att blogga på engelska. Det kommer att göra det lättare att diskutera blogginlägg med internationella kompisar från mailinglistor.

Så med lite svengelskt stuk på språket skapade jag ”Voice Steam” idag, med URL objarni.wordpress.com efter mitt programmerar-alterego ”objarni”.

Taggar:


Python+Ubuntu+TDD

19 december 2009

A couple of weeks ago I tried to record my desktop using gtk-recordmydesktop. It was simpler than I had imagined, so I went ahead and tried uploading the resulting .ogv file to Youtube. To my surprise Youtube swallowed the file without any fuzz – no need to resize or convert the video at all. Joy happy joy 🙂

I was a bit enthusiastic by then, so I thought ”can’t I solve some problem using my pyTDDmon tool and show it to others?”. So I picked a simple problem from the TDD-Problems site and went on.

Below you can watch the result. The first three parts were recorded the same night, with the comments added a few days later. I recorded and commented Part 4 tonight. It uses an updated version of the pyTDDmon tool, which has a little more user-friendly text-output in the console and pyTDDmon window.

Enjoy! I recommend watching the videos either in full-screen or zoomed-in. The smallish version directly below is kind of hard on my eyes at least.

Taggar: , , , , ,


Merrinian – bygg moderna textspel [under utveckling]

27 oktober 2009

För några veckor sedan fick jag en ingivelse att börja koda textspel igen. Det är något jag återkommit till då och då under hela mitt programmerarliv. T.ex. var det allra första ”programmet” jag hackade ihop ett textspel som hette ”Bigew” – mest för att jag tyckte om bokstavskombinationen, inte så mycket mening bakom dem ;). ”Program” inom citattecken för jag kom aldrig längre än att skriva ut ”Det här är ett rymdskepp” och rita lite ASCII-art (framgooglat exempel – inte mitt!) på Commodore64:an.

Sedan har jag byggt ett antal hack&slash(klicka Press to Start!)-kloner (BBS-oldtime-goodie för dem som var med när det begav sig på 80-talet), och någon enklare MUD-historia (en spelare i taget fast mot samma värld, Slasher kallade jag spelet som började på miniräknaren TI-80, fortsatte till Windows 3.11 och sedan i sin mest utvecklade form i DOS med sitt svart-vita drama!). Blev också en Telnet-variant kallad Stasher (tack Tor!), baserat på samma koncept en-värld-flera-spelare-men-bara-en-i-taget, fast denna gång över internet alltså.

Sedan blev det ett simplistiskt textspelsspråk kallat kLyWe Text Game, KTG, som genererade två-tre små halvfärdiga textäventyr i grannskapet. Enspelarspel. Dock var språket för begränsat i sig. T.ex. fanns det inget sätt att stoppa spelet, om det blev Game over eller om spelaren klarade sista questen.

Denna gång tänkte jag ”back to basics” – textäventyr. En spelare, inget nätverk, inga megaregler, utan bara texten och problemlösningen. Lite mera Zork-stuket alltså. Genren kallas ”Interactive Fiction” (tack för denna allmänbildning bror!).

Så jag påbörjade projektet som fått namnet Merrinian förra veckan. Det är open source (MIT-license), och hittills finns det bara ett teknikdemo.

Det som jag tror är lite nytt med Merrinian är framförallt att man kan spela mp3/ogg-musik i bakgrunden medans spelaren befinner sig på en plats i spelet. Dessutom renderas allt med en handskriven font, för att få lite mera hemtrevlig känsla. Här är en screenshot.

Projektet befinner sig alltså än så länge på konceptstadiet. Därmed har du chansen att vara med och hjälpa till i dess utveckling! Om du är intresserad av att testa/vara med och utveckla detta (finns för Windows/Ubuntu/ren source code) än så länge, skicka mig ett mejl! (min mailadress står ute till höger under avatarbilden).

Läs mer om Merrinian på dess utvecklings-site: sites.google.com/site/merrinian.

Merrinian

Taggar: , , , , , ,


MVP pattern practice, part 1

26 september 2009

At work a couple of weeks ago I was given the task to build a multi document interface text editor for the LISP programming language. It was supposed to provide syntax highlighting and bracket matching, and the usual Open/Load/Save/Close operations.

Being a TDD enthusiast, I wanted to give autotesting that graphical user inteface a try. Previously I’ve tried the Humble Dialog pattern, aswell as some home-brewn MVC mixtures in the past. Both with mixed feelings (too awkward, too hard to easily test).

Anyway, since building a syntax highlighting text editor from ground-up seemed like a bad idea when there are fine Open Source alternatives like the TextEditor component from the SharpDevelop community, I started out learning the API in a spike project first of all.

When I spike-hacked away, I continously thought ”how am I going isolate/test this?”. And when I finally got to the point where I wanted to build ”Open/Close” and those basic commands, I still had no idea how to make it work.

So I started to read up on another pattern I’d heard of, the Model View Presenter (MVP) pattern. It seemed to provide even more loosely coupled types than the previous two, giving air to unit tests. But I took a too big chew; practicing and understanding the new pattern while also working with the new component was a little too stressful at the high pace of work, so I made a pragmatic decision to practice the pattern at home first, before I started using it at work.

Here we are! And I’m going to choose a really simple GUI to practice on; it will be a ”item list pick/reorder” GUI. The user is presented with a list of text items, which can be reordered using up/down arrow buttons. Then, double clicking an item chooses that item, while clicking the cancel button picks no item. Reordering is left unaffected whether the user picks an item or cancels.

This is a schematic of the GUI dialog presented to the user:

gui-schematic
This is the first blog post in a series detailing what I find out about the MVP pattern. If all goes well, I might extend the example to more elaborate user interface. On the technology side, I intend to use Visual C# 2008 Express Edition, and the open source NUnit test framework.

Taggar: , , , , ,


ALT.NET [GBG]-mötet måndag kväll

15 september 2009

Jag kom till Bishops Arms vid 19.20 måndag kväll. Jag tänkte jag skulle vara först, och invänta de andra. Tji fick jag! Magnus och Kristoffer hade redan anlänt. De hittade ett litet ”krypin” under trappan, som ett slags avsides rum. Perfekt för nördsnack!

Med varsin öl och mat på ingång satte vi igång och snackade .NET och branchen. Snart dök också Johan upp. Det blev en heltrevlig kväll som tog slut först efter tio.

Kristoffer hade med sig sin laptop och visade ett open-source-projekt han pysslar med — ska inte avslöja vilket då han fortfarande inte vill gå ut alltför ”officiellt” med det. Det verkade spännande och användbart – så mycket jag nu förstod av det. Det var webbrelaterat, och eftersom jag är en WinForms-kille nästan uteslutande (i alla fall i .NET-världen) hade jag lite svårt att hänga med. Och så hade jag fått i mig ett par öl vid tidpunkten 😉

Ett litet enhetstesttips gav jag, nämligen att man kan använda ordet ”Expect” istället för ”Assert.That” i sina NUnit-tester. Detta gör man genom att låta ens testklass ärva ifrån klassen ”AssertionHelper”:


public class SomeTests : AssertionHelper {

  [Test]

  public void Example1() {

    var result = new MySUT(1).Compute(2);

    Expect(result, Is.EqualTo(3));

  }

}

En lång och energisk diskussion vi tog upp var olika indelningar av automatiska tester. Jag sysslar än så länge uteslutande med mikro/fokus/enhetstester i samband med utvecklingsmetodiken TDD. Så för mig var det mäkta intressant att ta del av floran av verktyg som finns för .NET när det gäller automatiska tester.

Jag vill dela med mig av den ”tabell” vi ställde upp för att strukturera våra tankar (eller mina framförallt hehe).

Till att börja med sorterade vi alla termer för tester vi kom på i tre olika mer eller mindre väldefinierade kategorier. De tre kategorierna var (jag väljer ut en av termerna för att namnge kategorin så jag enkelt kan diskutera den nedan):

  1. Acceptanstest. Relaterade termer: Acceptanskriterier, User stories, Customer tests, GUI-tester*.
  2. End-to-end-test. Relaterade termer: GUI-tester*, integrationstest, regressionstest, systemtest, lasttest, smoketest.
  3. Enhetstest. Relaterade termer: mikrotest, fokustest.

* just GUI-tester valde vi att lägga ”mittemellan” kategori 1 och 2, då de inte riktigt kändes klockrena i någondera kategorin.

Sedan valde jag ut några olika egenskaper att beskriva de tre kategorierna utifrån. Jag går igenom egenskap för egenskap nedan.

Verktyg
På denna rad i tabellen fyllde vi i alla de verktyg vi diskuterat under kvällen.
Acceptanstest: TestComplete, StoryTeller, WebAII, Watin, FitNesse, Selenium.
End-to-end-test: NUnit, MbUnit, MSTest, xUnit.
Enhetstest: NUnit, MbUnit, xUnit, MSTest, Moq, RhinoMocks, Typemock, Pex.

Före/efter
På denna rad fyllde vi i om tester inom kategorin ifråga vanligtvis kodas före eller efter produktionskod.
Acceptanstest: Efter (dock skrivs User stories och deras acceptanskriterier före, fast dessa består inte av kod utan vardagsspråk!)
End-to-end-test: Efter (eftersom de brukar vara känsliga eftersom de är långa och nära inpå systemet).
Enhetstest: Före (såklart!)

Antal
Här gjorde vi ett slags grovuppskattning om antal tester inom varje kategori för ”ett typiskt projekt”.
Acceptanstest: 100 st
End-to-end-test: 300-400 st
Enhetstest: 2000-4000 st

% av utvecklingstiden
Här försökte vi uppskatta hur tidsfördelningen i ett typiskt projekt var, alltså utvecklingstid.
Acceptanstest: 20%
End-to-end-test: 20%
Enhetstest: 60%

Sammanfattningsvis kändes det nyttigt att få ett slags ”helhetsperspektiv” över automatiserade tester. Jag är som sagt novis på Acceptanstest/end-to-end-test, och det skulle vara kul att börja testa några av verktygen på riktigt.

Ytterligare en jämförelsediskussion jag kom på idag är ”Varför?”. Alltså något slags moralisk förklaring till vilket problem en viss kategori är till för att lösa.

Kanske något att diskutera på nästa möte..?

Innan vi skildes åt kom vi fram till att vi spikar 2:a måndagen varje månad under hösten för ALT.NET-GBG-möte. Detta eftersom det passade oss alla fyra bra tidsmässigt. Runt 18.00 den 12e oktober ska du alltså boka in om du är .NET-kodare, gillar modern programvaruutveckling och en eller annan öl!

Taggar: , , ,


ALT.NET [GBG] Samling ikväll!

14 september 2009

ALT.NET är en internationell rörelse för .NET-utvecklare (C#/VisualBasic) som inte stirrar sig blinda på att endast använda Microsoftverktyg. T.ex. används många opensource-verktyg istället. Själv använder jag NUnit för Testdriven utveckling (TDD).

ALT.NET har en egen Sverige-site som heter ”ALT.NET Sverige”.

Göteborg fick sin egen ALT.NET-grupp i våras, och består än så länge av blygsamma tre-fyra stycken tappra programmera. Joina oss genom att gå med på mailinglistan!

Ikväll blir det pubBishops Arms Avenyn lite nedanför Coop. Vi samlas kring 19.30. Jag klantade mig för någon vecka sedan och dubbelbokade mötet – därför bjuder jag på öl på de tre som först dyker upp! 😉

Välkommen!

Taggar: , , ,


Continous Integration

17 augusti 2009

källkodHar du jobbat med andra programmerare mot samma källkodsbas någon gång? Kanske CVS, SVN, bzr eller git? Då vet du att det ofta känns bättre att upload:a än att download:a.

Upload kallas lite olika i olika system; commit i CVS/SVN, och push i bzr. git kan jag inte så där vet jag inte vad det kallas.

Download heter update i CVS/SVN, och har lite olika namn beroende på vad exakt man ska göra i bzr: merge, update eller pull.

lianer

Kodbas = djungel?

I vilket fall — den teknik jag vill prata om idag kallas alltså ”kontinuerlig integration” vilket känns lite sisådär namnmässigt. Det låter mera som det är en matematisk definition eller teorem snarare än en mjukvaruutvecklingsteknik.

Så vad går CI ut på? Kort kan man säga att CI går ut på att kontinuerligt bygga trunken/mainline/gemensamma källkodsbasen på en separat ”byggmaskin”, och signalera programmerarna så fort något går fel. T.ex. via mail eller en tray-ikon som blir röd istället för grön.

Så enkel är principen bakom CI!

Du kanske frågar dig ”Vad gör detta för nytta då?”. Grejen är den att om du kan se någonstans på skärmen att trunk är ”healthy” så är det inte så mycket att oroa sig för innan du gör en uppdatering av din kodbas. Du litar helt enkelt mera på den gemensamma kodbasen.

heart_monitor

CI = Hjärtmonitor för trunk

Ett CI-system kan alltså betraktas som en ”hjärtmonitor” för den gemensamma koden!

Omvänt, om det finns ett tydligt signalsystem till programmerarna, hur den gemensamma basen ”mår”, så är man lite mera försiktig vid checkin/commit. Och om man råkar göra fel, får man reda på det inom några minuter, istället för när en halvirriterad kollega gnäller på att man glömt Add:a någon ny fil.

I praktiken kan en CI vara allt från ett schemalagt litet byggscript på din egen utvecklingsdator, till en separat server med massa avancerade verktyg.

På jobbet har jag en gammal ”skruttdator” för CI. Det känns bra att en gammal ”obrukbar” dator kommer till användning! Jag har gjort det lätt för mig och byggt några .bat-filer (ja, jag jobbar i Windows på jobbet på gott och ont) som i tur och ordning:

  1. uppdaterar den lokala källkoden på servern så den får senaste version av gemensamma kodbasen
  2. bygger hela lokala Solution i Release-config
  3. kollar om det gick bra eller ej. Om det gick kass, skapas en liten ”flaggfil” (typ ERROR) på nätverket.

Detta ”CI-script” körs c:a var femte minut.

Byggmonitor

Min lilla "Byggmonitor"

På min egen jobbdator har jag en Tray-applikation byggd i C# som kontrollerar den här flaggfilen en gång i minuten. Sedan visar den antingen en grön eller en röd ikon beroende på om flaggfilen finns eller ej. Jag kallar applikationen ”Byggmonitor”.

Det är väldigt enkelt och simplistiskt – men det är så jag gillar saker!

För övrigt har jag utökat flaggfilen med att inkludera Error-rader från kompileringen på CI-servern, så det blir lite mera info om hur bygget gick. Den innehåller också information om när sista bygget skedde. På så sätt vet jag om CI-scriptet plötsligt slutat fungera.

Sedan kan man ju utöka CI-scriptet så det kör alla enhetstester/integrationstester på servern också. Men bara kompileringssteget är det allra mest givande i min erfarenhet. Utvecklare kör ju enhetstester/integrationstester så ofta på sina egna burkar.

Sammanfattningsvis kanske man kan säga att med ett CI-system ökar utvecklarnas förtroende för den gemensamma källkoden. Därmed uppdaterar alla oftare och committar oftare.

Taggar: , , , , , , ,


Grubblerier, fortsättning

01 augusti 2009

Jag skrev inlägget Grubblerier tidigare idag.

Jag har grubblat under dagen. Försökt analysera problemets ursprung.

Så kom jag på det: Jag oroar mig för att ändra på testkod. Det är ett välkänt ”TDD anti-pattern” – att man på något sätt känner sig känslomässigt fäst vid sina tester – så att man inte vågar eller vill röra vid dem.

Det är såklart en naiv inställning. Testerna liksom produktionskoden är under ständig utveckling i ett programvarusystem; betatanken – inget är någonsin färdigt, bara halvfärdigt. Och under ständig förändring/utveckling/evolution. [Betatanken kan för övrigt appliceras på allt: programvara, produkter, företag, människor, ekosystemen, samhällen, din chef, dig.]

Fortress Defender - en skärmdump

Så här ser Fortress Defender ut idag

Den naturliga vidareutvecklingen i mitt minispel är flytta ut ansvaret från Ball och Boat till en separat klass Entity eller kanske LinearEntity eftersom det handlar om linjär rörelse. Enhetstesterna för Entity kan utan skuldkänslor kopieras från t.ex. Ball och modiferas för att passa Entity. Entity själv kan utgå ifrån Ball.

Enhetstesterna för Ball och Boat som de står nu (som alltså testar linjärrörelse framför allt) är onödiga, då det inte är Ball eller Boats ansvar längre att utföra linjärrörelse. Det är Entity‘s ansvar. Ball/Boat testerna förpassas, när Entity är grön (alla tester OK), till papperskorgen.

Därefter är Ball och Boat enkla ”konfigurationer” av Entity. Vad behöver egentligen testas för dessa två? Frågan kan omformuleras till ”vad är Ball och Boats ansvar”. Och, utan att gå händelserna alltför mycket i förväg, känner jag redan nu att det som är Ball– och Boatspecifikt är punkterna A/B som Ball respektive Boat rör sig mellan. Så Ball och Boat kanske snarare ska vara ”Entititsskapande funktioner” än klasser.

Men förra stycket är ren spekulation. En sak i taget! Entity, here I come.

Taggar: , ,


Grubblerier

01 augusti 2009

Våndor i utveckling.

Jag tänkte skriva lite om det idag.

Fortress Defender - en skärmdump

Fortress Defender - en skärmdump

Som du kanske vet sedan tidigare håller jag på att utveckla ett minispel mha. multimediabiblioteket PyGame. Man skulle kunna säga att spelet ”är ett PyGame”.

Nå först byggde jag ”kanonbollarna”, kallade ”Ball” i koden. De rör sig linjärt över skärmen, genom centrumpunkten (eftersom fortet befinner sig i centrum av havet).

När jag började koda attackbåtarna, ”Boat”-klassen, igår upptäckte jag att de har stora likheter, dessa två entiteter. De rör sig båda linjärt, och de består av en enda bild som ritas ut på skärmen. Dessutom triggar de varsin händelse när de är ”klara”. I Ball-fallet triggas ”ta bort mig”-händelsen. I Boat-fallet triggas ”game over”.

BoatCode

En snutt av Boat.py-filen

Båda klasserna är enhetstestade och fina, fast testerna är ganska så likartade. De testar ”var befinner sig entiteten i början”, ”var i slutet” och ”var i mitten” (av sin bana/livstid). Dessutom kollar de så att rätt händelse triggas på slutet.

Så långt allt väl. Men vän av ordning vill såklart bryta loss den gemensamma funktionaliteten i detta – förenkla ”uttrycket” som koden kan ses som. Alltså faktorisera ut en basklass eller hjälpklass som har förmågan att ”röra sig från A till B på tiden T, och triggar händelsen H när den är framme”.

Om jag då skulle utveckla en sådan tredje, mera generell klass, kanske kallad Entity eller något lämpligt, så skulle jag få  ytterligare enhetstester som gör samma sak .

En tredje gång.

Aj.

Så med denna vånda har jag vankat fram och tillbaka i tankevärlden idag.

Du som är lite tekniskt insatt förstår – kanske programmerat några rader själv nångång – att dessa ting inte är tekniskt/matematiskt avancerade. De är snarare psykologiskt påfrestande.

Jag kan ge ett annat exempel på hur mycket psykologi påverkar programmerare. Åtminstone denna programmerare.

Jag kodar spelet i Python – men till vardags jobbar jag i .NET med programspråket C#. Där skrivs klasser så här ”DettaÄrEnKlass”, och metoder likadant: ”DettaÄrEnMetod”. Så naturligt nog använde jag samma konvention i detta projekt av gammal vana.

Igår hittade jag till ett slags Python-konventions-dokument. Metoder skrivs av tradition ”detta_är_en_metod” i Python. Klasser skrivs med samma konvention som i .NET.

Så? Vad betyder detta då? Ja inte ett smack rent tekniskt. Spelet kommer att funka precis lika bra eller dåligt oavsett hur namnen skrivs i källkodsfilerna. Men det är ett sådant där litet dammkorn i ögat varje gång jag nu ser metoder och metodanrop som är skrivna på ”fel” form. Rent psykologiskt.

Jaja. Nu ska jag fortsätta våndas över att jag kommer att ha tre-gånger-upprepade enhetstester i mitt projekt, tills dess jag kommer på en elegant lösning. Hjälpa mig?

Taggar: , ,


Lekt lite mera med Launchpad

30 juli 2009

Mitt minispel ”Fortress Defender” är nu uppladdat som Open-Source-projekt på Ubuntu/Canonicals OSS-host Launchpad.net. För att plocka hem det, om du har ‘bzr’ installerat, ska det räcka med att skriva:

bzr branch lp:fortressdefender

Jag har lekt lite med Launchpads Blueprint-system, som kan sägas vara ett slags upphottad TODO-lista. Det funkade riktigt bra tycker jag:

Blueprints

Listan med blueprints för Fortress Defender

Dessutom har jag så smått börjat lära mig hur Bazaar fungerar. Den stora skillnaden mot Subversion t.ex. är att varje branch är ”sin egen” – den har egen historik etc. och är så att säga ”lika mycket värd” som trunk-branchen. Men allt har jag inte förstått ännu.Det blir lite komplicerat eftersom det är så flexibelt – det stödjer t.ex. även ”centraliserad” versionshantering, via checkouts som CVS och Subversion.

Taggar: , , ,