<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Gabriele Lana</title>
	<atom:link href="http://www.gabrielelana.it/feed" rel="self" type="application/rss+xml" />
	<link>http://www.gabrielelana.it</link>
	<description>on Agile Methodologies and Programming</description>
	<lastBuildDate>Fri, 07 May 2010 14:12:28 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>&#8220;Ma quanto vuoi guadagnare?&#8221;</title>
		<link>http://www.gabrielelana.it/archives/167</link>
		<comments>http://www.gabrielelana.it/archives/167#comments</comments>
		<pubDate>Fri, 07 May 2010 07:47:29 +0000</pubDate>
		<dc:creator>Gabriele Lana</dc:creator>
				<category><![CDATA[agile]]></category>
		<category><![CDATA[human]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://www.gabrielelana.it/?p=167</guid>
		<description><![CDATA[Un bel giorno un uomo si presenta da un costruttore mostrandogli il disegno di una casa e gli chiede

Vorrei costruire una casa fatta esattamente in questo modo. Quanto ci metti a costruirmela? Quanto mi costerebbe?

Il costruttore stoicamente risponde

Tre mesi e 100.000 euro

L&#8217;uomo, guarda il costruttore con uno sguardo diretto&#8230; semplice&#8230; come se stesse parlando delle [...]]]></description>
			<content:encoded><![CDATA[<p>Un bel giorno un uomo si presenta da un costruttore mostrandogli il disegno di una casa e gli chiede</p>
<blockquote><p>
Vorrei costruire una casa fatta <strong>esattamente</strong> in questo modo. Quanto ci metti a costruirmela? Quanto mi costerebbe?
</p></blockquote>
<p>Il costruttore stoicamente risponde</p>
<blockquote><p>
Tre mesi e 100.000 euro
</p></blockquote>
<p>L&#8217;uomo, guarda il costruttore con uno sguardo diretto&#8230; semplice&#8230; come se stesse parlando delle condizioni metereologiche</p>
<blockquote><p>
Ti do una settimana e 5.000 euro
</p></blockquote>
<p>Il costruttore rimane sbigottito&#8230; non sa se lo stanno prendendo per il culo o se fanno sul serio: se lo stanno prendendo per il culo è il momento d&#8217;incazzarsi, se fanno sul serio è il momento di mettersi a piangere; decide in buona fede di cercare di capire meglio</p>
<blockquote><p>
Scusami, ammesso e non concesso che umanamente sia possibile farlo in una settimana, significherebbe utilizzare molte più risorse di quelle spese per farcela in tre mesi&#8230; quindi al limite ti costerà di più di 100.000 euro, perchè dovrebbero bastarne 5.000???
</p></blockquote>
<p>L&#8217;uomo, sempre con la stessa faccia risponde</p>
<blockquote><p>
Accidenti, ma quanto vorresti guadagnare in una settimana?!?!?!
</p></blockquote>
<p>&#8230; Ve lo dico io, non c&#8217;è dubbio, ci stanno prendendo per il culo</p>
<p>A questo proposito faccio un appello a chiunque può essere interessato, secondo me c&#8217;è (e crescerà sempre di più) un <a href="http://en.wikipedia.org/wiki/Blue_Ocean_Strategy">oceano blu</a>, ovvero un mercato di opportunità non ancora esplorato, che è quello del &#8220;Procuratore per sviluppatori&#8221;</p>
<p>Il procuratore dovrebbe trovare il cliente (anche se non è necessario, potrebbe trovarlo direttamente lo sviluppatore) e trattare gli aspetti economici e burocratici del progetto per conto dello sviluppatore, in cambio il procuratore si becca il 20% del fatturato, gli aspetti tecnici vengono gestiti direttamente dallo sviluppatore, esattamente come succede per i calciatori/sportivi (anche se ammetto di non saperne molto ;-P)</p>
<p>Ci sono molti dettagli che devono essere definiti, ma potrebbe funzionare, da gennaio/febbraio sto lavorando in questo modo e sono abbastanza soddisfatto, se qualcuno è interessato, mi contatti direttamente :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabrielelana.it/archives/167/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Una metrica per i professionisti</title>
		<link>http://www.gabrielelana.it/archives/160</link>
		<comments>http://www.gabrielelana.it/archives/160#comments</comments>
		<pubDate>Mon, 08 Mar 2010 10:38:43 +0000</pubDate>
		<dc:creator>Gabriele Lana</dc:creator>
				<category><![CDATA[agile]]></category>
		<category><![CDATA[communication]]></category>
		<category><![CDATA[human]]></category>

		<guid isPermaLink="false">http://www.gabrielelana.it/?p=160</guid>
		<description><![CDATA[Parto da un assunto fondamentale

Il desiderio di controllo nasce dalla paura di non averlo

Da cui una metrica molto semplice da misurare per colui che si definisce professionista

Tutte le volte che un cliente ti chiede a che punto sei in merito ad un lavoro che stai facendo per lui, hai perso 10 punti. Se non rispondi [...]]]></description>
			<content:encoded><![CDATA[<p>Parto da un assunto fondamentale</p>
<blockquote><p>
<em>Il desiderio di controllo nasce dalla paura di non averlo</em>
</p></blockquote>
<p>Da cui una metrica molto semplice da misurare per colui che si definisce professionista</p>
<blockquote><p>
<em>Tutte le volte che un cliente ti chiede a che punto sei in merito ad un lavoro che stai facendo per lui, hai perso 10 punti. Se non rispondi in tempo reale, hai perso 1000 punti</em>
</p></blockquote>
<p>Inutile dire che perdere punti è molto più semplice che guadagnarli&#8230; Quello che penso è che il &#8220;command &#038; control&#8221; non lo voglia spontaneamente nessuno, neanche il cliente, ci si arriva quando costretti, sopratutto per la mentalità italiana dove il 90% della popolazione vorrebbe fare <em>&#8220;l&#8217;intermediario&#8221;</em> nullafacente</p>
<p>Analizziamo il processo mentale del cliente</p>
<ul>
<li><em>Gli ho chiesto di fare questa &#8220;piccola&#8221; cosa due giorni fa e non ho più saputo niente, cosa starà facendo? Starà lavorando? E&#8217; una cosa importante, deve essere pronta per questa sera&#8230; Forse è meglio lasciarlo lavorare, fra poco si farà sentire&#8230;</em></li>
<li><em>Sono le 16:00 e non si è ancora sentito nessuno&#8230; eh no, adesso basta, gli faccio il culo, non è possibile, aveva detto che avrebbe consegnato prima di sera e sono due giorni che non si fa sentire, gli mando una e-mail</em></li>
<li><em>Non risponde <strong>neanche</strong> alle e-mail!!! Lo sapevo, non ha fatto niente!!! Per questa sera non sarà pronto niente e sarò nella merda!!! La prossima volta non ci casco più!!!</em></li>
</ul>
<p>Ora, poco importa se il nostro <em>&#8220;professionista&#8221;</em> era in meditazione per riuscire a finire in tempo, poco importa se effettivamente la consegna è avvenuta in tempo, l&#8217;ansia e il dubbio sono comunque entrati nella mente del cliente che vorrà avere sempre più <em>&#8220;controllo&#8221;</em>, anche se la sua forma di <em>&#8220;controllo&#8221;</em> sarà letale per il progetto :-)</p>
<p><strong>Ogni</strong> volta che un vostro cliente vi chiede informazioni su qualcosa, lo fa perchè si sente <strong>obbligato</strong> a farlo, se potesse eviterebbe, confrontatevi <strong>immediatamente</strong> con lui per capire come fornigli in anticipo le risposte ai suoi dubbi, siate <strong>veri professionisti</strong>, non ve ne pentirete</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabrielelana.it/archives/160/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Agilecamp2010 e Code Katas</title>
		<link>http://www.gabrielelana.it/archives/150</link>
		<comments>http://www.gabrielelana.it/archives/150#comments</comments>
		<pubDate>Mon, 01 Mar 2010 12:23:00 +0000</pubDate>
		<dc:creator>Gabriele Lana</dc:creator>
				<category><![CDATA[agile]]></category>
		<category><![CDATA[kata]]></category>
		<category><![CDATA[milano-codingdojo]]></category>
		<category><![CDATA[milano-xpug]]></category>

		<guid isPermaLink="false">http://www.gabrielelana.it/?p=150</guid>
		<description><![CDATA[Non dirò che è un bel po&#8217; di tempo che non scrivo e non dirò che nel frattempo sono successe troppe cose, dirò solo che sabato scorso sono stato in quel di Lugano al AgileCamp ospitato da Sketchin è stata veramente una bella giornata, a formare la &#8220;spedizione del milano-xpug&#8221; con me c&#8217;erano Giordano, Indrit [...]]]></description>
			<content:encoded><![CDATA[<p>Non dirò che è un bel po&#8217; di tempo che non scrivo e non dirò che nel frattempo sono successe troppe cose, dirò solo che sabato scorso sono stato in quel di Lugano al <a href="http://barcamp.org/AgileCamp">AgileCamp</a> ospitato da <a href="http://www.sketchin.ch/">Sketchin</a> è stata veramente una bella giornata, a formare la &#8220;spedizione del milano-xpug&#8221; con me c&#8217;erano <a href="http://giordano.scalzo.biz/">Giordano</a>, Indrit (Selimi) e Andrea (Francia)</p>
<p>L&#8217;atmosfera e il clima sono stati perfetti per un barcamp: bel posto (tra l&#8217;altro ero in poltrona in prima fila, l&#8217;unica cosa difficile è stata mantenere la lucidità dopo pranzo), bella gente, <a href="http://www.lucamascaro.info/blog">Luca</a> è stato un ottimo padrone di casa e sopratutto le competenze dei presenti erano molto eterogenee (programmatori, designer e product manager/owner)</p>
<p>Personalmente mi sono giocato la presentazione sui kata della programmazione</p>
<p><object width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=programmingkatas-100301054644-phpapp02&#038;stripped_title=programmingkatas" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=programmingkatas-100301054644-phpapp02&#038;stripped_title=programmingkatas" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></p>
<p>La stessa che ho portato al javaday</p>
<p><object width="480" height="390"><param name="movie" value="http://www.uniroma.tv/uniroma_network_player.swf?p=&#038;v=20100206201244_561025187.flv&#038;autoplay=false&#038;ext=true"></param><param name="allowFullScreen" value="true"></param><param name="base" value="http://www.uniroma.tv/"></param><embed src="http://www.uniroma.tv/uniroma_network_player.swf?p=&#038;v=20100206201244_561025187.flv&#038;autoplay=false&#038;ext=true" type="application/x-shockwave-flash" allowfullscreen="true" base="http://www.uniroma.tv/" width="480" height="390"></embed></object></p>
<p>Se siete interessati al tema vi consiglio di iscrivervi alla ml del <a href="http://tech.groups.yahoo.com/group/milano-xpug/">milano-xpug</a> e/o a quella del <a href="http://groups.google.com/group/milano-codingdojo">milano-codingdojo</a>, stiamo organizzando alcune attività anche non strettamente legate all&#8217;area di Milano :-)</p>
<p>P.S. Alla fine del talk dico di aver seguito la scuola di Martin Fowler del Clean Code, imperdonabile errore, ovviamente stavo parlando di Robert C. Martin :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabrielelana.it/archives/150/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CouchDB Performance</title>
		<link>http://www.gabrielelana.it/archives/131</link>
		<comments>http://www.gabrielelana.it/archives/131#comments</comments>
		<pubDate>Sun, 11 Oct 2009 09:36:43 +0000</pubDate>
		<dc:creator>Gabriele Lana</dc:creator>
				<category><![CDATA[couchdb]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.gabrielelana.it/?p=131</guid>
		<description><![CDATA[Finalmente sono riuscito a provare CouchDB con una quantità di dati interessante e su una macchina interessante. L&#8217;obiettivo era quello di verificare se CouchDB poteva reggere un carico di milioni di documenti e se il tempo per il calcolo delle view è effettivamente incrementale e con complessità logaritmica.
Una brevissima introduzione: CouchDB è un database documentale, [...]]]></description>
			<content:encoded><![CDATA[<p>Finalmente sono riuscito a provare <a href="http://couchdb.apache.org/">CouchDB</a> con una quantità di dati interessante e su una macchina interessante. L&#8217;obiettivo era quello di verificare se CouchDB poteva reggere un carico di milioni di documenti e se il tempo per il calcolo delle view è effettivamente incrementale e con complessità logaritmica.</p>
<p>Una brevissima introduzione: CouchDB è un database documentale, ogni documento (il record di una tabella in un database relazionale) è insieme di coppie chiave/valore, non esiste uno schema dei dati, ogni documento può contenere qualsiasi insieme di coppie chiave/valore, ad ogni database possono essere associati una o più view (query in un database relazione), ogni view è composta da due funzioni javascript, una funzione <em>map</em> che consente di trasformare ogni documento contenuto nel database in un altro insieme di coppie chiave/valore e di associarle ad una chiave, e una funzione <em>reduce</em> (opzionale) che prende in pasto l&#8217;output della funzione map precedente raggruppata per chiave (una sorta di <em>group by</em> dei database relazionali) e che può essere utilizzata per computare valori aggregati</p>
<p>Un piccolissimo esempio che è molto vicino al test che ho fatto. Supponiamo di avere un database (ovvero un insieme di documenti) di questo tipo</p>
<blockquote><p>
[<br />
  {<br />
    "url": "http://salute.corriere.it/news/some-news.html",<br />
    "visits": 3<br />
  },<br />
  {<br />
    "url": "http://lavoro.corriere.it/index.html",<br />
    "visits": 10<br />
  }<br />
]
</p></blockquote>
<p>Ovvero associamo ad ogni url il numero di volte che è stata visitata. Noi vogliamo sapere il numero di visite per ogni <em>&#8220;sezione&#8221;</em> delle url presenti nel nostro database. Definiamo intuitivamente il significato di <em>&#8220;sezione&#8221;</em> dicendo che l&#8217;url <em>&#8220;http://salute.corriere.it/news/some-news.html&#8221;</em> appartiene a tre sezioni <em>&#8220;corriere.it&#8221;</em>, <em>&#8220;salute.corriere.it&#8221;</em> e <em>&#8220;salute.corriere.it/news&#8221;</em>. Supponiamo di avere a disposizione una funzione <em>&#8220;forEachSectionOf(url,doSomething)&#8221;</em> che prede in pasto una <em>url</em> e richiama la funzione <em>doSomething</em> per ogni sezione dell&#8217;url passandogli la sezione stessa come parametro. La nostra funzione map sarebbe una cosa del tipo</p>
<blockquote><p>
function(doc) {<br />
  forEachSectionOf(doc['url'], function(section) {<br />
    emit(section, doc['visits'])<br />
  });<br />
}
</p></blockquote>
<p>La funzione <em>emit</em> viene chiamata tutte le volte che vi vuole produrre un output, il primo parametro è la chiave del risultato e il secondo è il valore (sia la chiave che il valore possono essere strutture dati complesse, non devono essere per forza valori come in questo caso, ma questa è un&#8217;altra storia). L&#8217;output prodotto dalla <em>map</em> applicata al database di cui sopra sarà</p>
<blockquote><p>
[<br />
  { "corriere.it": 3 },<br />
  { "salute.corriere.it": 3 },<br />
  { "salute.corriere.it/news": 3 },<br />
  { "corriere.it": 10 },<br />
  { "lavoro.corriere.it": 10 }<br />
]
</p></blockquote>
<p>Abbiamo detto che l&#8217;imput alla <em>reduce</em> è l&#8217;output della <em>map</em> raggruppato per chiave, quindi</p>
<blockquote><p>
[<br />
  { "corriere.it": [ 3, 10 ] },<br />
  { &#8220;salute.corriere.it&#8221;: [ 3 ] },<br />
  { &#8220;salute.corriere.it/news&#8221;: [ 3 ] },<br />
  { &#8220;lavoro.corriere.it&#8221;: [ 10 ] }<br />
]
</p></blockquote>
<p>Ricordandoci che vogliamo calcolare il numero di visite per ogni sezione, la reduce è molto semplice</p>
<blockquote><p>
function(keys, values, rereduce) {<br />
  return sum(values)<br />
}
</p></blockquote>
<p>Che produce il risultato atteso</p>
<blockquote><p>
[<br />
  { "corriere.it": 13 },<br />
  { "salute.corriere.it": 3 },<br />
  { "salute.corriere.it/news": 3 },<br />
  { "lavoro.corriere.it": 10 }<br />
]
</p></blockquote>
<p>Il grosso vantaggio di CouchDB in termini di perfomance è che le view vengono calcolate in maniera incrementale, ovvero tutte le volte che interroghi una view CouchDB ricalcola solo i valori relativi ai documenti che sono cambiati o che sono stati aggiunti dall&#8217;ultima volta che la stessa view era stata calcolata (la cosa più vicina a questa nel mondo dei database relazionali sono le <a href="http://download.oracle.com/docs/cd/B10500_01/server.920/a96567/repmview.htm">materialized view</a> di Oracle). Inoltre il costo del calcolo dell&#8217;incremento dovrebbe aumentare in maniera logaritmica rispetto all&#8217;aumentare della dimensione del database.</p>
<p>Ho voluto toccare con mano e quindi ho fatto il seguente esperimento:</p>
<ul>
<li>Fetch di 10000 record da una tabella di mysql contenente 15 milioni di record</li>
<li>Store di ogni record come documento in CouchDB (i documenti non sono stati salvati singolarmente, ma in modalità batch che è molto più performante)</li>
<li>Query della view di CouchDB che equivale al ricalcolo della view stessa</li>
</ul>
<p>Ho misurato ognuna delle tre fasi e l&#8217;ho ripetuto fino a consumare tutti e 15 i milioni di record, di seguito i risultati</p>
<p><a href="http://www.gabrielelana.it/wp-content/uploads/2009/10/urls_per_domain.times.gif"><img src="http://www.gabrielelana.it/wp-content/uploads/2009/10/urls_per_domain.times-300x225.gif" alt="urls_per_domain.times" title="urls_per_domain.times" width="300" height="225" class="aligncenter"/></a></p>
<ul>
<li>Pro: la complessità del ricalcolo della view è effettivamente logaritmico</li>
<li>Pro: il costo d&#8217;inserimento dei documenti in CouchDB è costante (la struttura dati utilizzata è append-only, quindi c&#8217;era da aspettarselo, ma fa comunque piacere verificarlo)</li>
<li>Pro: una volta calcolata la view, i tempi di risposta sono stupefacenti, praticamente istantanei</li>
<li>Pro: il tempo totale d&#8217;inserimento di 15 milioni di documenti è stato di 26 minuti</li>
<li>Pro: l&#8217;occupazione di memoria durante tutto il processo non ha mai superato i 50MB</li>
<li>Contro: il tempo totale di calcolo della view è stato di circa 17 ore. Bisogna tener conto che le view vengono calcolate da funzioni javascript in un processo separato e che la comunicazione fra CouchDB e l&#8217;interprete javascript è stdin/stdout, quindi a parte la velocità dell&#8217;interprete javascript (di default spidermonkey) c&#8217;è anche un costo notevole di serializzazione/deserializzazione. Scommetto che scrivendo le map/reduce direttamente in Erlang questo numero cambierebbe sensibilmente
<li>Contro: lo spazio occupato dal database è di 21GB contro i 7.5GB di mysql (anche se ci metterei un bel chissene visto il costo degli storage)</li>
<li>Contro: lo spazio occupato dalla view è di 32GB (again chissene)</li>
<li>Contro: per ogni database CouchDB usa uno ed un solo processore, quindi anche se avete 16 processori come nel mio caso, non ve ne fate niente a meno di non avere database multipli. Il modello map/reduce implementato da CouchDB potrebbe tranquillamente consentire il partizionamento dei dati su più database, ma attualmente gli sviluppatori si stanno concentrando solamente sulla replicazione, se volete dovete implementare voi il meccanismo di reduce finale</li>
</ul>
<p>Conclusione: se vi trovate in una situazione per cui avete una grande quantità di dati e le query che fate non cambiano spesso, un database come CouchDB potrebbe essere un bel passo in avanti rispetto ad un database tradizionale</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabrielelana.it/archives/131/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Code Katas</title>
		<link>http://www.gabrielelana.it/archives/109</link>
		<comments>http://www.gabrielelana.it/archives/109#comments</comments>
		<pubDate>Sun, 04 Oct 2009 16:55:50 +0000</pubDate>
		<dc:creator>Gabriele Lana</dc:creator>
				<category><![CDATA[kata]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.gabrielelana.it/?p=109</guid>
		<description><![CDATA[ Avendo apprezzato Peter Seibel in &#8220;Founders at Work&#8221; ( consigliatissimo) in questi giorni sto leggendo con piacere il suo ultimo lavoro &#8220;Coders at Work&#8221;, stando all&#8217;ultimo suo post anche Joel Spolsky lo sta leggendo.
Joel ha elogiato Jamie Zawinski (uno dei programmatori intervistati da Seibel nel suo libro) per la sua capacità di scrivere velocemente [...]]]></description>
			<content:encoded><![CDATA[<p><img class="on_the_left" src="http://www.gabrielelana.it/wp-content/uploads/2009/10/21nk4xz-150x150.jpg" alt="Coders at Work" title="Coders at Work"/> Avendo apprezzato Peter Seibel in &#8220;Founders at Work&#8221; ( consigliatissimo) in questi giorni sto leggendo con piacere il suo ultimo lavoro &#8220;Coders at Work&#8221;, stando all&#8217;ultimo suo <a href="http://www.joelonsoftware.com/items/2009/09/23.html">post</a> anche Joel Spolsky lo sta leggendo.</p>
<p>Joel ha elogiato Jamie Zawinski (uno dei programmatori intervistati da Seibel nel suo libro) per la sua capacità di scrivere <strong>velocemente</strong> codice <strong>funzionante</strong> e <strong>fruibile</strong> da un utente finale. Joel ha chiamato questo tipo di programmatore &#8220;Duct Tape Programmer&#8221;, un&#8217;etichetta che ha suscitato un bel <a href="http://blog.objectmentor.com/articles/2009/09/24/the-duct-tape-programmer">polverone</a>.</p>
<p>Insomma si parla del solito tradeoff <a href="http://en.wikipedia.org/wiki/Project_triangle">&#8220;time, quality, money &#8211; pick two&#8221;</a>, che poi ufficialmente si traduce <strong>sempre</strong> in &#8220;scegliamo tempo e denaro, per la qualità speriamo di farla franca&#8221;.</p>
<p>Cosa centra tutto questo con i <a href="http://codekata.pragprog.com/">kata</a>? Quando qualcuno si lamenta del fatto che le tecniche che propongo non sono praticabili nella loro realtà perchè non c&#8217;è il tempo (la solita storia del &#8220;bello, ma da noi non si può fare&#8221;), mi ricordo quando anch&#8217;io mi lamentavo della stessa cosa, vedevo la carenza di tempo come la prima ragione di tutti i miei fallimenti, poi però ho iniziato a chiedermi: &#8220;se fino ad oggi non ho <strong>mai</strong> avuto tempo per fare le cose <strong>bene</strong>, come faccio ad essere sicuro di saperle fare? Come faccio ad essere sicuro di riuscire a scrivere codice <strong>pulito</strong> se non ho mai avuto il tempo di scriverlo?&#8221;&#8230; Interessante quesito che ci porta ai kata e alla nozione generale di esercizio</p>
<p>Gli esercizi di programmazione hanno due obiettivi</p>
<ul>
<li>Darci la possibilità di lavorare in un ambiente controllato e privo di vincoli. Il fallimento è visto in maniera positiva, venire a conoscenza dei nostri limiti è l&#8217;unico modo per poterli superare</li>
<li>Visto che non avrete mai il tempo che volete, l&#8217;unica cosa che potete fare è diventare più veloci nello scrivere codice di qualità</li>
</ul>
<p>Il secondo punto ci riporta al tema iniziale: dove sta scritto che per scrivere del buon codice serve tanto tempo? Io sono fermamente convinto che l&#8217;unica ragione per la quale intuitivamente lo pensiamo è perchè quando ci proviamo  facciamo fatica, e l&#8217;unica ragione per la quale facciamo fatica è perchè non siamo abituati/allenati.</p>
<p>Ultimamente ho dedicato un po&#8217; di tempo a pensare ai kata e ad esercitarmi, venerdì della settimana scorsa ho partecipato al <a href="http://www.javascriptcamp.com/">primo javascript camp italiano</a> organizzato da <a href="http://www.ideato.it/">Ideato</a> e ho presentato il kata &#8220;the game of life&#8221; in javascript, è stato molto divertente ed istruttivo</p>
<p>Gli ingredienti per un buon kata/esercizio sono</p>
<ul>
<li>Un problema sfidante per le vostre capacità e per la vostra preparazione</li>
<li>Una o più persone pronte a darvi il loro feedback, fondamentale per capire come e dove migliorarsi</li>
<li>Ripetere l&#8217;esercizio più e più volte finchè sentite che ormai il problema non ha più niente da insegnarvi</li>
</ul>
<p>Il mio consiglio è di provare e di mettervi in gioco, per quanto mi riguarda le prossime mosse saranno: pubblicare gli screencast dei miei kata ed organizzare dei gruppi di esercizio/studio, se siete interessati contattatemi o iscrivetevi <a href="http://groups.google.com/group/milano-codingdojo">milano-codingdojo</a> (non preoccupatevi se non siete di Milano, stiamo organizzandoci per fare qualcosa di distribuito ;-))</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabrielelana.it/archives/109/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Non c&#8217;entra niente, ma&#8230;</title>
		<link>http://www.gabrielelana.it/archives/107</link>
		<comments>http://www.gabrielelana.it/archives/107#comments</comments>
		<pubDate>Thu, 06 Aug 2009 11:25:09 +0000</pubDate>
		<dc:creator>Gabriele Lana</dc:creator>
				<category><![CDATA[fun]]></category>
		<category><![CDATA[stuff]]></category>

		<guid isPermaLink="false">http://www.gabrielelana.it/archives/107</guid>
		<description><![CDATA[Stimolato dal professore l&#8217;ho fatto anch&#8217;io. Di solito i risultati di questi test su di me funzionano poco, quando facevo il militare ci facevano regolarmente dei test attitudinali/caratteriali/? e regolarmente su 12 profili possibili io risultavo appartenere in egual misura a 6/7 profili contemporaneamente&#8230; :-)
My Political ViewsI am a centrist social moderateLeft: 0.14, Libertarian: 0.95

]]></description>
			<content:encoded><![CDATA[<p>Stimolato dal <a href="http://www.alfonsofuggetta.org/?p=5883">professore</a> l&#8217;ho <a href="http://www.gotoquiz.com/politics/political-spectrum-quiz.html">fatto</a> anch&#8217;io. Di solito i risultati di questi test su di me funzionano poco, quando facevo il militare ci facevano regolarmente dei test attitudinali/caratteriali/? e regolarmente su 12 profili possibili io risultavo appartenere <strong>in egual misura</strong> a 6/7 profili contemporaneamente&#8230; :-)</p>
<p><b>My Political Views</b><br />I am a centrist social moderate<br />Left: 0.14, Libertarian: 0.95<br />
<img src="http://www.gotoquiz.com/politics/grid/20x22.gif"></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabrielelana.it/archives/107/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Splittare le User Story come strategia di business</title>
		<link>http://www.gabrielelana.it/archives/106</link>
		<comments>http://www.gabrielelana.it/archives/106#comments</comments>
		<pubDate>Tue, 04 Aug 2009 08:30:08 +0000</pubDate>
		<dc:creator>Gabriele Lana</dc:creator>
				<category><![CDATA[agile]]></category>
		<category><![CDATA[business]]></category>
		<category><![CDATA[user story]]></category>

		<guid isPermaLink="false">http://www.gabrielelana.it/archives/106</guid>
		<description><![CDATA[Oggi ho visto l&#8217;ennesimo strepitoso intervento di Eric Ries a proposito della pratica del MVP (Minimum Viable Product). Il problema è molto chiaro: la nostra vision di prodotto potrebbe portare ad un business non sostenibile; la strategia proposta lo è altrettanto: trovare il minimo set di funzionalità in grado di poterci dare un feedback reale [...]]]></description>
			<content:encoded><![CDATA[<p>Oggi ho visto l&#8217;ennesimo strepitoso <a href="http://startuplessonslearned.blogspot.com/2009/08/minimum-viable-product-guide.html">intervento</a> di <a href="http://startuplessonslearned.blogspot.com">Eric Ries</a> a proposito della pratica del <a href="http://venturehacks.com/articles/minimum-viable-product">MVP (Minimum Viable Product)</a>. Il problema è molto chiaro: la nostra <strong>vision</strong> di prodotto potrebbe portare ad un business non sostenibile; la strategia proposta lo è altrettanto: trovare il <strong>minimo</strong> set di funzionalità in grado di poterci dare un feedback reale sulle esigenze dei nostri utenti e in che misura il nostro prodotto le soddisfa.</p>
<p>Maggior conoscenza acquisiamo sui nostri utenti, maggiori saranno le probabilità che la prossima funzionalità pensata/implementata sarà apprezzata (aumentando il valore dell&#8217;applicazione). Minore sarà il tempo/costo d&#8217;implementazione di una nuova funzionalità, maggiori saranno le funzionalità che potremmo utilizzare per acquisire conoscenza sui nostri utenti</p>
<p>Cosa possiamo fare per minimizzare i tempi/costi d&#8217;implementazione? Chiaramente possiamo intervenire da un punto di vista tecnico migliorando la nostra capacità di produrre software, mantenendo sempre <a href="http://www.amazon.com/o/ASIN/0132350882">pulita</a> la nostra base di codice, migliorando costantemente gli aspetti di project automation e di <a href="http://en.wikipedia.org/wiki/Autonomation">autonomation</a>, ecc&#8230; insomma avete capito</p>
<p>L&#8217;altra cosa che possiamo fare è splittare in maniera creativa ed aggressiva le user story esistenti del prodotto. Prima possiamo iniziare a selezionere un minimo set di user story in grado di dare dignità di prodotto al nostro progetto, poi possiamo iniziare a considerarle singolarmente e a capire cosa possiamo togliere da ogni user story conservando la possibilità di poter utilizzare il risultato come MVP</p>
<p>Un esempio? Avevo 10 giorni (nessuna domanda please sul perchè di questo numero magico&#8230;) di tempo per realizzare un&#8217;applicativo piuttosto complesso, ovviamente c&#8217;era di mezzo uno storage, ovviamente il cliente aveva richiesto un&#8217;interfaccia di amministrazione/gestione di questo storage e ovviamente non aveva tralasciato nessun &#8220;goodies&#8221;: utenti, gruppi, ruoli, permessi, editing, viste configurabili sui dati, ecc&#8230; praticamente mi sarebbero serviti molti più giorni di quelli a disposizione solo per questa parte <strong>accessoria</strong> del sistema. Volevo iniziare dal <strong>vero</strong> prodotto, ma volevo anche che il cliente lo potesse utilizzare da subito, così ho installato <a href="http://www.phpmyadmin.net/home_page/index.php">phpMyAdmin</a> e ho fatto vedere al cliente come utilizzarlo: ho creato utenti, viste, maschere, ecc&#8230; alla fine il cliente mi ha detto che è esattamente quello che voleva :-D Ok, sono stato fortunato, ma è stata una vera epifania</p>
<p>Un&#8217;altro esempio un po&#8217; più creativo? Kent Beck qualche hanno fa ha tenuto un workshop sullo split delle user story usando un esempio alquanto &#8220;ardito&#8221;: il gioco del tetris&#8230; qual&#8217;è secondo voi la prima user story per Beck? Una colonna, un quadratino 1&#215;1 che scende a velocià costante, quando un quadratino tocca il fondo parte un altro quadratino, il nuovo fondo è il quadratino precedente, quando il fondo arriva in cima alla colonna &#8220;game over&#8221; :-D</p>
<p>Ancora una volta una conferma del fatto che il business (il <strong>problem team</strong> come lo chiama Ries) e la tecnologia (<strong>solution team</strong>) non si possono/devono ignorare a vicenda</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabrielelana.it/archives/106/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Una metafora per le stime nelle metodologie Agili</title>
		<link>http://www.gabrielelana.it/archives/105</link>
		<comments>http://www.gabrielelana.it/archives/105#comments</comments>
		<pubDate>Fri, 31 Jul 2009 10:45:24 +0000</pubDate>
		<dc:creator>Gabriele Lana</dc:creator>
				<category><![CDATA[agile]]></category>

		<guid isPermaLink="false">http://www.gabrielelana.it/archives/105</guid>
		<description><![CDATA[ Qualche settimana fa ho capito una cosa tanto semplice quanto per me importante, il miglioramento della produttività applicando una metodologia Agile si ottiene su due fronti

Pianificazione: identificare le User Story tenendole ad una granularità/indipendenza sufficiente da poter realizzare prima quelle con il più alto valore di business. Inutile dire che la valutazione del valore [...]]]></description>
			<content:encoded><![CDATA[<p><a class="on_the_left" href='http://www.gabrielelana.it/wp-content/uploads/2009/07/boxes.png' title='boxes'><img src='http://www.gabrielelana.it/wp-content/uploads/2009/07/boxes.thumbnail.png' alt='boxes' /></a> Qualche settimana fa ho capito una cosa tanto semplice quanto per me importante, il miglioramento della produttività applicando una metodologia Agile si ottiene su due fronti</p>
<ul style="clear:left">
<li>Pianificazione: identificare le <em>User Story</em> tenendole ad una granularità/indipendenza sufficiente da poter realizzare prima quelle con il più alto valore di business. Inutile dire che la valutazione del valore di business di ogni singola user story è fondamentale</li>
<li>Esecuzione: migliorare costantemente la velocità di realizzazione delle suddette <em>User Story</em></li>
</ul>
<p>L&#8217;obiettivo supremo è sempre quello di massimizzare la quantità di valore consegnato nell&#8217;unità di tempo e in subordine la capacità di produrne in futuro, il resto sono chiacchere</p>
<p>E&#8217; un concetto estremamente semplice, ma estremamente efficace se dovete introdurre a qualcuno le pratiche proprie delle metodologie Agili. Detto questo però se avete poco tempo a disposizione per catturare l&#8217;attenzione di qualcuno, se dovete fare un <a href="http://it.wikipedia.org/wiki/Elevator_pitch">elevator pitch</a>, vi serve qualcosa di molto immediato, vi servono delle metafore</p>
<p>Negli ultimi due anni ne ho raffinata una per spiegare come funziona la pianificazione e visto che è risultata essere particolarmente efficace la condivido con tutti, la scrivo come la racconto di solito</p>
<blockquote><p>
Supponiamo che dall&#8217;altro lato di quella porta (nda. di solito c&#8217;è una porta nelle vicinanze :-)) ci sia un team di programmatori che deve iniziare un progetto per il quale sono necessarie determinate conoscenze, queste conoscenze possono essere acquisite attraverso lo studio di alcuni libri, il vostro compito è quello di fornirglieli</p>
<p>Il materiale che vi viene dato consiste in 15m^3 di libri e di uno scatolone di 10m^3, se vi state chiedendo <em>&#8220;esiste una metodologia in grado di far entrare 15m^3 di libri in uno scatolone di 10m^3?&#8221;</em> la risposta è no! Anche le metodologie Agili non fanno eccezione :-)</p>
<p>Quindi cosa facciamo? Se seguissimo alla lettera i vincoli che ci sono stati dati e se non fossimo abbastanza svegli da misurare i volumi che abbiamo a disposizione, probabilmente spenderemo la maggior parte del nostro tempo a tentare di organizzare i libri per riuscire a farceli stare tutti nello scatolone. Una volta arrivati in prossimità della scadenza ficcheremo il maggior numero possibile di libri all&#8217;interno dello scatolone per poi spingerlo finalmente al di là della porta dove ci sono i programmatori che lo aspettano</p>
<p>Evidentemente non è una strategia molto furba&#8230; come possiamo migliorarla? Ci chiediamo: <em>&#8220;qual&#8217;è il reale obiettivo di questo lavoro?&#8221;</em> Massimizzare al quantità di conoscenza da passare al team di programmatori che sta al di là della porta, <em>&#8220;la quantità di conoscenza erogata è indipendente dal libro?&#8221;</em> Ovviamente no, quindi una cosa che possiamo fare è scegliere <strong>i 10m^3 di libri in grado di fornire la maggior quantità di conoscenza</strong> (nda. in questo caso stiamo dicendo che la scelta delle user story da implementare è il primo passo verso la massimizzazione del flusso di valore)</p>
<p>Bene, possiamo migliorare? Ci chiediamo <em>&#8220;ogni capitolo all&#8217;interno di un libro eroga la stessa quantità di conoscenza?&#8221;</em> Nella maggior parte dei casi no, sicuramente non erogano conoscenza le copertine cartonate, le prefazioni, i ringraziamenti, ecc&#8230; Quindi possiamo procedere con un approcio creativo e stracciare ogni libro tenendo solo i capitoli migliori e quindi scegliere <strong>i 10m^3 di materiale in grado di fornire la maggior quantità di conoscenza</strong> (nda. in questo caso stiamo dicendo che splittando le user story possiamo prendere la maggior parte del valore minimizzando il costo)</p>
<p>Ottimo! Possiamo ancora migliorare? Ci chiediamo <em>&#8220;chi è che decide la quantità di conoscenza erogata da un testo?&#8221;</em> Fino a questo momento siamo stati noi ma effettivamente è un assunto grave, cosa succederebbe se avessimo torto? La nostra strategia sarebbe ancora valida, ma le nostre misurazioni sarebbero pura speculazione, non possiamo essere sicuri di aver <strong>realmente</strong> erogato la maggior quantità di conoscenza possibile. <em>&#8220;chi potrebbe valutare con maggiore accuratezza?&#8221;</em> Sicuramente il team di programmatori che sta dietro alla porta</p>
<p>Quindi possiamo essere ancora più creativi e possiamo chiedere di barattare lo scatolone da 10m^3 con 10 scatoloni da 1m^3, nel primo scatolone ci mettiamo quello che <strong>noi</strong> riteniamo essere il miglior metro cubo di materiale possibile e lo spingiamo fuori dalla porta chiedendo ai programmatori di chiamarci una volta letto tutto. Quando i programmatori ci chiameranno chiederemo il loro feedback sul materiale, sulla base di queste informazioni sceglieremo cosa mettere nel prossimo scatolone. In questo modo non solo avremo una corretta valutazione del <strong>valore</strong> consegnato, ma abbiamo anche la possibilità di adattarci al contesto del progetto (nda. in questo caso stiamo dicendo che le funzionalità individuate all&#8217;inizio del progetto e la stima di valore che ne viene fatta è nella maggior parte dei casi errata e che quindi serve un reale strumento di feedback)
</p></blockquote>
<p>Secondo me funziona bene perchè</p>
<ul>
<li>All&#8217;inizio non ti aspetti di poter migliorare molto, quando capisci che puoi farlo è una bella sensazione :-)</li>
<li>I 15m^3 in 10m^3 danno quella sensazione di claustrofobia che tutti hanno provato nei progetti &#8220;fixed *&#8221; (leggi: dove tutto è prefissato)</li>
<li>Si capisce chiaramente che il modo per migliorare dipende poco dalla capacità di fare stime &#8220;corrette&#8221; quando dall&#8217;organizzazione del flusso di lavoro e di feedback
</li>
</ul>
<p>Cosa ne pensate? Possiamo ancora migliorare? :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabrielelana.it/archives/105/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Regole per un business di successo</title>
		<link>http://www.gabrielelana.it/archives/103</link>
		<comments>http://www.gabrielelana.it/archives/103#comments</comments>
		<pubDate>Sun, 26 Jul 2009 10:27:21 +0000</pubDate>
		<dc:creator>Gabriele Lana</dc:creator>
				<category><![CDATA[agile]]></category>
		<category><![CDATA[business]]></category>
		<category><![CDATA[startup]]></category>

		<guid isPermaLink="false">http://www.gabrielelana.it/archives/103</guid>
		<description><![CDATA[Dopo aver letto un bel po&#8217; di cose sull&#8217;argomento, questa è una perfetta sintesi


The customer is the most important thing in your business
The best business plan is to sell people the things they want
Your business is successfull if your earnings are higher than your spendings


Troppo spesso le startup vengono fondate su una vision di progetto [...]]]></description>
			<content:encoded><![CDATA[<p>Dopo aver letto un bel po&#8217; di cose sull&#8217;argomento, <a href="http://www.codemonkeyism.com/archives/2006/05/03/rules-for-a-successfull-business/">questa</a> è una perfetta sintesi</p>
<blockquote>
<ul>
<li>The customer is the most important thing in your business</li>
<li>The best business plan is to sell people the things they want</li>
<li>Your business is successfull if your earnings are higher than your spendings</li>
</ul>
</blockquote>
<p>Troppo spesso le startup vengono fondate su una <strong>vision</strong> di progetto che esiste solo nelle menti degli stessi fondatori, <a href="http://startuplessonslearned.blogspot.com/">Eric Ries</a> dice sempre nelle sue presentazioni <em>&#8220;vision not delusion&#8221;</em>, che potrebbe anche essere <em>&#8220;vision not illusion&#8221;</em>. Il compito principale di una startup è quello di validare/raffinare nel più breve tempo possibile la propria vision di progetto confrontandosi con l&#8217;unica fonte di verità: <strong>gli utenti</strong></p>
<p>VC: &#8220;Interessante la vostra idea, potete mostrarci il vostro business plan?&#8221;<br />
Startup: &#8220;Inizialmente avevamo questo set di funzionalità, poi abbiamo eliminato queste funzionalità ed abbiamo aggiunto queste altre e siamo passati da X utenti a 3X utenti, a partire da questa informazione abbiamo modificato il nostro posizionamento nel mercato, abbiamo validato queste informazioni passando da 3X utenti a 10X utenti aggiungendo queste altre funzionalità in accordo con quanto avevamo scoperto. Ora ci aspettiamo di raggiungere i 100X utenti, quindi una revenue di Y, togliendo queste funzionalità e aggiungedo queste altre nei prossimi 2 mesi&#8221;</p>
<p>Questo è un business plan nel quale metterei dei soldi&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabrielelana.it/archives/103/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bowling kata in Erlang</title>
		<link>http://www.gabrielelana.it/archives/102</link>
		<comments>http://www.gabrielelana.it/archives/102#comments</comments>
		<pubDate>Fri, 24 Jul 2009 14:10:54 +0000</pubDate>
		<dc:creator>Gabriele Lana</dc:creator>
				<category><![CDATA[erlang]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://www.gabrielelana.it/archives/102</guid>
		<description><![CDATA[Qualche giorno fa Robert Martin come esercizio per imparare Clojure ha risolto il kata del bowling (da lui stesso ideato). Qualche programmatore più avvezzo al mondo funzionale ha cassato la soluzione ritenendola troppo &#8220;imperativa&#8221;, accusando non tanto Martin stesso quanto la presenza dei test :-D
L&#8217;argomentazione utilizzata per minimizzare l&#8217;utilità dei test è la semplicità dell&#8217;esercizio, [...]]]></description>
			<content:encoded><![CDATA[<p>Qualche giorno fa <a href="http://objectmentor.com/omTeam/martin_r.html">Robert Martin</a> come esercizio per imparare <a href="http://clojure.org/">Clojure</a> ha <a href="http://blog.objectmentor.com/articles/2009/07/19/uncle-bob-jsps-learning-clojure">risolto</a> il <a href="http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata">kata del bowling</a> (da lui stesso ideato). Qualche programmatore più avvezzo al mondo funzionale ha cassato la soluzione ritenendola troppo &#8220;imperativa&#8221;, accusando non tanto Martin stesso quanto la presenza dei test :-D</p>
<p>L&#8217;argomentazione utilizzata per minimizzare l&#8217;utilità dei test è la semplicità dell&#8217;esercizio, al che ho pensato a come l&#8217;avrei risolto in <a href="http://erlang.org/">Erlang</a>, mi sono detto che &#8220;effettivamente la soluzione è semplice&#8221;, ho iniziato a scriverla provandola nella shell del linguaggio e subito ho provato un senso di fastidio</p>
<p>Continuavo a scrivere e riscrivere (va bhe, la shell ti da la possibilità di richiamare i comandi passati, ma il discorso non cambia) le stesse invocazioni verificando ad occhio il risultato, al che ho capito il senso di fastidio: che differenza c&#8217;è fra quello che stavo facendo e scrivere dei test unitari? Nessuna, tranne che i primi sono effimeri e non ti possono venire in aiuto quando sarai chiamato a fare refactoring. Quindi, amici dei linguaggi funzionali, perchè non vedete i test unitari come delle sessioni di interazione con la shell permanenti e automatiche?</p>
<p>Vi dirò di più, la soluzione che avevo inizialmente pensato era sbagliata :-) Dopo aver passato tutti i test che Martin aveva fatto nella presentazione di cui sopra, mi sono chiesto se potevo rompere il codice in qualche modo, ho visto che non erano coperti dei corner case, per esempio c&#8217;è la partita peggiore (tutti 0), ma non c&#8217;è la partita migliore (tutti strike), scrivo un test&#8230; e non passa :-)</p>
<p>Come vedete qui sotto, utilizzo una variabile per tenere il conto dei frame elaborati, inizialmente non lo facevo e nel caso di uno strike nell&#8217;ultimo frame, i due tiri di bonus successivi metchavano con la terza clausola e venivano considerati dei frame normali, quindi il &#8220;perfect game&#8221; che dovrebbe avere uno score di 300 aveva score 320</p>
<p><script src="http://gist.github.com/154187.js"></script></p>
<p>Alla fine ho guardato il codice e quella variabile arbitraria per contare il numero dei frame proprio non mi andava giù e senza cambiare i test sono arrivato a questa seconda soluzione</p>
<p><script src="http://gist.github.com/154189.js"></script></p>
<p>Che non mi piace perchè anche se rende più esplicito (forse anche più imperativo?) il conto dei frame, secondo me si capisce di meno, sopratutto non mi piace <strong>score_frame</strong> perchè si occupa sia di calcolare lo score di un frame (e fin qui), sia di selezionare i tiri rimanenti eliminando quelli del frame corrente</p>
<p>Cosa ne dite? Quale vi piace di più?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabrielelana.it/archives/102/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
