lunedì 25 gennaio 2010

Kata karate chop

Rimandando ad un altro post la discussione sul primo kata, comincio oggi a postare i risultati ottenuti effettuando il secondo. La specifica del problema è molto semplice (l'implementazione di binary search su un array di interi); la sostanza del kata, no. L'esercizio richiede in fatti di implementare la specifica in cinque modi differenti e, se da una parte è molto facile pensare agli approcci tradizionali (iterativo, ricorsivo, funzionale...), trovare nuove strategie risolutive non è affatto banale.
Oggi volevo presentare l'implementazione iterativa a cui sono arrivato (probabilmente niente di speciale ma, in puro stile kata, l'importante non è il risultato, ma la strada percorsa per giungervi... e vi assicuro che anche su una cosa così apparentemente banale, tale strada è stata costellata di tentativi ed errori).
Una premessa: tanto per semplificarmi la vita, ho deciso di affrontare questi kata utilizzando un linguaggio di programmazione che non conoscevo se non di nome: Ruby. Pertanto, a tutti i rubisti (con rispetto parlando) lì fuori: se doveste vedere qualcosa che non vi piace, non giratevi stizziti dall'altra parte; ogni consiglio è bene accetto ;-)
Ok, partiamo con il codice


def chop(i, a)
if a.size > 0
l_index = 0
r_index = a.size - 1

while r_index - l_index > 1
middle = ((r_index - l_index) / 2) + l_index
if a[middle] >= i
r_index = middle
else
l_index = middle
end
end

if a[l_index] == i
return l_index
elsif a[r_index] == i
return r_index
end

end
-1
end

L'implementazione è molto standard, con due indici per tenere traccia dell'inizio e della fine del sotto-array dell'iterazione corrente. Ed è proprio la gestione degli indici a farla da padrona fra le varie considerazioni che mi sono venute in mente effettuando questo kata.
  • Il caso di dimensione 0 è triviale
  • La divisione intera mi ritorna il valore middle approssimato per eccesso o per difetto? (come ho poi verificato, viene approssimato per eccesso, rendendo la dimensione 2 dell'array un caso particolare, alla stregua di dimensione 1 e 0. Infatti, con un array di due elementi, l'elemento middle diventa il secondo elemento - r_index -, e l'iterazione non va avanti)
  • La condizione di terminazione del ciclo nasce proprio dalle considerazione al punto precedente: il ciclo deve terminare quando l'array contiene 0, 1 o 2 elementi
  • Anche il blocco di controllo alle righe 15-19 nasce dalla considerazioni ai punti 1 e 2. Inizialmente pensavo che si potesse fare in modo che l'iterazione terminasse sempre puntando ad un singolo elemento dell'array e che dunque fosse necessario un solo controllo. Terminando sempre con due elementi (eventualmente coincidenti) i controlli da effettuare sono due: uno su a[l_index] e l'altro su a[r_index]. (nota: è possibile riprogettare l'algoritmo per farlo terminare sempre su un solo elemento?)
  • L'uso dell'offset l_index alla riga 7 per puntare correttamente all'inizio del sotto-array non mi è venuto in mente subito...
Come si può vedere, anche un semplice esercizio come questo, nella sua incarnazione più semplice, ha portato a diverse considerazioni. Altra parte dell'esercizio sarà vedere se le considerazioni fatte adesso saranno d'aiuto nelle prossime implementazioni. Vedremo.
Per ora posso dire che i kata stanno facendo il loro dovere.

venerdì 22 gennaio 2010

Code Kata

Dopo averne sentito parlare in diverse occasioni, ho deciso che volevo saperne un po' di più su CodeKata.
CodeKata è un termine coniato da Dave Thomas, co-autore di The Pragmatic Programmer, prendendo spunto dal concetto giapponese di kata nelle arti marziali. Per farla breve, quello che Dave Thomas propone è l'introduzione di sessioni ripetute di pratica di programmazione volte a migliorare il proprio stile e la propria "esecuzione", così come farebbe un'atleta, un praticante di arti marziali (tramite la continua ripetizione dei kata) o un musicista.
In pratica, si dovrebbe individuare un particolare problema (di programmazione, ma anche di analisi o design) e cominciare a rifletterci sopra tentando più soluzioni e più approcci senza il timore di sbagliare. E' proprio la possibilità di sbagliare che dovrebbe portare alla riflessione sulle proprie competenze e sulle proprie capacità e aiutare a trovare nuove e migliori strade per la risoluzione dei problemi. Ed è anche il motivo per cui queste sessioni di pratica devono essere tenute in una sorta di "sandbox" isolato da qualsiasi ambiente di produzione (a nessun responsabile di progetto piace che si facciano esperimenti sulle cose per cui lui rischia la faccia... per non citare altre parti anatomiche ;-) ).
CodeKata mi è sembrato molto interessante, soprattutto dal momento che normalmente, lavorando come programmatore o studiando informatica, si è portati a pensare di aver assimilato tutta una serie di competenze e capacità derivanti dalla normale attività lavorativa o dallo studio, salvo poi fare la figura del pivello davanti a problemi un po' diversi dal solito o sui quali non abbiamo mai avuto voglia di soffermarci.
Sul suo sito, Dave Thomas propone una serie di kata di vario tipo da svolgere. In questi giorni ho intenzione di cimentarmi e di riportare su questo blog i risultati dei mie sforzi :-)