<?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>Flying memes &#187; Librerie</title>
	<atom:link href="http://sandropaganotti.com/categoria/librerie/feed/" rel="self" type="application/rss+xml" />
	<link>http://sandropaganotti.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Sun, 08 Jan 2012 16:00:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Ruby Spell Doctor: a Ruby binding to Hunspell</title>
		<link>http://sandropaganotti.com/2010/11/25/ruby-spell-doctor-a-ruby-binding-to-hunspell/</link>
		<comments>http://sandropaganotti.com/2010/11/25/ruby-spell-doctor-a-ruby-binding-to-hunspell/#comments</comments>
		<pubDate>Thu, 25 Nov 2010 22:02:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Librerie]]></category>
		<category><![CDATA[Hunspell]]></category>
		<category><![CDATA[Ruby Mendicant University]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=456</guid>
		<description><![CDATA[The idea behind this project was in my head since a while. Then thanks to Gregory Brown and his Ruby Mendicant University, I had the opportunity and the incentive to start developing it. Ruby Spell Doctor bind some of the most useful Hunspell functions making them available to Ruby developers. For who don&#8217;t know, Hunspell is [...]]]></description>
			<content:encoded><![CDATA[<p>The idea behind this project was in my head since a while. Then thanks to <a title="Ruby Mendicant University Homepage" href="http://university.rubymendicant.com/" target="_blank">Gregory Brown and his Ruby Mendicant University</a>, I had the opportunity and the incentive to start developing it. Ruby Spell Doctor bind some of the most useful Hunspell functions making them available to Ruby developers. For who don&#8217;t know, <a title="Hunspell homepage" href="http://hunspell.sourceforge.net/" target="_blank">Hunspell</a> is a widely used open source syntax checker library that is implemented in a lot of softwares, such as OpenOffice, Google Chrome and Mac OSX.</p>
<p><span id="more-456"></span></p>
<p>To archive this result I used <a href="https://github.com/ffi/ffi" target="_blank">FFI</a>: the Ruby snippet used to map the native C function look like this:</p>
<pre><code class="ruby">module Hunspell
  module Wrapper
    extend FFI::Library
    ffi_lib(LIBRARY_PATH)
    attach_function :create,  :Hunspell_create, [:string,  :string], :pointer
    attach_function :spell,   :Hunspell_spell,  [:pointer, :string], :int
    attach_function :suggest, :Hunspell_suggest,[:pointer, :pointer, :string], :int;
  end
end</code></pre>
<p>where LIBRARY_PATH is the path to the compiled hunspell library.</p>
<p>Then the next step was to create a Hunspell class which wraps this module creating a nice ruby-sh interface to the library:</p>
<pre><code class="ruby">module Hunspell
  class Hunspell

    # initialize the class and the anonymus module acting as a wrapper to
    # hunspell
    def initialize(config_obj = nil)
      @dicts = bootstrap(config_obj || CONFIGURATION)
      respawn_handler('default')
    end

    def respawn_handler(dictionary)
      # create the hunspell library object
      @hunspell = FFI::MemoryPointer.new :pointer
      @hunspell = Wrapper.create(
        @dicts[dictionary]['aff'],@dicts[dictionary]['dic']
      )
    end

    # returns true if words is not correct, false otherwise
    def spelled_correctly?(word)
      Wrapper.spell(@hunspell,word) != 0
    end

    # returns an array with suggested words of a given word ([] if no
    # suggestions)
    def suggest(word)
      suggestions = FFI::MemoryPointer.new :pointer, 1
      suggestions_number = Wrapper.suggest(@hunspell,suggestions, word)
      suggestion_pointer = suggestions.read_pointer
      if (suggestion_pointer.null?)
        []
      else
        suggestion_pointer.get_array_of_string(0,suggestions_number).compact
      end
    end

    private

    # get lib directory and default dictionary path
    def bootstrap(config_obj)
      if config_obj.nil?
        raise BootstrapError.new("No configuration info supplied to Hunspell" +
            "constructor and no default configuration file available")
      end
      return config_obj['dictionaries'].merge({
          'default' =&gt; config_obj['dictionaries'][
                          config_obj['dictionaries']['default']]
      })
    end

  end
end
</code></pre>
<p>Well, it&#8217;s almost all here, except for some configuration details that let you choose which language dictionary files to load. The path of these files (a pair of .dic and .aff) can be specified in a .yml file and then sent to the constructor method in a way like this:</p>
<p><strong>YAML (config.yml)</strong></p>
<pre><code class="ruby">dictionaries:
  default: en
  en:
    aff: '/Users/sandropaganotti/RMU/hunspell/hunspell_en_dict/en_US.aff'
    dic: '/Users/sandropaganotti/RMU/hunspell/hunspell_en_dict/en_US.dic'
  it:
    aff: '/Users/sandropaganotti/RMU/hunspell/hunspell_it_dict/it_IT.aff'
    dic: '/Users/sandropaganotti/RMU/hunspell/hunspell_it_dict/it_IT.dic'
</code></pre>
<p><strong>Usage Example</strong></p>
<pre><code class="ruby">module Hunspell
    LIBRARY_PATH = '/path/to/your/hunspell.lib'
end
require 'yaml'
require 'lib/hunspell'
hunspell = Hunspell::Hunspell.new(Yaml.load(File.read('config.yml')))
require 'lib/hunspell'
hunspell.respawn_handler 'it'
hunspell.suggest 'spagtti'
=&gt; ["spaghetti", "spaginati", "spagliati", "spaghetto"]
</code></pre>
<p>And that&#8217;s it! You can find the source code of this library <a title="Ruby Spell Doctor Homepage" href="https://github.com/sandropaganotti/ruby_spell_doctory" target="_blank">on my github account</a>; hope it may be useful!</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2010/11/25/ruby-spell-doctor-a-ruby-binding-to-hunspell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Abacus, Pierre Hérigone e la mnemotecnica</title>
		<link>http://sandropaganotti.com/2010/02/28/abacus-pierre-herigone-e-la-mnemotecnica/</link>
		<comments>http://sandropaganotti.com/2010/02/28/abacus-pierre-herigone-e-la-mnemotecnica/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 16:31:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Librerie]]></category>
		<category><![CDATA[abacus]]></category>
		<category><![CDATA[Hérigone]]></category>
		<category><![CDATA[mnemotecnica]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=306</guid>
		<description><![CDATA[Ho recentemente acquistato un libro che mi stà regalando una serie di spunti per interessanti approfondimenti e delle simpatiche occasioni per scrivere due righe di codice. Il libro in questione si chiama &#8220;Enigmi e giochi matematici&#8221; di Martin Gardner e raccoglie gli articoli che lo stesso Martin pubblicò negli anni sulla rivista Scientific American. Il [...]]]></description>
			<content:encoded><![CDATA[<p>Ho recentemente acquistato un libro che mi stà regalando una serie di spunti per interessanti approfondimenti e delle simpatiche occasioni per scrivere due righe di codice. Il libro in questione si chiama &#8220;<a href="http://www.ibs.it/code/9788817127479/gardner-martin/enigmi-giochi-matematici.html" target="_blank">Enigmi e giochi matematici</a>&#8221; di <a href="http://it.wikipedia.org/wiki/Martin_Gardner" target="_blank">Martin Gardner</a> e raccoglie gli articoli che lo stesso Martin pubblicò negli anni sulla rivista Scientific American.</p>
<p><span id="more-306"></span></p>
<p>Il capitolo numero 11 tratta di mnemotecnica, la disciplina che studia il modo di memorizzare lunghe sequenze di numeri, e tratta del metodo di <a href="http://en.wikipedia.org/wiki/Herigone%27s_mnemonic_system" target="_blank">Pierre Hérigone</a>, che può essere riassunto nel seguente modo:</p>
<ol>
<li>Associa le cifre del numero che vuoi memorizzare a delle consonanti secondo <a href="http://it.wikipedia.org/wiki/Mnemotecnica#La_conversione_fonetica" target="_blank">una tabella nota</a>; ad esempio la temperatura di ebollizione del mercurio, 357°C, diverrebbe mlk;</li>
<li>Trova una parola che contenga quelle consonanti in quell&#8217;ordine (senza altre &#8216;consonanti di disturbo in mezzo&#8217;); ad esempio per mlk andrebbe benissimo milk, mentre non andrebbe bene multik;</li>
<li>Associa la parola appena trovata ad una frase che in qualche modo leghi con il significato originario della cifra, possibilmente in modo che la frase risultante contenga uno stimolo visuale; ad esempio si può immaginare un allevatore stupito dal fatto che le sue mucche producano mercurio invece che latte.</li>
<li>Se la cifra dovesse essere molto lunga utilizza una sequenza di più parole seguendo lo schema appena descritto.</li>
</ol>
<p>Nel tempo libero stò cercando di trasporre questi quattro semplici passaggi all&#8217;interno di una gemma: <a href="http://rubygems.org/gems/abacus" target="_blank">abacus</a>, della quale ho rilasciato giusto oggi la versione 0.0.1; vediamo come si usa:</p>
<pre><code class="ruby">&gt;&gt; require 'abacus'
=&gt; true
&gt;&gt; include Abacus
=&gt; Object
&gt;&gt; number = HerigoneNumber.find_by_number(357)
=&gt; #&lt;Abacus::HerigoneNumber id: 19081, system: "default", number: 357&gt;
&gt;&gt; number.article_keys.map{|article_key| article_key.the_key}
=&gt; ["hemlock", "milk", "milky"]
</code></pre>
<p>Per poter funzionare Abacus utilizza un database sqllite che crea all&#8217;interno della cartella home dell&#8217;utente (il percorso in realtà è configurabile, ma per questi dettagli vi rimando <a href="http://github.com/sandropaganotti/Abacus/blob/master/README.markdown" target="_blank">alle note di installazione su github</a>) e nel quale struttura il/i dizionari di riferimento.</p>
<p>Abacus implementa un parser (molto base ad oggi) <a href="http://xdxf.sourceforge.net/" target="_blank">XDXF</a>, un formato open per la memorizzazione di dizionari: esistono già parecchie opere convertite più o meno bene in questo formato che possono essere <a href="http://xdxf.revdanica.com/down/" target="_blank">scaricate gratuitamente</a>, io ad esempio ho utilizzato <a href="http://downloads.sourceforge.net/xdxf/comn_sdict05_eng_eng_main.tar.bz2" target="_blank">questo dizionario base di inglese</a>:</p>
<pre><code># da shell:
sudo gem install abacus
wget http://downloads.sourceforge.net/xdxf/comn_sdict05_eng_eng_main.tar.bz2
tar -xjvf comn_sdict05_eng_eng_main.tar.bz2
abacus db:create
abacus db:xdxf:import  eng_eng_main/dict.xdxf
abacus db:herigone:generate
</code></pre>
<p>La sfida più interessante di questo piccolo progetto è stata mantenere delle performances adeguate durante la sessione di traduzione numero -&gt; parola, per fare questo in fase di import (con il comando db:herigone:generate) la gemma traduce ogni lemma del dizionario nel suo corrispettivo numerico rendendo la fase di ricerca una semplice SELECT su di un campo indicizzato.</p>
<p>In futuro vorrei estendere questo piccolo progetto aggiungendo due funzionalità di aggregazione semantica: in caso di sequenze di cifre lunghe mi piacerebbe infatti includere un generatore di linguaggio naturale con l&#8217;obiettivo creare una frase che almento nell&#8217;apparenza manifesti una certa correttezza (sarebbe bellissimo tradurre le prima 1000 cifre del PI in uno strampalato poema no?). Sarebbe inoltre interessante utilizzare <a href="http://wordnet.princeton.edu/" target="_blank">wordnet</a> per ridurre la variabilità semantica delle singole parole trovate a quanto di più vicino ad una parola che serva da &#8216;rappresentante logico&#8217; per la cifra in ingresso (ad esempio per 357 il rappresentante logico sarebbe &#8216;mercurio&#8217;).</p>
<p>Nel frattempo, per chiunque fosse interessato, i sorgenti della gemma sono disponibili <a href="http://github.com/sandropaganotti/Abacus" target="_blank">sul mio account di GitHub</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2010/02/28/abacus-pierre-herigone-e-la-mnemotecnica/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby linguistic, Wordnet e LinkParser su Snow Leopard</title>
		<link>http://sandropaganotti.com/2010/02/03/ruby-linguistic-wordnet-e-linkparser-su-snow-leopard/</link>
		<comments>http://sandropaganotti.com/2010/02/03/ruby-linguistic-wordnet-e-linkparser-su-snow-leopard/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 22:46:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Librerie]]></category>
		<category><![CDATA[linguistics]]></category>
		<category><![CDATA[link parser]]></category>
		<category><![CDATA[link-grammar]]></category>
		<category><![CDATA[natural language generator]]></category>
		<category><![CDATA[natural language parser]]></category>
		<category><![CDATA[wordnet]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=292</guid>
		<description><![CDATA[Update, 05/02/10: Ecco il link alle slide della presentazione! Ringrazio tutti i partecipanti alla bellissima serata! Il prossimo giovedì (4 febbraio 2010) terrò un Lightning Talk al Ruby Social Club su alcuni strumenti interessanti che orbitano attorno al concetto di Natural Language Generation/Parsing. In particolare vedremo due librerie che consentono di interfacciarsi con  WordNet e [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update, 05/02/10: </strong>Ecco il <a title="Natural Languages and Ruby" href="http://prezi.com/hdlhowymuge2/" target="_blank">link alle slide della presentazione</a>! Ringrazio tutti i partecipanti alla bellissima serata!</p>
<p>Il prossimo giovedì (4 febbraio 2010) terrò un Lightning Talk al <a href="http://therubymine.com/2010/01/25/primo-ruby-social-club-del-2010/" target="_blank">Ruby Social Club</a> su alcuni strumenti interessanti che orbitano attorno al concetto di Natural Language Generation/Parsing. In particolare vedremo due librerie che consentono di interfacciarsi con  <a href="http://wordnet.princeton.edu/" target="_blank">WordNet</a> e <a href="http://www.link.cs.cmu.edu/link/" target="_blank">Link-Grammar</a>.</p>
<p>Non voglio svelare nulla dello speech in questo post (anche se sicuramente venerdi farò un update allegando le slide della presentazione) ma solamente fornire a coloro che lo ritengano utile le istruzioni su come installare tali librerie sul proprio Mac.</p>
<p><span id="more-292"></span></p>
<h3>WordNet</h3>
<p><strong>Update, 05/02/10:</strong> mi segnalano <a href="http://github.com/roja/words" target="_blank">Words</a>, un wrapper analogo a quello che presento nelle prossime righe ma decisamente più aggiornato, it worths a look.</p>
<p>Partiamo da WordNet; la prima cosa da fare è installare la gemma BerkleyDB, il che comporta in primis l&#8217;installazione dello stesso BDB, quindi il primo comando è:</p>
<pre><code>sudo port install db47
</code></pre>
<p>Fatto questo <a href="ftp://ftp.eenet.ee/pub/FreeBSD/distfiles/ruby/bdb-0.6.4.tar.gz" target="_blank">scarichiamo la versione vecchia della gemma BDB</a> (<a href="http://github.com/mattbauer/bdb" target="_blank">quella su GitHub</a> non va bene, hanno cambiato i nomi alle costanti), decomprimiamola e modifichiamo la chiamata alla funzione &#8216;have_library&#8217; nel file src/extconf.rb (riga 72 e riga 79) come segue:</p>
<pre><code>have_library("db-#{with_ver}", db_version)
</code></pre>
<p>lanciamo infine la compilazione e l&#8217;installazione della libreria con i comandi (da eseguire all&#8217;interno della cartella di BDB):</p>
<pre><code>sudo env ARCHFLAGS="-arch x86_64" ruby extconf.rb  -- --with-db-include=/opt/local/include/db46 --with-db-lib=/opt/local/lib/db46 --with-db-version=4.6
make
sudo make install
</code></pre>
<p>Ok, ora installiamo la gemma di wordnet:</p>
<pre><code>sudo gem install wordnet
</code></pre>
<p>modifichiamo quindi il file &#8216;lib/wordnet/lexicon.rb&#8217; all&#8217;interno della gemma impostando alla riga 68 un path assoluto come ad esempio:</p>
<pre><code>DEFAULT_DB_ENV = File::join( '/Library/Ruby/Gems/1.8/gems/wordnet-0.0.5/ruby-wordnet' )
</code></pre>
<p>A questo punto non ci resta che  scaricare e convertire il database di wordnet nel formato BDB richiesto dalla gemma, per fare questo recuperiamo <a href="http://wordnetcode.princeton.edu/3.0/WordNet-3.0.tar.gz" target="_blank">l&#8217;ultima versione di wordnet disponibile</a> e decomprimiamola. Poi eseguiamo da linea di comando lo script presente nella cartella della gemma &#8216;convertdb.db&#8217; e, quando ci viene chiesto, inseriamo il percorso assoluto alla cartella &#8216;dict&#8217; all&#8217;interno dell&#8217;archivio di wordnet appena decompresso.<br />
Testiamo il funzionamento del tutto eseguendo questo semplice script:</p>
<pre><code class="ruby">require 'rubygems'
require 'wordnet'
include WordNet::Constants

lex     = WordNet::Lexicon::new
origins = lex.lookup_synsets( "house", Noun )
puts "#{(o=origins.first).words}: #{o.lex_info}"
[:meronyms,:hypernyms,:derivations,:hyponyms].each do |m|
  puts "#{m}: #{o.send(m).map{|s| s.words}.flatten.uniq.join(",")}"
end</code></pre>
<h3>Link Grammar</h3>
<p>Installiamo link grammar usando i MacPort:</p>
<pre><code>sudo port install link-grammar</code></pre>
<p>quindi <a href="http://deveiate.org/projects/Ruby-LinkParser" target="_blank">scarichiamo il sorgente della gemma</a> che fungerà da wrapper e decomprimiamolo in una cartella a nostro piacimento. Dall&#8217;interno di questa cartella compiliamo ed installiamo la gemma con questi comandi:</p>
<pre><code>ARCHFLAGS="-arch x86_64" rake --  --with-link-grammar-include=/opt/local/include/link-grammar --with-link-grammar-lib=/opt/local/lib
sudo rake install
</code></pre>
<p>Testiamo anche questa installazione eseguendo questo piccolo script:</p>
<pre><code class="ruby">require 'rubygems'
require 'linkparser'

dict = LinkParser::Dictionary.new('en')
sent = dict.parse( "People use Ruby for all kinds of nifty things." )

puts sent.subject
puts sent.verb
puts sent.object
</code></pre>
<h3>Linguistic</h3>
<p>Questa gemma funziona un pò da meta-wrapper raggruppando le funzionalità delle due gemme finora installate in un unico e omogeneo set di API. Installiamola con rubygems:</p>
<pre><code>sudo gem install linguistics</code></pre>
<p>quindi modifichiamo il file &#8216;lib/linguistics/en/linkparser.rb&#8217; all&#8217;interno della cartella dove risiede la gemma sistemando la riga 90 come segue:</p>
<pre><code>return @lp_dict ||= LinkParser::Dictionary.new('en', :verbosity =&gt; 0 )
</code></pre>
<p>Eseguiamo quindi un piccolo script di prova per sancirne la riuscita installazione:</p>
<pre><code class="ruby">require 'rubygems'
require 'linguistics'

Linguistics::use( :en )
frase = "the cat chased a snake"

puts &lt;&lt;-EOS
  Sogg:        #{frase.en.sentence.subject}
  Verbo:       #{frase.en.sentence.verb}
  Comp.ogg:    #{frase.en.sentence.object}
  Verbo (inf): #{frase.en.sentence.verb.en.infinitive}
EOS
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2010/02/03/ruby-linguistic-wordnet-e-linkparser-su-snow-leopard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby e Gosu: un multiplayer a schermo condiviso</title>
		<link>http://sandropaganotti.com/2009/12/08/ruby-e-gosu-un-multiplayer-a-schermo-condiviso/</link>
		<comments>http://sandropaganotti.com/2009/12/08/ruby-e-gosu-un-multiplayer-a-schermo-condiviso/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 20:21:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[Librerie]]></category>
		<category><![CDATA[Gosu]]></category>
		<category><![CDATA[multiplayer]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=246</guid>
		<description><![CDATA[Tutto è nato da una bellissima presentazione che ho seguito ormai quasi un anno fa: si parla dell&#8217;Euruko 2009 in quel di Barcellona; lo speech in oggetto si intitolava &#8216;Fun with ruby (and without r***s). Program your own games with gosu&#8216; e trattava di una libreria per lo sviluppo di giochi scritta in Ruby chiamata [...]]]></description>
			<content:encoded><![CDATA[<p>Tutto è nato da una bellissima presentazione che ho seguito ormai quasi un anno fa: si parla dell&#8217;Euruko 2009 in quel di Barcellona; lo speech in oggetto si intitolava <a href="http://app.euruko2009.org/talks/9-fun-with-ruby-and-without-r-s-program-your-own-games-with-gosu" target="_blank">&#8216;Fun with ruby (and without r***s). Program your own games with gosu</a>&#8216; e trattava di una libreria per lo sviluppo di giochi scritta in Ruby chiamata <a href="http://code.google.com/p/gosu/" target="_blank">Gosu</a>.</p>
<p><span id="more-246"></span></p>
<p>Per tutta una serie di impegni/dimenticanze/ritardi/&#8230; non sono più riuscito ad avvicinarmi a Gosu anche se le sue potenzialità sembravano quantomeno interessanti; oggi approfittando del piovoso ponte lavorativo  mi sono cimentato nella stesura di  una piccolissima applicazione (non la si può nemmeno chiamare gioco) che gestisca, su un unico schermo, una moltitudine di client associando ad ognuno di essi uno sprite e consentendogli di pilotarlo con dei semplici comandi.</p>
<p>In questa proof-of-concept ogni client può connettersi alla porta 8888 del server e dialogando in TCP può pilotare il proprio areo da caccia sullo schermo dell&#8217;applicazione; la sintassi del messaggio è semplicissima:</p>
<pre><code>codice_client|comando</code></pre>
<p>I comandi supportati sono, al momento, solo &#8216;left&#8217;, &#8216;right&#8217;, &#8216;close&#8217; e &#8216;welcome&#8217; ma ben presto introdurrò almeno &#8216;shot&#8217; per consentire all&#8217;areo di difendersi dai (futuri) nemici. L&#8217;intera implementazione è come al solito presente sul mio <a href="http://github.com/sandropaganotti/Gosu-Multiplayer-Shared-Screen" target="_blank">account di github</a>; a seguire invece uno screenshot dell&#8217;applicazione con due client connessi:</p>
<div id="attachment_248" class="wp-caption aligncenter" style="width: 650px"><img class="size-full wp-image-248" title="Multiplayer, shared screen" src="http://sandropaganotti.com/wp-content/uploads/2009/12/ishot-55.png" alt="Ogni aereo è controllato da un client diverso" width="640" height="502" /><p class="wp-caption-text">Ogni aereo è controllato da un client diverso</p></div>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2009/12/08/ruby-e-gosu-un-multiplayer-a-schermo-condiviso/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Prime prove con WebKit e WebGL</title>
		<link>http://sandropaganotti.com/2009/11/16/webkit-firefox-e-webgl/</link>
		<comments>http://sandropaganotti.com/2009/11/16/webkit-firefox-e-webgl/#comments</comments>
		<pubDate>Mon, 16 Nov 2009 21:14:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Librerie]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[WebGL]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=233</guid>
		<description><![CDATA[Dal 19 ottobre i nightly builds di Webkit (e anche di Firefox credo) offrono il supporto per le interessantissime estensioni Javascript WebGL. Da quanto ho appreso nel tutorial sembra che il set di API ricalchi abbastanza fedelmente quello delle note OpenGL ES 2.0. Scaricando il primo esempio e dandogli una veloce occhiata mi è sembrato [...]]]></description>
			<content:encoded><![CDATA[<p>Dal 19 ottobre i nightly builds di Webkit (e anche di Firefox credo) <a href="http://webkit.org/blog/603/webgl-now-available-in-webkit-nightlies/" target="_blank">offrono il supporto per le interessantissime estensioni Javascript WebGL</a>. Da quanto ho appreso nel tutorial sembra che il set di API ricalchi abbastanza fedelmente quello delle note OpenGL ES 2.0.</p>
<p><span id="more-233"></span></p>
<p>Scaricando il primo esempio e dandogli una veloce occhiata mi è sembrato tutto abbastanza lineare e comprensibile, dopo pochissimo sono riuscito senza particolari problemi ad individuare il punto di loading della texture e a modificarlo come segue:</p>
<p><img class="aligncenter size-full wp-image-234" title="Primi esperimenti con WebGL" src="http://sandropaganotti.com/wp-content/uploads/2009/11/ishot-45.png" alt="Primi esperimenti con WebGL" width="587" height="648" /></p>
<p>Ora stò importando <a href="http://jquery.com/" target="_blank">JQuery</a>, il prossimo passo è utilizzare questa famosissima libreria per recuperare alcune immagini dalla <a href="http://www.flickr.com/photos/22085175@N02/" target="_blank">mia gallery di Flickr</a> e mostrarle sul cubo.</p>
<p>Stay Tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2009/11/16/webkit-firefox-e-webgl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Face recognition con Ruby e OpenCV</title>
		<link>http://sandropaganotti.com/2009/06/07/face-recognition-con-ruby-e-opencv/</link>
		<comments>http://sandropaganotti.com/2009/06/07/face-recognition-con-ruby-e-opencv/#comments</comments>
		<pubDate>Sun, 07 Jun 2009 14:31:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[Librerie]]></category>
		<category><![CDATA[HaarClassifier]]></category>
		<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[Riconoscimento Facciale]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=159</guid>
		<description><![CDATA[Update &#8211; 18/06 : ieri sera ho tenuto una presentazione su questo tema al Ruby Social Club: ne approfitto quindi per aggiornare questo post con il link alle slide che ho utilizzato. Negli ultimi mesi sono emerse le prime applicazioni che fanno uso di algoritmi di riconoscimento oggetti e, più specificatamente, volti. Cito, ad esempio, Picasa [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update &#8211; 18/06 : </strong>ieri sera ho tenuto una presentazione su questo tema al <a href="http://blog.mikamai.com/2009/06/face-recognition-con-ruby-e-opencv/">Ruby Social Club</a>: ne approfitto quindi per aggiornare questo post con il <a href="http://prezi.com/102921">link alle slide che ho utilizzato</a>.</p>
<p>Negli ultimi mesi sono emerse le prime applicazioni che fanno uso di algoritmi di riconoscimento oggetti e, più specificatamente, volti. Cito, ad esempio, Picasa ed il filtro per visionare solo le facce in Google Images ma la lista di chi ha deciso di incorporare al suo interno questa funzionalità è decisamente più lunga.</p>
<p>Mi sono interessato subito al lato tecnico di questa nuova feature (grazie anche ad un <a href="http://app.euruko2009.org/talks/10-who-needs-photoshop-creative-image-manipulation-and-processing-using-ruby-to-do-image-recognition-movie-decomposition-and-more">ottimo speech</a> ascoltato all&#8217;<a href="http://www.euruko2009.org/">Erukuo 2009</a>) imbattendomi in un <a href="http://opencv.willowgarage.com/wiki/FaceDetection">particolare classificatore</a> chiamato &#8216;cascade of boosted classifiers working with haar-like features&#8217; che funziona nel seguente modo:</p>
<p><span id="more-159"></span></p>
<ol>
<li>Attraverso un training set viene generato un descrittore delle variazioni  di contrasto più comuni per un particolare oggetto (contrasto e orientamento);</li>
<li>Tale descrittore, che intrinsecamente ha una sua dimensione (quella delle immagini con le quali è stato creato), viene fatto scorrere sull&#8217;imagine da identificare ridimensionandolo ad ogni passaggio (in modo da &#8216;intercettare&#8217; possibili oggetti anche di dimensioni diverse rispetto a quelle del training set);</li>
<li>Il descrittore presenta a sua volta una struttura &#8216;incrementale&#8217; nella quale esso è composto da una sequenza di filtri che vengono verificati in sequenza sulla regione di interesse finche un filtro non fallisce o tutti i filtri passano, certificando in questo modo il match.</li>
<li>Ogni filtro è, concludendo, creato da una serie di operazioni basilari, che vengono anch&#8217;esse applicate in sequenza sulla regione di interesse; il risultato in questo caso è misurato pesando i risultati delle singole operazioni.</li>
</ol>
<p>Sfruttando<a href="http://github.com/bantic/image_labs/blob/f9c0a602347acf77392234a5c8d58265028f4387/lib/facer/facer.rb"> un esempio</a> creato da <a href="http://coryforsyth.com/">Cory Forsyth</a> ho costruito un face detector &#8216;seriale&#8217;, capace di applicare più descrittori su più immagini, creando in output una pagina html che evidenzi, per ogni immagine, le aree riconosciute come appartenenti ad un oggetto.</p>
<p>Ecco il codice:</p>
<pre><code class="ruby">
require 'rubygems'
require 'opencv'

face_detectors = %w(
  /usr/local/share/opencv/haarcascades/haarcascade_frontalface_default.xml
  # inserire qui l'elenco dei descrittori da utilizzare
).collect { |fd| OpenCV::CvHaarClassifierCascade::load(fd) }

file_names =  Dir.glob(ARGV[0] || "/Users/sandro/Ruby/image_labs/lib/facer/euruko2/*.jpg") 

file_names.each_with_index do |file_name,i|

  face_rectangles = []
  opencv_load = OpenCV::IplImage.load(file_name)
  face_detectors.each_with_index do |face_detector,k|
    face_detector.detect_objects(opencv_load).each do |rect|
      face_rectangles &lt;&lt; [
        rect.top_left.x,      rect.top_left.y,
        rect.top_right.x    - rect.top_left.x,
        rect.bottom_left.y  - rect.top_left.y
      ]
    end
  end

  File.open("#{File.basename(file_name)}.html","w") do |file|
    file.write &lt;&lt;-HTML
      &lt;html&gt;
         &lt;body style="margin:0px; background: url('file://#{file_name}') no-repeat top left;"&gt;
          #{  face_rectangles.collect do |(x,y,w,h)|
                " &lt;div class=\"face\" style=\"position: absolute; left: #{x}px;
                  top: #{y}px; width: #{w}px; height: #{h}px; border: 2px solid red; \"&gt;&lt;/div&gt;"
              end.join("\n") }
         &lt;/body&gt;
       &lt;/html&gt;
    HTML
  end

  puts "End #{file_name}"

end
</code></pre>
<p>Unico requisito per il corretto funzionamento del tutto è l&#8217;installazione di <a href="http://opencv.willowgarage.com/wiki/">OpenCV</a>, una libreria opensource che contiene una serie di strumenti dedicati alla &#8216;real time computer vision&#8217;, tra i quali figurano anche algoritmi di <a href="http://opencv.willowgarage.com/wiki/FaceRecognition">Face Recognition</a>. Installare OpenCV ed i necessari binding per Ruby non è esattamente una procedura semplicissima, l&#8217;intera sequenza è però ottimamente illustrata in <a href="http://github.com/bantic/ruby-opencv/tree/master">questo how-to</a>.</p>
<p>Chiudo questo post con un<a href="http://www.sandropaganotti.com/wp-content/facer/3517443572.jpg.html" target="_blank"> link ad una pagina htm</a>l generata utilizzando il programmino di cui sopra, potete notare come seppur il risultato in termini di riconoscimento sia ottimo vi siano pure dei falsi positivi. Una possibile tecnica di rimozione potrebbe essere modificare l&#8217;elenco dei descrittori, magari riducendolo,  in questo modo però si incorre nella possibilità di non individuare correttamente alcuni volti.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2009/06/07/face-recognition-con-ruby-e-opencv/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nabaztag e Playlist.com</title>
		<link>http://sandropaganotti.com/2008/12/21/nabaztag-e-playlistcom/</link>
		<comments>http://sandropaganotti.com/2008/12/21/nabaztag-e-playlistcom/#comments</comments>
		<pubDate>Sun, 21 Dec 2008 23:26:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Librerie]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[Nabaztag]]></category>
		<category><![CDATA[playlist.com]]></category>
		<category><![CDATA[scrubyt]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=80</guid>
		<description><![CDATA[Per chi ancora non conoscesse i due termini che compongono il titolo di questo articolo ecco una breve introduzione: Playlist.com Questo sito utilizza un motore di ricerca interno per indicizzare i file mp3 che trova nella rete, tali file vengono poi categorizzati utilizzando le informazioni disponibili (tag mp3, ecc..). Utilizzando una form di ricerca è [...]]]></description>
			<content:encoded><![CDATA[<p>Per chi ancora non conoscesse i due termini che compongono il titolo di questo articolo ecco una breve introduzione:</p>
<p><span id="more-80"></span></p>
<p><strong><a href="http://www.playlist.com" target="_blank">Playlist.com<br />
</a></strong>Questo sito utilizza un motore di ricerca interno per indicizzare i file mp3 che trova nella rete, tali file vengono poi categorizzati utilizzando le informazioni disponibili (tag mp3, ecc..). Utilizzando una form di ricerca è possibile ricercare tra i file indicizzati, ascoltarli e costruirsi una propria playlist che si può poi condividere con altre persone.</p>
<p><strong><a href="http://www.nabaztag.com" target="_blank">NabazTag</a></strong><br />
Il nabaztag è un gadget elettronico, dalla forma di un coniglio, capace di connettersi alla rete wireless domestica di intrattenere ospiti e residenti con tutta una serie di servizi vocali (text-to-speech, podcast, lettura di messaggi, email ed RSS, ecc.. ). Violet, la casa produttrice, ha ben pensato di mettere a disposizione di eventuali sviluppatori interessati <a href="http://doc.nabaztag.com/api/home.html" target="_blank">delle API con le quali interagire col coniglio</a>.</p>
<p><strong><a href="http://github.com/sandropaganotti/nabaztag-command-line-tool/tree/master">Nabaztag Command Line Tool</a><br />
</strong>Ho creato (<a href="http://github.com/sandropaganotti/nabaztag-command-line-tool/tree/master">e caricato su github</a>) uno script in Ruby che, dato l&#8217;identificativo di una playlist di playlist.com, si interfaccia con le API del nabaztag e, utilizzando apposite funzioni, fa in modo che il coniglio esegua l&#8217;intera playlist selezionata.</p>
<p>Fulcro di questo piccolissimo programma è una bellissima libreria di cui ho sentito parlare poco tempo fa: <a href="http://www.scrubyt.org">Scrubyt</a>. Scrubyt serve essenzialmente ad interagire con il web, questo comprende parsing di pagine HTML ma anche compilazione di form e click su link.</p>
<p>Per darvi un assaggio delle potenzialità di questa libreria vi allego il codice che ho usato per recupeare le informazioni sull&#8217;url dei vari file mp3, questi sono i passi:</p>
<ol>
<li>recuperare il file xml dall&#8217;indirizzo view.playlist.com/[id_playlist]/asx</li>
<li>estrarre per ogni nodo &#8216;entry&#8217; l&#8217;attributo href del tag ref</li>
</ol>
<pre><code class="ruby">
      playlist = Scrubyt::Extractor.define do
          fetch "http://view.playlist.com/#{params[0]}/asx"
          ele "//entry//ref" do
            mp3 "href", :type=&gt;:attribute
          end
      end
</code></pre>
<p>A questo punto nella variabile &#8216;playlist&#8217; avrò un elenco di hash ognuno di essi nella forma :mp3 =&gt; &#8216;url&#8217;.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2008/12/21/nabaztag-e-playlistcom/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Risolvere i Sudoku in Ruby con i Dancing Links: ruby-dlx</title>
		<link>http://sandropaganotti.com/2008/12/02/risolvere-i-sudoku-in-ruby-con-i-dancing-links-ruby-dlx/</link>
		<comments>http://sandropaganotti.com/2008/12/02/risolvere-i-sudoku-in-ruby-con-i-dancing-links-ruby-dlx/#comments</comments>
		<pubDate>Tue, 02 Dec 2008 21:40:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[Librerie]]></category>
		<category><![CDATA[Dancing Links]]></category>
		<category><![CDATA[Library]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=57</guid>
		<description><![CDATA[Ho appena effettuato il commit della prima release funzionante di ruby-dlx. Ruby dlx è una piccola libreria che implementa in Ruby l&#8217;algoritmo dei Dancing Links descritto nel post di settimana scorsa. Per rendere il tutto più utilizzabile ho inoltre allegato alla libreria anche un esempio: un piccolo programma che usando la matrice di costrizione spiegata [...]]]></description>
			<content:encoded><![CDATA[<p>Ho appena effettuato il commit della prima release funzionante di <a href="http://github.com/sandropaganotti/ruby-dlx/tree/master">ruby-dlx</a>. Ruby dlx è una piccola libreria che implementa in Ruby l&#8217;algoritmo dei Dancing Links descritto nel <a href="http://sandropaganotti.com/2008/11/23/knuth-e-i-dancing-links/">post di settimana scorsa</a>.</p>
<p><span id="more-57"></span></p>
<p>Per rendere il tutto più utilizzabile ho inoltre allegato alla libreria anche un esempio: un piccolo programma che usando la matrice di costrizione spiegata <a href="http://sandropaganotti.com/2008/11/14/un-algoritmo-per-creare-sudoku/">nell&#8217;articolo di due settimane fa</a> è capace di risolvere un Sudoku.</p>
<p>Potete trovare questo programma all&#8217;interno del mio repository di GitHub, nella sottocartella <a href="http://github.com/sandropaganotti/ruby-dlx/tree/master/examples/sudoku">examples/sudoku</a>; per eseguirlo lanciate il file sudoku.rb.</p>
<p>La settimana prossima proporrò un tutorial nel quale utilizzeremo questa libreria per risolvere  il famosissimo <a href="http://it.wikipedia.org/wiki/Rompicapo_delle_otto_regine">problema delle otto regine</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2008/12/02/risolvere-i-sudoku-in-ruby-con-i-dancing-links-ruby-dlx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

