<?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>Appunti Digitali &#187; Programmazione</title>
	<atom:link href="http://mariano.altervista.org/wordpress/category/programmazione/feed/" rel="self" type="application/rss+xml" />
	<link>http://mariano.altervista.org/wordpress</link>
	<description>Tutti desiderano possedere la conoscenza, pochi sono disposti a pagarne il prezzo</description>
	<lastBuildDate>Wed, 18 Nov 2009 20:32:00 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Join multipli sulla stessa tabella</title>
		<link>http://mariano.altervista.org/wordpress/2008/11/17/join-multipli-sulla-stessa-tabella/</link>
		<comments>http://mariano.altervista.org/wordpress/2008/11/17/join-multipli-sulla-stessa-tabella/#comments</comments>
		<pubDate>Mon, 17 Nov 2008 18:29:23 +0000</pubDate>
		<dc:creator>mariano</dc:creator>
				<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://mariano.altervista.org/wordpress/?p=182</guid>
		<description><![CDATA[Spesso può essere necessario fare due join sullo stesso campo della stessa tabella. Ad esempio, considerando di voler gestire un calendario di calcio, sarebbe probabile avere due tabelle, una partite, l&#8217;altra squadre. Nella prima potremmo memorizzare tutti i dati della partita, semplificando memorizzeremo, l&#8217;identificativo univoco della partita, l&#8217;id delle due squadre, e il risultato. La [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Spesso può essere necessario fare due join sullo stesso campo della stessa tabella. Ad esempio, considerando di voler gestire un calendario di calcio, sarebbe probabile avere due tabelle, una <em>partite</em>, l&#8217;altra <em>squadre</em>. Nella prima potremmo memorizzare tutti i dati della partita, semplificando memorizzeremo, l&#8217;identificativo univoco della partita, l&#8217;id delle due squadre, e il risultato. La seconda tabella può essere utilizzata per memorizzare l&#8217;idi delle squadre, il nome e altre informazioni che non servono al nostro esempio. Come fare ora per eseguire una query che sostituisca agli id delle due squadre nella tabella <em>partite</em> il nome memorizzato nella tabella <em>squadre</em><span id="more-182"></span></p>
<p>Ricapitolando, la tabella <em>squadre</em>:</p>
<ul>
<li>id_squadra</li>
<li>nome</li>
</ul>
<p>tabella <em>partite</em></p>
<ul>
<li>id_partita</li>
<li>id_casa</li>
<li>id_ospiti</li>
<li>gol_casa</li>
<li>gol_ospiti</li>
</ul>
<p style="text-align: justify;">Probabilmente, la prima soluzione che ci verrebbe in mente sarebbe quella di scrivere qualcosa del genere:</p>
<pre class="brush: sql">
SELECT *
FROM partite
JOIN squadre ON partite.id_casa = squadre.id_squadra
JOIN squadre ON partite.id_ospiti = squadre.id_squadra
</pre>
<p style="text-align: justify;">Qualcuno subito potrebbe notare che questa query andrà sicuramente in errore, in quanto così facendo stiamo chiedendo all&#8217;interprete SQL di eseguire due JOIN diverse sulla stessa tabella e sullo stesso campo, questo non gli piacerà e ci ritornerà un errore del tipo:</p>
<blockquote><p>#1066 &#8211; Not unique table/alias: &#8217;squadre&#8217;</p></blockquote>
<p style="text-align: justify;">La soluzione più veloce per risolvere questo problema consiste nel rinominare le tabelle su cui fare i due JOIN, ovvero rinominare la tabella <em>squadre</em> in modo da far credere all&#8217;interprete SQL che sia una tabella diversa. Ovvero:</p>
<pre class="brush: sql">
SELECT *
FROM partite
JOIN squadre AS sq_casa ON partite.id_casa = sq_casa.id_squadra
JOIN squadre AS sq_ospite ON partite.id_ospite = sq_ospite.id_squadra
</pre>
<p style="text-align: justify;">
In questo modo è come se avessimo 3 tabelle: <em>partite</em>, <em>sq_casa</em>, <em>sq_ospite</em> su cui potremmo operare indipendentemente.</p>
]]></content:encoded>
			<wfw:commentRss>http://mariano.altervista.org/wordpress/2008/11/17/join-multipli-sulla-stessa-tabella/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>La validazione del codice fiscale</title>
		<link>http://mariano.altervista.org/wordpress/2008/11/07/la-validazione-del-codice-fiscale/</link>
		<comments>http://mariano.altervista.org/wordpress/2008/11/07/la-validazione-del-codice-fiscale/#comments</comments>
		<pubDate>Fri, 07 Nov 2008 16:43:26 +0000</pubDate>
		<dc:creator>mariano</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Programmazione]]></category>

		<guid isPermaLink="false">http://mariano.altervista.org/wordpress/?p=164</guid>
		<description><![CDATA[Il codice fiscale è un codice alfanumerico di 16 caratteri, serve a identificare in modo univoco a fini fiscali le persone fisiche residenti sul territorio italiano, prima che venisse inglobato nella tessera sanitaria era consegnato su una tessera plastificata con tanto di banda magnetica. Sulla parte anteriore della tessera sono riportati &#8211; oltre al codice [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Il codice fiscale è un codice alfanumerico di 16 caratteri, serve a identificare in modo univoco a fini fiscali le persone fisiche residenti sul territorio italiano, prima che venisse <a href="http://www.agenziaentrate.it/ilwwcm/connect/Nsi/Servizi/Codice+fiscale+-+Tessera+Sanitaria/" target="_tab">inglobato</a> nella tessera sanitaria era consegnato su una tessera plastificata con tanto di banda magnetica. Sulla parte anteriore della tessera sono riportati &#8211; oltre al codice stesso &#8211; nome, cognome, luogo e data di nascita, sesso e provincia. I 16 caratteri all&#8217;interno del codice sono così divisi:</p>
<ul>
<li>3 caratteri per il cognome</li>
<li>3 caratteri per il nome</li>
<li>5 caratteri per la data di nascita e il sesso</li>
<li>4 caratteri per il luogo di nascita</li>
<li>1 carattere di controllo</li>
</ul>
<p><span id="more-164"></span></p>
<p style="text-align: justify;">Spesso, in particolare se ci troviamo a dover programmare form di registrazione, ci troveremo prima o poi a doverne controllare la correttezza. Sebbene in pochi lo sanno, il codice fiscale, ha un algoritmo (intrinseco) di verifica della correttezza abbastanza robusto. In questo articolo vedremo concettualmente come funziona questo algoritmo di controllo e come implementarlo in un linguaggio di programmazione. Verrà utilizzato Java per la scrittura dell&#8217;algoritmo ma non dovrebbe essere complicato emularlo in altri linguaggi, se avete realizzato una versione in un linguaggio di programmazione diverso da Java potete postarlo tra i commenti e lo inserirò nell&#8217;articolo.</p>
<h3>Il concetto</h3>
<p style="text-align: justify;">Supponendo che ci sia stato inviato un codice fiscale, il nostro algoritmo dovrà controllarne la correttezza sintattica, (ovvero che non ci siano numeri nelle posizioni che dovrebbero essere occupate da lettere) e semantica (ovvero che il carattere di controllo risulti &#8220;solidale&#8221; rispetto agli altri 15). Per controllare la correttezza sintattica del codice fiscale passato useremo le espressioni regolari, mentre per la correttezza semantica costruiremo un algoritmo apposito per calcolare il sedicesimo carattere sfruttando i 15 forniti. L&#8217;esito del confronto tra il carattere di controllo inviato e quello calcolato rileverà la correttezza o meno del codice. </p>
<h3>L&#8217;algoritmo</h3>
<p style="text-align: justify;">La correttezza semantica del codice fiscale, come abbiamo già detto, si basa sulla presenza del sedicesimo carattere di controllo, ricavato attraverso una serie di operazioni <em>X</em> sui 15 caratteri precedenti. Se il sedicesimo carattere inserito dall&#8217;utente è diverso da quello risultante dalle operazioni <em>X</em> allora il codice è semanticamente non corretto. In cosa consistono queste operazioni? Si converte ognuno dei 15 caratteri del codice in un valore numerico rispettando due distinte tabelle di conversione a seconda che stiamo convertendo un carattere pari o un carattere dispari. Ecco le tabelle di conversione:</p>
<p>&nbsp;</p>
<table style="font-size: 90%; border-collapse: collapse;" border="1" cellspacing="1" cellpadding="4" align="center">
<tr align="center" bgcolor="lightgreen">
<td colspan="8"><strong>CARATTERI ALFANUMERICI DISPARI</strong></td>
</tr>
<tr align="center" bgcolor="#efefef">
<td><strong>Carattere</strong></td>
<td><strong>Valore</strong></td>
<td><strong>Carattere</strong></td>
<td><strong>Valore</strong></td>
<td><strong>Carattere</strong></td>
<td><strong>Valore</strong></td>
<td><strong>Carattere</strong></td>
<td><strong>Valore</strong></td>
</tr>
<tr align="center">
<td><strong>0</strong></td>
<td>1</td>
<td><strong>9</strong></td>
<td>21</td>
<td><strong>I</strong></td>
<td>19</td>
<td><strong>R</strong></td>
<td>8</td>
</tr>
<tr align="center">
<td><strong>1</strong></td>
<td>0</td>
<td><strong>A</strong></td>
<td>1</td>
<td><strong>J</strong></td>
<td>21</td>
<td><strong>S</strong></td>
<td>12</td>
</tr>
<tr align="center">
<td><strong>2</strong></td>
<td>5</td>
<td><strong>B</strong></td>
<td>0</td>
<td><strong>K</strong></td>
<td>2</td>
<td><strong>T</strong></td>
<td>14</td>
</tr>
<tr align="center">
<td><strong>3</strong></td>
<td>7</td>
<td><strong>C</strong></td>
<td>5</td>
<td><strong>L</strong></td>
<td>4</td>
<td><strong>U</strong></td>
<td>16</td>
</tr>
<tr align="center">
<td><strong>4</strong></td>
<td>9</td>
<td><strong>D</strong></td>
<td>7</td>
<td><strong>M</strong></td>
<td>18</td>
<td><strong>V</strong></td>
<td>10</td>
</tr>
<tr align="center">
<td><strong>5</strong></td>
<td>13</td>
<td><strong>E</strong></td>
<td>9</td>
<td><strong>N</strong></td>
<td>20</td>
<td><strong>W</strong></td>
<td>22</td>
</tr>
<tr align="center">
<td><strong>6</strong></td>
<td>15</td>
<td><strong>F</strong></td>
<td>13</td>
<td><strong>O</strong></td>
<td>11</td>
<td><strong>X</strong></td>
<td>25</td>
</tr>
<tr align="center">
<td><strong>7</strong></td>
<td>17</td>
<td><strong>G</strong></td>
<td>15</td>
<td><strong>P</strong></td>
<td>3</td>
<td><strong>Y</strong></td>
<td>24</td>
</tr>
<tr align="center">
<td><strong>8</strong></td>
<td>19</td>
<td><strong>H</strong></td>
<td>17</td>
<td><strong>Q</strong></td>
<td>6</td>
<td><strong>Z</strong></td>
<td>23</td>
</tr>
</table>
<p>&nbsp;</p>
<table style="font-size: 90%; border-collapse: collapse;" border="1" cellspacing="1" cellpadding="4" align="center">
<tr align="center" bgcolor="lightgreen">
<td colspan="8"><strong>CARATTERI ALFANUMERICI PARI</strong></td>
</tr>
<tr align="center" bgcolor="#efefef">
<td><strong>Carattere</strong></td>
<td><strong>Valore</strong></td>
<td><strong>Carattere</strong></td>
<td><strong>Valore</strong></td>
<td><strong>Carattere</strong></td>
<td><strong>Valore</strong></td>
<td><strong>Carattere</strong></td>
<td><strong>Valore</strong></td>
</tr>
<tr align="center">
<td><strong>0</strong></td>
<td>0</td>
<td><strong>9</strong></td>
<td>9</td>
<td><strong>I</strong></td>
<td>8</td>
<td><strong>R</strong></td>
<td>17</td>
</tr>
<tr align="center">
<td><strong>1</strong></td>
<td>1</td>
<td><strong>A</strong></td>
<td>0</td>
<td><strong>J</strong></td>
<td>9</td>
<td><strong>S</strong></td>
<td>18</td>
</tr>
<tr align="center">
<td><strong>2</strong></td>
<td>2</td>
<td><strong>B</strong></td>
<td>1</td>
<td><strong>K</strong></td>
<td>10</td>
<td><strong>T</strong></td>
<td>19</td>
</tr>
<tr align="center">
<td><strong>3</strong></td>
<td>3</td>
<td><strong>C</strong></td>
<td>2</td>
<td><strong>L</strong></td>
<td>11</td>
<td><strong>U</strong></td>
<td>20</td>
</tr>
<tr align="center">
<td><strong>4</strong></td>
<td>4</td>
<td><strong>D</strong></td>
<td>3</td>
<td><strong>M</strong></td>
<td>12</td>
<td><strong>V</strong></td>
<td>21</td>
</tr>
<tr align="center">
<td><strong>5</strong></td>
<td>5</td>
<td><strong>E</strong></td>
<td>4</td>
<td><strong>N</strong></td>
<td>13</td>
<td><strong>W</strong></td>
<td>22</td>
</tr>
<tr align="center">
<td><strong>6</strong></td>
<td>6</td>
<td><strong>F</strong></td>
<td>5</td>
<td><strong>O</strong></td>
<td>14</td>
<td><strong>X</strong></td>
<td>23</td>
</tr>
<tr align="center">
<td><strong>7</strong></td>
<td>7</td>
<td><strong>G</strong></td>
<td>6</td>
<td><strong>P</strong></td>
<td>15</td>
<td><strong>Y</strong></td>
<td>24</td>
</tr>
<tr align="center">
<td><strong>8</strong></td>
<td>8</td>
<td><strong>H</strong></td>
<td>7</td>
<td><strong>Q</strong></td>
<td>16</td>
<td><strong>Z</strong></td>
<td>25</td>
</tr>
</table>
<p>&nbsp;</p>
<p style="text-align: justify;">Una volta completata la fase precedente avremo 15 numeri, li sommeremo tra loro e il risultato ottenuto lo divideremo per 26. Il resto di tale divisione restituirà ovviamente un numero intero che dovrà essere trasformato in un carattere alfabetico grazie ad un ulteriore tabella di trasformazione. La tabella è in realtà la tabella dei numeri pari, priva dei caratteri numerici e con i soli caratteri alfabetici.</p>
<p>&nbsp;</p>
<table style="font-size: 90%; border-collapse: collapse;" align="center" border="1" cellpadding="4" cellspacing="1">
<tr align="center" bgcolor="lightgreen">
<td colspan="8"><b>RESTO</b></td>
</tr>
<tr align="center" bgcolor="#efefef">
<td><b>Resto</b></td>
<td><b>Lettera</b></td>
<td><b>Resto</b></td>
<td><b>Lettera</b></td>
<td><b>Resto</b></td>
<td><b>Lettera</b></td>
<td><b>Resto</b></td>
<td><b>Lettera</b></td>
</tr>
<tr align="center">
<td><b>0</b></td>
<td>A</td>
<td><b>7</b></td>
<td>H</td>
<td><b>14</b></td>
<td>O</td>
<td><b>21</b></td>
<td>V</td>
</tr>
<tr align="center">
<td><b>1</b></td>
<td>B</td>
<td><b>8</b></td>
<td>I</td>
<td><b>15</b></td>
<td>P</td>
<td><b>22</b></td>
<td>W</td>
</tr>
<tr align="center">
<td><b>2</b></td>
<td>C</td>
<td><b>9</b></td>
<td>J</td>
<td><b>16</b></td>
<td>Q</td>
<td><b>23</b></td>
<td>X</td>
</tr>
<tr align="center">
<td><b>3</b></td>
<td>D</td>
<td><b>10</b></td>
<td>K</td>
<td><b>17</b></td>
<td>R</td>
<td><b>24</b></td>
<td>Y</td>
</tr>
<tr align="center">
<td><b>4</b></td>
<td>E</td>
<td><b>11</b></td>
<td>L</td>
<td><b>18</b></td>
<td>S</td>
<td><b>25</b></td>
<td>Z</td>
</tr>
<tr align="center">
<td><b>5</b></td>
<td>F</td>
<td><b>12</b></td>
<td>M</td>
<td><b>19</b></td>
<td>T</td>
<td></td>
<td></td>
</tr>
<tr align="center">
<td><b>6</b></td>
<td>G</td>
<td><b>13</b></td>
<td>N</td>
<td><b>20</b></td>
<td>U</td>
<td></td>
<td></td>
</tr>
</table>
<p style="text-align: justify;">Se il carattere ricavato coincide col sedicesimo carattere fornito dall&#8217;utente il codice risulterà semanticamente corretto.</p>
<h3>L&#8217;algoritmo in Java</h3>
<pre class="brush: java">
package validatorecodicefiscale;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

public class ValidatoreCodiceFiscale {
    public void validaCF(String cf) throws CFException{
       /* espr. regolare per controllare la correttezza sintattica del CF */
       String regex = &quot;[a-zA-Z]{6}[0-9]{2}[a-zA-Z][0-9]{2}[a-zA-Z][0-9]{3}[a-zA-Z]&quot;;
       int somma = 0;

       /* Creazione dell&#039;HashMap che realizza l&#039;associazione chiave valore per
       i caratteri dispari */
       Map chrDispari = new HashMap();
       chrDispari.put(&quot;0&quot;, &quot;1&quot;);
       chrDispari.put(&quot;1&quot;, &quot;0&quot;);
       // ...
       chrDispari.put(&quot;Y&quot;, &quot;24&quot;);
       chrDispari.put(&quot;Z&quot;, &quot;23&quot;);

       /* HashMap che realizza l&#039;associazione chiave-valore per i caratteri
        pari all&#039;interno del codice fiscale. */
       Map chrPari = new HashMap();
       chrPari.put(&quot;0&quot;, &quot;0&quot;);
       chrPari.put(&quot;1&quot;, &quot;1&quot;);
       // ...
       chrPari.put(&quot;Y&quot;, &quot;24&quot;);
       chrPari.put(&quot;Z&quot;, &quot;25&quot;);

       /* HashMap che associa un valore numerico per ogni carattere che potrebbe
        essere presente come ultimo carattere del codice fiscale */
       Map chrControllo = new HashMap();
       chrControllo.put(&quot;0&quot;, &quot;A&quot;);
       chrControllo.put(&quot;1&quot;, &quot;B&quot;);
       // ...
       chrControllo.put(&quot;24&quot;, &quot;Y&quot;);
       chrControllo.put(&quot;25&quot;, &quot;Z&quot;);

       /* Effettua la somma di tutti i valori ricavati da ogni singolo carattere
        del CF. Se il carattere è pari, il valore è prelevato dall&#039;HashMap dei
        numeri pari, dispari altrimenti. */
       for(int i=0; i&lt;15; i++) {
           if (i % 2 == 1)
               {
                    somma += Integer.parseInt((String)
                            chrPari.get(Character.toString(cf.charAt(i))));
               }
           else
               {
                    somma += Integer.parseInt((String)
                            chrDispari.get(Character.toString(cf.charAt(i))));
               }
       }

       /* Calcolo l&#039;esatto carattere di controllo in base al codice fiscale
        fornito dall&#039;utente */
       String strControlloCalcolato = (String)chrControllo.get(&quot;&quot;+somma%26);
       Character chrControlloCalcolato = strControlloCalcolato.charAt(0);

       /* Ricavo il carattere di controllo fornito dall&#039;utente */
       Character chrControlloInserito = cf.charAt(15);

       if (!Pattern.matches(regex, cf) ||
           !chrControlloInserito.equals(chrControlloCalcolato)
          )
                throw new CFException();
    }
}
</pre>
<p style="text-align: justify;">Le tre HashMap sono state accorciate nel listato sopra per ovvi motivi di spazio, ma seguendo le giuste tabelle non sarà un problema ricrearle. Nel caso in cui il codice passato dall&#8217;utente sarà errato l&#8217;algoritmo solleverà un&#8217;eccezione definita come segue:</p>
<pre class="brush: java">
package validatorecodicefiscale;

public class CFException extends Exception {

    public CFException() {
        super(&quot;Errore: Il Codice Fiscale inseirto non è valido.&quot;);
    }
}
</pre>
<p style="text-align: justify;">La definizione dell&#8217;eccezione è volutamente semplice, in quanto il nostro scopo era quello di comprendere come poter controllare la validità del codice fiscale, non ci perderemo dunque in argomenti collaterali. Per chiunque volesse approfondire la conoscenza delle eccezioni consiglio di leggere questo link: <a target="_tab" href="http://www.claudiodesio.com/java/excs.htm">http://www.claudiodesio.com/java/excs.htm</a>. Una volta che abbiamo scritto l&#8217;algoritmo di controllo e definito l&#8217;eccezione che l&#8217;algoritmo potrebbe sollevare, l&#8217;unica cosa che ci resta da fare è implementarlo.</p>
<pre class="brush: java">
ValidatoreCodiceFiscale v = new ValidatoreCodiceFiscale();
        try {
            v.validaCF(&quot;CODICEFISCALE&quot;);
        } catch (CFException ex) {
            System.out.println(&quot;Errore di sintassi e/o di semantica.&quot;);
        }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://mariano.altervista.org/wordpress/2008/11/07/la-validazione-del-codice-fiscale/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Robocode: realizza il tuo robot personale (in Java)</title>
		<link>http://mariano.altervista.org/wordpress/2008/10/12/robocode-realizza-il-tuo-robot-personale-in-java/</link>
		<comments>http://mariano.altervista.org/wordpress/2008/10/12/robocode-realizza-il-tuo-robot-personale-in-java/#comments</comments>
		<pubDate>Sun, 12 Oct 2008 13:00:34 +0000</pubDate>
		<dc:creator>mariano</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Programmazione]]></category>

		<guid isPermaLink="false">http://mariano.altervista.org/wordpress/?p=173</guid>
		<description><![CDATA[Fonte: Geekisimo.com
Per un programmatore alle prime armi, volenteroso e con molta voglia di imparare c’è sempre l’ostacolo di “sì, ma che cosa programmo?”. Effettivamente seguendo le guide che vengono proposte sui libri del codice scelto, nelle prime 100 pagine viene proposto il classico “Hello World” e poco di più. Ma un geek non può mettersi [...]]]></description>
			<content:encoded><![CDATA[<p>Fonte: <a href="http://www.geekissimo.com/">Geekisimo.com</a></p>
<p align="justify">Per un programmatore alle prime armi, volenteroso e con molta voglia di imparare c’è sempre l’ostacolo di “sì, ma che cosa programmo?”. Effettivamente seguendo le guide che vengono proposte sui libri del codice scelto, nelle prime 100 pagine viene proposto il classico “Hello World” e poco di più. Ma un geek non può mettersi davanti ad un libro ed aspettare che la conoscenza piova dal cielo… un vero geek la conoscenza se la costruisce!<span id="more-173"></span></p>
<p align="justify">Per quelli che vogliono avvicinarsi al mondo Java c’è un “programma giochino” che permetterà di imparare divertendosi (soprattutto divertendosi anche dopo aver imparato): <a target="_tab" href="http://robocode.sourceforge.net/">Robocode</a>. Robocode venne proposto inizialmente dall’IBM (non so bene cosa se ne facesse l’IBM di una cosa simile, probabilmente era per il settore di ricerca IBM) e, nel tempo è stato proposto in diversi linguaggi (la prima sintassi del gioco che vidi era in C). Sostanzialmente, quello che un “giocatore” deve fare, <strong>è crearsi il proprio robottino</strong> (nella versione per java è più un carroarmato che non un robot) e buttarlo in un arena per farlo combattere contro altri. La progettazione del robottino corrisponde nient’altro che alla scrittura del codice che gli permetta di muoversi e di reagire agli eventi. Quindi è possibile per esempio, impostare una traiettoria inziale del robot, come può essere “avanti alla velocità x” e poi intercettare eventuali eventi al fine di cambiare il comportamento della propria creatura. Per esempio se scopro dove si trova il mio avvessario, posso fare in modo che il mio robottino si metta ad inseguirlo sparandogli, oppure, per evitare che sia lui a vincere lo farò inseguire a zig-zag o qualasiasi cosa possa venirvi in mente. Assicuro che il divertimento, anche per uno come me che il Java lo usa ormai da qualche anno, è assicurato… e la vittoria sui vostri amici non ha prezzo! </p>
<p align="justify">Le battaglie, soprattutto quelle che fate online, contro i robo-programmatori di tutto il mondo, si dividono in categorie. Il vostro robot potrà essere <strong>Megabots</strong> se non viene imposta nessuna restrizione alla dimensione del vostro file compilato (anche 10 Mbyte di robot va bene); <strong>Minibots</strong> impone una dimensione inferiore a 1500 bytes; <strong>Microbots</strong> dimensione inferiore a 750 bytes; <strong>Nanobots</strong> inferiore 250 bytes. E’ ovvio che più la dimensione del file deve essere ridotta, meno cose sarà possibile far fare al robot, o comunque qui si vedrà chi dei programmatori riesce ad ottimizzare al meglio il codice, facendo cioè fare molte cose in poche righe di codice. Chi si aggiudicherà la coppa di “miglior programmatore dell’anno” distruggendo tutti gli avversari/colleghi?</p>
<p>Per qualsiasi informazione, oltre al sito ufficiale di Robocode, vi rimando anche a questa <a target="_tab" href="http://en.wikipedia.org/wiki/Robocode">pagina su wikipedia</a> che contiene una serie di utili link per trovare risorse per giocare.</p>
<p>Finita la citazione dal post di geekissimo annuncio che ormai è quasi pronto un tutorial in cui sarannno spiegate le varie interfacce di Robocode e come creare il primo robot.</p>
]]></content:encoded>
			<wfw:commentRss>http://mariano.altervista.org/wordpress/2008/10/12/robocode-realizza-il-tuo-robot-personale-in-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java e il passaggio di parametri</title>
		<link>http://mariano.altervista.org/wordpress/2008/09/24/java-e-il-passaggio-di-parametri/</link>
		<comments>http://mariano.altervista.org/wordpress/2008/09/24/java-e-il-passaggio-di-parametri/#comments</comments>
		<pubDate>Wed, 24 Sep 2008 07:24:02 +0000</pubDate>
		<dc:creator>mariano</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Programmazione]]></category>

		<guid isPermaLink="false">http://mariano.altervista.org/wordpress/?p=140</guid>
		<description><![CDATA[Robustezza a parte, una delle qualità di Java, che viene più esaltata è la semplicità. Java è un linguaggio per programmatori creato da programmatori. Gli inventori, hanno cercato, dunque, di venirci incontro, sollevandoci dalla responsabilità di dover gestire fasi di sviluppo in cui è possibile causare errori o peggio ancora bug. Come sappiamo una delle [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Robustezza a parte, una delle qualità di Java, che viene più esaltata è la semplicità. Java è un linguaggio per programmatori creato da programmatori. Gli inventori, hanno cercato, dunque, di venirci incontro, sollevandoci dalla responsabilità di dover gestire fasi di sviluppo in cui è possibile causare errori o peggio ancora bug. Come sappiamo una delle responsabilità più grandi che un programmatore assolve durante la programmazione è la gestione della memoria: allocazione, ridimensionamento (di un array dinamico ad esempio), deallocazione e altro. Un&#8217;operazione come la deallocazione (compromettente se gestita male in un qualsiasi linguaggio), in Java è superflua grazie all&#8217;introduzione del garbage collector. Il garbage collector, tra le semplificazioni, è solo quella più palese, un&#8217;altra delle tante, meno evidente ai più, riguarda il passaggio dei parametri.<span id="more-140"></span></p>
<p style="text-align: justify;">Per passaggio di parametri si intende l&#8217;operazione tramite cui, durante la fase di definizione di una funzione/metodo associamo ad essa dei parametri formali. Al momento dell&#8217;esecuzione del metodo/funzione tali parametri non saranno più parametri formali ma parametri attuali. Il passaggio di parametri ad una funzione, in programmazione, può avvenire in due modi, per valore o per indirizzo. Supponiamo, in questo articolo, di voler realizzare una funzione che prenda in input due variabili e ne scambi il valore. Realizzeremo il tutto in C (dopo spiegherò anche perché C e non Java).</p>
<h3>Passaggio di parametri per valore</h3>
<p style="text-align: justify;">L&#8217;esempio che vogliamo realizzare, è molto semplice, e anche se fossimo dei programmatori alle prime armi non ci porterebbe via molto tempo. Creeremo dunque il nostro programma e all&#8217;interno definiremo una funzione chiamata <code>swap</code> che prende come parametri formali due variabili e ne scambia i valori.</p>
<pre class="brush: c">
#include &lt;stdio.h&gt;

void swap(int, int);

int main()
{
    int x = 2;
    int y = 4;
    printf(&quot;output: x=%d, y=%d\n&quot;, x, y); // output: x=2, y=4
    swap(x, y); // x e y sono parametri attuali di swap
    printf(&quot;output: x=%d, y=%d\n&quot;, x, y); // output: x=2, y=4
    return 0;
}

void swap(int a, int b) // a e b sono parametri formali di swap
{
   int tmp;
   tmp = a;
   a = b;
   b = tmp;
}
</pre>
<p style="text-align: justify;">Come tutti potrete vedere in questo caso le due chiamate alla funzione <code>printf</code> producono lo stesso output anche se tra le due abbiamo chiamato <code>swap</code>. Come è possibile? Un programmatore meno esperto potrebbe pensare che la causa del problema sia che in realtà la funzione <code>swap</code> è scritta male, ma non è questo il punto. I meno fiduciosi possono copiare il corpo della funzione <code>swap</code> ed incollarla tra le due chiamate a <code>printf</code>. Compilando e rieseguendo il programma la seconda <code>printf</code> dimostrerà che lo scambio c&#8217;è stato e che quindi la funzione <code>swap</code> era corretta. Cosa c&#8217;era allora che non andava? La risposta è intrinseca al meccanismo che i linguaggi di programmazione come il C usano nel passaggio dei parametri. In C, salvo nostre <em>&#8220;manipolazioni&#8221;</em>, i parametri vengono passati per valore, questo significa che al momento dell&#8217;esecuzione della funzione <code>swap</code> i parametri attuali vengono copiati e durante il ciclo di vita di <code>swap</code> saranno sempre e solo le copie ad essere modificate. Al termine di vita della funzione cesseranno di esistere anche le copie dei parametri attuali. La seconda <code>printf</code> confermerà che nulla è cambiato nelle nostre variabili.</p>
<h3>Passaggio di parametri per indirizzo (o per riferimento)</h3>
<p style="text-align: justify;">Un modo per evitare il problema precedente esiste e fa ricorso all&#8217;uso dei puntatori. Grazie ad essi possiamo <em>puntare</em> all&#8217;area di memoria (indirizzo) dove sono contenuti i valori delle variabili che vogliamo modificare. A questo punto quando inizierà il ciclo di vita della funzione <code>swap</code> non verranno modificate delle copie dei parametri attuali come avveniva prima, ma il valore contenuto in un indirizzo di memoria. Ecco perché questo passaggio di parametri vien detto <em>&#8220;passaggio per indirizzo&#8221;</em>. Il nostro programma dovrà essere quindi modificato per assecondare tale logica:</p>
<pre class="brush: c">
#include &lt;stdio.h&gt;

void swap(int *, int *);

int main()
{
    int x = 2;
    int y = 4;
    printf(&quot;output: x=%d, y=%d\n&quot;, x, y); // output: x=2, y=4
    swap(&amp;x, &amp;y); // x e y sono parametri attuali di swap e sono gli indirizzi di x e y
    printf(&quot;output: x=%d, y=%d\n&quot;, x, y); // output: x=4, y=2
    return 0;
}

void swap(int *a, int *b) // a e b sono parametri formali di swap di tipo puntatore a intero
{
   int tmp;
   tmp = *a;
   *a = *b;
   *b = tmp;
}
</pre>
<h3>E per quel che riguarda Java?</h3>
<p style="text-align: justify;">Per quel che riguarda Java come al solito c&#8217;è qualche mito da sfatare. Il più famoso è quello che sostiene che i tipi primitivi siano passati per valore e gli oggetti per indirizzo. Niente di più errato! E&#8217; corretto dire invece che <strong>in Java tutto è passato per valore</strong>. Infatti, per rendere il tutto quanto più semplice possibile non esiste il passaggio per riferimento (ecco perchè l&#8217;esempio è in C), così come confermato dallo stesso James Gosling, uno degli inventori di Java:</p>
<blockquote>
<p style="text-align: justify;">Some people will say incorrectly that objects are passed &#8220;by reference.&#8221; In programming language design, the term pass by reference properly means that when an argument is passed to a function, the invoked function gets a reference to the original value, not a copy of its value. If the function modifies its parameter, the value in the calling code will be changed because the argument and parameter use the same slot in memory&#8230;. The Java programming language does not pass objects by reference; it passes object references by value. Because two copies of the same reference refer to the same actual object, changes made through one reference variable are visible through the other. There is exactly one parameter passing mode &#8212; pass by value &#8212; and that helps keep things simple.</p>
<p><strong>James Gosling &#8211; The Java Programming Language, 4th Edition</strong> </p></blockquote>
<p style="text-align: justify;">Facendo 2+2, ne viene che l&#8217;unico modo che abbiamo per effettuare uno scambio di variabile in Java è quello di farlo senza usare metodi.</p>
]]></content:encoded>
			<wfw:commentRss>http://mariano.altervista.org/wordpress/2008/09/24/java-e-il-passaggio-di-parametri/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Groovy: Ruby per i programmatori Java</title>
		<link>http://mariano.altervista.org/wordpress/2008/09/18/groovy-ruby-per-i-programmatori-java/</link>
		<comments>http://mariano.altervista.org/wordpress/2008/09/18/groovy-ruby-per-i-programmatori-java/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 14:13:31 +0000</pubDate>
		<dc:creator>mariano</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Programmazione]]></category>

		<guid isPermaLink="false">http://mariano.altervista.org/wordpress/?p=117</guid>
		<description><![CDATA[Ieri, avevo pubblicato un post riguardo NetBeans e la beta della versione 6.5 in cui citavo le varie novità di questa versione, tra tutte queste una che meritava attenzione a mio modo di vedere era Groovy. Già lo hanno definito &#8220;Java 2.0&#8243;, ma cos&#8217;è pochi lo sanno. Cercherò in questo articolo di spiegare cosa sia [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Ieri, avevo pubblicato un post riguardo <a href="http://mariano.altervista.org/wordpress/2008/09/17/netbeans-65-e-quasi-alle-porte/">NetBeans e la beta della versione 6.5</a> in cui citavo le varie novità di questa versione, tra tutte queste una che meritava attenzione a mio modo di vedere era Groovy. Già lo hanno definito &#8220;Java 2.0&#8243;, ma cos&#8217;è pochi lo sanno. Cercherò in questo articolo di spiegare cosa sia Groovy, confrontandolo con Java e cercando gli aspetti positivi. Lo sviluppo iniziale di Groovy risale al lontano 2003, quando <a href="http://macstrac.blogspot.com/" target="_tab">James Strachan</a> gettò le basi del progetto con un post sul suo blog. Successivamente, nel 2004, diventò una Java Specification Request, con id 241, questo è il motivo per cui a volte viene menzionato come <a href="http://www.jcp.org/en/jsr/detail?id=241">JSR241</a>. La versione 1.0 è stata rilasciata il 2 Gennaio 2007. L&#8217;ultima versione stabile è la 1.5.6 rilasciata il 25 Aprile 2008. Ma cos&#8217;è Groovy?<span id="more-117"></span></p>
<p style="text-align: justify;">Groovy è un linguaggio di programmazione orientato agli oggetti nato con la pretesa di far avvicinare la robustezza di Java alla semplicità ed alla velocità di sviluppo dei linguaggi più moderni come Python, Ruby e i meno moderni Perl e SmallTalk. La particolarità è che stavolta non ci troviamo dinanzi all&#8217;ennesimo linguaggio di programmazione così come siamo abituati a considerare, bensì un linguaggio di programmazione per l&#8217;ambiente Java, ad esso alternativo e completamente interoperabile (o quasi). Possiamo includere codice Java in codice Groovy, di seguito entrambi verranno semi-compilati in bytecode per poi essere eseguito da qualsiasi JVM. Gli sviluppatori Groovy affermano che la curva di apprendimento per passare da Java a Groovy è prossima allo zero. Vediamo se è vero e vediamo se davvero lo sviluppo in Groovy è più agile. Quella che segue è una lista delle principali differenze, spero sia quanto più completa possibile, se mi è sfuggito qualcosa di interessante basta un commento:</p>
<h4>Import di default</h4>
<p style="text-align: justify;">A differenza di Java, vengono importate di default una serie di librerie che sono:</p>
<blockquote><p>java.io.*<br />
java.lang.*<br />
java.math.BigDecimal<br />
java.math.BigInteger<br />
java.net.*<br />
java.util.*<br />
groovy.lang.*<br />
groovy.util.*</p></blockquote>
<h4>Array</h4>
<p style="text-align: justify;">Sebbene la sintassi sia molto simile a Java, non useremo le parentesi graffe per dichiarare un array, bensì le quadre:</p>
<pre class="brush: java">
int[] a = {1,2,3};   // Sintassi Java
int[] a = [1,2,3];     // Sintassi Groovy
</pre>
<h4>Ciclo for</h4>
<p style="text-align: justify;">Il ciclo <em>for</em> non può essere scritto come siamo abituati a fare, ma abbiamo delle sintassi alternative:</p>
<pre class="brush: java">
// Sintassi Java
for (int i=0; i &lt; len; i++) {...}

// Alternative Groovy
for (i in 0..len-1) {...}
for (i in 0..&lt;len) {...}
len.times {...}
</pre>
<p style="text-align: justify;">Per ora, non so se sia una scelta voluta, o dovuta a problemi di sviluppo, nella testata del <em>for</em> può essere aggiunta una sola variabile di incremento.</p>
<h4>Liste</h4>
<p style="text-align: justify;">In Java una <code>list</code> è una collezione ordinata, come l&#8217;array ha un indice per ogni elemento ed ammette duplicati. Le principali implementazioni di <code>list</code> sono <code>ArrayList</code>, <code>Vector </code>e <code>LinkedList</code>. Qualsiasi implementazione vogliamo usare, in Java, va per l&#8217;appunto istanziata:</p>
<pre class="brush: java">
ArrayList list = new ArrayList(3);
list.add(5);
list.add(6);
list.add(7);
list.add(8);
</pre>
<p style="text-align: justify;">In Groovy non abbiamo bisogno di crearle con <code>new</code>:</p>
<pre class="brush: java">
def list = [5, 6, 7, 8]
</pre>
<h4>Supporto ai linguaggi di Markup</h4>
<pre class="brush: java">
import groovy.xml.MarkupBuilder
    def myXMLDoc = new MarkupBuilder()
    myXMLDoc.workbook {
       worksheet(caption:&quot;Employees&quot;) {
          row(fname:&quot;John&quot;, lname:&quot;McDoe&quot;)
          row(fname:&quot;Nancy&quot;, lname:&quot;Davolio&quot;)
       }
       worksheet(caption:&quot;Products&quot;) {
          row(name:&quot;Veeblefeetzer&quot;, id:&quot;sku34510&quot;)
          row(name:&quot;Prune Unit Zappa&quot;, id:&quot;sku3a550&quot;)
       }
    }
    println myXMLDoc
</pre>
<p style="text-align: justify;">produce in output:</p>
<pre class="brush: xml">
&lt;workbook&gt;
  &lt;worksheet caption=&#039;Employees&#039;&gt;
    &lt;row fname=&quot;John&quot; lname=&quot;McDoe&quot; /&gt;
    &lt;row fname=&quot;Nancy&quot; lname=&quot;Davolio&quot; /&gt;
  &lt;/worksheet&gt;
  &lt;worksheet caption=&#039;Products&#039;&gt;
    &lt;row name=&quot;Veeblefeetzer&quot; id=&quot;sku34510&quot; /&gt;
    &lt;row name=&quot;Prune Unit Zappa&quot; id=&quot;sku3a550&quot; /&gt;
  &lt;/worksheet&gt;
&lt;/workbook&gt;
</pre>
<p style="text-align: justify;">Se avessimo voluto farlo in Java:</p>
<pre class="brush: java">
import java.io.StringWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class XMLFun {

        public static void main(String[] args) throws Exception {
                TransformerFactory factory = TransformerFactory.newInstance();
                factory.setAttribute(&quot;indent-number&quot;, 2);
                Transformer trans = factory.newTransformer();
                trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, &quot;yes&quot;);
                trans.setOutputProperty(OutputKeys.INDENT, &quot;yes&quot;);

                DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
                DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
                Document doc = docBuilder.newDocument();
                Element workbook = doc.createElement(&quot;workbook&quot;);
                doc.appendChild(workbook);
                Element worksheet = doc.createElement(&quot;worksheet&quot;);
                worksheet.setAttribute(&quot;caption&quot;, &quot;Employees&quot;);
                workbook.appendChild(worksheet);
                Element row = doc.createElement(&quot;row&quot;);
                row.setAttribute(&quot;fname&quot;, &quot;John&quot;);
                row.setAttribute(&quot;lname&quot;, &quot;McDoe&quot;);
                worksheet.appendChild(row);
                row = doc.createElement(&quot;row&quot;);
                row.setAttribute(&quot;fname&quot;, &quot;Nancy&quot;);
                row.setAttribute(&quot;lname&quot;, &quot;Davolio&quot;);
                worksheet.appendChild(row);

                worksheet = doc.createElement(&quot;worksheet&quot;);
                worksheet.setAttribute(&quot;caption&quot;, &quot;Products&quot;);
                workbook.appendChild(worksheet);
                row = doc.createElement(&quot;row&quot;);
                row.setAttribute(&quot;name&quot;, &quot;Veeblefeetzer&quot;);
                row.setAttribute(&quot;id&quot;, &quot;sku34510&quot;);
                worksheet.appendChild(row);
                row = doc.createElement(&quot;row&quot;);
                row.setAttribute(&quot;name&quot;, &quot;Prune Unit Zappa&quot;);
                row.setAttribute(&quot;id&quot;, &quot;sku3a550&quot;);
                worksheet.appendChild(row);

                StringWriter writer = new StringWriter();
                StreamResult out = new StreamResult(writer);
                DOMSource dsource = new DOMSource(doc);
                trans.transform(dsource, out);
                System.out.println(writer.toString());
        }
}
</pre>
<p style="text-align: justify;">Altre differenze altrettanto importanti sono: la possibilità di non terminare le istruzioni con un punto e virgola, questo va fatto solo se scriviamo più istruzioni su una stessa riga; l&#8217;istruzione <code>return</code> non è obbligatoria; metodi e classi sono <code>public</code> di default; non c&#8217;è differenza tra eccezioni checked e unchecked; supporto nativo alle espressioni regolari; possibilità di tipizzazione statica o dinamica per variabili e metodi. Per maggiori informazioni consiglio di dare un&#8217;occhiata al sito ufficiale del progetto, <a href="http://groovy.codehaus.org/">http://groovy.codehaus.org/</a>, dove possiamo trovare preziose informazioni e documenti che ho usato per creare questo articolo. Detto questo non resta che mostrare il classico <em>&#8220;Hello World&#8221;</em>.</p>
<pre class="brush: java">
class Greet {
  def name
  Greet(who) { name = who[0].toUpperCase() + who[1..-1] }
  def salute() { println &quot;Hello $name!&quot; }
}

g = new Greet(&#039;world&#039;)  // create object
g.salute()               // Output &quot;Hello World!&quot;
</pre>
<p style="text-align: justify;">Sebbene le somiglianze con Java siano evidenti, è anche vero che per un programmatore esperto abituato con la sintassi Java è noiso per i primi tempi capire come scrivere il codice e magari fare continuamente riferimento alla documentazione per creare una classe, un metodo o un ciclo for. Nonostante tutto, penso che questo <em>&#8220;spreco&#8221;</em> di tempo iniziale sarà ben ripagato nel futuro. L&#8217;esempio del documento XML è quello più lampante di quanto può essere veloce programmare con Groovy.<br />
Intanto la comunità sta apprezzando il progetto, tant&#8217;è che a corredo sono nati anche vari framework, Grails è il primo che mi viene in mente. Non resta dunque che iniziare a provare&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://mariano.altervista.org/wordpress/2008/09/18/groovy-ruby-per-i-programmatori-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NetBeans 6.5 è (quasi) alle porte</title>
		<link>http://mariano.altervista.org/wordpress/2008/09/17/netbeans-65-e-quasi-alle-porte/</link>
		<comments>http://mariano.altervista.org/wordpress/2008/09/17/netbeans-65-e-quasi-alle-porte/#comments</comments>
		<pubDate>Wed, 17 Sep 2008 14:40:13 +0000</pubDate>
		<dc:creator>mariano</dc:creator>
				<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[Varie]]></category>

		<guid isPermaLink="false">http://mariano.altervista.org/wordpress/?p=119</guid>
		<description><![CDATA[Non mi dilungo molto su cosa sia NetBeans, ormai non ha bisogno di presentazioni. Basta sapere che è un IDE della Sun, gratuita e open-source, che ci permette di programamre con un&#8217;infinità di tecnologie, tra cui: Ajax, C/C++, Java EE, JavaFX, Java ME, Java SE, JavaScript, PHP, Ruby, WSDL, XML. Ho iniziato a provarlo a livello accademico qualche [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Non mi dilungo molto su cosa sia NetBeans, ormai non ha bisogno di presentazioni. Basta sapere che è un IDE della Sun, gratuita e open-source, che ci permette di programamre con un&#8217;infinità di tecnologie, tra cui: <a href="http://www.netbeans.org/features/web/ajax.html" target="_tab">Ajax</a>, <a href="http://www.netbeans.org/features/cpp/index.html" target="_tab">C/C++</a>, <a href="http://www.netbeans.org/features/web/java-ee.html" target="_tab">Java EE</a>, <a href="http://javafx.netbeans.org/" target="_tab">JavaFX</a>, <a href="http://www.netbeans.org/features/javame/index.html" target="_tab">Java ME</a>, <a href="http://www.netbeans.org/features/java/index.html" target="_tab">Java SE</a>, <a href="http://www.netbeans.org/features/web/web-app.html" target="_tab">JavaScript</a>, <a href="http://www.netbeans.org/features/web/web-app.html#php" target="_tab">PHP</a>, <a href="http://www.netbeans.org/features/ruby/index.html">Ruby</a>, <a href="http://www.netbeans.org/features/soa/index.html" target="_tab">WSDL</a>, <a href="http://www.netbeans.org/features/soa/index.html" target="_tab">XML</a>. Ho iniziato a provarlo a livello accademico qualche anno fa che era ancora alla versione 5 e devo ammettere che la successiva uscita della versione 6 mi aveva stupito per gli aggiornamenti corposi che c&#8217;erano. Ma era una major release, dopottutto ci era dovuto. Apprendo, sinceramente un po&#8217; in ritardo, da Geekissimo che è già disponibile la beta della 6.5 [ <a href="http://download.netbeans.org/netbeans/6.5/beta/" target="_blank">link</a> ] ed anche stavolta la lista delle innovazioni è sostanziale:<span id="more-119"></span></p>
<p><strong>PHP</strong></p>
<ul>
<li>Potente Editor PHP (Completamente del codice, controllo sintattico e semantico con evidenziazione del codice)</li>
<li>Supporto per la notazione <em>heredoc</em> e PHTML</li>
<li>Debugging con Xdebug</li>
<li>Generatore automatico di query per MySQL database</li>
</ul>
<p><strong>JavaScript e Ajax</strong></p>
<ul>
<li>Editor e debugger per JavaScript</li>
<li>Gestore di librerie JavaScript</li>
<li>Inclusione di alcuni dei principale framework ajax in circolazione: Yahoo UI, Woodstock, jQuery, Dojo, Scriptaculous, Prototype</li>
<li>Migliorato l’editor CSS</li>
</ul>
<p><strong>Java EE &amp; Sviluppo Web</strong></p>
<ul>
<li>Migliorato il supporto per Spring, Hibernate, JSF, JSF CRUD generator, JPA (Java Persistence API)</li>
<li>Creazione di webservices RESTful a partire da tabelle database o entità JPA</li>
<li>Drag and drop di servizi SaaS in file PHP</li>
<li>Migliorato l’editor SQL Editor: autocompletamento del codice, salvataggio query</li>
<li>Migliorata l’importazione e sincronizzazione di progetti Eclipse</li>
<li>Salvataggio e deploy delle applicazioni automatico</li>
</ul>
<p><strong>Groovy and Grails</strong></p>
<ul>
<li>Sviluppo di applicazioni in Groovy puro o inclusione di classi e script Groovy in progetti Java</li>
<li>Editor Groovy: autompletamento del codice, evidenziazione keywords</li>
<li>Support per applicazioni web Grails</li>
<li>Apertura e gestione di applicazioni Grails esistenti senza creazione di Metadati di progetto</li>
</ul>
<p><strong>Ruby e Rails</strong></p>
<ul>
<li>Nuova interfaccia per lanciare i test e mostrare i risultati</li>
<li>Miglioramenti Rake: Rake Runner e pre-generazione del file Rake</li>
<li>Debugger: Breakpoints condizionali e “Catchpoints”</li>
<li>Progetti Ruby accettano opzioini JVM da riga di comando</li>
</ul>
<p><strong>GlassFish v3</strong></p>
<ul>
<li>Modulare e basato su architettura OSGi</li>
<li>Velocizzata la procedura di avvio e quella di deploy delle applicazioni</li>
<li>Supporto per scripting</li>
</ul>
<p><strong>C/C++</strong></p>
<ul>
<li>Migliorato l’autocompletamento del codice, evidenziazione degli errori e delle keywords</li>
<li>Grafico delle chiamate e finestra della memoria usata/allocata</li>
<li>Sviluppo remoto</li>
<li>Pacchettizzazione delle applicazioni come tar, zip o SVR4</li>
</ul>
<p><strong>Java ME</strong></p>
<ul>
<li>Nuovo wizard che permette di aggiungere componenti personalizzati alla Palette</li>
<li>Nuovo componente SVG UI</li>
<li>Nuovo componente Data Binding personalizzato</li>
<li>Aggiornato il tool ProGuard alla versione 4.2 e il framework di test JMUnit alla versione 1.1.0</li>
</ul>
<p><strong>Java SE</strong></p>
<ul>
<li>possibilità di debuggare applicazioni Java Multi-thread</li>
<li>Java Swing GUI Builder: Editor TreeModel per JTrees</li>
<li>Autocompilazione e salvataggio</li>
<li>Migliorato il supporto per l’importazione e sincronizzazione di progetti Eclipse</li>
</ul>
<p>[Fonte: <a href="http://www.geekissimo.com" target="_blank">http://www.geekissimo.com</a>]</p>
]]></content:encoded>
			<wfw:commentRss>http://mariano.altervista.org/wordpress/2008/09/17/netbeans-65-e-quasi-alle-porte/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gestire la musica dal browser usando comandi testuali</title>
		<link>http://mariano.altervista.org/wordpress/2008/09/14/gestire-musica-da-browser-tramite-comandi-testuali/</link>
		<comments>http://mariano.altervista.org/wordpress/2008/09/14/gestire-musica-da-browser-tramite-comandi-testuali/#comments</comments>
		<pubDate>Sun, 14 Sep 2008 15:38:47 +0000</pubDate>
		<dc:creator>mariano</dc:creator>
				<category><![CDATA[Java-Script]]></category>
		<category><![CDATA[Programmazione]]></category>

		<guid isPermaLink="false">http://mariano.altervista.org/wordpress/?p=96</guid>
		<description><![CDATA[Aggiornamento 18 Novembre 2009: Questo articolo è stato pubblicato sul numero di Novembre/Dicembre della rivista DEV Magazine edita da Infomedia.

Se c&#8217;è qualcuno che non adora navigare per il web con un piacevole sottofondo musicale alzi la mano. Poche mani vedo. Beh, in effetti è un comfort da cui non vorremo mai separarci e quando lo [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>Aggiornamento 18 Novembre 2009:</strong> Questo articolo è stato pubblicato sul numero di Novembre/Dicembre della rivista DEV Magazine edita da Infomedia.<br />
</em></p>
<p style="text-align: justify;">Se c&#8217;è qualcuno che non adora navigare per il web con un piacevole sottofondo musicale alzi la mano. Poche mani vedo. Beh, in effetti è un comfort da cui non vorremo mai separarci e quando lo facciamo, a malincuore, è solo perché, magari, dobbiamo anche studiare quello che stiamo visualizzando a video. Assodato che non stiamo studiando e vogliamo solo ascoltare musica, la scocciatura maggiore è dover passare ogni volta che vogliamo cambiare canzone dal browser, al player e poi nuovamente al browser. Se non abbiamo una tastiera in grado di controllare i comandi del nostro player audio non abbiamo tante scelte e la noiosa operazione di passare da una finestra all&#8217;altra sembrerebbe inevitabile. Da un po&#8217; di tempo, però, abbiamo la possibilità di aggiungere i comandi di esecuzione <em>(play, pause, next &#8230;)</em> direttamente nella barra di stato del nostro browser, ma, ammesso che la barra di stato non sia nascosta, si tratta di centrare col puntatore del mouse dei bottoni non più larghi di 10 pixel. Scomodo, non trovate? Useremo queste, seppur irrisorie, scusanti per implementare un meccanismo che ci permetta di gestire il nostro player usando soltanto dei comandi testuali (evitando di conseguenza di utilizzare il mouse).<span id="more-96"></span></p>
<h3>FoxyTunes</h3>
<p style="text-align: justify;"><a href="http://www.foxytunes.com/" target="_blank">FoxyTunes</a> è un plugin che permette di controllare la nostra libreria musicale direttamente dal nostro browser preferito. E&#8217; disponibile sia per <a href="http://www.microsoft.com/windows/downloads/ie/getitnow.mspx" target="_blank">Internet Explorer</a> che per <a href="http://www.mozilla-europe.org/it/firefox/" target="_blank">Mozilla FireFox</a>. Per quest&#8217;ultimo l&#8217;installazione è semplicissima ed immediata e basta cliccare <a href="http://downloads.foxytunes.com/firefox/FoxyTunes_3.0.4.1.xpi" target="_blank">qui</a> per avviarla. Una volta comlpetata l&#8217;installazione, dobbiamo riavviare il browser, alla riapertura, potremo notare che nella barra di stato sono stati aggiunti i comandi per gestire il player (<a href="http://www.foxytunes.com/firefox/supportedPlayers.html" target="_blank">qui</a> troviamo una lista di tutti i player supportati). Abbiamo anche un tasto molto utile che ci condurrà a <a href="http://www.foxytunes.com/planet" target="_blank">FoxyTunes Planet</a>, un progetto FoxyTunes acquisito poi da <a href="http://it.yahoo.com/" target="_blank">Yahoo</a>. Cliccando sul tasto Planet nel nostro browser verremo portati ad una pagina dove otterremo informazioni riguardo la canzone, l&#8217;artista, l&#8217;album in cui è presente quella canzone, video e tanto, tanto altro. <a href="http://www.foxytunes.com/artist/the_clash#/track/rock_the_casbah" target="_blank">Questa</a> è la pagina che otterremmo se cliccassimo il tasto FoxyTunes Planet mentre ascoltiamo <em>Rock the Casbah</em> dei <em>Clash</em>. Durante la stesura di questo articolo è stata utilizziata la versione 3.0.4.1 su browser Mozilla FireFox versione 3.0.1.</p>
<p style="text-align: center;">
<div id="attachment_208" class="wp-caption aligncenter" style="width: 160px"><a href="http://mariano.altervista.org/wordpress/wp-content/uploads/2008/09/bottom.png"><img class="size-thumbnail wp-image-208" title="bottom" src="http://mariano.altervista.org/wordpress/wp-content/uploads/2008/09/bottom-150x50.png" alt="bottom" width="150" height="50" /></a><p class="wp-caption-text">La barra dei comandi di FoxyTunes.</p></div>
</p>
<h3>Ubiquity</h3>
<p style="text-align: justify;"><a href="http://azarask.in" target="_blank">Aza Raskin</a>, figlio del più noto <a href="http://it.wikipedia.org/wiki/Jef_Raskin" target="_blank">Jef Raskin</a>, non è soddisfatto di come al giorno d&#8217;oggi si condividono le informazioni nel web. Se qualcuno di noi volesse invitare un amico a pranzo in un ristorante, premurandosi di spiegare come raggiungere il locale allegando anche una recensione per tranquillizzarlo sulla qualità del cibo dovrebbe (nel proprio browser): aprire una tab per l&#8217;account mail, aprire una tab per cercare la mappa per le indicazioni, aprire una tab per trovare la recensione del ristorante e infine assemblare i link ottenuti nella stessa mail e inviarla. Abbastanza dispersivo, non ha tutti i torti. Per non parlare se ci trovassimo a compiere tale operazione su dispositivi palmari. Più naturale sarebbe spiegare in linguaggio <em>umano</em> quello che c&#8217;è da fare e lasciar compiere a qualcun&#8217;altro il lavoro noioso per noi. Questo qualcun&#8217;altro, potrebbe essere proprio <a href="http://labs.mozilla.com/projects/ubiquity/" target="_blank">Ubiquity</a> (<a href="https://people.mozilla.com/~avarma/ubiquity-0.1.1.xpi" target="_blank">installa estensione</a>). Supponiamo che, ad esempio, il ristorante si trovi a Roma, in Via dei Fori Imperiali 34. In gMail (o qualunque altra webMail con una Rich Text Area) creiamo una nuova mail, puntiamo il cursore nell&#8217;area dove va scritto il testo, a questo punto premiamo ALT+SPAZIO sulla tastiera, nella finestra che si aprirà scriveremo <code>map Rome Via dei fori imperiali 34</code> una nuova mappa apparirà, ci basterà cliccare <em>&#8220;Insert map in page&#8221;</em> ed il gioco è fatto. Quello che segue è un video dimostrativo, in inglese, realizzato dallo stesso Aza Raskin:</p>
<div style="text-align: center;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="298" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.vimeo.com/moogaloop.swf?clip_id=1561578&amp;server=www.vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed type="application/x-shockwave-flash" width="400" height="298" src="http://www.vimeo.com/moogaloop.swf?clip_id=1561578&amp;server=www.vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></div>
<h3>Sfruttiamo i due plugin</h3>
<p style="text-align: justify;">Ora che abbiamo accennato ai due strumenti principali è venuto il momento di spiegare come farli comunicare tra loro. L&#8217;idea di base è stata quella di creare un comando Ubiquity che accetti un parametro, l&#8217;esecuzione di tale comando, combinata al parametro, esegue una specifica funzione di FoxyTunes. I comandi vanno scritti in Javascript/JQuery rispettando le convenzioni stabilite da Ubiquity e sono molto semplici da realizzare. Il plugin Ubiquity ci fornisce una pagina molto utile, raggiungibile scrivendo nella barra degli indirizzi del browser <code>about:ubiquity</code>. Tramite questa pagina possiamo vedere varie informazioni, come la versione, verificare la presenza di aggiornamenti, cambiare la combinazione di accesso (ovvero l&#8217;ALT+INVIO citato prima), oppure, la cosa che a noi interessa di più, accedere all&#8217;editor dei comandi, dove finalmente possiamo iniziare la programmazione del comando.</p>
<pre class="brush: js">
// version: 0.1
// released: 13/09/2008
CmdUtils.CreateCommand({
name: &quot;foxy-tunes&quot;,
takes: {&quot;play|pause|stop|next|prev&quot;: noun_arb_text},
description: &quot;&quot;,
homepage: &quot;http://mariano.altervista.org/wordpress&quot;,
author: { name: &quot;Mariano Calandra&quot;, email: &quot;mariano.calandra@altervista.org&quot;},
help: &quot;foxy-tunes command must be followed from one of these actions: play, pause, stop, next, prev.&quot;,

preview: function( pblock, param ) {
if (param.text  == &quot;play&quot;)
pblock.innerHTML = &quot;Play song&quot;;
else if (param.text  == &quot;pause&quot;)
pblock.innerHTML = &quot;Pause song&quot;;
else if (param.text  == &quot;stop&quot;)
pblock.innerHTML = &quot;Stop music&quot;;
else if (param.text  == &quot;next&quot;)
pblock.innerHTML = &quot;Play the next song&quot;;
else if (param.text  == &quot;prev&quot;)
pblock.innerHTML = &quot;Play the previous song&quot;;
else
pblock.innerHTML = &quot;Uncorrect or empty action! Choice between: play, pause, stop, next, prev.&quot;;
},

execute: function(param) {
if (param.text  == &quot;play&quot;)
window.foxytunesDispatchPlayerCommand(&#039;Play&#039;, true);
else if (param.text  == &quot;pause&quot;)
window.foxytunesDispatchPlayerCommand(&#039;Pause&#039;)
else if (param.text  == &quot;stop&quot;)
window.foxytunesDispatchPlayerCommand(&#039;Stop&#039;)
else if (param.text  == &quot;next&quot;)
window.foxytunesDispatchPlayerCommand(&#039;Next&#039;, true)
else if (param.text  == &quot;prev&quot;)
window.foxytunesDispatchPlayerCommand(&#039;Previous&#039;, true)
else
displayMessage( &quot;Uncorrect or empty action! Choice between: play, pause, stop, next, prev.&quot;);
}
})
</pre>
<p style="text-align: justify;">Il nostro codice Ubiquity è stato racchiuso tra <code>CmdUtils.CreateCommand({ <em>codice</em> })</code>, per questo non ci sono molte spiegazioni in quanto è l&#8217;unico modo per creare comandi degni di esser chiamati tali. Segue una lista di attributi abbastanza autoesplicativi circa le informazioni da dare all&#8217;utente finale. Degne di attenzione sono invece la funzione di <code>preview</code> e di <code>execute</code>. La prima, <code>preview</code>, gestisce il comportamento che deve avere Ubiquity man mano che digitiamo i nostri comandi. La funzione accetta due parametri, <em>pblock</em> e <em>param</em>, il primo rappresenta la parte inferiore del nostro pannello dei comandi Ubiquity (ovvero la parte viola nella figura in basso), il secondo rappresenta quello che scriviamo dopo il comando (il nostro parametro). Se ad esempio scrivessi <code>foxy-tunes ciao</code> allora <em>param</em> varrebbe <em>ciao</em>. All&#8217;interno della funzione <code>preview</code> una serie di if controllano i parametri che vengono inseriti, se il parametro esiste spiega in <em>pblock</em> cosa fa quel comando, altrimenti, mostra l&#8217;errore e comunica quali sono i parametri accettati. Chi è abituato alla programmazione web dinamica non può non aver notato la presenza del metodo <code>innerHTML</code> associato all&#8217;elemento <em>pblock</em>, chi non conosce questo metodo trova una breve spiegazione <a href="http://developer.mozilla.org/en/DOM/element.innerHTML" target="_blank">qui</a>.</p>
<div id="attachment_207" class="wp-caption aligncenter" style="width: 310px"><a href="http://mariano.altervista.org/wordpress/wp-content/uploads/2008/09/up.png"><img class="size-medium wp-image-207" title="up" src="http://mariano.altervista.org/wordpress/wp-content/uploads/2008/09/up-300x150.png" alt="up" width="300" height="150" /></a><p class="wp-caption-text">Il prompt dei comandi</p></div>
<p style="text-align: center;">
<p style="text-align: justify;"><strong>Premessa:</strong> <em>Ubiquity è un progetto sperimentale e nei prossimi tempi potrebbe subire migliorie sostanziali che comporteranno notevoli cambiamenti, il listato di codice precedente è etichettato con versione e data, in modo da render noti quanto più possibile i cambiamenti.</em>La funzione <strong><code>execute</code></strong> invece si occupa di gestire il comportamento del comando immediatamente dopo la pressione del tasto Invio. Prende in ingresso un parametro, <em>param</em>, che rappresenta il parametro passato al comando al momento dell&#8217;invio. Una serie di if controllano il parametro fornito, se il parametro è corretto allora viene eseguita la relativa funzione del plugin foxy-tunes. Ad esempio, se il parametro è <em>play</em>, verrà eseguita la funzione <code>foxytunesDispatchPlayerCommand('Play', true)</code>. Se viene inviato un parametro non corretto, una popup avvertirà la non correttezza del parametro. Gli utenti Windows visualizzeranno tale avviso vicino l&#8217;orologio, in Mac OS X bisogna installare il gestore di richieste <a href="http://growl.info/" target="_blank">Growl</a>.</p>
<h3>Rendilo disponibile a tutti</h3>
<p style="text-align: justify;">Ora che il nostro comando è funzionante e (si spera) funzionale possiamo pensare di condividerlo con tutto il resto del mondo, e permettere di installarlo senza troppe complicazioni. La prima cosa da fare è salvare il comando in un file Javascript, <em>mioComando.js</em> per esempio. Bisognerà creare poi una pagina HTML e tra i tag head aggiungeremo:</p>
<blockquote><p><code>&lt;link rel="commands" href="http://percorso" name="Titolo" /&gt;</code></p></blockquote>
<p style="text-align: justify;">L&#8217;attributo <code>rel</code> non va modificato. Quando un utente con Ubiquity visualizzerà questa pagina gli verrà chiesto se vuole effettuare la sottoscrizione del comando. Se l&#8217;utente accetta, il comando farà parte della sua lista comandi Ubiquity. Non mi resta quindi che augurarvi buon divertimento e segnalarvi la <a href="https://wiki.mozilla.org/Labs/Ubiquity/Ubiquity_0.1_Author_Tutorial" target="_blank">wiki</a> di Ubiquity.</p>
]]></content:encoded>
			<wfw:commentRss>http://mariano.altervista.org/wordpress/2008/09/14/gestire-musica-da-browser-tramite-comandi-testuali/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Forse cercavi: distanza di Levenshtein</title>
		<link>http://mariano.altervista.org/wordpress/2008/09/11/forse-cercavi-distanza-di-levenshtein/</link>
		<comments>http://mariano.altervista.org/wordpress/2008/09/11/forse-cercavi-distanza-di-levenshtein/#comments</comments>
		<pubDate>Thu, 11 Sep 2008 10:54:56 +0000</pubDate>
		<dc:creator>mariano</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Programmazione]]></category>

		<guid isPermaLink="false">http://mariano.altervista.org/wordpress/?p=37</guid>
		<description><![CDATA[Aggiornamento 14 Ottobre 2009: Questo artciolo è stato pubblicato sul numero di Settembre/Ottobre della rivista DEV Magazine edita da Infomedia.
Spesso capita di digitare in maniera errata una chiave di ricerca e  vedersela correggere non appena clicchiamo il tasto &#8216;Invio&#8217;. Cosa succede? Come può un computer, nella maggior parte dei casi, capire cosa volevamo veramente [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><em><strong>Aggiornamento 14 Ottobre 2009:</strong> Questo artciolo è stato pubblicato sul numero di Settembre/Ottobre della rivista DEV Magazine edita da Infomedia.</em></p>
<p style="text-align: justify;">Spesso capita di digitare in maniera errata una chiave di ricerca e  vedersela correggere non appena clicchiamo il tasto &#8216;Invio&#8217;. Cosa succede? Come può un computer, nella maggior parte dei casi, capire cosa volevamo veramente scrivere? La risposta, abbastanza diretta, è: distanza di Levenshtein (o se lo trovate troppo complicato da pronunciare/scrivere, distanza di edit). Considerate due stringhe <em>sorgente</em> e <em>destinazione</em>, la distanza di Levenshtein è il numero di operazioni elementari necessarie per trasformare la stringa <em>sorgente</em> in quella di <em>destinazione</em>. Essa definisce tre operazioni elementari: <em>i) la cancellazione di un carattere; ii) la sostituzione di un carattere; iii) l&#8217;inserimento di un nuovo carattere</em>. Due stringhe uguali hanno distanza di Levenshtein pari a 0.<span id="more-37"></span></p>
<h3>L&#8217;algoritmo</h3>
<p style="text-align: justify;">Considerando <em>s</em> come la lunghezza della stringa <em>sorgente</em> e <em>d</em> come la lunghezza della stringa <em>destinazione </em>implementeremo un algoritmo che faccia uso di una matrice <em>(s + 1) * (d + 1)</em>. In colonna scriveremo la stringa sorgente, come riga inseriremo invece la stringa di destinazione. In ogni cella della matrice è rappresentata la distanza che intercorre tra una porzione di stringa sorgente e una porzione di stringa destinazione. Nell&#8217;angolo in basso a destra le porzioni di stringa sono complete, quindi, il valore che vi è rappresentato è l&#8217;effettiva distanza tra la stringa sorgente e quella di destinazione. Un esempio: supponiamo che io voglia conoscere la distanza tra il mio vero nome <em>mariano</em> e una stringa ottenuta per errata digitazione, supponiamo <em>marinao</em> (errore comune).</p>
<div>
<table border="0">
<tbody>
<tr style="border: 1px dashed black;">
<td style="text-align: center;" width="20"></td>
<td style="text-align: center;" width="20"></td>
<td style="text-align: center;" width="20"><strong>m</strong></td>
<td style="text-align: center;" width="20"><strong>a</strong></td>
<td style="text-align: center;" width="20"><strong>r</strong></td>
<td style="text-align: center;" width="20"><strong>i</strong></td>
<td style="text-align: center;" width="20"><strong>a</strong></td>
<td style="text-align: center;" width="20"><strong>n</strong></td>
<td style="text-align: center;" width="20"><strong>o</strong></td>
</tr>
<tr>
<td style="text-align: center;"></td>
<td style="text-align: center;"><span style="border-bottom:1px dotted" title="sorgente e destinazione sono entrambe vuote">0</span></td>
<td style="text-align: center;"><span style="border-bottom:1px dotted" title="la stringa vuota diventa 'm' con un'operazione di aggiunta">1</span></td>
<td style="text-align: center;"><span style="border-bottom:1px dotted" title="la stringa vuota diventa 'ma' con 2 operazioni di aggiunta">2</span></td>
<td style="text-align: center;"><span style="border-bottom:1px dotted" title="la stringa vuota diventa 'mar' con 3 operazioni di aggiunta">3</span></td>
<td style="text-align: center;"><span style="border-bottom:1px dotted" title="la stringa vuota diventa 'mari' con 4 operazioni di aggiunta">4</span></td>
<td style="text-align: center;"><span style="border-bottom:1px dotted" title="la stringa vuota diventa 'maria' con 5 operazioni di aggiunta">5</span></td>
<td style="text-align: center;"><span style="border-bottom:1px dotted" title="la stringa vuota diventa 'marian' con 6 operazioni di aggiunta">6</span></td>
<td style="text-align: center;"><span style="border-bottom:1px dotted" title="la stringa vuota diventa 'mariano' con 7 operazioni di aggiunta">7</span></td>
</tr>
<tr>
<td style="text-align: center;"><strong>m</strong></td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">2</td>
<td style="text-align: center;">3</td>
<td style="text-align: center;">4</td>
<td style="text-align: center;">5</td>
<td style="text-align: center;">6</td>
</tr>
<tr>
<td style="text-align: center;"><strong>a</strong></td>
<td style="text-align: center;">2</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">2</td>
<td style="text-align: center;">3</td>
<td style="text-align: center;">4</td>
<td style="text-align: center;">5</td>
</tr>
<tr>
<td style="text-align: center;"><strong>r</strong></td>
<td style="text-align: center;">3</td>
<td style="text-align: center;">2</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">2</td>
<td style="text-align: center;">3</td>
<td style="text-align: center;">4</td>
</tr>
<tr>
<td style="text-align: center;"><strong>i</strong></td>
<td style="text-align: center;">4</td>
<td style="text-align: center;">3</td>
<td style="text-align: center;">2</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">2</td>
<td style="text-align: center;">3</td>
</tr>
<tr>
<td style="text-align: center;"><strong>n</strong></td>
<td style="text-align: center;">5</td>
<td style="text-align: center;">4</td>
<td style="text-align: center;">3</td>
<td style="text-align: center;">2</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">2</td>
</tr>
<tr>
<td style="text-align: center;"><strong>a</strong></td>
<td style="text-align: center;">6</td>
<td style="text-align: center;">5</td>
<td style="text-align: center;">4</td>
<td style="text-align: center;">3</td>
<td style="text-align: center;">2</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">2</td>
<td style="text-align: center;">2</td>
</tr>
<tr>
<td style="text-align: center;"><strong>o</strong></td>
<td style="text-align: center;">7</td>
<td style="text-align: center;">6</td>
<td style="text-align: center;">5</td>
<td style="text-align: center;">4</td>
<td style="text-align: center;">3</td>
<td style="text-align: center;">2</td>
<td style="text-align: center;">2</td>
<td style="text-align: center;">2</td>
</tr>
</tbody>
</table>
</div>
<p style="text-align: justify;">La matrice sopra rappresenta il calcolo che svolge l&#8217;algoritmo per arrivare al risultato finale, ossia la distanza contenuta nella cella in basso a destra, tutte le altre celle sono intermedie. Per alcune celle, (quelle tratteggiate in basso), è stata aggiunta una breve spiegazione su come è stata calcolata la distanza, basterà tenere il puntatore fermo per qualche secondo e leggerne l&#8217;etichetta. In <a href="http://www-igm.univ-mlv.fr/~lecroq/seqcomp/node2.html" target="_blank">questa</a> pagina c&#8217;è un&#8217;applet Java che prende in ingresso una stringa di destinazione e una di origine e ci mostra la matrice, risultante da provare.  Ovviamente quest&#8217;algoritmo si trova in numerose versioni, sia per quello che riguarda il linguaggio in cui è stato sviluppato sia per il modo in cui è stato sviluppato. Il seguente algoritmo, infatti, non è il più efficiente nel calcolo della distanza di Levenshtein ma in compenso ci permette di avere un codice più autoesplicativo. Per coloro che sviluppano in <a href="http://it.php.net" target="_blank">PHP</a> la funzione per il calcolo della distanza è una built-in del linguaggio [<a href="http://it.php.net/levenshtein" target="_blank">link</a>]. La versione di questo articolo è in linguaggio Java.</p>
<pre class="brush: java">
public class Distance {
/** Questo metodo calcola il minimo tra tre numeri interi*/
private int getMinimo(int a, int b, int c) {
int min;

// imposto il minimo uguale ad a
min = a;
// se il parametro b è minore del minimo
if (b &lt; min) {
// il nuovo minimo sarà il parametro b
min = b;
}

// se il parametro c è minore del minimo
if (c &lt; min) {
// il nuovo minimo sarà il parametro c
min = c;
}
// ritorno il minimo (min)
return min;
}

/** Funzione per il calcolo effettivo della distanza di Levenshtein*/
private int getDistanza(String s, String t) {
int d[][];     // matrice
int n;         // lunghezza di s
int m;         // lunghezza di t
int i;         // iterazioni su s
int j;         // iterazioni su t
char s_i;      // i-esimo carattere di s
char t_j;      // j-esimo carattere di t
int costo;

n = s.length(); // n conterrà il num di caratteri di s
m = t.length(); // m conterrà il num di caratteri di t
// se la stringa sorgente è vuota
if (n == 0) {
// la distanza è il num di chr della dest.
return m;
}
// se la stringa destinazione è vuota
if (m == 0) {
// la distanza è il num di chr della sorg.
return n;
}
// creo la matrice (n+1)*(m+1)
d = new int[n + 1][m + 1];

// la prima riga della mat. conterrà le distanze da 0 a n
// la distanza 1 è associata al primo chr della stringa, 0 al vuoto
// Nel caso del nostro esempio:
// 0 1 2 3 4 5 6 7
// - M A R I A N O
for (i = 0; i &lt;= n; i++) {
d[i][0] = i;
}

// la prima colonna della mat. conterrà le distanze da 0 a m
// la distanza 1 è associato al primo chr della stringa, 0 al vuoto
// Nel caso del nostro esempio:
// - 0
// M 1
// A 2
// R 3
// I 4
// N 5
// A 6
// O 7
for (j = 0; j &lt;= m; j++) {
d[0][j] = j;
}

// esamino ogni carattere di s (i da 1 a n)
for (i = 1; i &lt;= n; i++) {
s_i = s.charAt(i - 1);

// Esamino ogni carattere di t (j da 1 a m)
for (j = 1; j &lt;= m; j++) {
t_j = t.charAt(j - 1);

// Se l&#039;i-esimo elemento di s
// è uguale al j-esimo elemento di t
if (s_i == t_j) {
// il costo è 0
costo = 0;
} else { // altrimenti
// il costo è 1
costo = 1;
}

// imposto la cella d[i][j] scegliendo il valore minimo tra:
//   - la cella immediatamente superiore + 1
//   - la cella immediatamente a sinistra + 1
//   - la cella diagonalmente in alto a sinistra più il costo
d[i][j] = getMinimo(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + costo);
}
}

// una volta completate tutte le iterazioni la cella
// d[n][m] contiene la distanza finale tra la stringa
// sorgente e quella di destianzione
return d[n][m];
}
}
</pre>
<p style="text-align: justify;">Eseguendo come da esempio il metodo <code>getDistanza()</code> e passando come parametri le stringhe <em>mariano</em> e <em>marinao</em> avremo come risultato la distanza di Levenshtein tra le due stringhe, ossia: 2. Il lettore più ansioso di arrivare alla soluzione si starà chiedendo cosa farsene di questo numero, d&#8217;altronde Google (ad esempio) accetta una stringa e se questa non esiste tenta di fornire la stringa corretta, fin qui invece la nostra funzione necessita come argomenti sia della stringa corretta che di quella errata. Che senso ha? Bene! Il solito lettore ansioso sappia di non aver perso tempo fino ad ora. Siamo infatti arrivati solo a metà dell&#8217;articolo.</p>
<h3>Come sfruttare la distanza</h3>
<p style="text-align: justify;">Ora che abbiamo un metodo in grado di fornirci la distanza tra due stringhe possiamo passare alla parte più interessante, ovvero, come &#8220;indovinare&#8221; la parola che avrebbe voluto scrivere in realtà l&#8217;utente. L&#8217;idea di base è concettualmente molto semplice, restringiamo il campo alla ricerca in un array in modo da non essere troppo dispersivi. Vogliamo verificare se nell&#8217;array <code>dizionario</code> è presente la parola <code>x</code>. Se tale parola non è presente allora si cerca in <code>dizionario</code> qual&#8217;è la parola che più somiglia alla parola <code>x</code>, ovvero, <strong>quella con la minore distanza di Levenshtein</strong> rispetto a <code>x</code>. In pratica calcoleremo la distanza di Levenshtein tra <code>x</code> ed ogni parola di <code>dizionario</code>, la parola con distanza minore potrebbe essere quella che l&#8217;utente cercava. La classe precedente sarà quindi completata con l&#8217;aggiunta di un nuovo metodo.</p>
<pre class="brush: java">
/** Calcolo una parola alt alternativa alla parola input s*/
public String getAlternativa(String s, String d[]) {
int i,             // iteratore ciclo for
min = 100;     // iniziallizzo il minimo a 100
int rit;           // distanza di hamming
String alt = &quot;&quot;;   // stringa da ritornare

// per ogni elemento dell&#039;array d
for (i = 0; i &lt; d.length; i++) {
// calcolo della distanza tra s e l&#039;i-esimo elemento d
rit = getDistanza(s, d[i]);
// se la distanza è minore del minimo
if (rit &lt; min) {
// la distanza rit sarà il nuovo minimo
min = rit;
// e l&#039;i-esimo elemento di d sarà l&#039;alternativa
alt = d[i];
}
}
// ritorno l&#039;alternativa
return alt;
}
</pre>
<p style="text-align: justify;">Ora abbiamo la nostra classe <code>Distance</code> che ci fornisce tutti i mezzi per realizzare il nostro scopo, basterà creare un&#8217;istanza di tale classe quando serve per poter trovare un alternativa valida ad una parola digitata in maniera errata. L&#8217;approccio scelto utilizza un dizionario di parole al cui interno sono memorizzate le parole esatte. Ovviamente quanto più è grande il dizionario maggiore sarà la precisione con cui l&#8217;algoritmo &#8220;indovinerà&#8221; la parola esatta e di conseguenza maggiore sarà il carico. che la macchina dovrà sopportare Questo che segue è l&#8217;esempio di una classe che implementa la distanza di Levenshtein per trovare la giusta alternativa alla parola <em>marinao</em>, avendo un dizionario limitato a solo 3 parole:</p>
<pre class="brush: java">
public class Main {
public static void main(String[] args) {
String parole[];

parole = new String[3];
parole[0] = &quot;mariano&quot;;
parole[1] = &quot;marziano&quot;;
parole[2] = &quot;martino&quot;;

Distance d = new Distance();
System.out.println(&quot;Forse cercavi: &quot;+d.getAlternativa(&quot;marinao&quot;, parole));
// Forse cercavi: mariano
}
}</pre>
<h3>Limiti matematici</h3>
<p style="text-align: justify;">L&#8217;algoritmo per la distanza di Levenshtein è caratterizzato da dei limiti strettamente matematici e sono i seguenti:</p>
<ul>
<li>il limite superiore è pari alla lunghezza della stringa più lunga;</li>
<li>il limite inferiore è pari alla differenza fra le lunghezze delle due stringhe;</li>
<li>se le stringhe sono identiche la distanza è 0 (e la distanza di Levenshtein non supera la <a href="http://it.wikipedia.org/wiki/Distanza_di_Hamming" target="_blank">distanza di Hamming</a>)</li>
</ul>
<h3>Conclusioni</h3>
<p style="text-align: justify;">Sebbene funzionale, tale algoritmo, se usato con grandi moli di dati mostrerebbe subito i suoi limiti.  <em>E&#8217; possibile ridurre l&#8217;occupazione di memoria del precendente algoritmo osservando che ad ogni passo dell&#8217;iterazione è sufficiente mantenere due righe della matrice, quella corrente e qualle precedente. Usando questo accorgimento è possibile ridurre l&#8217;occupazione di memoria da O(mn) a O(m). </em>Inoltre potrebbe essere interessante relegare al database il calcolo della distanza, visto che sarebbe molto più conveniente mantenere il nostro <em>dizionario</em> di parole direttamente in una base di dati, insomma, ci sono ancora sperimentazioni da fare. C&#8217;è da ricordare che l&#8217;algoritmo è case-sensitive per cui la stringa <em>&#8220;Mariano&#8221;</em> è diversa da <em>&#8220;mariano&#8221;</em>, quindi prima di un confronto sarebbe opportuno portare le stringhe completamente <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#toUpperCase()" target="_blank">toUpperCase()</a> o <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#toLowerCase()">toLowerCase()</a>. Un buon tool di supporto per comprendere bene come funziona il calcolo della distanza di Levenshtein lo trovate <a href="http://www-igm.univ-mlv.fr/~lecroq/seqcomp/node2.html">qui</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://mariano.altervista.org/wordpress/2008/09/11/forse-cercavi-distanza-di-levenshtein/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Accesso a un membro non-statico da un metodo statico</title>
		<link>http://mariano.altervista.org/wordpress/2008/08/24/accesso-a-un-membro-non-statico-da-un-metodo-statico/</link>
		<comments>http://mariano.altervista.org/wordpress/2008/08/24/accesso-a-un-membro-non-statico-da-un-metodo-statico/#comments</comments>
		<pubDate>Sun, 24 Aug 2008 22:39:36 +0000</pubDate>
		<dc:creator>mariano</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Programmazione]]></category>

		<guid isPermaLink="false">http://mariano.altervista.org/wordpress/?p=52</guid>
		<description><![CDATA[Non si scappa! Tanto un programmatore esperto che conosce Java come le sue tasche, tanto un programmatore alle prime armi commettono degli errori mentre programmano. Le cause possono essere varie e anche il tipo di errori, ma alcuni sono più frequenti degli altri. Questo che considereremo in questo post è molto frequente ed è un [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Non si scappa! Tanto un programmatore esperto che conosce Java come le sue tasche, tanto un programmatore alle prime armi commettono degli errori mentre programmano. Le cause possono essere varie e anche il tipo di errori, ma alcuni sono più frequenti degli altri. Questo che considereremo in questo post è molto frequente ed è un errore molto più comune nei programmatori Java alle prime armi. Il metodo main infatti è dichiarato static questo significa che non serve creare un&#8217;istanza di quella classe per invocare il metodo (ed è giusto che sia così, in quanto sarà il primo metodo che verrà invocato). <span id="more-52"></span>Si consideri questo codice:</p>
<pre class="brush: java">
public class StaticDemo
{
   // Questo è un membro non-static
   public String non_static = &quot;pippo&quot;;

   // Questo è un metodo static
   public static void main (String args[])
   {
      /* Qui provo a leggere il valore di una variabile
      non-static da un metodo static (main) */
      System.out.println (&quot;Valore:&quot; + non_static );
   }
}
</pre>
<p style="text-align: justify;">Errore di compilazione! In questo caso, infatti, sto cercando di accedere ad un membro non-static (come l&#8217;attributo non_static) della classe da un metodo static (come il main), per risolvere devo creare un&#8217;istanza della classe. Ecco come fare:</p>
<pre class="brush: java">
public class StaticDemo
{
   // Questo è un membro non-static
   public String non_static = &quot;pippo&quot;;

   // Questo è un metodo static
   public static void main (String args[])
   {
      // Qui creo un&#039;istanza della classe
      StaticDemo demo = new StaticDemo();

      /* Ora grazie alla notazione dotted posso accedere
      alla variabile non statica */
      System.out.println (&quot;Valore:&quot; + demo.non_static );
   }
}</pre>
<p style="text-align: justify;">Tutto qui! Sebbene molto frequente quest&#8217;errore non è insidioso in quanto viene immediatamente rilevato in fase di compilazione:</p>
<blockquote><p>non-static variable [identificativo] cannot be referenced from a static context</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://mariano.altervista.org/wordpress/2008/08/24/accesso-a-un-membro-non-statico-da-un-metodo-statico/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
