So long Digipolis

As the year is nearing it’s end, so is my time with Digipolis.

I had an amazing time here and made friends for life. It sounds like something everyone would say, but I actually can. Working for a city is different. It has it’s very specific set of problems and challenges, but in the end you’re trying to make a better city. Believe it or not, most of the people I worked with actually had this in mind. It should be included in the oath you take (something, I think, every employee related to the city should swear by).

It started out with joining a group of people who were looking to change everything web-related. Small projects like a website for city translators but also bigger challenges like Kotweb and the new A-Kaart platform. After a couple of years, the big one came, no doubt one of the defining projects in my career.
One would think that would’ve been my Mount Everest at this firm, but afterwards I had the honour (and pleasure) to assist Tom in building the UX competence within Digipolis and Jasper with the birth of a front-end framework, Tink.

As Homer said (and Arto on Facebook a couple of months ago when he jumped): the terrifying lows, the dizzying highs, the creamy middles, … we had it all. I’ll miss you guys but I’ll be keeping a close eye on everything happening in “my” city.

Recode

Back in the day, and man, do we have to go back for that one, I used to do a bit of coding. I learned some java and covered all the basics. This was during the years of a web startup we had in the ’90s.

After that I switched to Business Intelligence which was all about databases. Sure, some coding still happened, but I’d rather call it hacking a bit here and there. Now, however, I wondered if I could get back in the game. Just for fun. The A-Stad project gave me a good view on what’s currently happening on the web. I decided to start out with Team Treehouse and focus on some front-end. Great fun, and I learned a lot, but I grew tired of the childish tone of voice they use. I think I’ll return there someday, but for now I wanted a more decent view on back-end and programming in general.

So why not go back to basics? I quickly stumbled upon Harvard’s CS50 which is a general introduction to the world of computer science. A lot of steps back, you might think but, boy, is it fun. It makes me wonder whether Belgian University is boring as hell or whether I just grew up and am more interested now in actually learning stuff. The course is free to everyone in the world to follow (except for people living in Crimea apparently) and they will review and grade all your submissions. If you want a certificate of completion it’ll set you back $90.

Nodeschool

While doing that I decided to check out the technologies we’re using at the company I work at, more specifically NodeJS. Why? Well there’s a whole javascipt world growing. I dived into the nodeschool. Their excercises are entirely command line which might seem daunting at first. It throws you into the water and teaches you that way one of the most important things: learn to find answers online.

But once you start digging it takes you to a lot of places. Heroku for hosting, Github for soure control and some common extra’s of node like ExpressJS and Jade. It’s a lot to digest but it’s actually quite fun and it’s rewarding in a way that you see results quite fast.

One more thing: it’s a mac world. I switched to Mac a year ago and I think it helps quite a lot since you’ll find most things just work as documented online when you’re using OSX.

What’s next? Finish CS50 and continue my research while putting everything I learn to use while developing a sort of planningtool I can use for the team at work. Good thing is that there’s a whole floor of node devs at Digipolis where I can ask questions when I get stuck during my after-hours sessions. And I’ll eventually start exploring AngularJS. And once we get all that done (let’s meet in another year or so) I might dive into some more cutting edge stuff like Polymer.

A-Stad

A-StadEen dik half jaar geleden werd besloten dat digitaal de norm is voor Stad Antwerpen. De websites antwerpen.be en dna.be moeten elkaar terug vinden en in plaats van een nieuwe website kozen we voor een radicaal nieuw iets. De gebruiker centraal stellen, relevantie brengen, converseren, de stad openbreken en ontsluiten in alle transparantie.

Meer dan een half jaar zwoegen we met een team al aan deze droom. Gisteren hebben we de pers eens laten proeven van waar we naar toe gaan. Indrukken kan je terugvinden op, onder andere, GVA en ATV.

Het geeft kriebels, nu ze er over beginnen te praten. Vooral omdat het een project is waar ik in geloof, waar enorm straffe mensen aan werken en waarin we de vrijheid hebben gekregen het op een manier te doen die niet zo traditioneel is.

Tussen februari  en mei zullen velen de kans krijgen er mee te spelen en ons te vertellen wat ze er van vinden en waar het beter kan.

Ik kan niet wachten.

Open Data

AppsForAntwerpDe Stad Antwerpen zal binnenkort haar eerste stapjes zetten in de wereld van Open Data. Een aantal bronnen zullen volgende maand worden opengesteld voor iedereen die er mee wil werken. Het is de eerste stap naar een andere manier van denken. Iets dat invloed zal helpen op de gehele werking: alle data per definitie open. Motiveren waarom iets niet publiek mag, zal de norm worden. Het begin van de zoektocht naar alle schatten aan informatie die een Stad heeft en het streven naar het openbreken van de sloten die er op zitten. Het begin van een werk van jaren, eentje zonder eind.

Om dat te vieren is er AppsForAntwerp, waar we iedereen uitnodigen om aan de slag te gaan met het platform dat we openen en de data die er op staat. De details van het programma volgen nog. Noteer dus alvast 8 december in je agenda, grab a ticket en zeg het voort.

Persoonlijk is dit ‘ a big deal’. Ik geloof sterk in het verhaal en het feit dat ik er rechtstreeks bij betrokken ben betekent wat voor me. Call me a hopeless romantic, maar ik ben bij Digipolis gaan werken met een duidelijk voornemen: de Stad waar ik woon, waar ik werk en zo veel van hou een nog betere plek te maken. Werken aan een toekomst die een rechtstreeks effect op me heeft. Dit project, samen met vele anderen waar ik aan mag meewerken geven een gevoel van voldoening die ik iedereen toewens in hun job.

Nu we toch persoonlijk bezig zijn: ik wil terug meer schrijven. Of dat lukt weet ik niet, maar zonder proberen zal het er nooit van komen. Op dat vlak kwam de oproep van Steph gisteren op een goed moment. En daarnaast is het ook bijna NaNoWriMo, iets dat ik dit jaar wel eens écht wil meedoen (beste vrienden en familie: u weze bij deze gewaarschuwd).

Let’s jump in and see what happens.

Autovrij

Sinds een kleine twee weken leef ik autovrij. Ik leverde mijn wagen in bij mijn vorige werkgever en startte zonder bij mijn nieuwe. Vanaf nu verplaats ik me met de fiets en als het niet anders kan (lees: het regent) met de bus.

Het kunnen de wittebroodsweken zijn maar ik vind het geweldig. Ik fiets vrolijk fluitend door ‘t Stad en probeer de voetgangers die nog half slapen zo goed mogelijk te ontwijken. Het lukt me aardig, ik heb mijn bel leren gebruiken. Niet dat die iets uithaalt bij de tieners met hun oortjes in, maar je leert deze detecteren en anticiperen.
De afstand van mij thuis naar het werk is 6km. Dat is zoals vroeger, toen ik met de fiets naar school reed. Met dat verschil dat je vroeger in groep reed. Ik vertrok thuis en pikte iedereen op. Soms at ik zelfs nog een hapje mee bij een van m’n vrienden omdat ze zich overslapen hadden of omdat ik wat vroeger was omdat ze nu eenmaal een enorm knappe, doch iets oudere zus hadden. Doorheen mijn middelbare schooljaren fietste ik steeds met die groep die elk jaar iets groter leek te worden 12 km. Nu ik daar aan terug denk lijkt het raar dat van de ene dag op de andere die groep voor mij verdween. Ah, nostalgie.

Het werk is super. Ik werk nu voor de stad waarin ik woon en bouw dus mee aan die A waar ik van hou, met een leuke groep collega’s. Ik heb genoten van mijn dagen in Brussel en Gent en heb deze steden leren kennen en appreciëren. Maar dit, dit is thuiskomen.

Het is niet helemaal waar, natuurlijk, ik rij nog met de wagen. Evelyne heeft er nog eentje en die is nodig om Alexander naar mijn ouders te brengen op vrijdag, om inkopen te gaan doen en op uitstap te gaan. Stuff like that. Ik geloof niet dat ik volledig autovrij kan leven, jammer genoeg. Maar ik kan enkel mijn best doen. En sinds twee weken staat er toch eentje minder in de file.

IT

Er is nog werk voor ons IT-ers, nog veel werk. Klein voorbeeldje van hoe ik als consultant mijn uren moet registreren:

  • Voor mijn eigen werkgever is er een online applicatie waarin ik noteer op welk project ik wanneer gewerkt heb.
  • Voor mijn huidige klant heb ik een badge. Ik moet badgen bij het binnenkomen en het buitengaan en ook onder de middag. Als de pauze tijdens de middag kleiner is dan een half uur wordt er toch een half uur aangerekend. Indien ik niet tijdens de middag badge, dan rekenen ze anderhalf uur pauze aan. Neem ik minder dan een half uur pauze dan wordt dit naar een half uur gebracht. Met nog deze uitzondering: als ik een pauze kleiner dan 10 minuten neem dan zitten we terug met anderhalf uur (wat een bug blijkt te zijn).
    Ik kan eventuele badgesessies die ik vergeten ben (of als ik op een andere locatie zat) nog ingeven via een online applicatie.
  • Natuurlijk weet de klant nog niet wat ik nu juist gedaan heb. Daarom is er ook een soort online MS Project waar mijn projectmanager mij taken geeft waarop ik dan uren kan boeken. En daar begint de echte Kafka.
  • Als ik alles daar netjes ingegeven heb moet ik een nachtje wachten tot de verwerking van deze gegevens. Daarna kan ik een rapport trekken dat ik moet laten handtekenen door de klant.
  • Met dit papier trek ik naar de administratie bij de klant die er een ‘code’ zal opschrijven.
  • Dit papier stuur ik dan naar mijn werkgever zodat deze dit bij het factuur kan steken dat ze gaan sturen naar de klant.

Ik ben er zeker van dat er nog straffer verhalen zijn. Het probleem is dat ik ergens nog ‘snap’ waarom al deze stappen nodig zijn. Het jammere is dat ik heel slecht ben in zo’n dingen en ik eigenlijk een grondige hekel heb aan controle.

Een zeer grondige hekel.

Schoolvakanties in SQL

Omdat mijn huidige klant met onderwijs te maken heeft, moest de kalender dimensie alle schoolvakanties bevatten. Deze berekenen kan aan de hand van, jawel, enkele regels die je kan terugvinden op de website van de Vlaamse Overheid.

Met de hulp van een paar berekeningen die het internet reeds voor mij deed (een stored procedure om Pasen te berekenen en eentje om een weekdag van een bepaalde week te kunnen vinden):

CREATE FUNCTION dbo.udf_nthWeekDay
(
  @n       INT,
  @weekDay CHAR(3),
  @year    INT,
  @month   INT
)
RETURNS DATETIME
AS
BEGIN
  DECLARE @date    DATETIME,
    @dow         INT,
    @offset      INT,
    @wd          INT;
   
  SELECT @wd = CASE @weekDay
      WHEN 'SUN' THEN 1
      WHEN 'MON' THEN 2
      WHEN 'TUE' THEN 3
      WHEN 'WED' THEN 4
      WHEN 'THU' THEN 5
      WHEN 'FRI' THEN 6
      WHEN 'SAT' THEN 7
    END,
    @date = CAST
    (
      CAST(@year AS VARCHAR(4)) +
      RIGHT
      (
        '0' + CAST
        (
          @month AS VARCHAR(2)
        ), 2
      ) +
      '01' AS DATETIME
    ),
    @dow = DATEPART(dw, @date),
    @offset = @wd - @dow,
    @date = DATEADD(day, @offset + (@n - CASE WHEN @offset >= 0 THEN 1 ELSE 0 END) * 7, @date);
  RETURN @date;
END;
GO


CREATE FUNCTION [dbo].[fn_EasterSundayByYear]
(@Year char(4))
RETURNS smalldatetime
AS
BEGIN

declare
@c int
, @n int
, @k int
, @i int
, @j int
, @l int
, @m int
, @d int
, @Easter datetime

set @c = (@Year / 100)
set @n = @Year - 19 * (@Year / 19)
set @k = (@c - 17) / 25
set @i = @c - @c / 4 - ( @c - @k) / 3 + 19 * @n + 15
set @i = @i - 30 * ( @i / 30 )
set @i = @i - (@i / 28) * (1 - (@i / 28) * (29 / (@i + 1)) * ((21 - @n) / 11))
set @j = @Year + @Year / 4 + @i + 2 - @c + @c / 4
set @j = @j - 7 * (@j / 7)
set @l = @i - @j
set @m = 3 + (@l + 40) / 44
set @d = @l + 28 - 31 * ( @m / 4 )

set @Easter = (select right('0' + convert(varchar(2),@m),2) + '/' 
    + right('0' + convert(varchar(2),@d),2) + '/' + convert(char(4),@Year))

return @Easter
END 


CREATE TABLE [dbo].[DimKalender](
    [KalenderId] [int] NOT NULL,
    [KalenderDatum] [datetime] NOT NULL,
    [KalenderDag] [int] NOT NULL,
    [KalenderMaandNaam] [varchar](20) NOT NULL,
    [KalenderMaand] [int] NOT NULL,
    [KalenderTrimester] [int] NOT NULL,
    [KalenderSemester] [int] NOT NULL,
    [KalenderJaar] [int] NOT NULL,
    [KalenderSchooljaar] [varchar](9) NOT NULL,
    [KalenderVakantieNaam] [varchar] (10) NOT NULL,
 CONSTRAINT [DimKalender_PK_IT] PRIMARY KEY CLUSTERED 
(
    [KalenderId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF
    , ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

… heb ik om de tabel te vullen, en dus effectief de schoolvakanties te berekenen dit in elkaar gestoken:

SET DATEFIRST 1

DECLARE @startdate                DATETIME
DECLARE @enddate                DATETIME
DECLARE @year                    INT
DECLARE @yearasstring            VARCHAR(4)
DECLARE @month                    INT
DECLARE @prevyearasstring        VARCHAR(4)
DECLARE @nextyearasstring        VARCHAR(4)
DECLARE @easter                    DATETIME
DECLARE @day                    INT
DECLARE @twoweeksaftereaster    DATETIME
DECLARE @firstaprilmonday        DATETIME
DECLARE @xmas                    DATETIME
DECLARE @xmasprevyear            DATETIME
DECLARE @xmasdow                INT
DECLARE @xmasdowprevyear        INT
DECLARE @eastermonday            DATETIME
DECLARE @eastermonth            INT
DECLARE @weekday                INT

SET @startdate = CONVERT(DATETIME,'01-01-1990') 
SET @enddate = CONVERT(DATETIME,'01-01-2100')

WHILE @startdate < @enddate

BEGIN

SET @year = DATEPART(yy,@startdate)
SET @yearasstring = CAST(@year AS VARCHAR(4))
SET @month = DATEPART(MM,@startdate)
SET @prevyearasstring = CAST((@year-1) AS VARCHAR(4))
SET @nextyearasstring = CAST((@year+1) AS VARCHAR(4))
SET @easter = [dbo].fn_EasterSundayByYear(@yearasstring)
SET @day = DATEPART(dd,@startdate)
SET @twoweeksaftereaster = DATEADD(DD,14,@easter)
SET @firstaprilmonday = dbo.udf_nthWeekDay(1,'MON',@year,4)
SET @xmas = ('12-25-')+ @yearasstring
SET @xmasprevyear = ('12-25-')+ @prevyearasstring
SET @xmasdow = DATEPART(DW,@xmas)
SET @xmasdowprevyear = DATEPART(DW,('12-25-')+ @prevyearasstring)
SET @eastermonday = DATEADD(DD,1,@easter)
SET @eastermonth = DATEPART(MM,(@easter))
SET @weekday = DATEPART(DW,@startDate)

INSERT INTO [dbo].[DimKalender]
           ([KalenderId]
           ,[KalenderDatum]
           ,[KalenderDag]
           ,[KalenderMaand]
           ,[KalenderMaandNaam]
           ,[KalenderTrimester]
           ,[KalenderJaar]
           ,[KalenderSchoolJaar]
           ,[KalenderVakantieNaam]
           )
           
           
VALUES  (
/*[KalenderId]*/                @year*10000 + @month*100 + @day,
/*[KalenderDatum]*/                @startdate,
/*[KalenderDag]*/                @day,
/*[KalenderMaand]*/                @month,    
/*[KalenderMaandNaam]*/            CASE @month
                                    WHEN 1 THEN 'Januari'
                                    WHEN 2 THEN 'Februari'
                                    WHEN 3 THEN 'Maart'
                                    WHEN 4 THEN 'April'
                                    WHEN 5 THEN 'Mei'
                                    WHEN 6 THEN 'Juni'
                                    WHEN 7 THEN 'Juli'
                                    WHEN 8 THEN 'Augustus'
                                    WHEN 9 THEN 'September'
                                    WHEN 10 THEN 'Oktober'
                                    WHEN 11 THEN 'November'
                                    WHEN 12 THEN 'December'
                                END,
/*[KalenderTrimester]*/            DATEPART(qq, @startdate),                                
/*[KalenderJaar]*/                @year,
/*[KalenderSchooljaar]*/        CASE WHEN @month <= 8 
                                    THEN @prevyearasstring + '-' + @yearasstring
                                    ELSE @yearasstring + '-' + @nextyearasstring
                                END,
/*[KalenderVakantieNaam]*/        CASE 
                                    WHEN @month = 7 THEN 'Zomer'
                                    WHEN @month = 8 THEN 'Zomer'
                                    WHEN DATEPART(dw,('11-01-' + @yearasstring)) = 7 
                                        AND (@startDate between ('11-02-'+ @yearasstring) 
                                        and ('11-08-'+ @yearasstring)) THEN 'Herfst'
                                    WHEN DATEPART(dw,('11-01-' + @yearasstring)) != 7 
                                        AND DATEPART(WW,@startdate) = DATEPART(WW,('11-01-'+@yearasstring)) 
                                        THEN 'Herfst'
                                    WHEN @month = 12 AND @xmasdow = 6 AND @startdate between ('12-27-' + @yearasstring) 
                                        and ('01-09-' + @nextyearasstring) THEN 'Kerst'
                                    WHEN @month = 12 AND @xmasdow = 7 AND @startdate between ('12-26-' + @yearasstring) 
                                        and ('01-08-' + @nextyearasstring) THEN 'Kerst'
                                    WHEN @month = 12 AND @xmasdow < 6 AND @startdate 
                                        between (DATEADD (dd,(-(@weekday - 1)),(@xmas))) 
                                        and (DATEADD (dd,(- @weekday + 14),(@xmas))) THEN 'Kerst'
                                    WHEN @month = 1 AND @xmasdowprevyear = 6 AND @startdate <= ('01-09-' + @yearasstring) 
                                        THEN 'Kerst'
                                    WHEN @month = 1 AND @xmasdowprevyear = 7 AND @startdate <= ('01-08-' + @yearasstring) 
                                        THEN 'Kerst'
                                    WHEN @month = 1 AND @xmasdowprevyear < 6 AND @startdate    
                                        between (DATEADD (dd,(-(@weekday - 1)),(@xmasprevyear))) 
                                        and (DATEADD (dd,(- @weekday + 14),(@xmasprevyear))) THEN 'Kerst'                                    
                                    WHEN @startdate = '11-11-' + @yearasstring THEN '11 November'
                                    WHEN @startdate = '05-01-' + @yearasstring THEN '1 Mei'
                                    WHEN @eastermonth = 3 AND @startdate between @eastermonday AND @twoweeksaftereaster 
                                        THEN 'Pasen'
                                    WHEN @easter > ('04-15-' + @yearasstring) AND @startdate 
                                        between (DATEADD(DD,-13,@easter)) AND @eastermonday THEN 'Pasen'
                                    WHEN @eastermonth != 3 AND @easter <= ('04-15-' + @yearasstring) 
                                        AND @startdate between @firstaprilmonday AND DATEADD(DD,13,@firstaprilmonday) 
                                            THEN 'Pasen'
                                    WHEN @startdate = DATEADD(DD,49,@twoweeksaftereaster) THEN 'PinksterMaandag'
                                    WHEN @startdate between DATEADD(DD,-48,@easter) AND DATEADD(DD,-42,@easter) 
                                        THEN 'Krokus'
                                    WHEN @startdate between DATEADD(DD,39,@easter) AND DATEADD(DD,40,@easter) 
                                        THEN 'Hemelvaart'
                                    ELSE 'Geen'
                                END                    
)

SET @startdate = DATEADD(dd,1,@startdate)

END

Enjoy ;)